diff --git a/DEPS b/DEPS index e065460..5c487ac 100644 --- a/DEPS +++ b/DEPS
@@ -253,19 +253,19 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'a83b8c6a78bd9ce39b621fa557e52e770269864f', + 'skia_revision': 'c6e373d47d5172544ed45dba717d1963bca743b5', # 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': '8ff9ed3e60e742ff412cf8dd5f16f6ed343fe809', + 'v8_revision': 'dbe4449b3e52cf1205dcf1ff05b721b0a180b638', # 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': 'c874943b952e4aa24ec1c37a5542e3bcb8c20fad', + 'angle_revision': '1e1505b53cf065466f21424b5279ace31570ff4c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '732515a031faeecfee06c821d9039ebabd6bb71e', + 'swiftshader_revision': '7021c484697491248e8336f1be45aa6d068a8b80', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -296,7 +296,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling NaCl # and whatever else without interference from each other. - 'nacl_revision': 'eb062b0b356274c74fe3f567d0165ad97a428ae1', + 'nacl_revision': 'ab384dc06c9b5bafd0f6ba74083cc67b5fdc16ed', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -368,7 +368,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': '420f4c9fae6773f41982c0fa1883804db995d3ed', + 'dawn_revision': '2335a974eff76ab3b396652f2a0f051f115ec08c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -1131,7 +1131,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'c1ab734908f09df3d4c6672acd66c0cfcd584114', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '6b28c1ddef177b44521ab5e8c438942c397a56d8', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1271,7 +1271,7 @@ Var('chromium_git') + '/chromium/deps/hunspell_dictionaries.git' + '@' + '18e09b9197a3b1d771c077c530d1a4ebad04c167', 'src/third_party/icu': - Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '901474b1806d6b5a068606006dbb4c08e9974353', + Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '1fa4e3959ec6637182b7318ac1d382799454806d', 'src/third_party/icu4j': { 'packages': [ @@ -1735,7 +1735,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '96e54a1b92e78f651941f64c703b98a34df37a1f', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'caf2063a9e8afbdec9af767395bbe74e69237ae3', + Var('webrtc_git') + '/src.git' + '@' + '48cda468aa2343731e252a821f926b05411a1603', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1805,7 +1805,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@b0e85070320af039efe9a4dd3be4f41375159ad2', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@dfd275583c7e04bb78054d2f10af210669d2a362', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/aw_contents.cc b/android_webview/browser/aw_contents.cc index 56e69c9..12d9709 100644 --- a/android_webview/browser/aw_contents.cc +++ b/android_webview/browser/aw_contents.cc
@@ -418,6 +418,18 @@ return render_process->GetJavaObject(); } +ScopedJavaLocalRef<jstring> AwContents::GetVariationsHeader(JNIEnv* env) { + const bool is_signed_in = false; + auto headers = + variations::VariationsIdsProvider::GetInstance()->GetClientDataHeaders( + is_signed_in); + if (!headers) + return ConvertUTF8ToJavaString(env, ""); + return ConvertUTF8ToJavaString( + env, + headers->headers_map.at(variations::mojom::GoogleWebVisibility::ANY)); +} + void AwContents::Destroy(JNIEnv* env) { java_ref_.reset(); delete this;
diff --git a/android_webview/browser/aw_contents.h b/android_webview/browser/aw_contents.h index d10b619e..9674bb99 100644 --- a/android_webview/browser/aw_contents.h +++ b/android_webview/browser/aw_contents.h
@@ -111,6 +111,7 @@ base::android::ScopedJavaLocalRef<jobject> GetRenderProcess( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); + base::android::ScopedJavaLocalRef<jstring> GetVariationsHeader(JNIEnv* env); void Destroy(JNIEnv* env); void DocumentHasImages(JNIEnv* env,
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/SharedWebViewChromium.java b/android_webview/glue/java/src/com/android/webview/chromium/SharedWebViewChromium.java index 9f0a2a0e..cd31a2af 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/SharedWebViewChromium.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/SharedWebViewChromium.java
@@ -174,6 +174,14 @@ return mContentsClientAdapter.getWebViewRendererClientAdapter(); } + public String getVariationsHeader() { + mAwInit.startYourEngines(true); + if (checkNeedsPost()) { + return mRunQueue.runOnUiThreadBlocking(() -> getVariationsHeader()); + } + return mAwContents.getVariationsHeader(); + } + protected boolean checkNeedsPost() { boolean needsPost = !mRunQueue.chromiumHasStarted() || !ThreadUtils.runningOnUiThread(); if (!needsPost && mAwContents == null) {
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index c165420..3020ed3 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -3512,6 +3512,13 @@ return AwContentsJni.get().getRenderProcess(mNativeAwContents, AwContents.this); } + public String getVariationsHeader() { + if (isDestroyed(NO_WARN)) { + return ""; + } + return AwContentsJni.get().getVariationsHeader(mNativeAwContents); + } + @VisibleForTesting public AwDisplayCutoutController getDisplayCutoutController() { return mDisplayCutoutController; @@ -4425,5 +4432,6 @@ WebMessageListenerInfo[] getJsObjectsInfo( long nativeAwContents, AwContents caller, Class clazz); void onConfigurationChanged(long nativeAwContents); + String getVariationsHeader(long nativeAwContents); } }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/VariationsHeadersTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/VariationsHeadersTest.java index d176ebb..9a94eaa 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/VariationsHeadersTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/VariationsHeadersTest.java
@@ -77,6 +77,14 @@ Assert.assertFalse(mTestServer.getLastRequest(PATH).headerValue(HEADER_NAME).isEmpty()); } + @MediumTest + @Test + public void testMatchesApiValue() throws Throwable { + mActivityTestRule.loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), mUrl); + String serverHeaderValue = mTestServer.getLastRequest(PATH).headerValue(HEADER_NAME); + Assert.assertEquals(serverHeaderValue, mAwContents.getVariationsHeader()); + } + @CommandLineFlags.Add({"disable-features=WebViewSendVariationsHeaders"}) @MediumTest @Test
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/CrashReceiverService.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/CrashReceiverService.java index 39c7329..79eb69cf 100644 --- a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/CrashReceiverService.java +++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/CrashReceiverService.java
@@ -25,6 +25,8 @@ import java.util.List; import java.util.Map; +import javax.annotation.concurrent.GuardedBy; + /** * Service that is responsible for receiving crash dumps from an application, for upload. */ @@ -32,6 +34,8 @@ private static final String TAG = "CrashReceiverService"; private final Object mCopyingLock = new Object(); + + @GuardedBy("mCopyingLock") private boolean mIsCopying; private final ICrashReceiverService.Stub mBinder = new ICrashReceiverService.Stub() {
diff --git a/android_webview/support_library/boundary_interfaces/BUILD.gn b/android_webview/support_library/boundary_interfaces/BUILD.gn index 3938d4e..348cbf57 100644 --- a/android_webview/support_library/boundary_interfaces/BUILD.gn +++ b/android_webview/support_library/boundary_interfaces/BUILD.gn
@@ -13,7 +13,6 @@ "src/org/chromium/support_lib_boundary/ProxyControllerBoundaryInterface.java", "src/org/chromium/support_lib_boundary/SafeBrowsingResponseBoundaryInterface.java", "src/org/chromium/support_lib_boundary/ScriptHandlerBoundaryInterface.java", - "src/org/chromium/support_lib_boundary/ScriptReferenceBoundaryInterface.java", "src/org/chromium/support_lib_boundary/ServiceWorkerClientBoundaryInterface.java", "src/org/chromium/support_lib_boundary/ServiceWorkerControllerBoundaryInterface.java", "src/org/chromium/support_lib_boundary/ServiceWorkerWebSettingsBoundaryInterface.java",
diff --git a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/ScriptHandlerBoundaryInterface.java b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/ScriptHandlerBoundaryInterface.java index 4dcaa75..0be98f8 100644 --- a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/ScriptHandlerBoundaryInterface.java +++ b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/ScriptHandlerBoundaryInterface.java
@@ -7,4 +7,6 @@ /** * Boundary interface for AwContents.addDocumentStartJavascript(). */ -public interface ScriptHandlerBoundaryInterface extends ScriptReferenceBoundaryInterface {} +public interface ScriptHandlerBoundaryInterface { + void remove(); +}
diff --git a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/ScriptReferenceBoundaryInterface.java b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/ScriptReferenceBoundaryInterface.java deleted file mode 100644 index aba822a..0000000 --- a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/ScriptReferenceBoundaryInterface.java +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.support_lib_boundary; - -/** - * Boundary interface for AwContents.addDocumentStartJavascript(). - * - * TODO(ctzsm): Delete this interface once we've updated the APKs on - * the AndroidX bots and move the remove method to ScriptHandlerBoundaryInterface. - */ -public interface ScriptReferenceBoundaryInterface { - void remove(); -}
diff --git a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebViewProviderBoundaryInterface.java b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebViewProviderBoundaryInterface.java index d524b31..c59afcf 100644 --- a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebViewProviderBoundaryInterface.java +++ b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebViewProviderBoundaryInterface.java
@@ -28,4 +28,5 @@ /* WebViewRendererClient */ InvocationHandler getWebViewRendererClient(); void setWebViewRendererClient( /* WebViewRendererClient */ InvocationHandler webViewRendererClient); + String getVariationsHeader(); }
diff --git a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java index 238e343..53fd95c1 100644 --- a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java +++ b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java
@@ -184,7 +184,7 @@ public static final String SET_SUPPORT_LIBRARY_VERSION = "SET_SUPPORT_LIBRARY_VERSION"; // WebViewCompat.addDocumentStartJavascript - public static final String DOCUMENT_START_SCRIPT = "DOCUMENT_START_SCRIPT"; + public static final String DOCUMENT_START_SCRIPT = "DOCUMENT_START_SCRIPT:1"; // WebSettingsCompat.setWebAuthnSupport // WebSettingsCompat.getWebAuthnSupport @@ -195,4 +195,7 @@ // ServiceWorkerWebSettingsCompat.setRequestedWithHeaderMode // ServiceWorkerWebSettingsCompat.getRequestedWithHeaderMode public static final String REQUESTED_WITH_HEADER_CONTROL = "REQUESTED_WITH_HEADER_CONTROL"; + + // WebViewCompat.getVariationsHeader + public static final String GET_VARIATIONS_HEADER = "GET_VARIATIONS_HEADER"; }
diff --git a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromium.java b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromium.java index 0b0dd257..a52884070 100644 --- a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromium.java +++ b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromium.java
@@ -135,4 +135,10 @@ ? new SupportLibWebViewRendererClientAdapter(webViewRendererClient) : null); } + + @Override + public String getVariationsHeader() { + recordApiCall(ApiCall.GET_VARIATIONS_HEADER); + return mSharedWebViewChromium.getVariationsHeader(); + } }
diff --git a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java index fb1a6e8..c26be720 100644 --- a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java +++ b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java
@@ -84,7 +84,8 @@ Features.SET_SUPPORT_LIBRARY_VERSION + Features.DEV_SUFFIX, Features.DOCUMENT_START_SCRIPT, Features.PROXY_OVERRIDE_REVERSE_BYPASS, - Features.REQUESTED_WITH_HEADER_CONTROL + Features.DEV_SUFFIX + Features.REQUESTED_WITH_HEADER_CONTROL + Features.DEV_SUFFIX, + Features.GET_VARIATIONS_HEADER + Features.DEV_SUFFIX }; // These values are persisted to logs. Entries should not be renumbered and @@ -148,7 +149,8 @@ ApiCall.WEB_SETTINGS_SET_REQUESTED_WITH_HEADER_MODE, ApiCall.WEB_SETTINGS_GET_REQUESTED_WITH_HEADER_MODE, ApiCall.SERVICE_WORKER_SETTINGS_SET_REQUESTED_WITH_HEADER_MODE, - ApiCall.SERVICE_WORKER_SETTINGS_GET_REQUESTED_WITH_HEADER_MODE}) + ApiCall.SERVICE_WORKER_SETTINGS_GET_REQUESTED_WITH_HEADER_MODE, + ApiCall.GET_VARIATIONS_HEADER}) public @interface ApiCall { int ADD_WEB_MESSAGE_LISTENER = 0; int CLEAR_PROXY_OVERRIDE = 1; @@ -210,8 +212,9 @@ int WEB_SETTINGS_GET_REQUESTED_WITH_HEADER_MODE = 57; int SERVICE_WORKER_SETTINGS_SET_REQUESTED_WITH_HEADER_MODE = 58; int SERVICE_WORKER_SETTINGS_GET_REQUESTED_WITH_HEADER_MODE = 59; + int GET_VARIATIONS_HEADER = 60; // Remember to update AndroidXWebkitApiCall in enums.xml when adding new values here - int COUNT = 60; + int COUNT = 61; } // clang-format on
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 74d22535..6cfa4e1b 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -1985,6 +1985,7 @@ "wm/wm_event.h", "wm/wm_highlight_item_border.cc", "wm/wm_highlight_item_border.h", + "wm/wm_metrics.h", "wm/wm_shadow_controller_delegate.cc", "wm/wm_shadow_controller_delegate.h", "wm/work_area_insets.cc",
diff --git a/ash/accelerators/accelerator_controller_impl.cc b/ash/accelerators/accelerator_controller_impl.cc index fb8aa89..a3eb71c 100644 --- a/ash/accelerators/accelerator_controller_impl.cc +++ b/ash/accelerators/accelerator_controller_impl.cc
@@ -79,6 +79,7 @@ #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" +#include "ash/wm/wm_metrics.h" #include "base/bind.h" #include "base/callback_helpers.h" #include "base/command_line.h" @@ -901,7 +902,11 @@ : WM_EVENT_CYCLE_SNAP_SECONDARY); aura::Window* active_window = window_util::GetActiveWindow(); DCHECK(active_window); - WindowState::Get(active_window)->OnWMEvent(&event); + + auto* window_state = WindowState::Get(active_window); + window_state->set_snap_action_source( + WindowSnapActionSource::kKeyboardShortcutToSnap); + window_state->OnWMEvent(&event); } void HandleWindowMinimize() {
diff --git a/ash/ash_prefs.cc b/ash/ash_prefs.cc index b53bed43..780fb04 100644 --- a/ash/ash_prefs.cc +++ b/ash/ash_prefs.cc
@@ -44,6 +44,7 @@ #include "ash/system/unified/hps_notify_controller.h" #include "ash/system/unified/top_shortcuts_view.h" #include "ash/system/unified/unified_system_tray_controller.h" +#include "ash/system/usb_peripheral/usb_peripheral_notification_controller.h" #include "ash/touch/touch_devices_controller.h" #include "ash/wallpaper/wallpaper_controller_impl.h" #include "ash/wm/desks/desks_restore_util.h" @@ -100,6 +101,7 @@ tray::VPNListView::RegisterProfilePrefs(registry); UnifiedSystemTrayController::RegisterProfilePrefs(registry); MediaTray::RegisterProfilePrefs(registry); + UsbPeripheralNotificationController::RegisterProfilePrefs(registry); WallpaperControllerImpl::RegisterProfilePrefs(registry); WindowCycleController::RegisterProfilePrefs(registry);
diff --git a/ash/components/cryptohome/userdataauth_util.cc b/ash/components/cryptohome/userdataauth_util.cc index b5623aa..ea4932c 100644 --- a/ash/components/cryptohome/userdataauth_util.cc +++ b/ash/components/cryptohome/userdataauth_util.cc
@@ -65,6 +65,10 @@ template COMPONENT_EXPORT(ASH_COMPONENTS_CRYPTOHOME) CryptohomeErrorCode ReplyToCryptohomeError(const absl::optional<AddCredentialsReply>&); template COMPONENT_EXPORT(ASH_COMPONENTS_CRYPTOHOME) CryptohomeErrorCode + ReplyToCryptohomeError(const absl::optional<AuthenticateAuthFactorReply>&); +template COMPONENT_EXPORT(ASH_COMPONENTS_CRYPTOHOME) CryptohomeErrorCode + ReplyToCryptohomeError(const absl::optional<AddAuthFactorReply>&); +template COMPONENT_EXPORT(ASH_COMPONENTS_CRYPTOHOME) CryptohomeErrorCode ReplyToCryptohomeError(const absl::optional<UnmountReply>&); std::vector<cryptohome::KeyDefinition> GetKeyDataReplyToKeyDefinitions(
diff --git a/ash/constants/ash_pref_names.cc b/ash/constants/ash_pref_names.cc index 166abae..c1544f8 100644 --- a/ash/constants/ash_pref_names.cc +++ b/ash/constants/ash_pref_names.cc
@@ -780,6 +780,11 @@ // Ignored unless powerd is configured to honor charging-related prefs. const char kUsbPowerShareEnabled[] = "ash.power.usb_power_share_enabled"; +// A bool pref to block the USB-C cable limiting device speed notification if it +// has already been clicked by the user. +const char kUsbPeripheralCableSpeedNotificationShown[] = + "ash.usb_peripheral_cable_speed_notification_shown"; + // An integer pref that specifies how many times the Suggested Content privacy // info has been shown in Launcher. This value will increment by one every time // when Launcher changes state from Peeking to Half or FullscreenSearch up to a
diff --git a/ash/constants/ash_pref_names.h b/ash/constants/ash_pref_names.h index d7027cb4..f9dd68d 100644 --- a/ash/constants/ash_pref_names.h +++ b/ash/constants/ash_pref_names.h
@@ -355,6 +355,9 @@ COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kUsbPowerShareEnabled[]; COMPONENT_EXPORT(ASH_CONSTANTS) +extern const char kUsbPeripheralCableSpeedNotificationShown[]; + +COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kSuggestedContentInfoShownInLauncher[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kSuggestedContentInfoDismissedInLauncher[];
diff --git a/ash/drag_drop/tab_drag_drop_delegate.cc b/ash/drag_drop/tab_drag_drop_delegate.cc index 4d650ba..ef6f5bec 100644 --- a/ash/drag_drop/tab_drag_drop_delegate.cc +++ b/ash/drag_drop/tab_drag_drop_delegate.cc
@@ -18,6 +18,7 @@ #include "ash/wm/splitview/split_view_drag_indicators.h" #include "ash/wm/splitview/split_view_utils.h" #include "ash/wm/tablet_mode/tablet_mode_browser_window_drag_session_windows_hider.h" +#include "ash/wm/wm_metrics.h" #include "base/pickle.h" #include "base/strings/utf_string_conversions.h" #include "chromeos/crosapi/cpp/lacros_startup_state.h" @@ -224,6 +225,8 @@ snap_position) { overview_session->MergeWindowIntoOverviewForWebUITabStrip(new_window); } else { + WindowState::Get(new_window) + ->set_snap_action_source(WindowSnapActionSource::kDragTabToSnap); split_view_controller->SnapWindow(new_window, snap_position, /*activate_window=*/true); } @@ -243,6 +246,8 @@ // |source_window_| is itself a child window of the browser since it // hosts web content (specifically, the tab strip WebUI). Snap its // toplevel window which is the browser window. + WindowState::Get(new_window) + ->set_snap_action_source(WindowSnapActionSource::kDragTabToSnap); split_view_controller->SnapWindow(source_window_, opposite_position); }
diff --git a/ash/frame/snap_controller_impl.cc b/ash/frame/snap_controller_impl.cc index b21005b..79080ad 100644 --- a/ash/frame/snap_controller_impl.cc +++ b/ash/frame/snap_controller_impl.cc
@@ -64,6 +64,9 @@ return; WindowState* window_state = WindowState::Get(window); + window_state->set_snap_action_source( + WindowSnapActionSource::kUseCaptionButtonToSnap); + const WMEvent snap_event(snap == chromeos::SnapDirection::kPrimary ? WM_EVENT_SNAP_PRIMARY : WM_EVENT_SNAP_SECONDARY);
diff --git a/ash/quick_pair/message_stream/message_stream_lookup_impl.cc b/ash/quick_pair/message_stream/message_stream_lookup_impl.cc index c4c1d16b..9007ce1 100644 --- a/ash/quick_pair/message_stream/message_stream_lookup_impl.cc +++ b/ash/quick_pair/message_stream/message_stream_lookup_impl.cc
@@ -225,8 +225,8 @@ base::TimeTicks connect_to_service_start_time, const CreateMessageStreamAttemptType& type, scoped_refptr<device::BluetoothSocket> socket) { - QP_LOG(VERBOSE) << __func__ << ": device = " << device_address - << " Type = " << CreateMessageStreamAttemptTypeToString(type); + QP_LOG(INFO) << __func__ << ": device = " << device_address + << " Type = " << CreateMessageStreamAttemptTypeToString(type); RecordMessageStreamConnectToServiceResult(/*success=*/true); RecordMessageStreamConnectToServiceTime(base::TimeTicks::Now() - connect_to_service_start_time); @@ -246,8 +246,8 @@ // Because we need to attempt to create MessageStreams at many different // iterations due to the variability of Bluetooth APIs, we can expect to // see errors here frequently, along with errors followed by a success. - QP_LOG(VERBOSE) << __func__ << ": Error = [ " << error_message << "]. Type = " - << CreateMessageStreamAttemptTypeToString(type); + QP_LOG(INFO) << __func__ << ": Error = [ " << error_message + << "]. Type = " << CreateMessageStreamAttemptTypeToString(type); RecordMessageStreamConnectToServiceResult(/*success=*/false); RecordMessageStreamConnectToServiceError(error_message); }
diff --git a/ash/quick_pair/pairing/fast_pair/fast_pair_pairer_impl.cc b/ash/quick_pair/pairing/fast_pair/fast_pair_pairer_impl.cc index de5b8b9..765f633 100644 --- a/ash/quick_pair/pairing/fast_pair/fast_pair_pairer_impl.cc +++ b/ash/quick_pair/pairing/fast_pair/fast_pair_pairer_impl.cc
@@ -215,7 +215,7 @@ // will not be able to find the device this way, and we will have to // connect via address and add ourselves as a pairing delegate. - QP_LOG(VERBOSE) << "Key-based pairing changed. Address: " + QP_LOG(VERBOSE) << "Sending pair request to device. Address: " << device_address << ". Found device: " << ((bt_device != nullptr) ? "Yes" : "No") << "."; @@ -229,7 +229,8 @@ PAIRING_DELEGATE_PRIORITY_HIGH); adapter_->ConnectDevice( - device_address, /*address_type=*/absl::nullopt, + device_address, + device::BluetoothDevice::AddressType::ADDR_TYPE_PUBLIC, base::BindOnce(&FastPairPairerImpl::OnConnectDevice, weak_ptr_factory_.GetWeakPtr()), base::BindOnce(&FastPairPairerImpl::OnConnectError,
diff --git a/ash/quick_pair/pairing/retroactive_pairing_detector_impl.cc b/ash/quick_pair/pairing/retroactive_pairing_detector_impl.cc index da42ca5..f747040 100644 --- a/ash/quick_pair/pairing/retroactive_pairing_detector_impl.cc +++ b/ash/quick_pair/pairing/retroactive_pairing_detector_impl.cc
@@ -65,6 +65,10 @@ return; } + // If we get to this point in the constructor, it means that the user is + // logged in to enable this scenario, so we can being our observations. If we + // get any log in events, we know to ignore them, since we already + // instantiated our retroactive pairing detector. retroactive_pairing_detector_instatiated_ = true; device::BluetoothAdapterFactory::Get()->GetAdapter(
diff --git a/ash/shelf/drag_window_from_shelf_controller.cc b/ash/shelf/drag_window_from_shelf_controller.cc index 27f5f8c..ca01761 100644 --- a/ash/shelf/drag_window_from_shelf_controller.cc +++ b/ash/shelf/drag_window_from_shelf_controller.cc
@@ -422,6 +422,8 @@ SplitViewController::Get(Shell::GetPrimaryRootWindow()); if (split_view_controller->InSplitViewMode() || snap_position != SplitViewController::NONE) { + WindowState::Get(window_)->set_snap_action_source( + WindowSnapActionSource::kDragUpFromShelfToSnap); split_view_controller->OnWindowDragEnded( window_, snap_position, gfx::ToRoundedPoint(location_in_screen)); }
diff --git a/ash/system/toast/toast_manager_unittest.cc b/ash/system/toast/toast_manager_unittest.cc index d26bb68..994c7a6d 100644 --- a/ash/system/toast/toast_manager_unittest.cc +++ b/ash/system/toast/toast_manager_unittest.cc
@@ -514,16 +514,8 @@ EXPECT_EQ(3, GetToastSerial()); } -// TODO(crbug.com/1298361): Flakes on CrOS. -#if BUILDFLAG(IS_CHROMEOS) -#define MAYBE_ReplaceContentsOfCurrentToastBeforePriorReplacementFinishes \ - DISABLED_ReplaceContentsOfCurrentToastBeforePriorReplacementFinishes -#else -#define MAYBE_ReplaceContentsOfCurrentToastBeforePriorReplacementFinishes \ - ReplaceContentsOfCurrentToastBeforePriorReplacementFinishes -#endif TEST_F(ToastManagerImplTest, - MAYBE_ReplaceContentsOfCurrentToastBeforePriorReplacementFinishes) { + ReplaceContentsOfCurrentToastBeforePriorReplacementFinishes) { // By default, the animation duration is zero in tests. Set the animation // duration to non-zero so that toasts don't immediately close. ui::ScopedAnimationDurationScaleMode animation_duration( @@ -555,7 +547,7 @@ // Cancel the shown toast and wait for the animation to finish. CancelToast(id1); - task_environment()->FastForwardBy(base::Seconds(1)); + task_environment()->FastForwardBy(base::Seconds(2)); // Confirm that the toast now showing corresponds with id2. EXPECT_EQ(u"TEXT2", GetCurrentText());
diff --git a/ash/system/usb_peripheral/usb_peripheral_notification_controller.cc b/ash/system/usb_peripheral/usb_peripheral_notification_controller.cc index e34b239..149e789 100644 --- a/ash/system/usb_peripheral/usb_peripheral_notification_controller.cc +++ b/ash/system/usb_peripheral/usb_peripheral_notification_controller.cc
@@ -4,12 +4,15 @@ #include "ash/system/usb_peripheral/usb_peripheral_notification_controller.h" +#include "ash/constants/ash_pref_names.h" #include "ash/public/cpp/new_window_delegate.h" #include "ash/public/cpp/notification_utils.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/session/session_controller_impl.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/cros_system_api/dbus/typecd/dbus-constants.h" #include "ui/base/l10n/l10n_util.h" @@ -37,6 +40,18 @@ const char kNotificationDeviceLandingPageUrl[] = "https://support.google.com/chromebook?p=cable_notification_2"; +bool GetCableSpeedNotificationShownPref() { + PrefService* prefs = + Shell::Get()->session_controller()->GetActivePrefService(); + return prefs->GetBoolean(prefs::kUsbPeripheralCableSpeedNotificationShown); +} + +void SetCableSpeedNotificationShownPref(bool pref) { + PrefService* prefs = + Shell::Get()->session_controller()->GetActivePrefService(); + prefs->SetBoolean(prefs::kUsbPeripheralCableSpeedNotificationShown, pref); +} + bool ShouldDisplayNotification() { return Shell::Get()->session_controller()->GetSessionState() == session_manager::SessionState::ACTIVE && @@ -46,6 +61,9 @@ void OnCableNotificationClicked(const std::string& notification_id, const std::string& landing_page, absl::optional<int> button_index) { + if (notification_id == kUsbPeripheralSpeedLimitingCableNotificationId) + SetCableSpeedNotificationShownPref(true); + if (button_index) { NewWindowDelegate::GetInstance()->OpenUrl( GURL(landing_page), NewWindowDelegate::OpenUrlFrom::kUserInteraction); @@ -68,6 +86,13 @@ ash::PeripheralNotificationManager::Get()->RemoveObserver(this); } +// static +void UsbPeripheralNotificationController::RegisterProfilePrefs( + PrefRegistrySimple* registry) { + registry->RegisterBooleanPref( + prefs::kUsbPeripheralCableSpeedNotificationShown, false); +} + void UsbPeripheralNotificationController:: OnPeripheralNotificationManagerInitialized() { DCHECK(ash::PeripheralNotificationManager::IsInitialized()); @@ -207,7 +232,7 @@ // Notify the user that the cable limits USB device performance. void UsbPeripheralNotificationController::OnSpeedLimitingCableWarning() { - if (!ShouldDisplayNotification()) + if (!ShouldDisplayNotification() || GetCableSpeedNotificationShownPref()) return; message_center::RichNotificationData optional;
diff --git a/ash/system/usb_peripheral/usb_peripheral_notification_controller.h b/ash/system/usb_peripheral/usb_peripheral_notification_controller.h index a466014..ad48d76 100644 --- a/ash/system/usb_peripheral/usb_peripheral_notification_controller.h +++ b/ash/system/usb_peripheral/usb_peripheral_notification_controller.h
@@ -8,6 +8,8 @@ #include "ash/ash_export.h" #include "ash/components/peripheral_notification/peripheral_notification_manager.h" +class PrefRegistrySimple; + namespace message_center { class MessageCenter; } // namespace message_center @@ -25,6 +27,8 @@ const UsbPeripheralNotificationController&) = delete; ~UsbPeripheralNotificationController() override; + static void RegisterProfilePrefs(PrefRegistrySimple* registry); + // Called after parent class is initialized. void OnPeripheralNotificationManagerInitialized();
diff --git a/ash/system/usb_peripheral/usb_peripheral_notification_controller_unittest.cc b/ash/system/usb_peripheral/usb_peripheral_notification_controller_unittest.cc index a7f1c53d..3f76eaf6 100644 --- a/ash/system/usb_peripheral/usb_peripheral_notification_controller_unittest.cc +++ b/ash/system/usb_peripheral/usb_peripheral_notification_controller_unittest.cc
@@ -4,8 +4,10 @@ #include "ash/system/usb_peripheral/usb_peripheral_notification_controller.h" +#include "ash/constants/ash_features.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" +#include "base/test/scoped_feature_list.h" #include "ui/message_center/message_center.h" using message_center::MessageCenter; @@ -29,7 +31,9 @@ class UsbPeripheralNotificationControllerTest : public AshTestBase { public: - UsbPeripheralNotificationControllerTest() {} + UsbPeripheralNotificationControllerTest() { + feature_list_.InitAndEnableFeature(features::kUsbNotificationController); + } UsbPeripheralNotificationControllerTest( const UsbPeripheralNotificationControllerTest&) = delete; UsbPeripheralNotificationControllerTest& operator=( @@ -39,6 +43,9 @@ UsbPeripheralNotificationController* controller() { return Shell::Get()->usb_peripheral_notification_controller(); } + + private: + base::test::ScopedFeatureList feature_list_; }; TEST_F(UsbPeripheralNotificationControllerTest, InvalidDpCableNotification) { @@ -118,4 +125,24 @@ EXPECT_EQ(MessageCenter::Get()->NotificationCount(), 1u); } +TEST_F(UsbPeripheralNotificationControllerTest, + SpeedLimitingCableNotificationWithClick) { + EXPECT_EQ(MessageCenter::Get()->NotificationCount(), 0u); + controller()->OnSpeedLimitingCableWarning(); + EXPECT_EQ(MessageCenter::Get()->NotificationCount(), 1u); + + message_center::Notification* notification = + MessageCenter::Get()->FindVisibleNotificationById( + kUsbPeripheralSpeedLimitingCableNotificationId); + ASSERT_TRUE(notification); + + // Click the notification to close it. + notification->delegate()->Click(absl::nullopt, absl::nullopt); + + // Resend the notification, but expect it not to show after being clicked. + EXPECT_EQ(MessageCenter::Get()->NotificationCount(), 0u); + controller()->OnSpeedLimitingCableWarning(); + EXPECT_EQ(MessageCenter::Get()->NotificationCount(), 0u); +} + } // namespace ash
diff --git a/ash/wm/base_state.cc b/ash/wm/base_state.cc index d479262..78ed57f 100644 --- a/ash/wm/base_state.cc +++ b/ash/wm/base_state.cc
@@ -142,6 +142,8 @@ // then snap |window| to the side that corresponds to |desired_snap_state|. if (window_state->CanSnap() && window_state->GetStateType() != desired_snap_state) { + window_state->RecordAndResetWindowSnapActionSource(); + if (Shell::Get()->overview_controller()->InOverviewSession()) { // |window| must already be in split view, and so we do not need to check // |SplitViewController::CanSnapWindow|, although in general it is more
diff --git a/ash/wm/client_controlled_state.cc b/ash/wm/client_controlled_state.cc index e18c9dc..3797b36 100644 --- a/ash/wm/client_controlled_state.cc +++ b/ash/wm/client_controlled_state.cc
@@ -328,6 +328,13 @@ next_state_type == WindowStateType::kPrimarySnapped ? WM_EVENT_SNAP_PRIMARY : WM_EVENT_SNAP_SECONDARY); + + if (event_type == WM_EVENT_RESTORE) { + window_state->set_snap_action_source( + WindowSnapActionSource::kSnapByWindowStateRestore); + } + window_state->RecordAndResetWindowSnapActionSource(); + // Get the desired window bounds for the snap state. gfx::Rect bounds = GetSnappedWindowBoundsInParent(window, next_state_type);
diff --git a/ash/wm/default_state.cc b/ash/wm/default_state.cc index 1d1ecb7..b69a075 100644 --- a/ash/wm/default_state.cc +++ b/ash/wm/default_state.cc
@@ -365,6 +365,15 @@ return; } + if (next_state_type == WindowStateType::kPrimarySnapped || + next_state_type == WindowStateType::kSecondarySnapped) { + if (type == WM_EVENT_RESTORE) { + window_state->set_snap_action_source( + WindowSnapActionSource::kSnapByWindowStateRestore); + } + window_state->RecordAndResetWindowSnapActionSource(); + } + EnterToNextState(window_state, next_state_type); }
diff --git a/ash/wm/overview/overview_window_drag_controller.cc b/ash/wm/overview/overview_window_drag_controller.cc index b643be9..c2b3bec4 100644 --- a/ash/wm/overview/overview_window_drag_controller.cc +++ b/ash/wm/overview/overview_window_drag_controller.cc
@@ -635,13 +635,15 @@ const gfx::Point rounded_screen_point = gfx::ToRoundedPoint(location_in_screen); if (should_allow_split_view_) { - // Update the split view divider bar stuatus if necessary. The divider bar + // Update the split view divider bar status if necessary. The divider bar // should be placed above the dragged window after drag ends. Note here the // passed parameters |snap_position_| and |location_in_screen| won't be used // in this function for this case, but they are passed in as placeholders. + aura::Window* window = item_->GetWindow(); + WindowState::Get(window)->set_snap_action_source( + WindowSnapActionSource::kDragOrSelectOverviewWindowToSnap); SplitViewController::Get(Shell::GetPrimaryRootWindow()) - ->OnWindowDragEnded(item_->GetWindow(), snap_position_, - rounded_screen_point); + ->OnWindowDragEnded(window, snap_position_, rounded_screen_point); // Update window grid bounds and |snap_position_| in case the screen // orientation was changed. @@ -812,6 +814,9 @@ DCHECK(!SplitViewController::Get(Shell::GetPrimaryRootWindow()) ->IsDividerAnimating()); aura::Window* window = item_->GetWindow(); + WindowState::Get(window)->set_snap_action_source( + WindowSnapActionSource::kDragOrSelectOverviewWindowToSnap); + split_view_controller->SnapWindow(window, snap_position, /*activate_window=*/true); item_ = nullptr;
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc index b3cf199..426a662 100644 --- a/ash/wm/splitview/split_view_controller.cc +++ b/ash/wm/splitview/split_view_controller.cc
@@ -288,6 +288,9 @@ void EndTabDragging(aura::Window* window, bool is_being_destroyed) { dragged_window_->RemoveObserver(this); dragged_window_ = nullptr; + + WindowState::Get(window)->set_snap_action_source( + WindowSnapActionSource::kDragTabToSnap); split_view_controller_->EndWindowDragImpl(window, is_being_destroyed, desired_snap_position_, last_location_in_screen_); @@ -564,6 +567,8 @@ // Snap the window on the non-default side of the screen if split view mode // is active. + WindowState::Get(window)->set_snap_action_source( + WindowSnapActionSource::kAutoSnapBySplitview); split_view_controller_->SnapWindow( window, (split_view_controller_->default_snap_position() == LEFT) ? RIGHT @@ -1404,6 +1409,9 @@ OverviewStartAction::kOverviewButtonLongPress, OverviewEnterExitType::kImmediateEnter); + WindowState::Get(target_window) + ->set_snap_action_source( + WindowSnapActionSource::kLongPressOverviewButtonToSnap); SnapWindow(target_window, SplitViewController::LEFT, /*activate_window=*/true); base::RecordAction( @@ -1714,6 +1722,9 @@ // is notified. overview_item->RestoreWindow(/*reset_transform=*/false); overview_session->RemoveItem(overview_item.get()); + + WindowState::Get(window)->set_snap_action_source( + WindowSnapActionSource::kAutoSnapBySplitview); SnapWindow(window, (default_snap_position_ == LEFT) ? RIGHT : LEFT); // If ending overview causes a window to snap, also do not do exiting // overview animation.
diff --git a/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc b/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc index 4611cbf..e026714 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc
@@ -286,6 +286,9 @@ ShouldDropWindowIntoOverview(snap_position, location_in_screen), snap_position != SplitViewController::NONE); } + + WindowState::Get(dragged_window_) + ->set_snap_action_source(WindowSnapActionSource::kDragDownFromTopToSnap); split_view_controller_->OnWindowDragEnded( dragged_window_, snap_position, gfx::ToRoundedPoint(location_in_screen)); split_view_drag_indicators_->SetWindowDraggingState(
diff --git a/ash/wm/tablet_mode/tablet_mode_window_state.cc b/ash/wm/tablet_mode/tablet_mode_window_state.cc index 54d909bd..3689b3a 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_state.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_state.cc
@@ -294,12 +294,17 @@ case WM_EVENT_RESTORE: { // We special handle WM_EVENT_RESTORE event here. WindowStateType restore_state = window_state->GetRestoreWindowState(); - if (restore_state == WindowStateType::kPrimarySnapped) + if (restore_state == WindowStateType::kPrimarySnapped) { + window_state->set_snap_action_source( + WindowSnapActionSource::kSnapByWindowStateRestore); DoTabletSnap(window_state, WM_EVENT_SNAP_PRIMARY); - else if (restore_state == WindowStateType::kSecondarySnapped) + } else if (restore_state == WindowStateType::kSecondarySnapped) { + window_state->set_snap_action_source( + WindowSnapActionSource::kSnapByWindowStateRestore); DoTabletSnap(window_state, WM_EVENT_SNAP_SECONDARY); - else + } else { UpdateWindow(window_state, restore_state, /*animate=*/true); + } break; } case WM_EVENT_SNAP_PRIMARY: @@ -533,6 +538,7 @@ } // If |window| can snap in split view, then snap |window| in |snap_position|. if (split_view_controller->CanSnapWindow(window)) { + window_state->RecordAndResetWindowSnapActionSource(); split_view_controller->SnapWindow(window, snap_position); return; } @@ -553,6 +559,8 @@ } window_state->set_bounds_changed_by_user(true); + window_state->RecordAndResetWindowSnapActionSource(); + // A snap WMEvent will put the window in tablet split view. split_view_controller->OnWindowSnapWMEvent(window, snap_event_type);
diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc index ef043bcb..fe19f303 100644 --- a/ash/wm/window_state.cc +++ b/ash/wm/window_state.cc
@@ -31,6 +31,7 @@ #include "ash/wm/window_state_observer.h" #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" +#include "ash/wm/wm_metrics.h" #include "base/auto_reset.h" #include "base/containers/adapters.h" #include "base/containers/fixed_flat_map.h" @@ -1189,4 +1190,10 @@ return true; } +void WindowState::RecordAndResetWindowSnapActionSource() { + base::UmaHistogramEnumeration(kWindowSnapActionSourceHistogram, + snap_action_source_); + snap_action_source_ = WindowSnapActionSource::kOthers; +} + } // namespace ash
diff --git a/ash/wm/window_state.h b/ash/wm/window_state.h index 29d35e7..53203e7 100644 --- a/ash/wm/window_state.h +++ b/ash/wm/window_state.h
@@ -11,6 +11,7 @@ #include "ash/ash_export.h" #include "ash/display/persistent_window_info.h" #include "ash/wm/drag_details.h" +#include "ash/wm/wm_metrics.h" #include "base/gtest_prod_util.h" #include "base/observer_list.h" #include "base/time/time.h" @@ -370,6 +371,10 @@ const DragDetails* drag_details() const { return drag_details_.get(); } DragDetails* drag_details() { return drag_details_.get(); } + void set_snap_action_source(WindowSnapActionSource type) { + snap_action_source_ = type; + } + const std::vector<chromeos::WindowStateType>& window_state_restore_history_for_testing() const { return window_state_restore_history_; @@ -512,6 +517,8 @@ bool CanUnresizableSnapOnDisplay(display::Display display) const; + void RecordAndResetWindowSnapActionSource(); + // The owner of this window settings. aura::Window* window_; std::unique_ptr<WindowStateDelegate> delegate_; @@ -576,6 +583,10 @@ // can restore back to. See kWindowStateRestoreHistoryLayerMap in the cc file // for what window state types that can be put in the restore history stack. std::vector<chromeos::WindowStateType> window_state_restore_history_; + + // This is used to record where the current snap window state change request + // comes from. + WindowSnapActionSource snap_action_source_ = WindowSnapActionSource::kOthers; }; } // namespace ash
diff --git a/ash/wm/window_state_unittest.cc b/ash/wm/window_state_unittest.cc index c43d96d..b9ef138 100644 --- a/ash/wm/window_state_unittest.cc +++ b/ash/wm/window_state_unittest.cc
@@ -8,16 +8,21 @@ #include "ash/constants/app_types.h" #include "ash/metrics/pip_uma.h" +#include "ash/public/cpp/accelerators.h" #include "ash/public/cpp/shelf_config.h" #include "ash/public/cpp/window_properties.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "ash/test/test_window_builder.h" +#include "ash/wm/overview/overview_item.h" +#include "ash/wm/overview/overview_test_util.h" #include "ash/wm/pip/pip_positioner.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" +#include "ash/wm/window_resizer.h" #include "ash/wm/window_state_util.h" #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" +#include "ash/wm/wm_metrics.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "chromeos/ui/base/window_state_type.h" @@ -1280,6 +1285,77 @@ EXPECT_EQ(window_state->GetStateType(), WindowStateType::kNormal); } +TEST_F(WindowStateTest, WindowSnapActionSourceUmaMetrics) { + UpdateDisplay("800x600"); + base::HistogramTester histograms; + std::unique_ptr<aura::Window> window(CreateAppWindow()); + WindowState* window_state = WindowState::Get(window.get()); + + // Use WMEvent to directly snap the window. + WMEvent snap_left(WM_EVENT_SNAP_PRIMARY); + window_state->OnWMEvent(&snap_left); + histograms.ExpectBucketCount(kWindowSnapActionSourceHistogram, + WindowSnapActionSource::kOthers, 1); + window_state->Maximize(); + + // Drag the window to the screen edge to snap. + std::unique_ptr<WindowResizer> resizer(CreateWindowResizer( + window.get(), gfx::PointF(), HTCAPTION, ::wm::WINDOW_MOVE_SOURCE_TOUCH)); + resizer->Drag(gfx::PointF(0, 400), 0); + resizer->CompleteDrag(); + resizer.reset(); + histograms.ExpectBucketCount(kWindowSnapActionSourceHistogram, + WindowSnapActionSource::kDragWindowToEdgeToSnap, + 1); + window_state->Maximize(); + + // Use keyboard to snap a window. + AcceleratorController::Get()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_LEFT, + {}); + histograms.ExpectBucketCount(kWindowSnapActionSourceHistogram, + WindowSnapActionSource::kKeyboardShortcutToSnap, + 1); + window_state->Maximize(); + + // Restore the maximized window to snap window state. + window_state->Restore(); + histograms.ExpectBucketCount( + kWindowSnapActionSourceHistogram, + WindowSnapActionSource::kSnapByWindowStateRestore, 1); + window_state->Maximize(); + + // Drag or select overview window to snap window. + ui::test::EventGenerator* generator = GetEventGenerator(); + EnterOverview(); + ASSERT_TRUE(GetOverviewSession()); + const gfx::Point center_point = + gfx::ToRoundedPoint(GetOverviewSession() + ->GetOverviewItemForWindow(window.get()) + ->target_bounds() + .CenterPoint()); + generator->MoveMouseTo(center_point); + generator->DragMouseTo(gfx::Point(0, 400)); + histograms.ExpectBucketCount( + kWindowSnapActionSourceHistogram, + WindowSnapActionSource::kDragOrSelectOverviewWindowToSnap, 1); + window_state->Maximize(); + + Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true); + EXPECT_TRUE(Shell::Get()->tablet_mode_controller()->InTabletMode()); + + // Use keyboard to snap the window in tablet mode. + AcceleratorController::Get()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_LEFT, + {}); + histograms.ExpectBucketCount(kWindowSnapActionSourceHistogram, + WindowSnapActionSource::kKeyboardShortcutToSnap, + 2); + + // Auto-snap in splitview. + std::unique_ptr<aura::Window> window2(CreateAppWindow()); + histograms.ExpectBucketCount(kWindowSnapActionSourceHistogram, + WindowSnapActionSource::kAutoSnapBySplitview, 1); +} + // Test WindowStateTest functionalities with portrait display. This test is // parameterized to enable vertical layout or horizontal layout snap in // portrait display.
diff --git a/ash/wm/wm_metrics.h b/ash/wm/wm_metrics.h new file mode 100644 index 0000000..b39adc0 --- /dev/null +++ b/ash/wm/wm_metrics.h
@@ -0,0 +1,35 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_WM_WM_METRICS_H_ +#define ASH_WM_WM_METRICS_H_ + +namespace ash { + +// Used to record different ways to snap a window. Note this should be kept in +// sync with WindowSnapActionSource enum in tools/metrics/histograms/enums.xml. +enum class WindowSnapActionSource { + kDragWindowToEdgeToSnap, + kUseCaptionButtonToSnap, + kKeyboardShortcutToSnap, + kDragOrSelectOverviewWindowToSnap, + kLongPressOverviewButtonToSnap, + kDragUpFromShelfToSnap, + kDragDownFromTopToSnap, + kDragTabToSnap, + kAutoSnapBySplitview, + kSnapByWindowStateRestore, + kOthers, // This can include any actions that's not covered above, e.g., + // window snap by full restore, desk template, desk switch or user + // switch, etc + kMaxValue = kOthers, +}; + +// Used to save histogram metrics about how the user initiates window snapping. +constexpr char kWindowSnapActionSourceHistogram[] = + "Ash.Wm.WindowSnapActionSource"; + +} // namespace ash + +#endif // ASH_WM_WM_METRICS_H_
diff --git a/ash/wm/workspace/workspace_window_resizer.cc b/ash/wm/workspace/workspace_window_resizer.cc index b827e89..17d46e0 100644 --- a/ash/wm/workspace/workspace_window_resizer.cc +++ b/ash/wm/workspace/workspace_window_resizer.cc
@@ -866,10 +866,14 @@ switch (snap_type_) { case SnapType::kPrimary: type = WM_EVENT_SNAP_PRIMARY; + window_state()->set_snap_action_source( + WindowSnapActionSource::kDragWindowToEdgeToSnap); base::RecordAction(base::UserMetricsAction("WindowDrag_MaximizeLeft")); break; case SnapType::kSecondary: type = WM_EVENT_SNAP_SECONDARY; + window_state()->set_snap_action_source( + WindowSnapActionSource::kDragWindowToEdgeToSnap); base::RecordAction(base::UserMetricsAction("WindowDrag_MaximizeRight")); break; case SnapType::kMaximize: @@ -1655,6 +1659,9 @@ case WindowStateType::kPrimarySnapped: if (window_state->CanSnap()) { window_state->SetRestoreBoundsInParent(restore_bounds_for_gesture_); + window_state->set_snap_action_source( + WindowSnapActionSource::kDragWindowToEdgeToSnap); + const WMEvent event(WM_EVENT_SNAP_PRIMARY); window_state->OnWMEvent(&event); } @@ -1662,6 +1669,9 @@ case WindowStateType::kSecondarySnapped: if (window_state->CanSnap()) { window_state->SetRestoreBoundsInParent(restore_bounds_for_gesture_); + window_state->set_snap_action_source( + WindowSnapActionSource::kDragWindowToEdgeToSnap); + const WMEvent event(WM_EVENT_SNAP_SECONDARY); window_state->OnWMEvent(&event); }
diff --git a/base/json/string_escape.cc b/base/json/string_escape.cc index d1253e2..4fb9630 100644 --- a/base/json/string_escape.cc +++ b/base/json/string_escape.cc
@@ -92,8 +92,7 @@ for (int32_t i = 0; i < length; ++i) { uint32_t code_point; if (!ReadUnicodeCharacter(str.data(), length, &i, &code_point) || - code_point == static_cast<decltype(code_point)>(CBU_SENTINEL) || - !IsValidCodepoint(code_point)) { + code_point == static_cast<decltype(code_point)>(CBU_SENTINEL)) { code_point = kReplacementCodePoint; did_replacement = true; }
diff --git a/base/memory/raw_ptr.h b/base/memory/raw_ptr.h index 0671814..3069c513 100644 --- a/base/memory/raw_ptr.h +++ b/base/memory/raw_ptr.h
@@ -17,6 +17,7 @@ #include "base/check.h" #include "base/compiler_specific.h" #include "base/dcheck_is_on.h" +#include "base/trace_event/base_tracing_forward.h" #include "build/build_config.h" #include "build/buildflag.h" @@ -828,6 +829,14 @@ std::swap(lhs.wrapped_ptr_, rhs.wrapped_ptr_); } + // If T can be serialised into trace, its alias is also + // serialisable. + template <class U = T> + typename perfetto::check_traced_value_support<U>::type WriteIntoTrace( + perfetto::TracedValue&& context) const { + perfetto::WriteIntoTracedValue(std::move(context), get()); + } + private: // This getter is meant for situations where the pointer is meant to be // dereferenced. It is allowed to crash on nullptr (it may or may not),
diff --git a/base/memory/raw_ptr_unittest.cc b/base/memory/raw_ptr_unittest.cc index b291d913..b25b1ce47 100644 --- a/base/memory/raw_ptr_unittest.cc +++ b/base/memory/raw_ptr_unittest.cc
@@ -17,6 +17,10 @@ #include "build/buildflag.h" #include "testing/gtest/include/gtest/gtest.h" +#if BUILDFLAG(ENABLE_BASE_TRACING) +#include "third_party/perfetto/include/perfetto/test/traced_value_test_support.h" // no-presubmit-check nogncheck +#endif // BUILDFLAG(ENABLE_BASE_TRACING) + using testing::Test; static_assert(sizeof(raw_ptr<void>) == sizeof(void*), @@ -962,6 +966,31 @@ checked_derived2_ptr); } +#if BUILDFLAG(ENABLE_BASE_TRACING) +TEST_F(RawPtrTest, TracedValueSupport) { + // Serialise nullptr. + EXPECT_EQ(perfetto::TracedValueToString(raw_ptr<int>()), "0x0"); + + { + // If the pointer is non-null, its dereferenced value will be serialised. + int value = 42; + EXPECT_EQ(perfetto::TracedValueToString(raw_ptr<int>(&value)), "42"); + } + + struct WithTraceSupport { + void WriteIntoTrace(perfetto::TracedValue ctx) const { + std::move(ctx).WriteString("result"); + } + }; + + { + WithTraceSupport value; + EXPECT_EQ(perfetto::TracedValueToString(raw_ptr<WithTraceSupport>(&value)), + "result"); + } +} +#endif // BUILDFLAG(ENABLE_BASE_TRACING) + class PmfTestBase { public: int MemFunc(char, double) const { return 11; }
diff --git a/base/trace_event/base_tracing_forward.h b/base/trace_event/base_tracing_forward.h index f72f9fde..677966b8 100644 --- a/base/trace_event/base_tracing_forward.h +++ b/base/trace_event/base_tracing_forward.h
@@ -19,7 +19,7 @@ class TracedValue; template <typename T> -void WriteIntoTrace(TracedValue context, T&& value); +void WriteIntoTracedValue(TracedValue context, T&& value); template <typename T, class = void> struct TraceFormatTraits;
diff --git a/base/types/DEPS b/base/types/DEPS deleted file mode 100644 index d89c3e1..0000000 --- a/base/types/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "-third_party", -]
diff --git a/base/types/strong_alias.h b/base/types/strong_alias.h index 8c148d4..fcd6716 100644 --- a/base/types/strong_alias.h +++ b/base/types/strong_alias.h
@@ -10,6 +10,7 @@ #include <utility> #include "base/template_util.h" +#include "base/trace_event/base_tracing_forward.h" namespace base { @@ -135,6 +136,14 @@ } }; + // If UnderlyingType can be serialised into trace, its alias is also + // serialisable. + template <class U = UnderlyingType> + typename perfetto::check_traced_value_support<U>::type WriteIntoTrace( + perfetto::TracedValue&& context) const { + perfetto::WriteIntoTracedValue(std::move(context), value_); + } + protected: UnderlyingType value_; };
diff --git a/base/types/strong_alias_unittest.cc b/base/types/strong_alias_unittest.cc index 94f3198..c9f559c 100644 --- a/base/types/strong_alias_unittest.cc +++ b/base/types/strong_alias_unittest.cc
@@ -17,6 +17,10 @@ #include "base/template_util.h" #include "testing/gtest/include/gtest/gtest.h" +#if BUILDFLAG(ENABLE_BASE_TRACING) +#include "third_party/perfetto/include/perfetto/test/traced_value_test_support.h" // no-presubmit-check nogncheck +#endif // BUILDFLAG(ENABLE_BASE_TRACING) + namespace base { namespace { @@ -381,4 +385,11 @@ !base::internal::SupportsOstreamOperator<NonStreamableAlias>::value, ""); } +#if BUILDFLAG(ENABLE_BASE_TRACING) +TEST(StrongAliasTest, TracedValueSupport) { + using IntAlias = StrongAlias<class FooTag, int>; + EXPECT_EQ(perfetto::TracedValueToString(IntAlias(42)), "42"); +} +#endif // BUILDFLAG(ENABLE_BASE_TRACING) + } // namespace base
diff --git a/build/sanitizers/tsan_suppressions.cc b/build/sanitizers/tsan_suppressions.cc index f575398a..01f25b21 100644 --- a/build/sanitizers/tsan_suppressions.cc +++ b/build/sanitizers/tsan_suppressions.cc
@@ -81,9 +81,6 @@ // http://crbug.com/380554 "deadlock:g_type_add_interface_static\n" - // http:://crbug.com/386385 - "race:content::AppCacheStorageImpl::DatabaseTask::CallRunCompleted\n" - // http://crbug.com/397022 "deadlock:" "base::trace_event::TraceEventTestFixture_ThreadOnceBlocking_Test::"
diff --git a/build/toolchain/apple/linker_driver.py b/build/toolchain/apple/linker_driver.py index 2afe63b..33809eb 100755 --- a/build/toolchain/apple/linker_driver.py +++ b/build/toolchain/apple/linker_driver.py
@@ -51,9 +51,17 @@ # -Wcrl,strippath,<strip_path> # Sets the path to the strip to run with -Wcrl,strip, in which case # `xcrun` is not used to invoke it. +# +# -Wcrl,pad_linkedit,<size> +# Pads the total size of the linker's output to the specified size in bytes, +# after running the linker and `strip`. Padding is added to the __LINKEDIT +# segment by the pad_linkedit.py script located in the same directory as this +# script. It is an error to attempt to reduce the size of the linked image +# using this option. class LinkerDriver(object): + def __init__(self, args): """Creates a new linker driver. @@ -74,6 +82,7 @@ ('unstripped,', self.run_save_unstripped), ('strippath,', self.set_strip_path), ('strip,', self.run_strip), + ('pad_linkedit,', self.run_pad_linkedit), ] # Linker driver actions can modify the these values. @@ -278,6 +287,21 @@ self._strip_cmd = [strip_path] return [] + def run_pad_linkedit(self, size_string): + """Linker driver action for -Wcrl,pad_linkedit,<size>. + + Args: + size_string: string, the size to pass to pad_linkedit.py. + + Returns: + list of string, Build step outputs. + """ + pad_linkedit_command = (os.path.join(os.path.dirname(__file__), + 'pad_linkedit.py'), + self._get_linker_output(), size_string) + subprocess.check_call(pad_linkedit_command) + return [] + # Regular expressions matching log spam messages from dsymutil. DSYM_SPURIOUS_PATTERNS = [
diff --git a/build/toolchain/apple/pad_linkedit.py b/build/toolchain/apple/pad_linkedit.py new file mode 100755 index 0000000..b41f186 --- /dev/null +++ b/build/toolchain/apple/pad_linkedit.py
@@ -0,0 +1,175 @@ +#!/usr/bin/env python3 +# coding: utf-8 + +# Copyright 2022 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Increases the size of a Mach-O image by adding padding to its __LINKEDIT +# segment. + +import argparse +import os +import struct +import sys + +# Constants from <mach-o/loader.h>. +_MH_MAGIC = 0xfeedface +_MH_MAGIC_64 = 0xfeedfacf +_LC_SEGMENT = 0x1 +_LC_SEGMENT_64 = 0x19 +_LC_CODE_SIGNATURE = 0x1d +_SEG_LINKEDIT = b'__LINKEDIT'.ljust(16, b'\x00') + + +class PadLinkeditError(Exception): + pass + + +def _struct_read_unpack(file, format_or_struct): + """Reads bytes from |file|, unpacking them via the struct module. This + function is provided for convenience: the number of bytes to read from + |file| is determined based on the size of data that the struct unpack + operation will consume. + + Args: + file: The file object to read from. + + format_or_struct: A string suitable for struct.unpack’s |format| + argument, or a struct.Struct object. This will be used to determine + the number of bytes to read and to perform the unpack. + + Returns: + A tuple of unpacked items. + """ + + if isinstance(format_or_struct, struct.Struct): + struc = format_or_struct + return struc.unpack(file.read(struc.size)) + + format = format_or_struct + return struct.unpack(format, file.read(struct.calcsize(format))) + + +def PadLinkedit(file, size): + """Takes |file|, a single-architecture (thin) Mach-O image, and increases + its size to |size| by adding padding (NUL bytes) to its __LINKEDIT segment. + If |file| is not a thin Mach-O image, if its structure is unexpected, if it + is already larger than |size|, or if it is already code-signed, raises + PadLinkeditError. + + The image must already have a __LINKEDIT segment, the load command for the + __LINKEDIT segment must be the last segment load command in the image, and + the __LINKEDIT segment contents must be at the end of the file. + + Args: + file: The file object to read from and modify. + + size: The desired size of the file. + + Returns: + None + + Raises: + PadLinkeditError if |file| is not suitable for the operation. + """ + + file.seek(0, os.SEEK_END) + current_size = file.tell() + file.seek(0, os.SEEK_SET) + + magic, = _struct_read_unpack(file, '<I') + if magic == _MH_MAGIC_64: + bits, endian = 64, '<' + elif magic == _MH_MAGIC: + bits, endian = 32, '<' + elif magic == struct.unpack('>I', struct.pack('<I', _MH_MAGIC_64)): + bits, endian = 64, '>' + elif magic == struct.unpack('>I', struct.pack('<I', _MH_MAGIC)): + bits, endian = 32, '>' + else: + raise PadLinkeditError('unrecognized magic', magic) + + if bits == 64: + lc_segment = _LC_SEGMENT_64 + segment_command_struct = struct.Struct(endian + '16s4Q4I') + else: + lc_segment = _LC_SEGMENT + segment_command_struct = struct.Struct(endian + '16s8I') + + grow = size - current_size + if grow < 0: + raise PadLinkeditError('file would need to shrink', grow) + + (cputype, cpusubtype, filetype, ncmds, sizeofcmds, + flags) = _struct_read_unpack(file, + endian + '6I' + ('4x' if bits == 64 else '')) + + load_command_struct = struct.Struct(endian + '2I') + found_linkedit = False + segment_max_offset = 0 + + # Iterate through the load commands. It’s possible to consider |sizeofcmds|, + # but since the file is being edited in-place, that would just be a sanity + # check. + for load_command_index in range(ncmds): + cmd, cmdsize = _struct_read_unpack(file, load_command_struct) + consumed = load_command_struct.size + if cmd == lc_segment: + if found_linkedit: + raise PadLinkeditError('__LINKEDIT segment not last') + + (segname, vmaddr, vmsize, fileoff, filesize, maxprot, initprot, + nsects, flags) = _struct_read_unpack(file, segment_command_struct) + consumed += segment_command_struct.size + + if segname == _SEG_LINKEDIT: + found_linkedit = True + + if fileoff < segment_max_offset: + raise PadLinkeditError('__LINKEDIT data not last') + if fileoff + filesize != current_size: + raise PadLinkeditError('__LINKEDIT data not at EOF') + + vmsize += grow + filesize += grow + file.seek(-segment_command_struct.size, os.SEEK_CUR) + file.write( + segment_command_struct.pack(segname, vmaddr, vmsize, + fileoff, filesize, maxprot, + initprot, nsects, flags)) + + segment_max_offset = max(segment_max_offset, fileoff + filesize) + elif cmd == _LC_CODE_SIGNATURE: + raise PadLinkeditError( + 'modifying an already-signed image would render it unusable') + + # Aside from the above, load commands aren’t being interpreted, or even + # read, so skip ahead to the next one. + file.seek(cmdsize - consumed, os.SEEK_CUR) + + if not found_linkedit: + raise PadLinkeditError('no __LINKEDIT') + + # Add the padding to the __LINKEDIT segment data. + file.seek(grow, os.SEEK_END) + file.truncate() + + +def _main(args): + parser = argparse.ArgumentParser( + description= + 'Increase the size of a Mach-O image by adding padding to its ' + + '__LINKEDIT segment.') + parser.add_argument('file', help='The Mach-O file to modify') + parser.add_argument('size', + type=int, + help='The desired final size of the file, in bytes') + parsed = parser.parse_args() + + with open(parsed.file, 'r+b') as file: + PadLinkedit(file, parsed.size) + + +if __name__ == '__main__': + sys.exit(_main(sys.argv[1:]))
diff --git a/cc/paint/image_transfer_cache_entry.cc b/cc/paint/image_transfer_cache_entry.cc index abc74d4..1c963381 100644 --- a/cc/paint/image_transfer_cache_entry.cc +++ b/cc/paint/image_transfer_cache_entry.cc
@@ -92,44 +92,6 @@ return image; } -// TODO(ericrk): Replace calls to this with calls to SkImage::makeTextureImage, -// once that function handles colorspaces. https://crbug.com/834837 -sk_sp<SkImage> MakeTextureImage( - GrDirectContext* context, - sk_sp<SkImage> source_image, - absl::optional<TargetColorParams> target_color_params, - GrMipMapped mip_mapped) { - // Step 1: Upload image and generate mips if necessary. If we will be applying - // a color-space conversion, don't generate mips yet, instead do it after - // conversion, in step 3. - // NOTE: |target_color_space| is only passed over the transfer cache if needed - // (non-null, different from the source color space). - bool add_mips_after_color_conversion = - target_color_params && mip_mapped == GrMipMapped::kYes; - sk_sp<SkImage> uploaded_image = source_image->makeTextureImage( - context, add_mips_after_color_conversion ? GrMipMapped::kNo : mip_mapped, - SkBudgeted::kNo); - - // Step 2: Apply a color-space conversion if necessary. - if (uploaded_image && target_color_params) { - // TODO(https://crbug.com/1286088): Pass a shared cache as a parameter. - gfx::ColorConversionSkFilterCache cache; - uploaded_image = cache.ConvertImage( - uploaded_image, target_color_params->color_space.ToSkColorSpace(), - target_color_params->sdr_max_luminance_nits, - target_color_params->hdr_max_luminance_relative, context); - } - - // Step 3: If we had a colorspace conversion, we couldn't mipmap in step 1, so - // add mips here. - if (uploaded_image && add_mips_after_color_conversion) { - uploaded_image = uploaded_image->makeTextureImage( - context, GrMipMapped::kYes, SkBudgeted::kNo); - } - - return uploaded_image; -} - base::CheckedNumeric<uint32_t> SafeSizeForPixmap(const SkPixmap& pixmap) { base::CheckedNumeric<uint32_t> safe_size; safe_size += sizeof(uint64_t); // color type @@ -491,6 +453,10 @@ plane_config_ = SkYUVAInfo::PlaneConfig::kUnknown; reader.Read(&plane_config_); + const GrMipMapped mip_mapped_for_upload = + has_mips_ && !target_color_params ? GrMipMapped::kYes : GrMipMapped::kNo; + SkPixmap rgba_pixmap; + sk_sp<SkImage> rgba_pixmap_image; if (plane_config_ != SkYUVAInfo::PlaneConfig::kUnknown) { SkYUVAInfo::Subsampling subsampling = SkYUVAInfo::Subsampling::kUnknown; reader.Read(&subsampling); @@ -524,18 +490,20 @@ } DCHECK(!target_color_params); - sk_sp<SkImage> plane = MakeSkImage(pixmap, target_color_params); + sk_sp<SkImage> plane = SkImage::MakeFromRaster(pixmap, nullptr, nullptr); if (!plane) { - DLOG(ERROR) << "Failed to upload plane pixmap"; + DLOG(ERROR) << "Failed to create image from plane pixmap"; + return false; + } + plane = plane->makeTextureImage(context_, mip_mapped_for_upload, + SkBudgeted::kNo); + if (!plane) { + DLOG(ERROR) << "Failed to upload plane pixmap to texture image"; return false; } DCHECK(plane->isTextureBacked()); - + plane->getBackendTexture(/*flushPendingGrContextIO=*/true); plane_sizes_.push_back(plane->textureSize()); - size_ += plane_sizes_.back(); - - // |plane_images_| must be set for use in EnsureMips(), memory dumps, and - // unit tests. plane_images_.push_back(std::move(plane)); } DCHECK(yuv_color_space_.has_value()); @@ -543,59 +511,78 @@ context_, plane_images_, plane_config_, subsampling_.value(), yuv_color_space_.value(), decoded_color_space); } else { - SkPixmap pixmap; - if (!ReadPixmap(reader, pixmap)) { + if (!ReadPixmap(reader, rgba_pixmap)) { DLOG(ERROR) << "Failed to read pixmap"; return false; } - fits_on_gpu_ = pixmap.width() <= max_size && pixmap.height() <= max_size; - image_ = MakeSkImage(pixmap, target_color_params); - if (image_) - size_ = image_->textureSize(); - } - - return true; -} - -sk_sp<SkImage> ServiceImageTransferCacheEntry::MakeSkImage( - const SkPixmap& pixmap, - absl::optional<TargetColorParams> target_color_params) { - DCHECK(context_); - sk_sp<SkImage> image; - if (fits_on_gpu_) { - image = SkImage::MakeFromRaster(pixmap, nullptr, nullptr); - if (!image) - return nullptr; - image = MakeTextureImage(context_, std::move(image), target_color_params, - has_mips_ ? GrMipMapped::kYes : GrMipMapped::kNo); - } else { - // If the image is on the CPU, no work is needed to generate mips. - has_mips_ = true; - sk_sp<SkImage> original = - SkImage::MakeFromRaster(pixmap, [](const void*, void*) {}, nullptr); - if (!original) - return nullptr; - if (target_color_params) { - // TODO(https://crbug.com/1286088): Pass a shared cache as a parameter. - gfx::ColorConversionSkFilterCache cache; - image = cache.ConvertImage( - original, target_color_params->color_space.ToSkColorSpace(), - target_color_params->sdr_max_luminance_nits, - target_color_params->hdr_max_luminance_relative, /*context=*/nullptr); - // If color space conversion is a noop, use original data. - if (image == original) - image = SkImage::MakeRasterCopy(pixmap); + rgba_pixmap_image = SkImage::MakeFromRaster(rgba_pixmap, nullptr, nullptr); + if (!rgba_pixmap_image) { + DLOG(ERROR) << "Failed to create image from plane pixmap"; + return false; + } + fits_on_gpu_ = + rgba_pixmap.width() <= max_size && rgba_pixmap.height() <= max_size; + if (fits_on_gpu_) { + image_ = rgba_pixmap_image->makeTextureImage( + context, mip_mapped_for_upload, SkBudgeted::kNo); + if (!image_) { + DLOG(ERROR) << "Failed to upload pixmap to texture image"; + return false; + } } else { - // No color conversion to do, use original data. - image = SkImage::MakeRasterCopy(pixmap); + // If the image is on the CPU, no work is needed to generate mips. + has_mips_ = true; + image_ = rgba_pixmap_image; + } + } + DCHECK(image_); + + // Perform color conversion. + if (target_color_params) { + // TODO(https://crbug.com/1286088): Pass a shared cache as a parameter. + gfx::ColorConversionSkFilterCache cache; + image_ = cache.ConvertImage( + image_, target_color_params->color_space.ToSkColorSpace(), + target_color_params->sdr_max_luminance_nits, + target_color_params->hdr_max_luminance_relative, + fits_on_gpu_ ? context_ : nullptr); + if (!image_) { + DLOG(ERROR) << "Failed image color conversion"; + return false; + } + + // Color conversion converts to RGBA. Remove all YUV state. + plane_images_.clear(); + plane_sizes_.clear(); + plane_config_ = SkYUVAInfo::PlaneConfig::kUnknown; + plane_sizes_.clear(); + subsampling_ = absl::nullopt; + yuv_color_space_ = absl::nullopt; + + // If mipmaps were requested, create them after color conversion. + if (has_mips_ && fits_on_gpu_) { + image_ = + image_->makeTextureImage(context, GrMipMapped::kYes, SkBudgeted::kNo); + if (!image_) { + DLOG(ERROR) << "Failed to generate mipmaps after color conversion"; + return false; + } } } - // Make sure the GPU work to create the backing texture is issued. - if (image) - image->getBackendTexture(true /* flushPendingGrContextIO */); + // If `image_` is still pointing at the original data from `rgba_pixmap`, make + // 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); + if (!image_) { + DLOG(ERROR) << "Failed to create raster copy"; + return false; + } + } - return image; + size_ = image_->textureSize(); + return true; } const sk_sp<SkImage>& ServiceImageTransferCacheEntry::GetPlaneImage( @@ -636,23 +623,25 @@ context_, mipped_planes, plane_config_, subsampling_.value(), yuv_color_space_.value(), image_->refColorSpace() /* image_color_space */); - if (!mipped_image) + if (!mipped_image) { + DLOG(ERROR) << "Failed to create YUV image from mipmapped planes"; return; + } // Note that we cannot update |size_| because the transfer cache keeps track // of a total size that is not updated after EnsureMips(). The original size // is used when the image is deleted from the cache. plane_images_ = std::move(mipped_planes); plane_sizes_ = std::move(mipped_plane_sizes); image_ = std::move(mipped_image); - has_mips_ = true; - return; + } else { + sk_sp<SkImage> mipped_image = + image_->makeTextureImage(context_, GrMipMapped::kYes, SkBudgeted::kNo); + if (!mipped_image) { + DLOG(ERROR) << "Failed to mipmapped image"; + return; + } + image_ = std::move(mipped_image); } - - sk_sp<SkImage> mipped_image = - image_->makeTextureImage(context_, GrMipMapped::kYes, SkBudgeted::kNo); - if (!mipped_image) - return; - image_ = std::move(mipped_image); has_mips_ = true; }
diff --git a/cc/paint/image_transfer_cache_entry.h b/cc/paint/image_transfer_cache_entry.h index cacf3df..5e810fbd 100644 --- a/cc/paint/image_transfer_cache_entry.h +++ b/cc/paint/image_transfer_cache_entry.h
@@ -151,11 +151,10 @@ } private: - sk_sp<SkImage> MakeSkImage( - const SkPixmap& pixmap, - absl::optional<TargetColorParams> target_color_params); - raw_ptr<GrDirectContext> context_ = nullptr; + // The individual planes that are used by `image_` when `image_` is a YUVA + // image. The planes are kept around for use in EnsureMips(), memory dumps, + // and unit tests. std::vector<sk_sp<SkImage>> plane_images_; SkYUVAInfo::PlaneConfig plane_config_ = SkYUVAInfo::PlaneConfig::kUnknown; std::vector<size_t> plane_sizes_; @@ -163,6 +162,8 @@ absl::optional<SkYUVAInfo::Subsampling> subsampling_; absl::optional<SkYUVColorSpace> yuv_color_space_; bool has_mips_ = false; + // The value of `size_` is computed during deserialization and never updated + // (even if the size of the image changes due to mipmaps being requested). size_t size_ = 0; bool fits_on_gpu_ = false; };
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index 5b57d134..e5d3e35 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -485,13 +485,15 @@ "//chrome/common:version_header", ] + ldflags = [] + if (enable_stripping) { # At link time, preserve the global symbols specified in the .exports # file. All other global symbols will be marked as private. The default # //build/config/mac:strip_all config will then remove the remaining # local and debug symbols. - ldflags = [ "-Wl,-exported_symbols_list," + - rebase_path("app/app.exports", root_build_dir) ] + ldflags += [ "-Wl,-exported_symbols_list," + + rebase_path("app/app.exports", root_build_dir) ] } if (is_component_build) { @@ -499,7 +501,7 @@ # executable because dlopen() and loading all the dependent dylibs # is time-consuming, see https://crbug.com/1197495. deps += [ ":chrome_framework+link" ] - ldflags = [ "-Wl,-rpath,@executable_path/../Frameworks" ] + ldflags += [ "-Wl,-rpath,@executable_path/../Frameworks" ] # The Framework is packaged inside the .app bundle. But when using the # component build, all the dependent shared libraries of :chrome_dll are @@ -513,6 +515,70 @@ if (enable_chromium_updater) { deps += [ ":chromium_updater_privileged_helper" ] } + + if (is_chrome_branded && is_official_build && current_cpu == "x64") { + # This is for https://crbug.com/1300598, and more generally, + # https://crbug.com/1297588 (and all of the associated bugs). It's + # horrible! + # + # When the main executable is updated on disk while the application is + # running, and the offset of the Mach-O image at the main executable's + # path changes from the offset that was determined when the executable was + # loaded, SecCode ceases to be able to work with the executable. This may + # be triggered when the product is updated on disk but the application has + # not yet relaunched. This affects SecCodeCopySelf and + # SecCodeCopyGuestWithAttributes. Bugs are evident even when validation + # (SecCodeCheckValidity) is not attempted. + # + # Practically, this is only a concern for fat (universal) files, because + # the offset of a Mach-O image in a thin (single-architecture) file is + # always 0. The branded product always ships a fat executable, and because + # some uses of SecCode are in OS code beyond Chrome's control, an effort + # is made to freeze the geometry of the branded (is_chrome_branded) + # for-public-release (is_official_build) main executable. + # + # The fat file is produced by installer/mac/universalizer.py. The x86_64 + # slice always precedes the arm64 slice: lipo, as used by + # universalizer.py, always places the arm64 slice last. See Xcode 12.0 + # https://github.com/apple-oss-distributions/cctools/blob/cctools-973.0.1/misc/lipo.c#L2672 + # cmp_qsort, used by create_fat at #L962. universalizer.py ensures that + # the first slice in the file is located at a constant offset (16kB since + # 98.0.4758.80), but if the first slice's size changes, it can affect the + # offset of the second slice, the arm64 one, triggering SecCode-related + # bugs for arm64 users across updates. + # + # As quite a hack of a workaround, the offset of the arm64 slice within + # the fat main executable is fixed at a constant value by introducing + # padding to the x86_64 slice that precedes it. The arm64 slice needs to + # remain at offset 304kB (since 98.0.4758.80), so enough padding is added + # to the x86_64 slice to ensure that the arm64 slice lands where it needs + # to be when universalized. This padding needs to be added to the thin + # form of the x86_64 image before being fed to universalizer.py. + # + # To make things extra tricky, the final size of the x86_64 image is not + # known when it is linked, because code signing will contribute more data + # to the file. Typically, official code signing adds a non-constant + # 22-23kB. The non-constancy makes a precise computation of the required + # padding at this stage of the build impossible. Luckily, the size of the + # x86_64 image doesn't need to be so precise. The arm64 slice that follows + # it in the fat file will be 16kB-aligned, so it's enough to ensure that + # the x86_64 slice ends at an offset in the range (288kB, 304kB], or, + # since the x86_64 slice itself begins at offset 16kB, its total size once + # signed must be in the range (272kB, 288kB]. Targeting size 280kB, right + # in the middle of that range, and assuming an expected 23200-byte + # contribution from code signing, the unsigned x86_64 image should be + # padded to 263520 bytes. Code signing may then add any amount in the + # range (15008 bytes, 31392 bytes] and the result, when universalized, + # will have its arm64 slice at the required 304kB offset. + # + # -Wcrl,pad_linkedit runs //build/toolchain/apple/pad_linkedit.py, and can + # only increase the size of the image. It will raise an error on an + # attempt to decrease the size. Fortunately, the x86_64 main executable in + # this build configuration is currently (at the time of this writing) + # smaller than this size, and is expected to shrink even further in the + # future. + ldflags += [ "-Wcrl,pad_linkedit,263520" ] + } } if (verify_dynamic_libraries) {
diff --git a/chrome/android/expectations/monochrome_public_bundle.AndroidManifest.expected b/chrome/android/expectations/monochrome_public_bundle.AndroidManifest.expected index 91e8b9dd..5f2f0d0 100644 --- a/chrome/android/expectations/monochrome_public_bundle.AndroidManifest.expected +++ b/chrome/android/expectations/monochrome_public_bundle.AndroidManifest.expected
@@ -642,6 +642,7 @@ </activity> # DIFF-ANCHOR: 66a0be05 <activity # DIFF-ANCHOR: a1fac31f android:name="org.chromium.chrome.browser.webauth.authenticator.CableAuthenticatorActivity" + android:configChanges="density|fontScale|keyboard|keyboardHidden|layoutDirection|locale|mcc|mnc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|touchscreen|uiMode" android:excludeFromRecents="true" android:exported="true" android:label="@string/cablev2_activity_title"
diff --git a/chrome/android/expectations/trichrome_chrome_bundle.AndroidManifest.expected b/chrome/android/expectations/trichrome_chrome_bundle.AndroidManifest.expected index 02ddb5fd..9e18493 100644 --- a/chrome/android/expectations/trichrome_chrome_bundle.AndroidManifest.expected +++ b/chrome/android/expectations/trichrome_chrome_bundle.AndroidManifest.expected
@@ -615,6 +615,7 @@ </activity> # DIFF-ANCHOR: 66a0be05 <activity # DIFF-ANCHOR: a1fac31f android:name="org.chromium.chrome.browser.webauth.authenticator.CableAuthenticatorActivity" + android:configChanges="density|fontScale|keyboard|keyboardHidden|layoutDirection|locale|mcc|mnc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|touchscreen|uiMode" android:excludeFromRecents="true" android:exported="true" android:label="@string/cablev2_activity_title"
diff --git a/chrome/android/features/cablev2_authenticator/java/res/layout-sw600dp/cablev2_ble_enable.xml b/chrome/android/features/cablev2_authenticator/java/res/layout-sw600dp/cablev2_ble_enable.xml index 298df85..39bd2cf 100644 --- a/chrome/android/features/cablev2_authenticator/java/res/layout-sw600dp/cablev2_ble_enable.xml +++ b/chrome/android/features/cablev2_authenticator/java/res/layout-sw600dp/cablev2_ble_enable.xml
@@ -3,41 +3,49 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<LinearLayout +<ScrollView xmlns:a="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" a:layout_width="match_parent" a:layout_height="match_parent" - a:orientation="vertical" - a:gravity="center" - tools:ignore="UseCompoundDrawables"> + a:fillViewport="true" + a:scrollbars="none"> - <TextView + <LinearLayout a:layout_width="match_parent" a:layout_height="wrap_content" - a:layout_marginTop="-104dp" - a:layout_marginLeft="24dp" - a:layout_marginRight="24dp" - a:gravity="center_horizontal" - a:text="@string/cablev2_ble_enable_title" - a:textSize="36sp" /> + a:orientation="vertical" + a:gravity="center" + tools:ignore="UseCompoundDrawables"> - <!-- This is a semantically-meaningless picture of a phone and BLE icon that - screen readers can ignore. Thus contentDescription is null. + <TextView + a:layout_width="match_parent" + a:layout_height="wrap_content" + a:layout_marginTop="-104dp" + a:layout_marginLeft="24dp" + a:layout_marginRight="24dp" + a:gravity="center_horizontal" + a:text="@string/cablev2_ble_enable_title" + a:textSize="36sp" /> - The visual center of this image isn't the pixel-center, and thus a left margin - is used to tweak the horizontal centering. The tooling thinks that's an RTL - issue, but RTL mode doesn't reflect images so the padding still needs to - be on the left. tools:ignore is used to skip this warning. --> - <ImageView - a:layout_width="match_parent" - a:layout_height="212dp" - a:layout_marginTop="52dp" - a:layout_marginLeft="40dp" - a:layout_marginBottom="35dp" - a:contentDescription="@null" - a:gravity="center_horizontal" - a:src="@drawable/ble" - tools:ignore="RtlHardcoded"/> + <!-- This is a semantically-meaningless picture of a phone and BLE icon that + screen readers can ignore. Thus contentDescription is null. -</LinearLayout> + The visual center of this image isn't the pixel-center, and thus a left margin + is used to tweak the horizontal centering. The tooling thinks that's an RTL + issue, but RTL mode doesn't reflect images so the padding still needs to + be on the left. tools:ignore is used to skip this warning. --> + <ImageView + a:layout_width="match_parent" + a:layout_height="212dp" + a:layout_marginTop="52dp" + a:layout_marginLeft="40dp" + a:layout_marginBottom="35dp" + a:contentDescription="@null" + a:gravity="center_horizontal" + a:src="@drawable/ble" + tools:ignore="RtlHardcoded"/> + + </LinearLayout> + +</ScrollView>
diff --git a/chrome/android/features/cablev2_authenticator/java/res/layout/cablev2_ble_enable.xml b/chrome/android/features/cablev2_authenticator/java/res/layout/cablev2_ble_enable.xml index ad1c43e..a823e35 100644 --- a/chrome/android/features/cablev2_authenticator/java/res/layout/cablev2_ble_enable.xml +++ b/chrome/android/features/cablev2_authenticator/java/res/layout/cablev2_ble_enable.xml
@@ -3,38 +3,46 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<LinearLayout +<ScrollView xmlns:a="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" a:layout_width="match_parent" a:layout_height="match_parent" - a:orientation="vertical" - tools:ignore="UseCompoundDrawables"> + a:fillViewport="true" + a:scrollbars="none"> - <TextView - style="@style/TextAppearance.Headline.Primary" + <LinearLayout a:layout_width="match_parent" a:layout_height="wrap_content" - a:layout_marginTop="104dp" - a:gravity="center_horizontal" - a:text="@string/cablev2_ble_enable_title"/> + a:orientation="vertical" + tools:ignore="UseCompoundDrawables"> - <!-- This is a semantically-meaningless picture of a phone and BLE icon that - screen readers can ignore. Thus contentDescription is null. + <TextView + style="@style/TextAppearance.Headline.Primary" + a:layout_width="match_parent" + a:layout_height="wrap_content" + a:layout_marginTop="104dp" + a:gravity="center_horizontal" + a:text="@string/cablev2_ble_enable_title"/> - The visual center of this image isn't the pixel-center, and thus a left margin - is used to tweak the horizontal centering. The tooling thinks that's an RTL - issue, but RTL mode doesn't reflect images so the padding still needs to - be on the left. tools:ignore is used to skip this warning. --> - <ImageView - a:layout_width="match_parent" - a:layout_height="212dp" - a:layout_marginTop="52dp" - a:layout_marginLeft="40dp" - a:layout_marginBottom="35dp" - a:contentDescription="@null" - a:gravity="center_horizontal" - a:src="@drawable/ble" - tools:ignore="RtlHardcoded"/> + <!-- This is a semantically-meaningless picture of a phone and BLE icon that + screen readers can ignore. Thus contentDescription is null. -</LinearLayout> + The visual center of this image isn't the pixel-center, and thus a left margin + is used to tweak the horizontal centering. The tooling thinks that's an RTL + issue, but RTL mode doesn't reflect images so the padding still needs to + be on the left. tools:ignore is used to skip this warning. --> + <ImageView + a:layout_width="match_parent" + a:layout_height="212dp" + a:layout_marginTop="52dp" + a:layout_marginLeft="40dp" + a:layout_marginBottom="35dp" + a:contentDescription="@null" + a:gravity="center_horizontal" + a:src="@drawable/ble" + tools:ignore="RtlHardcoded"/> + + </LinearLayout> + +</ScrollView>
diff --git a/chrome/android/features/cablev2_authenticator/java/res/layout/cablev2_usb_attached.xml b/chrome/android/features/cablev2_authenticator/java/res/layout/cablev2_usb_attached.xml index ba8f10f..936f54ab 100644 --- a/chrome/android/features/cablev2_authenticator/java/res/layout/cablev2_usb_attached.xml +++ b/chrome/android/features/cablev2_authenticator/java/res/layout/cablev2_usb_attached.xml
@@ -3,40 +3,48 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android" +<ScrollView + xmlns:a="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" a:layout_width="match_parent" a:layout_height="match_parent" - a:gravity="center" - a:orientation="vertical"> + a:fillViewport="true" + a:scrollbars="none"> - <TextView - a:id="@+id/usb_label" - xmlns:tools="http://schemas.android.com/tools" - style="@style/TextAppearance.Headline.Primary" - a:layout_width="match_parent" - a:layout_height="wrap_content" - a:layout_marginBottom="40dp" - a:gravity="center" - a:text="@string/cablev2_usb_discon_title" /> - - <ImageView - a:id="@+id/usb_icon_disconnect" - a:layout_height="203dp" - a:layout_width="296dp" - a:layout_marginLeft="100dp" - a:layout_marginRight="100dp" - a:layout_marginBottom="25dp" - a:contentDescription="@null" - a:gravity="center_horizontal" - a:src="@drawable/usb_conn_disconnect"/> - - <TextView - a:id="@+id/usb_title" - xmlns:tools="http://schemas.android.com/tools" - style="@style/TextAppearance.TextLarge.Secondary" + <LinearLayout a:layout_width="match_parent" a:layout_height="wrap_content" a:gravity="center" - a:text="@string/cablev2_usb_discon_body" /> + a:orientation="vertical"> -</LinearLayout> + <TextView + a:id="@+id/usb_label" + style="@style/TextAppearance.Headline.Primary" + a:layout_width="match_parent" + a:layout_height="wrap_content" + a:layout_marginBottom="40dp" + a:gravity="center" + a:text="@string/cablev2_usb_discon_title" /> + + <ImageView + a:id="@+id/usb_icon_disconnect" + a:layout_height="203dp" + a:layout_width="296dp" + a:layout_marginLeft="100dp" + a:layout_marginRight="100dp" + a:layout_marginBottom="25dp" + a:contentDescription="@null" + a:gravity="center_horizontal" + a:src="@drawable/usb_conn_disconnect"/> + + <TextView + a:id="@+id/usb_title" + style="@style/TextAppearance.TextLarge.Secondary" + a:layout_width="match_parent" + a:layout_height="wrap_content" + a:gravity="center" + a:text="@string/cablev2_usb_discon_body" /> + + </LinearLayout> + +</ScrollView>
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceBackButtonTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceBackButtonTest.java index 595726f..db42be3 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceBackButtonTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceBackButtonTest.java
@@ -56,6 +56,7 @@ import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.layouts.LayoutStateProvider; +import org.chromium.chrome.browser.layouts.LayoutTestUtils; import org.chromium.chrome.browser.layouts.LayoutType; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabLaunchType; @@ -66,7 +67,6 @@ import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.ChromeApplicationTestUtils; import org.chromium.chrome.test.util.MenuUtils; -import org.chromium.chrome.test.util.OverviewModeBehaviorWatcher; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.test.util.UiRestriction; @@ -251,11 +251,9 @@ -> Assert.assertTrue(StartSurfaceUserData.getKeepTab( cta.getTabModelSelector().getCurrentTab()))); - OverviewModeBehaviorWatcher overviewModeWatcher = - new OverviewModeBehaviorWatcher(cta.getLayoutManager(), true, false); StartSurfaceTestUtils.pressBack(mActivityTestRule); // Verifies the new Tab isn't deleted, and Start surface is shown. - overviewModeWatcher.waitForBehavior(); + LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.TAB_SWITCHER); TabUiTestHelper.verifyTabModelTabCount(cta, 2, 0); // Verifies Chrome is closed. @@ -295,12 +293,11 @@ StartSurfaceTestUtils.waitForTabModel(cta); TabUiTestHelper.verifyTabModelTabCount(cta, 1, 0); - OverviewModeBehaviorWatcher hideWatcher = TabUiTestHelper.createOverviewHideWatcher(cta); onViewWaiting(withId(org.chromium.chrome.start_surface.R.id.search_box_text)) .perform(replaceText("about:blank")); onView(withId(org.chromium.chrome.start_surface.R.id.url_bar)) .perform(pressKey(KeyEvent.KEYCODE_ENTER)); - hideWatcher.waitForBehavior(); + LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.BROWSING); TabUiTestHelper.verifyTabModelTabCount(cta, 2, 0); TabUiTestHelper.mergeAllNormalTabsToAGroup(cta);
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java index c78cb70..5f27ba6 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java
@@ -131,7 +131,6 @@ import org.chromium.chrome.test.util.ChromeRenderTestRule; import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.chrome.test.util.MenuUtils; -import org.chromium.chrome.test.util.OverviewModeBehaviorWatcher; import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.Features.DisableFeatures; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; @@ -1735,11 +1734,10 @@ // Click the chip and check the tab navigates back to the search result page. assertEquals(mUrl, ChromeTabUtils.getUrlStringOnUiThread(currentTab)); - OverviewModeBehaviorWatcher hideWatcher = TabUiTestHelper.createOverviewHideWatcher(cta); onView(withId(R.id.page_info_button)) .check(waitForView(allOf(withText(expectedTerm), isDisplayed()))); onView(withId(R.id.page_info_button)).perform(click()); - hideWatcher.waitForBehavior(); + LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.BROWSING); ChromeTabUtils.waitForTabPageLoaded(currentTab, searchUrl.get()); // Verify the chip is gone.
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceMVTilesTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceMVTilesTest.java index 7fe4494..9fb9987a 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceMVTilesTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceMVTilesTest.java
@@ -46,6 +46,7 @@ import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.layouts.LayoutStateProvider; +import org.chromium.chrome.browser.layouts.LayoutTestUtils; import org.chromium.chrome.browser.layouts.LayoutType; import org.chromium.chrome.browser.native_page.ContextMenuManager; import org.chromium.chrome.browser.suggestions.SiteSuggestion; @@ -56,7 +57,6 @@ import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; -import org.chromium.chrome.test.util.OverviewModeBehaviorWatcher; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule; import org.chromium.chrome.test.util.browser.suggestions.mostvisited.FakeMostVisitedSites; @@ -164,9 +164,8 @@ return; } // Press back button should close the tab opened from the Start surface. - OverviewModeBehaviorWatcher showWatcher = TabUiTestHelper.createOverviewShowWatcher(cta); StartSurfaceTestUtils.pressBack(mActivityTestRule); - showWatcher.waitForBehavior(); + LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.TAB_SWITCHER); assertThat(cta.getTabModelSelector().getCurrentModel().getCount(), equalTo(1)); } @@ -300,9 +299,8 @@ // Open the incognito tile using the context menu. TabUiTestHelper.verifyTabModelTabCount(cta, 1, 0); - OverviewModeBehaviorWatcher hideWatcher = TabUiTestHelper.createOverviewHideWatcher(cta); invokeContextMenu(tileView, ContextMenuManager.ContextMenuItemId.OPEN_IN_INCOGNITO_TAB); - hideWatcher.waitForBehavior(); + LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.BROWSING); CriteriaHelper.pollUiThread(() -> !cta.getLayoutManager().overviewVisible()); // Verifies a new incognito tab is created. TabUiTestHelper.verifyTabModelTabCount(cta, 1, 1);
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTabSwitcherTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTabSwitcherTest.java index 6364bbb..e21b534 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTabSwitcherTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTabSwitcherTest.java
@@ -65,7 +65,6 @@ import org.chromium.chrome.browser.toolbar.HomeButton; import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; -import org.chromium.chrome.test.util.OverviewModeBehaviorWatcher; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.test.util.UiRestriction; @@ -165,12 +164,11 @@ onViewWaiting(withId(org.chromium.chrome.start_surface.R.id.secondary_tasks_surface_view)); - OverviewModeBehaviorWatcher hideWatcher = - TabUiTestHelper.createOverviewHideWatcher(mActivityTestRule.getActivity()); onViewWaiting(allOf(withParent(withId(org.chromium.chrome.tab_ui.R.id.tasks_surface_body)), withId(org.chromium.chrome.tab_ui.R.id.tab_list_view))) .perform(RecyclerViewActions.actionOnItemAtPosition(0, click())); - hideWatcher.waitForBehavior(); + LayoutTestUtils.waitForLayout( + mActivityTestRule.getActivity().getLayoutManager(), LayoutType.BROWSING); } @Test @@ -330,10 +328,8 @@ () -> { Assert.assertNotEquals(tab1.getTitle(), tab2.getTitle()); }); // Returns to the Start surface. - OverviewModeBehaviorWatcher overviewModeWatcher = - new OverviewModeBehaviorWatcher(cta.getLayoutManager(), true, false); StartSurfaceTestUtils.pressHomePageButton(cta); - overviewModeWatcher.waitForBehavior(); + LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.TAB_SWITCHER); waitForView(allOf( withParent(withId(org.chromium.chrome.tab_ui.R.id.carousel_tab_switcher_container)), withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)));
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java index f5b5d9e..be516a4 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
@@ -95,7 +95,6 @@ import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.ChromeTabUtils; -import org.chromium.chrome.test.util.OverviewModeBehaviorWatcher; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule; import org.chromium.components.browser_ui.bottomsheet.BottomSheetTestSupport; @@ -224,9 +223,8 @@ StartSurfaceTestUtils.pressBack(mActivityTestRule); onViewWaiting(allOf(withId(R.id.primary_tasks_surface_view), isDisplayed())); - OverviewModeBehaviorWatcher hideWatcher = TabUiTestHelper.createOverviewHideWatcher(cta); StartSurfaceTestUtils.clickFirstTabInCarousel(); - hideWatcher.waitForBehavior(); + LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.BROWSING); } @Test @@ -280,9 +278,8 @@ onView(withId(org.chromium.chrome.tab_ui.R.id.incognito_toggle_tabs)) .check(matches(withEffectiveVisibility(GONE))); - OverviewModeBehaviorWatcher hideWatcher = TabUiTestHelper.createOverviewHideWatcher(cta); StartSurfaceTestUtils.clickFirstTabInCarousel(); - hideWatcher.waitForBehavior(); + LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.BROWSING); } @Test @@ -331,9 +328,8 @@ return; } - OverviewModeBehaviorWatcher hideWatcher = TabUiTestHelper.createOverviewHideWatcher(cta); StartSurfaceTestUtils.clickFirstTabInCarousel(); - hideWatcher.waitForBehavior(); + LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.BROWSING); } @Test @@ -385,9 +381,8 @@ StartSurfaceTestUtils.pressBack(mActivityTestRule); onViewWaiting(withId(R.id.primary_tasks_surface_view)); - OverviewModeBehaviorWatcher hideWatcher = TabUiTestHelper.createOverviewHideWatcher(cta); onViewWaiting(withId(org.chromium.chrome.tab_ui.R.id.single_tab_view)).perform(click()); - hideWatcher.waitForBehavior(); + LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.BROWSING); } @Test @@ -450,10 +445,9 @@ StartSurfaceTestUtils.waitForTabModel(cta); assertThat(cta.getTabModelSelector().getCurrentModel().getCount(), equalTo(1)); - OverviewModeBehaviorWatcher hideWatcher = TabUiTestHelper.createOverviewHideWatcher(cta); onViewWaiting(withId(R.id.search_box_text)).perform(replaceText("about:blank")); onViewWaiting(withId(R.id.url_bar)).perform(pressKey(KeyEvent.KEYCODE_ENTER)); - hideWatcher.waitForBehavior(); + LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.BROWSING); assertThat(cta.getTabModelSelector().getCurrentModel().getCount(), equalTo(2)); TestThreadUtils.runOnUiThreadBlocking(() -> cta.getTabCreator(false).launchNTP()); @@ -492,10 +486,9 @@ } assertTrue(cta.getTabModelSelector().isIncognitoSelected()); - OverviewModeBehaviorWatcher hideWatcher = TabUiTestHelper.createOverviewHideWatcher(cta); onViewWaiting(withId(R.id.search_box_text)).perform(replaceText("about:blank")); onView(withId(R.id.url_bar)).perform(pressKey(KeyEvent.KEYCODE_ENTER)); - hideWatcher.waitForBehavior(); + LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.BROWSING); assertThat(cta.getTabModelSelector().getCurrentModel().getCount(), equalTo(1)); }
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java index 33f8aed..180f6bad 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java
@@ -74,7 +74,6 @@ import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.ChromeApplicationTestUtils; -import org.chromium.chrome.test.util.OverviewModeBehaviorWatcher; import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule; import org.chromium.chrome.test.util.browser.suggestions.mostvisited.FakeMostVisitedSites; import org.chromium.content_public.browser.test.util.TestThreadUtils; @@ -386,7 +385,6 @@ */ public static void launchFirstMVTile(ChromeTabbedActivity cta, int currentTabCount) { TabUiTestHelper.verifyTabModelTabCount(cta, currentTabCount, 0); - OverviewModeBehaviorWatcher hideWatcher = TabUiTestHelper.createOverviewHideWatcher(cta); onViewWaiting(withId(org.chromium.chrome.tab_ui.R.id.mv_tiles_layout)) .perform(new ViewAction() { @Override @@ -405,7 +403,7 @@ mvTilesContainer.getChildAt(0).performClick(); } }); - hideWatcher.waitForBehavior(); + LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.BROWSING); CriteriaHelper.pollUiThread(() -> !cta.getLayoutManager().overviewVisible()); // Verifies a new Tab is created. TabUiTestHelper.verifyTabModelTabCount(cta, currentTabCount + 1, 0);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceCardView.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceCardView.java index 54616e1f..e2bfc4bd 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceCardView.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceCardView.java
@@ -12,7 +12,6 @@ import android.widget.FrameLayout; import android.widget.TextView; -import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.tab_ui.R; /** @@ -44,9 +43,8 @@ mPreviousPriceInfoBox = (TextView) findViewById(R.id.previous_price); mPreviousPriceInfoBox.setPaintFlags( mPreviousPriceInfoBox.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); - mPriceInfoBox.setTextColor(ApiCompatibilityUtils.getColor( - getResources(), R.color.price_drop_annotation_text_green)); + mPriceInfoBox.setTextColor(getContext().getColor(R.color.price_drop_annotation_text_green)); mPreviousPriceInfoBox.setTextColor( - ApiCompatibilityUtils.getColor(getResources(), R.color.chip_text_color_secondary)); + getContext().getColor(R.color.chip_text_color_secondary)); } }
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java index ca72b121..3e2c0b5 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java
@@ -57,6 +57,8 @@ import org.chromium.base.test.util.CriteriaHelper; import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; +import org.chromium.chrome.browser.layouts.LayoutTestUtils; +import org.chromium.chrome.browser.layouts.LayoutType; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tabmodel.TabModel; @@ -65,7 +67,6 @@ import org.chromium.chrome.tab_ui.R; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.ChromeTabUtils; -import org.chromium.chrome.test.util.OverviewModeBehaviorWatcher; import org.chromium.content_public.browser.test.util.TestThreadUtils; import java.io.File; @@ -107,12 +108,11 @@ * @param cta The current running activity. */ public static void enterTabSwitcher(ChromeTabbedActivity cta) { - OverviewModeBehaviorWatcher showWatcher = createOverviewShowWatcher(cta); assertFalse(cta.getLayoutManager().overviewVisible()); // TODO(crbug.com/1145271): Replace this with clicking tab switcher button via espresso. TestThreadUtils.runOnUiThreadBlocking( () -> { cta.findViewById(R.id.tab_switcher_button).performClick(); }); - showWatcher.waitForBehavior(); + LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.TAB_SWITCHER); } /** @@ -120,10 +120,9 @@ * @param cta The current running activity. */ public static void leaveTabSwitcher(ChromeTabbedActivity cta) { - OverviewModeBehaviorWatcher hideWatcher = createOverviewHideWatcher(cta); assertTrue(cta.getLayoutManager().overviewVisible()); pressBack(); - hideWatcher.waitForBehavior(); + LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.BROWSING); } /** @@ -162,10 +161,9 @@ * @param index The index of the target tab. */ static void clickNthTabInDialog(ChromeTabbedActivity cta, int index) { - OverviewModeBehaviorWatcher hideWatcher = createOverviewHideWatcher(cta); onView(allOf(withId(R.id.tab_list_view), withParent(withId(R.id.dialog_container_view)))) .perform(RecyclerViewActions.actionOnItemAtPosition(index, click())); - hideWatcher.waitForBehavior(); + LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.BROWSING); } /** @@ -390,20 +388,6 @@ } /** - * Create a {@link OverviewModeBehaviorWatcher} to inspect overview show. - */ - public static OverviewModeBehaviorWatcher createOverviewShowWatcher(ChromeTabbedActivity cta) { - return new OverviewModeBehaviorWatcher(cta.getLayoutManager(), true, false); - } - - /** - * Create a {@link OverviewModeBehaviorWatcher} to inspect overview hide. - */ - public static OverviewModeBehaviorWatcher createOverviewHideWatcher(ChromeTabbedActivity cta) { - return new OverviewModeBehaviorWatcher(cta.getLayoutManager(), false, true); - } - - /** * @return whether animators are enabled on device by checking whether the animation duration * scale is set to 0.0. */
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index e1948a0f..ac19edf 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -896,13 +896,19 @@ </intent-filter> </activity> - <activity android:name="org.chromium.chrome.browser.webauth.authenticator.CableAuthenticatorActivity" - android:theme="@style/Theme.Chromium.Activity.Fullscreen" - android:label="@string/cablev2_activity_title" - android:permission="com.google.android.gms.auth.cryptauth.permission.CABLEV2_SERVER_LINK" - android:exported="true" - android:excludeFromRecents="true" - android:launchMode="singleTop"> + <!-- configChanges is set here to prevent the destruction of the + activity after configuration changes. Since the bulk of this + activity's logic is in a feature module, restoring the activity + via a Bundle doesn't work. --> + <activity + android:name="org.chromium.chrome.browser.webauth.authenticator.CableAuthenticatorActivity" + android:configChanges="density|fontScale|keyboard|keyboardHidden|layoutDirection|locale|mcc|mnc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|touchscreen|uiMode" + android:theme="@style/Theme.Chromium.Activity.Fullscreen" + android:label="@string/cablev2_activity_title" + android:permission="com.google.android.gms.auth.cryptauth.permission.CABLEV2_SERVER_LINK" + android:exported="true" + android:excludeFromRecents="true" + android:launchMode="singleTop"> <!-- This activity can be started by GMSCore, and is thus exported with a permission set, or can be started by the Android system in the case that a USB device is attached. -->
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java index da247c1..43e9100 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java
@@ -28,10 +28,11 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.flags.ChromeSwitches; +import org.chromium.chrome.browser.layouts.LayoutTestUtils; +import org.chromium.chrome.browser.layouts.LayoutType; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.ChromeTabUtils; -import org.chromium.chrome.test.util.OverviewModeBehaviorWatcher; import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.ScrollDirection; import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.SwipeHandler; import org.chromium.content_public.browser.UiThreadTaskTraits; @@ -173,10 +174,6 @@ public void testHideSelectionOnPhoneTabSwitcher() throws Exception { mActivityTestRule.startMainActivityOnBlankPage(); // Setup - OverviewModeBehaviorWatcher showWatcher = new OverviewModeBehaviorWatcher( - mActivityTestRule.getActivity().getLayoutManager(), true, false); - OverviewModeBehaviorWatcher hideWatcher = new OverviewModeBehaviorWatcher( - mActivityTestRule.getActivity().getLayoutManager(), false, true); View currentView = mActivityTestRule.getActivity().getActivityTab().getContentView(); addFocusChangedListener(currentView); @@ -186,7 +183,8 @@ Assert.assertNotNull("'tab_switcher_button' view is not found.", tabSwitcherButton); TouchCommon.singleClickView( mActivityTestRule.getActivity().findViewById(R.id.tab_switcher_button)); - showWatcher.waitForBehavior(); + LayoutTestUtils.waitForLayout( + mActivityTestRule.getActivity().getLayoutManager(), LayoutType.TAB_SWITCHER); // Make sure the view loses focus. It is immediately given focus back // because it's the only focusable view. @@ -197,7 +195,8 @@ Assert.assertNotNull("'tab_switcher_button' view is not found.", tabSwitcherButton); TouchCommon.singleClickView( mActivityTestRule.getActivity().findViewById(R.id.tab_switcher_button)); - hideWatcher.waitForBehavior(); + LayoutTestUtils.waitForLayout( + mActivityTestRule.getActivity().getLayoutManager(), LayoutType.BROWSING); Assert.assertTrue("Content view didn't regain focus", blockForFocusChanged()); Assert.assertFalse("Unexpected focus change", haveFocusChanges());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java index 2754ec9d..8996752 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java
@@ -68,7 +68,6 @@ import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.chrome.test.util.MenuUtils; import org.chromium.chrome.test.util.NewTabPageTestUtils; -import org.chromium.chrome.test.util.OverviewModeBehaviorWatcher; import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.ScrollDirection; import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.SwipeHandler; import org.chromium.components.javascript_dialogs.JavascriptTabModalDialog; @@ -255,19 +254,18 @@ Assert.assertEquals("Data file for TabsTest", title); }); final int tabCount = mActivityTestRule.getActivity().getCurrentTabModel().getCount(); - OverviewModeBehaviorWatcher overviewModeWatcher = new OverviewModeBehaviorWatcher( - mActivityTestRule.getActivity().getLayoutManager(), true, false); View tabSwitcherButton = mActivityTestRule.getActivity().findViewById(R.id.tab_switcher_button); Assert.assertNotNull("'tab_switcher_button' view is not found", tabSwitcherButton); TouchCommon.singleClickView(tabSwitcherButton); - overviewModeWatcher.waitForBehavior(); - overviewModeWatcher = new OverviewModeBehaviorWatcher( - mActivityTestRule.getActivity().getLayoutManager(), false, true); + LayoutTestUtils.waitForLayout( + mActivityTestRule.getActivity().getLayoutManager(), LayoutType.TAB_SWITCHER); + View newTabButton = mActivityTestRule.getActivity().findViewById(R.id.new_tab_button); Assert.assertNotNull("'new_tab_button' view is not found", newTabButton); TouchCommon.singleClickView(newTabButton); - overviewModeWatcher.waitForBehavior(); + LayoutTestUtils.waitForLayout( + mActivityTestRule.getActivity().getLayoutManager(), LayoutType.BROWSING); InstrumentationRegistry.getInstrumentation().runOnMainSync( () -> Assert.assertEquals("The tab count is wrong", tabCount + 1,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/PermissionUpdateMessageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/PermissionUpdateMessageTest.java index 2cf244a..d6c240f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/PermissionUpdateMessageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/PermissionUpdateMessageTest.java
@@ -20,7 +20,6 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Criteria; import org.chromium.base.test.util.CriteriaHelper; -import org.chromium.chrome.R; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.profiles.Profile; @@ -32,10 +31,11 @@ import org.chromium.components.browser_ui.site_settings.PermissionInfo; import org.chromium.components.content_settings.ContentSettingValues; import org.chromium.components.content_settings.ContentSettingsType; -import org.chromium.components.messages.MessageContainer; +import org.chromium.components.messages.MessagesTestHelper; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.net.test.EmbeddedTestServer; +import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.permissions.AndroidPermissionDelegate; import org.chromium.ui.permissions.PermissionCallback; @@ -87,9 +87,9 @@ -> new PermissionInfo( ContentSettingsType.GEOLOCATION, locationUrl, null, false)); - mActivityTestRule.getActivity().getWindowAndroid().setAndroidPermissionDelegate( - new TestAndroidPermissionDelegate( - null, Arrays.asList(Manifest.permission.ACCESS_FINE_LOCATION), null)); + WindowAndroid windowAndroid = mActivityTestRule.getActivity().getWindowAndroid(); + windowAndroid.setAndroidPermissionDelegate(new TestAndroidPermissionDelegate( + null, Arrays.asList(Manifest.permission.ACCESS_FINE_LOCATION), null)); LocationSettingsTestUtil.setSystemLocationSettingEnabled(true); try { @@ -100,14 +100,11 @@ ContentSettingValues.ALLOW)); mActivityTestRule.loadUrl(mTestServer.getURL(GEOLOCATION_PAGE)); - CriteriaHelper.pollInstrumentationThread( - () -> mActivityTestRule.getActivity().findViewById(R.id.message_container)); - MessageContainer container = - (MessageContainer) mActivityTestRule.getActivity().findViewById( - R.id.message_container); - CriteriaHelper.pollInstrumentationThread( - () -> container.getChildCount() > 0, "Message is not enqueued."); + CriteriaHelper.pollUiThread(() -> { + Criteria.checkThat("Message is not enqueued.", + MessagesTestHelper.getMessageCount(windowAndroid), Matchers.is(1)); + }); final WebContents webContents = TestThreadUtils.runOnUiThreadBlockingNoException( () -> mActivityTestRule.getActivity().getActivityTab().getWebContents());
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index c84e127..151965a 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2454,7 +2454,7 @@ "//chrome/browser/ui/webui/chromeos/parent_access:mojo_bindings", "//chrome/browser/ui/webui/chromeos/vm:mojo_bindings", "//chrome/browser/ui/webui/settings/ash/os_apps_page/mojom", - "//chrome/browser/ui/webui/settings/chromeos/search:mojo_bindings", + "//chrome/browser/ui/webui/settings/ash/search:mojo_bindings", "//chrome/common/chromeos/extensions", "//chromeos/components/chromebox_for_meetings/buildflags", "//chromeos/components/local_search_service",
diff --git a/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.cc b/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.cc index a020ce9..4f6b23e 100644 --- a/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.cc +++ b/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.cc
@@ -244,19 +244,13 @@ // themselves track the current state of the monitoring settings and only // perform monitoring if it is active. if (install_attributes->IsCloudManaged()) { - managed_session_service_ = - std::make_unique<policy::ManagedSessionService>(); + CreateManagedSessionServiceAndReporters(); CreateStatusUploader(managed_session_service_.get()); syslog_uploader_ = std::make_unique<SystemLogUploader>(nullptr, task_runner_); heartbeat_scheduler_ = std::make_unique<HeartbeatScheduler>( g_browser_process->gcm_driver(), client(), device_store_.get(), install_attributes->GetDeviceId(), task_runner_); - login_logout_reporter_ = ash::reporting::LoginLogoutReporter::Create( - managed_session_service_.get()); - user_added_removed_reporter_ = - ::reporting::UserAddedRemovedReporter::Create( - managed_session_service_.get()); metric_reporting_manager_ = reporting::MetricReportingManager::Create( managed_session_service_.get()); } @@ -264,6 +258,14 @@ NotifyConnected(); } +void DeviceCloudPolicyManagerAsh::OnPolicyStoreReady( + chromeos::InstallAttributes* install_attributes) { + if (!install_attributes->IsCloudManaged()) { + return; + } + CreateManagedSessionServiceAndReporters(); +} + void DeviceCloudPolicyManagerAsh::Unregister(UnregisterCallback callback) { if (!service()) { LOG(ERROR) << "Tried to unregister but DeviceCloudPolicyManagerAsh is " @@ -333,4 +335,16 @@ kDeviceStatusUploadFrequency); } +void DeviceCloudPolicyManagerAsh::CreateManagedSessionServiceAndReporters() { + if (managed_session_service_) { + return; + } + + managed_session_service_ = std::make_unique<policy::ManagedSessionService>(); + login_logout_reporter_ = ash::reporting::LoginLogoutReporter::Create( + managed_session_service_.get()); + user_added_removed_reporter_ = ::reporting::UserAddedRemovedReporter::Create( + managed_session_service_.get()); +} + } // namespace policy
diff --git a/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.h b/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.h index 37934c5b..a45bea4 100644 --- a/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.h +++ b/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.h
@@ -110,6 +110,9 @@ void StartConnection(std::unique_ptr<CloudPolicyClient> client_to_connect, chromeos::InstallAttributes* install_attributes); + // Called when policy store is ready. + void OnPolicyStoreReady(chromeos::InstallAttributes* install_attributes); + // Sends the unregister request. |callback| is invoked with a boolean // parameter indicating the result when done. virtual void Unregister(UnregisterCallback callback); @@ -153,6 +156,20 @@ return machine_certificate_uploader_.get(); } + protected: + // Object that monitors managed session related events used by reporting + // services, protected for testing. + std::unique_ptr<ManagedSessionService> managed_session_service_; + + // Object that reports login/logout events to the server, protected for + // testing. + std::unique_ptr<ash::reporting::LoginLogoutReporter> login_logout_reporter_; + + // Object that reports user added/removed events to the server, protected for + // testing. + std::unique_ptr<reporting::UserAddedRemovedReporter> + user_added_removed_reporter_; + private: // Saves the state keys received from |session_manager_client_|. void OnStateKeysUpdated(); @@ -163,6 +180,10 @@ // Factory function to create the StatusUploader. void CreateStatusUploader(ManagedSessionService* managed_session_service); + // Init |managed_session_service_| and reporting objects such as + // |login_logout_reporter_|, and |user_added_removed_reporter_|. + void CreateManagedSessionServiceAndReporters(); + // Points to the same object as the base CloudPolicyManager::store(), but with // actual device policy specific type. std::unique_ptr<DeviceCloudPolicyStoreAsh> device_store_; @@ -183,17 +204,6 @@ // the server, to monitor connectivity. std::unique_ptr<HeartbeatScheduler> heartbeat_scheduler_; - // Object that monitors managed session related events used by reporting - // services. - std::unique_ptr<ManagedSessionService> managed_session_service_; - - // Object that reports login/logout events to the server. - std::unique_ptr<ash::reporting::LoginLogoutReporter> login_logout_reporter_; - - // Object that reports user added/removed events to the server. - std::unique_ptr<reporting::UserAddedRemovedReporter> - user_added_removed_reporter_; - // Object that initiates device metrics collection and reporting. std::unique_ptr<reporting::MetricReportingManager> metric_reporting_manager_;
diff --git a/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash_unittest.cc b/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash_unittest.cc index 6092148b..1e7218c 100644 --- a/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash_unittest.cc +++ b/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash_unittest.cc
@@ -122,6 +122,18 @@ } ~TestingDeviceCloudPolicyManagerAsh() override {} + + ManagedSessionService* GetManagedSessionService() { + return managed_session_service_.get(); + } + + ash::reporting::LoginLogoutReporter* GetLoginLogoutReporter() { + return login_logout_reporter_.get(); + } + + reporting::UserAddedRemovedReporter* GetUserAddedRemovedReporter() { + return user_added_removed_reporter_.get(); + } }; class DeviceCloudPolicyManagerAshTest @@ -140,11 +152,6 @@ chromeos::system::kSerialNumberKeyForTest, "test_sn"); fake_statistics_provider_.SetMachineStatistic( chromeos::system::kHardwareClassKey, "test_hw"); - std::vector<std::string> state_keys; - state_keys.push_back("1"); - state_keys.push_back("2"); - state_keys.push_back("3"); - session_manager_client_.set_server_backed_state_keys(state_keys); session_manager_client_.AddObserver(this); } @@ -229,10 +236,23 @@ ASSERT_EQ(chromeos::InstallAttributes::LOCK_SUCCESS, result); } + void AddStateKeys() { + std::vector<std::string> state_keys; + state_keys.push_back("1"); + state_keys.push_back("2"); + state_keys.push_back("3"); + session_manager_client_.set_server_backed_state_keys(state_keys); + } + void ConnectManager(bool expectExternalDataManagerConnectCall = true) { if (expectExternalDataManagerConnectCall) { EXPECT_CALL(*external_data_manager_, Connect(_)); } + AddStateKeys(); + InitDeviceCloudPolicyInitializer(); + } + + void InitDeviceCloudPolicyInitializer() { manager_->Initialize(&local_state_); policy::EnrollmentRequisitionManager::Initialize(); initializer_ = std::make_unique<DeviceCloudPolicyInitializer>( @@ -347,6 +367,9 @@ job_type); // Should create a status uploader for reporting on enrolled devices. EXPECT_TRUE(manager_->GetStatusUploader()); + EXPECT_TRUE(manager_->GetManagedSessionService()); + EXPECT_TRUE(manager_->GetLoginLogoutReporter()); + EXPECT_TRUE(manager_->GetUserAddedRemovedReporter()); VerifyPolicyPopulated(); ShutdownManager(); @@ -385,6 +408,9 @@ // Should create a status provider for reporting on enrolled devices, even // those that aren't managed. EXPECT_TRUE(manager_->GetStatusUploader()); + EXPECT_TRUE(manager_->GetManagedSessionService()); + EXPECT_TRUE(manager_->GetLoginLogoutReporter()); + EXPECT_TRUE(manager_->GetUserAddedRemovedReporter()); // Switch back to ACTIVE, service the policy fetch and let it propagate. device_policy_->policy_data().set_state(em::PolicyData::ACTIVE); @@ -416,11 +442,45 @@ EXPECT_TRUE(manager_->policies().Equals(bundle)); // Should not create a status provider for reporting on consumer devices. EXPECT_FALSE(manager_->GetStatusUploader()); + EXPECT_FALSE(manager_->GetManagedSessionService()); + EXPECT_FALSE(manager_->GetLoginLogoutReporter()); + EXPECT_FALSE(manager_->GetUserAddedRemovedReporter()); ShutdownManager(); EXPECT_TRUE(manager_->policies().Equals(bundle)); } +TEST_F(DeviceCloudPolicyManagerAshTest, EnrolledDeviceNoStateKeysGenerated) { + LockDevice(); + FlushDeviceSettings(); + EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); + EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + VerifyPolicyPopulated(); + + EXPECT_CALL(job_creation_handler_, OnJobCreation).Times(0); + AllowUninterestingRemoteCommandFetches(); + + EXPECT_FALSE(manager_->GetManagedSessionService()); + EXPECT_FALSE(manager_->GetLoginLogoutReporter()); + EXPECT_FALSE(manager_->GetUserAddedRemovedReporter()); + + InitDeviceCloudPolicyInitializer(); + + // Status uploader for reporting on enrolled devices is only created on + // connect call. + EXPECT_FALSE(manager_->GetStatusUploader()); + // Managed session service and reporters are created when notified by + // |DeviceCloudPolicyInitializer| that the policy store is ready. + EXPECT_TRUE(manager_->GetManagedSessionService()); + EXPECT_TRUE(manager_->GetLoginLogoutReporter()); + EXPECT_TRUE(manager_->GetUserAddedRemovedReporter()); + + ShutdownManager(); + + EXPECT_EQ(store_->policy()->service_account_identity(), + PolicyBuilder::kFakeServiceAccountIdentity); +} + class DeviceCloudPolicyManagerAshObserverTest : public DeviceCloudPolicyManagerAshTest, public DeviceCloudPolicyManagerAsh::Observer { @@ -521,6 +581,7 @@ EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _)) .WillOnce(WithArgs<5>(Invoke(CertCallbackSuccess))); } + AddStateKeys(); } void ExpectFailedEnrollment(EnrollmentStatus::Status status) {
diff --git a/chrome/browser/ash/policy/enrollment/device_cloud_policy_initializer.cc b/chrome/browser/ash/policy/enrollment/device_cloud_policy_initializer.cc index df4a1eda..2a09930 100644 --- a/chrome/browser/ash/policy/enrollment/device_cloud_policy_initializer.cc +++ b/chrome/browser/ash/policy/enrollment/device_cloud_policy_initializer.cc
@@ -259,15 +259,24 @@ return; } + if (!policy_store_->is_initialized() || !policy_store_->has_policy()) { + return; + } + + if (!policy_manager_store_ready_notified_) { + policy_manager_store_ready_notified_ = true; + policy_manager_->OnPolicyStoreReady(install_attributes_); + } + // Currently reven devices don't support sever-backed state keys, but they // also don't support FRE/AutoRE so don't block initialization of device // policy on state keys being available on reven. // TODO(b/208705225): Remove this special case when reven supports state keys. const bool allow_init_without_state_keys = ash::switches::IsRevenBranding(); + // TODO(b/181140445): If we had a separate state keys upload request to DM // Server we could drop the `state_keys_broker_->available()` requirement. - if (policy_store_->is_initialized() && policy_store_->has_policy() && - (allow_init_without_state_keys || state_keys_broker_->available())) { + if (allow_init_without_state_keys || state_keys_broker_->available()) { StartConnection(CreateClient(enterprise_service_)); } }
diff --git a/chrome/browser/ash/policy/enrollment/device_cloud_policy_initializer.h b/chrome/browser/ash/policy/enrollment/device_cloud_policy_initializer.h index 143f9ab2..657713f 100644 --- a/chrome/browser/ash/policy/enrollment/device_cloud_policy_initializer.h +++ b/chrome/browser/ash/policy/enrollment/device_cloud_policy_initializer.h
@@ -103,6 +103,7 @@ DeviceCloudPolicyManagerAsh* policy_manager_; chromeos::system::StatisticsProvider* statistics_provider_; bool is_initialized_ = false; + bool policy_manager_store_ready_notified_ = false; base::CallbackListSubscription state_keys_update_subscription_;
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc index b455296fc..03509986 100644 --- a/chrome/browser/chrome_browser_interface_binders.cc +++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -249,9 +249,9 @@ #include "chrome/browser/ui/webui/nearby_share/nearby_share_dialog_ui.h" #include "chrome/browser/ui/webui/nearby_share/public/mojom/nearby_share_settings.mojom.h" // nogncheck crbug.com/1125897 #include "chrome/browser/ui/webui/settings/ash/os_apps_page/mojom/app_notification_handler.mojom.h" +#include "chrome/browser/ui/webui/settings/ash/search/search.mojom.h" +#include "chrome/browser/ui/webui/settings/ash/search/user_action_recorder.mojom.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/user_action_recorder.mojom.h" #include "chromeos/components/local_search_service/public/mojom/index.mojom.h" #include "chromeos/services/bluetooth_config/public/mojom/cros_bluetooth_config.mojom.h" #include "chromeos/services/cellular_setup/public/mojom/cellular_setup.mojom.h"
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 65e42e5e..792ef16 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -4795,6 +4795,9 @@ "../ui/webui/settings/ash/calculator/size_calculator_test_api.h", "../ui/webui/settings/ash/os_apps_page/app_notification_handler_unittest.cc", "../ui/webui/settings/ash/os_apps_page/mojom/app_type_mojom_traits_unittest.cc", + "../ui/webui/settings/ash/search/per_session_settings_user_action_tracker_unittest.cc", + "../ui/webui/settings/ash/search/search_handler_unittest.cc", + "../ui/webui/settings/ash/search/search_tag_registry_unittest.cc", "../ui/webui/settings/chromeos/ambient_mode_handler_unittest.cc", "../ui/webui/settings/chromeos/bluetooth_handler_unittest.cc", "../ui/webui/settings/chromeos/change_picture_handler_unittest.cc", @@ -4806,9 +4809,6 @@ "../ui/webui/settings/chromeos/multidevice_handler_unittest.cc", "../ui/webui/settings/chromeos/os_settings_manager_unittest.cc", "../ui/webui/settings/chromeos/os_settings_section_unittest.cc", - "../ui/webui/settings/chromeos/search/per_session_settings_user_action_tracker_unittest.cc", - "../ui/webui/settings/chromeos/search/search_handler_unittest.cc", - "../ui/webui/settings/chromeos/search/search_tag_registry_unittest.cc", "../ui/webui/settings/chromeos/settings_user_action_tracker_unittest.cc", ] if (use_cups) {
diff --git a/chrome/browser/extensions/activity_log/activity_log_policy.cc b/chrome/browser/extensions/activity_log/activity_log_policy.cc index 4325583..2e36541 100644 --- a/chrome/browser/extensions/activity_log/activity_log_policy.cc +++ b/chrome/browser/extensions/activity_log/activity_log_policy.cc
@@ -90,7 +90,7 @@ // Strip query parameters, username/password, etc., from URLs. if (action->page_url().is_valid() || action->arg_url().is_valid()) { - url::Replacements<char> url_sanitizer; + GURL::Replacements url_sanitizer; url_sanitizer.ClearUsername(); url_sanitizer.ClearPassword(); url_sanitizer.ClearQuery();
diff --git a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api.cc b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api.cc index 7971b8b..b570d193 100644 --- a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api.cc +++ b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api.cc
@@ -65,8 +65,8 @@ safe_browsing::ReferrerChain referrer_chain; SafeBrowsingNavigationObserverManager::AttributionResult result = - navigation_observer_manager->IdentifyReferrerChainByWebContents( - contents, kReferrerUserGestureLimit, &referrer_chain); + navigation_observer_manager->IdentifyReferrerChainByRenderFrameHost( + contents->GetMainFrame(), kReferrerUserGestureLimit, &referrer_chain); // If the referrer chain is incomplete we'll append the most recent // navigations to referrer chain for diagnostic purposes. This only happens if
diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc index 094fe834..abf92f7 100644 --- a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc +++ b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
@@ -1198,8 +1198,11 @@ return RespondNow(ArgumentList( api::webstore_private::GetReferrerChain::Results::Create(""))); - content::WebContents* web_contents = GetSenderWebContents(); - if (!web_contents) { + content::RenderFrameHost* rfh = render_frame_host(); + content::RenderFrameHost* outermost_rfh = + rfh ? rfh->GetOutermostMainFrame() : nullptr; + + if (!outermost_rfh) { return RespondNow(ErrorWithArguments( api::webstore_private::GetReferrerChain::Results::Create(""), kWebstoreUserCancelledError)); @@ -1211,8 +1214,8 @@ safe_browsing::ReferrerChain referrer_chain; SafeBrowsingNavigationObserverManager::AttributionResult result = - navigation_observer_manager->IdentifyReferrerChainByWebContents( - web_contents, kExtensionReferrerUserGestureLimit, &referrer_chain); + navigation_observer_manager->IdentifyReferrerChainByRenderFrameHost( + outermost_rfh, kExtensionReferrerUserGestureLimit, &referrer_chain); // If the referrer chain is incomplete we'll append the most recent // navigations to referrer chain for diagnostic purposes. This only happens if
diff --git a/chrome/browser/file_select_helper.cc b/chrome/browser/file_select_helper.cc index c815d354..d2a7e57 100644 --- a/chrome/browser/file_select_helper.cc +++ b/chrome/browser/file_select_helper.cc
@@ -32,6 +32,7 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/file_select_listener.h" +#include "content/public/browser/global_routing_id.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" @@ -634,6 +635,9 @@ sb_service->download_protection_service()->CheckPPAPIDownloadRequest( requestor_url, render_frame_host_ ? render_frame_host_->GetLastCommittedURL() : GURL(), + render_frame_host_ + ? render_frame_host_->GetOutermostMainFrame()->GetGlobalId() + : content::GlobalRenderFrameHostId(), WebContents::FromRenderFrameHost(render_frame_host_), default_file_path, alternate_extensions, profile_, base::BindOnce(
diff --git a/chrome/browser/metrics/family_user_metrics_provider_browsertest.cc b/chrome/browser/metrics/family_user_metrics_provider_browsertest.cc index 3eb5f9b..e6b5f61 100644 --- a/chrome/browser/metrics/family_user_metrics_provider_browsertest.cc +++ b/chrome/browser/metrics/family_user_metrics_provider_browsertest.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/metrics/family_user_metrics_provider.h" +#include "ash/components/settings/cros_settings_names.h" #include "base/test/metrics/histogram_tester.h" #include "base/time/time.h" #include "chrome/browser/ash/login/test/device_state_mixin.h" @@ -12,6 +13,8 @@ #include "chrome/browser/ash/login/test/logged_in_user_mixin.h" #include "chrome/browser/ash/login/test/scoped_policy_update.h" #include "chrome/browser/ash/login/test/user_policy_mixin.h" +#include "chrome/browser/ash/settings/scoped_testing_cros_settings.h" +#include "chrome/browser/ash/settings/stub_cros_settings_provider.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/identity_manager_factory.h" @@ -215,6 +218,9 @@ ->set_ephemeral_users_enabled(true); device_policy_update.reset(); + + scoped_testing_cros_settings_.device_settings()->SetBoolean( + ash::kReportDeviceLoginLogout, false); } // MixinBasedInProcessBrowserTest: @@ -232,6 +238,8 @@ ash::LoggedInUserMixin logged_in_user_mixin_{ &mixin_host_, ash::LoggedInUserMixin::LogInType::kRegular, embedded_test_server(), this}; + + ash::ScopedTestingCrosSettings scoped_testing_cros_settings_; }; // Tests that regular ephemeral users report 0 for number of secondary accounts.
diff --git a/chrome/browser/net/secure_dns_util.cc b/chrome/browser/net/secure_dns_util.cc index 2280d42b..8821d9db 100644 --- a/chrome/browser/net/secure_dns_util.cc +++ b/chrome/browser/net/secure_dns_util.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/net/secure_dns_util.h" #include <algorithm> +#include <memory> #include <string> #include "base/check.h" @@ -14,6 +15,7 @@ #include "base/strings/string_piece.h" #include "base/strings/string_split.h" #include "build/build_config.h" +#include "chrome/browser/net/dns_probe_runner.h" #include "chrome/common/chrome_features.h" #include "components/country_codes/country_codes.h" #include "components/embedder_support/pref_names.h" @@ -22,10 +24,9 @@ #include "net/dns/public/dns_config_overrides.h" #include "net/dns/public/dns_over_https_config.h" #include "net/dns/public/doh_provider_entry.h" +#include "net/dns/public/secure_dns_mode.h" -namespace chrome_browser_net { - -namespace secure_dns { +namespace chrome_browser_net::secure_dns { namespace { @@ -145,13 +146,17 @@ UMA_HISTOGRAM_BOOLEAN("Net.DNS.UI.ProbeAttemptSuccess", success); } -void ApplyConfig(net::DnsConfigOverrides* overrides, - base::StringPiece doh_config) { - overrides->dns_over_https_config = - net::DnsOverHttpsConfig::FromString(doh_config); - CHECK(overrides->dns_over_https_config); // `doh_config` must be valid. +std::unique_ptr<DnsProbeRunner> MakeProbeRunner( + net::DnsOverHttpsConfig doh_config, + const DnsProbeRunner::NetworkContextGetter& network_context_getter) { + net::DnsConfigOverrides overrides; + overrides.search = std::vector<std::string>(); + overrides.attempts = 1; + overrides.secure_dns_mode = net::SecureDnsMode::kSecure; + overrides.dns_over_https_config = std::move(doh_config); + + return std::make_unique<DnsProbeRunner>(std::move(overrides), + network_context_getter); } -} // namespace secure_dns - -} // namespace chrome_browser_net +} // namespace chrome_browser_net::secure_dns
diff --git a/chrome/browser/net/secure_dns_util.h b/chrome/browser/net/secure_dns_util.h index 5e9b3c4..cd4d993 100644 --- a/chrome/browser/net/secure_dns_util.h +++ b/chrome/browser/net/secure_dns_util.h
@@ -5,21 +5,18 @@ #ifndef CHROME_BROWSER_NET_SECURE_DNS_UTIL_H_ #define CHROME_BROWSER_NET_SECURE_DNS_UTIL_H_ +#include <memory> #include <vector> #include "base/strings/string_piece.h" +#include "chrome/browser/net/dns_probe_runner.h" +#include "net/dns/public/dns_over_https_config.h" #include "net/dns/public/doh_provider_entry.h" -namespace net { -struct DnsConfigOverrides; -} // namespace net - class PrefRegistrySimple; class PrefService; -namespace chrome_browser_net { - -namespace secure_dns { +namespace chrome_browser_net::secure_dns { // Returns the subset of |providers| that are marked for use in the specified // country. @@ -47,9 +44,10 @@ void UpdateValidationHistogram(bool valid); void UpdateProbeHistogram(bool success); -// Modifies `overrides` to use the DoH servers specified by `doh_config`. -void ApplyConfig(net::DnsConfigOverrides* overrides, - base::StringPiece doh_config); +// Returns a DNS prober configured for testing DoH servers +std::unique_ptr<DnsProbeRunner> MakeProbeRunner( + net::DnsOverHttpsConfig doh_config, + const DnsProbeRunner::NetworkContextGetter& network_context_getter); // Registers the backup preference required for the DNS probes setting reset. // TODO(crbug.com/1062698): Remove this once the privacy settings redesign @@ -63,8 +61,6 @@ // is fully launched. void MigrateProbesSettingToOrFromBackup(PrefService* prefs); -} // namespace secure_dns - -} // namespace chrome_browser_net +} // namespace chrome_browser_net::secure_dns #endif // CHROME_BROWSER_NET_SECURE_DNS_UTIL_H_
diff --git a/chrome/browser/net/secure_dns_util_unittest.cc b/chrome/browser/net/secure_dns_util_unittest.cc index ee9bf61..955a38f 100644 --- a/chrome/browser/net/secure_dns_util_unittest.cc +++ b/chrome/browser/net/secure_dns_util_unittest.cc
@@ -5,9 +5,13 @@ #include "chrome/browser/net/secure_dns_util.h" #include <memory> +#include <string> +#include <vector> +#include "base/test/bind.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" +#include "base/test/task_environment.h" #include "build/build_config.h" #include "chrome/common/chrome_features.h" #include "components/country_codes/country_codes.h" @@ -17,14 +21,15 @@ #include "net/dns/public/dns_config_overrides.h" #include "net/dns/public/dns_over_https_config.h" #include "net/dns/public/doh_provider_entry.h" +#include "net/dns/public/secure_dns_mode.h" +#include "services/network/public/mojom/network_context.mojom.h" +#include "services/network/test/test_network_context.h" #include "testing/gmock/include/gmock/gmock-matchers.h" #include "testing/gtest/include/gtest/gtest.h" using testing::ElementsAre; -namespace chrome_browser_net { - -namespace secure_dns { +namespace chrome_browser_net::secure_dns { class SecureDnsUtilTest : public testing::Test {}; @@ -72,31 +77,21 @@ EXPECT_FALSE(prefs.GetBoolean(kAlternateErrorPagesBackup)); } -TEST(SecureDnsUtil, ApplyDohTemplatePost) { - std::string post_template("https://valid"); - net::DnsConfigOverrides overrides; - ApplyConfig(&overrides, post_template); +TEST(SecureDnsUtil, MakeProbeRunner) { + base::test::SingleThreadTaskEnvironment task_environment; - EXPECT_EQ(*net::DnsOverHttpsConfig::FromString(post_template), - overrides.dns_over_https_config); -} - -TEST(SecureDnsUtil, ApplyTwoDohTemplates) { - std::string two_templates("https://valid https://valid/{?dns}"); - net::DnsConfigOverrides overrides; - ApplyConfig(&overrides, two_templates); - - EXPECT_EQ(*net::DnsOverHttpsConfig::FromString(two_templates), - overrides.dns_over_https_config); -} - -TEST(SecureDnsUtil, ApplyDohTemplateGet) { - std::string get_template("https://valid/{?dns}"); - net::DnsConfigOverrides overrides; - ApplyConfig(&overrides, get_template); - - EXPECT_EQ(*net::DnsOverHttpsConfig::FromString(get_template), - overrides.dns_over_https_config); + auto doh_config = *net::DnsOverHttpsConfig::FromString( + "https://valid https://valid/{?dns}"); + network::TestNetworkContext test_context; + auto prober = MakeProbeRunner( + doh_config, + base::BindLambdaForTesting( + [&]() -> network::mojom::NetworkContext* { return &test_context; })); + auto overrides = prober->GetConfigOverridesForTesting(); + EXPECT_EQ(1, overrides.attempts); + EXPECT_EQ(std::vector<std::string>(), overrides.search); + EXPECT_EQ(net::SecureDnsMode::kSecure, overrides.secure_dns_mode); + EXPECT_EQ(doh_config, overrides.dns_over_https_config); } net::DohProviderEntry::List GetProvidersForTesting() { @@ -199,6 +194,4 @@ histograms.ExpectTotalCount(kUmaBase + ".Unselected", 1u); } -} // namespace secure_dns - -} // namespace chrome_browser_net +} // namespace chrome_browser_net::secure_dns
diff --git a/chrome/browser/prerender/prerender_omnibox_ui_browsertest.cc b/chrome/browser/prerender/prerender_omnibox_ui_browsertest.cc index ee1e629..1c5531c 100644 --- a/chrome/browser/prerender/prerender_omnibox_ui_browsertest.cc +++ b/chrome/browser/prerender/prerender_omnibox_ui_browsertest.cc
@@ -15,7 +15,10 @@ #include "chrome/browser/predictors/autocomplete_action_predictor_factory.h" #include "chrome/browser/prerender/prerender_manager.h" #include "chrome/browser/prerender/prerender_utils.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/safe_browsing/test_safe_browsing_navigation_observer_manager.h" #include "chrome/browser/search_engines/template_url_service_factory.h" +#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/location_bar/location_bar.h" @@ -28,8 +31,10 @@ #include "chrome/test/base/search_test_utils.h" #include "components/omnibox/browser/base_search_provider.h" #include "components/omnibox/browser/omnibox_edit_model.h" +#include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/search_engines/template_url_data.h" #include "components/search_engines/template_url_service.h" +#include "content/public/browser/global_routing_id.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/test/browser_test.h" @@ -878,4 +883,81 @@ EXPECT_NE(host_id, content::RenderFrameHost::kNoFrameTreeNodeId); } +class PrerenderOmniboxReferrerChainUIBrowserTest + : public PrerenderOmniboxUIBrowserTest { + public: + void SetUpOnMainThread() override { + // Disable Safe Browsing service so we can directly control when + // SafeBrowsingNavigationObserverManager and SafeBrowsingNavigationObserver + // are instantiated. + browser()->profile()->GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnabled, + false); + PrerenderOmniboxUIBrowserTest::SetUpOnMainThread(); + observer_manager_ = std::make_unique< + safe_browsing::TestSafeBrowsingNavigationObserverManager>(browser()); + observer_manager_->ObserveContents( + browser()->tab_strip_model()->GetActiveWebContents()); + } + + absl::optional<size_t> FindNavigationEventIndex( + const GURL& target_url, + content::GlobalRenderFrameHostId outermost_main_frame_id) { + return observer_manager_->navigation_event_list()->FindNavigationEvent( + base::Time::Now(), target_url, GURL(), SessionID::InvalidValue(), + outermost_main_frame_id, + (observer_manager_->navigation_event_list()->NavigationEventsSize() - + 1)); + } + + safe_browsing::NavigationEvent* GetNavigationEvent(size_t index) { + return observer_manager_->navigation_event_list() + ->navigation_events()[index] + .get(); + } + + void TearDownOnMainThread() override { observer_manager_.reset(); } + + private: + std::unique_ptr<safe_browsing::TestSafeBrowsingNavigationObserverManager> + observer_manager_; +}; + +IN_PROC_BROWSER_TEST_F(PrerenderOmniboxReferrerChainUIBrowserTest, + PrerenderHasNoInitiator) { + Observe(GetActiveWebContents()); + base::HistogramTester histogram_tester; + const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html"); + ASSERT_TRUE(GetActiveWebContents()); + ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), kInitialUrl)); + + content::test::PrerenderHostRegistryObserver registry_observer( + *GetActiveWebContents()); + + // Attempt to prerender a direct URL input. + ASSERT_TRUE(GetAutocompleteActionPredictor()); + const GURL kPrerenderingUrl = + embedded_test_server()->GetURL("/empty.html?prerender"); + AutocompleteMatch match; + match.type = AutocompleteMatchType::URL_WHAT_YOU_TYPED; + match.destination_url = kPrerenderingUrl; + GetAutocompleteActionPredictor()->StartPrerendering( + match, *GetActiveWebContents(), gfx::Size(50, 50)); + + registry_observer.WaitForTrigger(kPrerenderingUrl); + int host_id = prerender_helper().GetHostForUrl(kPrerenderingUrl); + ASSERT_NE(host_id, content::RenderFrameHost::kNoFrameTreeNodeId); + prerender_helper().WaitForPrerenderLoadCompletion(host_id); + // By using no id, we should get the most recent navigation event. + auto index = FindNavigationEventIndex(kPrerenderingUrl, + content::GlobalRenderFrameHostId()); + ASSERT_TRUE(index); + + // Since this was triggered by the omnibox (and hence by the user), we should + // have no initiator outermost main frame id. I.e., it would be incorrect to + // attribute this load to the document previously loaded in the outermost main + // frame. + auto* nav_event = GetNavigationEvent(*index); + EXPECT_FALSE(nav_event->initiator_outermost_main_frame_id); +} + } // namespace
diff --git a/chrome/browser/privacy/secure_dns_bridge.cc b/chrome/browser/privacy/secure_dns_bridge.cc index 341ee4b..aefdc1ef 100644 --- a/chrome/browser/privacy/secure_dns_bridge.cc +++ b/chrome/browser/privacy/secure_dns_bridge.cc
@@ -13,6 +13,7 @@ #include "base/android/jni_string.h" #include "base/android/scoped_java_ref.h" #include "base/bind.h" +#include "base/check.h" #include "base/strings/utf_string_conversions.h" #include "base/synchronization/waitable_event.h" #include "chrome/browser/browser_process.h" @@ -30,6 +31,7 @@ #include "net/dns/public/dns_over_https_config.h" #include "net/dns/public/doh_provider_entry.h" #include "net/dns/public/secure_dns_mode.h" +#include "third_party/abseil-cpp/absl/types/optional.h" using base::android::JavaParamRef; using base::android::ScopedJavaLocalRef; @@ -51,10 +53,13 @@ // |waiter| when the probe has completed. Must run on the UI thread. void RunProbe(base::WaitableEvent* waiter, bool* success, - net::DnsConfigOverrides overrides) { + const std::string& doh_config) { + absl::optional<net::DnsOverHttpsConfig> parsed = + net::DnsOverHttpsConfig::FromString(doh_config); + DCHECK(parsed.has_value()); // `doh_config` must be valid. auto* manager = g_browser_process->system_network_context_manager(); - auto runner = std::make_unique<DnsProbeRunner>( - std::move(overrides), + auto runner = secure_dns::MakeProbeRunner( + std::move(*parsed), base::BindRepeating(&SystemNetworkContextManager::GetContext, base::Unretained(manager))); auto* const runner_ptr = runner.get(); @@ -154,13 +159,6 @@ static jboolean JNI_SecureDnsBridge_ProbeConfig( JNIEnv* env, const JavaParamRef<jstring>& doh_config) { - net::DnsConfigOverrides overrides; - overrides.search = std::vector<std::string>(); - overrides.attempts = 1; - overrides.secure_dns_mode = net::SecureDnsMode::kSecure; - secure_dns::ApplyConfig(&overrides, - base::android::ConvertJavaStringToUTF8(doh_config)); - // Android recommends converting async functions to blocking when using JNI: // https://developer.android.com/training/articles/perf-jni. // This function converts the DnsProbeRunner, which can only be created and @@ -171,7 +169,8 @@ bool success; bool posted = content::GetUIThreadTaskRunner({})->PostTask( FROM_HERE, - base::BindOnce(RunProbe, &waiter, &success, std::move(overrides))); + base::BindOnce(RunProbe, &waiter, &success, + base::android::ConvertJavaStringToUTF8(doh_config))); DCHECK(posted); waiter.Wait();
diff --git a/chrome/browser/resources/new_tab_page/modules/modules.ts b/chrome/browser/resources/new_tab_page/modules/modules.ts index a03b49e7..7ae21ce 100644 --- a/chrome/browser/resources/new_tab_page/modules/modules.ts +++ b/chrome/browser/resources/new_tab_page/modules/modules.ts
@@ -145,15 +145,30 @@ if (loadTimeData.getBoolean('modulesRedesignedLayoutEnabled')) { // Wrap pairs of sibling short modules in a container. All other // modules will be placed in a container of their own. - if (moduleContainer.classList.contains(SHORT_CLASS_NAME) && + if ((moduleContainer.classList.contains(SHORT_CLASS_NAME) || + moduleContainer.hidden) && shortModuleSiblingsContainer) { - // Add current sibling short module to container which already - // contains the previous sibling short module by setting its parent - // to be 'shortModuleSiblingsContainer'. + // Add current sibling short module or hidden module to sibling + // container which already contains one or more other modules, by + // setting its parent to be 'shortModuleSiblingsContainer'. We add + // hidden modules to the sibling container, so if a user reverts a + // module from its hidden state, the module assumes its original + // position. moduleContainerParent = shortModuleSiblingsContainer; this.$.modules.appendChild(shortModuleSiblingsContainer); - shortModuleSiblingsContainer = null; + // If another visible short module is added, a visible tall module is + // next, or we've reached the end of our container list we stop adding + // to the container. + if (!moduleContainer.hidden || + index + 1 !== moduleContainers.length && + moduleContainers[index + 1].classList.contains( + TALL_CLASS_NAME) && + !moduleContainers[index + 1].hidden || + index + 1 === moduleContainers.length) { + shortModuleSiblingsContainer = null; + } } else if ( + !moduleContainer.hidden && moduleContainer.classList.contains(SHORT_CLASS_NAME) && index + 1 !== moduleContainers.length && moduleContainers[index + 1].classList.contains(SHORT_CLASS_NAME)) { @@ -325,6 +340,10 @@ moduleWrapper.parentElement!.hidden = this.moduleDisabled_(moduleWrapper.module.descriptor.id); }); + // Append modules again to accommodate for empty space from removed module. + const moduleContainers = [...this.shadowRoot!.querySelectorAll<HTMLElement>( + '.module-container')]; + this.appendModuleContainers_(moduleContainers); } /**
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn index 1b5e09f..103a292d 100644 --- a/chrome/browser/resources/settings/chromeos/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -42,7 +42,6 @@ deps = [ ":copy_browser_settings_tsc", ":preprocess_gen_v3", - ":preprocess_mojo_v3", ":preprocess_v3", "../../../../../ui/webui/resources:preprocess", "../../nearby_share/shared:preprocess_v3", @@ -94,18 +93,18 @@ # OS Settings specific mojo files, bundled in optimized builds. preprocess_if_expr("preprocess_mojo_v3") { deps = [ + "//chrome/browser/ui/webui/settings/ash/search:mojo_bindings_js", "//chrome/browser/ui/webui/settings/chromeos/constants:mojom_js", - "//chrome/browser/ui/webui/settings/chromeos/search:mojo_bindings_js", ] - in_folder = get_path_info("../../../ui/webui/settings/chromeos/", "gen_dir") + in_folder = get_path_info("../../../ui/webui/settings/", "gen_dir") out_folder = "$target_gen_dir/$preprocess_folder_v3" out_manifest = "$target_gen_dir/$preprocess_mojo_manifest" in_files = [ - "constants/routes.mojom-lite.js", - "constants/setting.mojom-lite.js", - "search/search.mojom-lite.js", - "search/search_result_icon.mojom-lite.js", - "search/user_action_recorder.mojom-lite.js", + "ash/search/search.mojom-lite.js", + "ash/search/search_result_icon.mojom-lite.js", + "ash/search/user_action_recorder.mojom-lite.js", + "chromeos/constants/routes.mojom-lite.js", + "chromeos/constants/setting.mojom-lite.js", ] } @@ -201,6 +200,7 @@ input_files_base_dir = rebase_path(".", "//") deps = [ ":preprocess_external_mojo", + ":preprocess_mojo_v3", "../../nearby_share:build_mojo_grdp", ] grdp_files = [ "$root_gen_dir/chrome/browser/resources/nearby_share/nearby_share_mojo_resources.grdp" ] @@ -213,6 +213,11 @@ "ui/webui/resources/cr_components/app_management/app_management.mojom-lite.js|app-management/app_management.mojom-lite.js", "chrome/browser/ui/webui/settings/ash/os_apps_page/mojom/app_notification_handler.mojom-lite.js|os_apps_page/app_notification_handler.mojom-lite.js", "components/services/app_service/public/mojom/types.mojom-lite.js|app-management/types.mojom-lite.js", + "ash/search/search.mojom-lite.js|search/search.mojom-lite.js", + "ash/search/search_result_icon.mojom-lite.js|search/search_result_icon.mojom-lite.js", + "ash/search/user_action_recorder.mojom-lite.js|search/user_action_recorder.mojom-lite.js", + "chromeos/constants/routes.mojom-lite.js|constants/routes.mojom-lite.js", + "chromeos/constants/setting.mojom-lite.js|constants/setting.mojom-lite.js", "../../nearby_share/shared/nearby_share_progress_bar_dark.json|nearby_share_progress_bar_dark.json", "../../nearby_share/shared/nearby_share_progress_bar_light.json|nearby_share_progress_bar_light.json", "../../nearby_share/shared/nearby_share_pulse_animation_dark.json|nearby_share_pulse_animation_dark.json", @@ -234,7 +239,6 @@ deps += [ ":copy_browser_settings_tsc", ":preprocess_gen_v3", - ":preprocess_mojo_v3", ":preprocess_v3", "../../nearby_share/shared:build_v3_grdp", "//ui/webui/resources/cr_components/app_management:build_ts", @@ -706,7 +710,7 @@ js_library("metrics_recorder") { sources = [ "metrics_recorder.m.js" ] - deps = [ "//chrome/browser/ui/webui/settings/chromeos/search:mojo_bindings_js_library_for_compile" ] + deps = [ "//chrome/browser/ui/webui/settings/ash/search:mojo_bindings_js_library_for_compile" ] } js_library("os_icons.m") { @@ -773,7 +777,7 @@ js_library("search_handler") { deps = [ - "//chrome/browser/ui/webui/settings/chromeos/search:mojo_bindings_js_library_for_compile", + "//chrome/browser/ui/webui/settings/ash/search:mojo_bindings_js_library_for_compile", "//ui/webui/resources/js:cr.m", ] }
diff --git a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_true_wireless_images.html b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_true_wireless_images.html index 41df625..7c3b8f3 100644 --- a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_true_wireless_images.html +++ b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_true_wireless_images.html
@@ -3,28 +3,36 @@ align-items: center; display: flex; flex-direction: row; - justify-content: space-around; - margin: 7% 10%; + gap: 100px; + justify-content: center; + margin: 40px 0; } .image-wrapper { - padding-bottom: 16px; + height: 60px; + margin-bottom: 16px; + width: 60px; } .image-wrapper img { - border: 1px solid lightgrey; + border: 1px solid var(--cros-color-primary-dark); border-radius: 50%; - height: 70px; - width: 70px; + height: 100%; + width: 100%; } .battery-container { align-items: center; display: flex; flex-direction: column; + height: 124px; justify-content: center; } + bluetooth-battery-icon-percentage { + margin-bottom: 8px; + } + #notConnectedLabel { color: gray; }
diff --git a/chrome/browser/safe_browsing/BUILD.gn b/chrome/browser/safe_browsing/BUILD.gn index 9a4e6cd..13621dd3 100644 --- a/chrome/browser/safe_browsing/BUILD.gn +++ b/chrome/browser/safe_browsing/BUILD.gn
@@ -474,12 +474,23 @@ "test_safe_browsing_service.h", ] + if (!is_android) { + sources += [ + "test_safe_browsing_navigation_observer_manager.cc", + "test_safe_browsing_navigation_observer_manager.h", + ] + } + deps = [ ":safe_browsing", + "//chrome/browser:browser", + "//chrome/browser/profiles:profile", + "//chrome/browser/ui:ui", "//chrome/common", "//chrome/common/safe_browsing:proto", "//components/enterprise/common/proto:connectors_proto", "//components/safe_browsing:buildflags", + "//components/safe_browsing/content/browser:browser", "//components/safe_browsing/content/browser:safe_browsing_blocking_page", "//components/safe_browsing/content/browser:safe_browsing_service", "//components/safe_browsing/core/browser/db:database_manager", @@ -487,6 +498,7 @@ "//components/safe_browsing/core/browser/db:v4_protocol_manager_util", "//content/public/browser", "//services/network:test_support", + "//testing/gtest", ] }
diff --git a/chrome/browser/safe_browsing/chrome_client_side_detection_host_delegate.cc b/chrome/browser/safe_browsing/chrome_client_side_detection_host_delegate.cc index 05be7683..38fc36d 100644 --- a/chrome/browser/safe_browsing/chrome_client_side_detection_host_delegate.cc +++ b/chrome/browser/safe_browsing/chrome_client_side_detection_host_delegate.cc
@@ -18,6 +18,7 @@ #include "components/safe_browsing/core/browser/db/database_manager.h" #include "components/safe_browsing/core/browser/sync/safe_browsing_primary_account_token_fetcher.h" #include "components/safe_browsing/core/browser/sync/sync_utils.h" +#include "content/public/browser/global_routing_id.h" namespace safe_browsing { @@ -88,7 +89,8 @@ void ChromeClientSideDetectionHostDelegate::AddReferrerChain( ClientPhishingRequest* verdict, - GURL current_url) { + GURL current_url, + const content::GlobalRenderFrameHostId& current_outermost_main_frame_id) { SafeBrowsingNavigationObserverManager* navigation_observer_manager = GetSafeBrowsingNavigationObserverManager(); if (!navigation_observer_manager) { @@ -97,6 +99,7 @@ SafeBrowsingNavigationObserverManager::AttributionResult result = navigation_observer_manager->IdentifyReferrerChainByEventURL( current_url, SessionID::InvalidValue(), + current_outermost_main_frame_id, kCSDAttributionUserGestureLimitForExtendedReporting, verdict->mutable_referrer_chain());
diff --git a/chrome/browser/safe_browsing/chrome_client_side_detection_host_delegate.h b/chrome/browser/safe_browsing/chrome_client_side_detection_host_delegate.h index 4052f28..f3d6b0ab 100644 --- a/chrome/browser/safe_browsing/chrome_client_side_detection_host_delegate.h +++ b/chrome/browser/safe_browsing/chrome_client_side_detection_host_delegate.h
@@ -8,6 +8,7 @@ #include "base/memory/raw_ptr.h" #include "components/safe_browsing/content/browser/client_side_detection_host.h" #include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h" +#include "content/public/browser/global_routing_id.h" namespace safe_browsing { @@ -37,7 +38,9 @@ scoped_refptr<BaseUIManager> GetSafeBrowsingUIManager() override; ClientSideDetectionService* GetClientSideDetectionService() override; void AddReferrerChain(ClientPhishingRequest* verdict, - GURL current_url) override; + GURL current_url, + const content::GlobalRenderFrameHostId& + current_outermost_main_frame_id) override; void SetNavigationObserverManagerForTesting( SafeBrowsingNavigationObserverManager* navigation_observer_manager) {
diff --git a/chrome/browser/safe_browsing/chrome_client_side_detection_host_delegate_unittest.cc b/chrome/browser/safe_browsing/chrome_client_side_detection_host_delegate_unittest.cc index 59586f41..921d7aa 100644 --- a/chrome/browser/safe_browsing/chrome_client_side_detection_host_delegate_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_client_side_detection_host_delegate_unittest.cc
@@ -14,6 +14,7 @@ #include "components/safe_browsing/content/browser/safe_browsing_navigation_observer.h" #include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h" #include "components/safe_browsing/core/common/features.h" +#include "content/public/browser/global_routing_id.h" #include "content/public/test/navigation_simulator.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -89,7 +90,8 @@ csd_host_delegate->SetNavigationObserverManagerForTesting( navigation_observer_manager_); std::unique_ptr<ClientPhishingRequest> verdict(new ClientPhishingRequest); - csd_host_delegate->AddReferrerChain(verdict.get(), GURL("http://b.com/")); + csd_host_delegate->AddReferrerChain(verdict.get(), GURL("http://b.com/"), + content::GlobalRenderFrameHostId()); ReferrerChain referrer_chain = verdict->referrer_chain(); EXPECT_EQ(2, referrer_chain.size()); @@ -115,7 +117,8 @@ std::make_unique<ChromeClientSideDetectionHostDelegate>( browser()->tab_strip_model()->GetWebContentsAt(0)); std::unique_ptr<ClientPhishingRequest> verdict(new ClientPhishingRequest); - csd_host_delegate->AddReferrerChain(verdict.get(), GURL("http://b.com/")); + csd_host_delegate->AddReferrerChain(verdict.get(), GURL("http://b.com/"), + content::GlobalRenderFrameHostId()); ReferrerChain referrer_chain = verdict->referrer_chain(); EXPECT_EQ(0, referrer_chain.size());
diff --git a/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service_unittest.cc b/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service_unittest.cc index 2290f74..fcc915a 100644 --- a/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service_unittest.cc
@@ -23,6 +23,7 @@ #include "components/sync_preferences/testing_pref_service_syncable.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/global_routing_id.h" #include "content/public/test/browser_task_environment.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" @@ -44,13 +45,15 @@ class MockReferrerChainProvider : public ReferrerChainProvider { public: virtual ~MockReferrerChainProvider() = default; - MOCK_METHOD3(IdentifyReferrerChainByWebContents, - AttributionResult(content::WebContents* web_contents, + MOCK_METHOD3(IdentifyReferrerChainByRenderFrameHost, + AttributionResult(content::RenderFrameHost* rfh, int user_gesture_count_limit, ReferrerChain* out_referrer_chain)); - MOCK_METHOD4(IdentifyReferrerChainByEventURL, + MOCK_METHOD5(IdentifyReferrerChainByEventURL, AttributionResult(const GURL& event_url, SessionID event_tab_id, + const content::GlobalRenderFrameHostId& + event_outermost_main_frame_id, int user_gesture_count_limit, ReferrerChain* out_referrer_chain)); MOCK_METHOD3(IdentifyReferrerChainByPendingEventURL,
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.cc b/chrome/browser/safe_browsing/chrome_password_protection_service.cc index 79207cf..711a790 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
@@ -1349,7 +1349,8 @@ profile_); SafeBrowsingNavigationObserverManager::AttributionResult result = navigation_observer_manager->IdentifyReferrerChainByEventURL( - event_url, event_tab_id, kPasswordEventAttributionUserGestureLimit, + event_url, event_tab_id, content::GlobalRenderFrameHostId(), + kPasswordEventAttributionUserGestureLimit, frame->mutable_referrer_chain()); size_t referrer_chain_length = frame->referrer_chain().size(); UMA_HISTOGRAM_COUNTS_100(
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service.cc b/chrome/browser/safe_browsing/download_protection/download_protection_service.cc index e7a9a1d..5c78aaf0 100644 --- a/chrome/browser/safe_browsing/download_protection/download_protection_service.cc +++ b/chrome/browser/safe_browsing/download_protection/download_protection_service.cc
@@ -52,6 +52,7 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/download_item_utils.h" +#include "content/public/browser/global_routing_id.h" #include "content/public/browser/web_contents.h" #include "net/base/url_util.h" #include "net/cert/x509_util.h" @@ -327,6 +328,7 @@ void DownloadProtectionService::CheckPPAPIDownloadRequest( const GURL& requestor_url, const GURL& initiating_frame_url, + const content::GlobalRenderFrameHostId& initiating_outermost_main_frame_id, content::WebContents* web_contents, const base::FilePath& default_file_path, const std::vector<base::FilePath::StringType>& alternate_extensions, @@ -341,9 +343,9 @@ return; } std::unique_ptr<PPAPIDownloadRequest> request(new PPAPIDownloadRequest( - requestor_url, initiating_frame_url, web_contents, default_file_path, - alternate_extensions, profile, std::move(callback), this, - database_manager_)); + requestor_url, initiating_frame_url, initiating_outermost_main_frame_id, + web_contents, default_file_path, alternate_extensions, profile, + std::move(callback), this, database_manager_)); PPAPIDownloadRequest* request_copy = request.get(); auto insertion_result = ppapi_download_requests_.insert( std::make_pair(request_copy, std::move(request))); @@ -535,23 +537,27 @@ return nullptr; } + content::RenderFrameHost* render_frame_host = + content::DownloadItemUtils::GetRenderFrameHost(&item); + content::RenderFrameHost* outermost_render_frame_host = + render_frame_host ? render_frame_host->GetOutermostMainFrame() : nullptr; + content::GlobalRenderFrameHostId frame_id = + outermost_render_frame_host ? outermost_render_frame_host->GetGlobalId() + : content::GlobalRenderFrameHostId(); + SessionID download_tab_id = sessions::SessionTabHelper::IdForTab(web_contents); // We look for the referrer chain that leads to the download url first. SafeBrowsingNavigationObserverManager::AttributionResult result = GetNavigationObserverManager(web_contents) ->IdentifyReferrerChainByEventURL( - item.GetURL(), download_tab_id, + item.GetURL(), download_tab_id, frame_id, GetDownloadAttributionUserGestureLimit(item), referrer_chain.get()); // If no navigation event is found, this download is not triggered by regular // navigation (e.g. html5 file apis, etc). We look for the referrer chain // based on relevant RenderFrameHost instead. - content::RenderFrameHost* render_frame_host = - content::DownloadItemUtils::GetRenderFrameHost(&item); - content::RenderFrameHost* outermost_render_frame_host = - render_frame_host ? render_frame_host->GetOutermostMainFrame() : nullptr; if (result == SafeBrowsingNavigationObserverManager::NAVIGATION_EVENT_NOT_FOUND && web_contents && outermost_render_frame_host && @@ -559,8 +565,9 @@ AddEventUrlToReferrerChain(item, outermost_render_frame_host, referrer_chain.get()); result = GetNavigationObserverManager(web_contents) - ->IdentifyReferrerChainByWebContents( - web_contents, GetDownloadAttributionUserGestureLimit(item), + ->IdentifyReferrerChainByRenderFrameHost( + outermost_render_frame_host, + GetDownloadAttributionUserGestureLimit(item), referrer_chain.get()); } @@ -607,8 +614,9 @@ SafeBrowsingNavigationObserverManager::AttributionResult result = GetNavigationObserverManager(item.web_contents) ->IdentifyReferrerChainByHostingPage( - item.frame_url, tab_url, tab_id, item.has_user_gesture, - kDownloadAttributionUserGestureLimit, referrer_chain.get()); + item.frame_url, tab_url, item.outermost_main_frame_id, tab_id, + item.has_user_gesture, kDownloadAttributionUserGestureLimit, + referrer_chain.get()); UMA_HISTOGRAM_ENUMERATION( "SafeBrowsing.ReferrerAttributionResult.NativeFileSystemWriteAttribution", @@ -637,6 +645,7 @@ void DownloadProtectionService::AddReferrerChainToPPAPIClientDownloadRequest( content::WebContents* web_contents, const GURL& initiating_frame_url, + const content::GlobalRenderFrameHostId& initiating_outermost_main_frame_id, const GURL& initiating_main_frame_url, SessionID tab_id, bool has_user_gesture, @@ -649,8 +658,9 @@ SafeBrowsingNavigationObserverManager::AttributionResult result = GetNavigationObserverManager(web_contents) ->IdentifyReferrerChainByHostingPage( - initiating_frame_url, initiating_main_frame_url, tab_id, - has_user_gesture, kDownloadAttributionUserGestureLimit, + initiating_frame_url, initiating_main_frame_url, + initiating_outermost_main_frame_id, tab_id, has_user_gesture, + kDownloadAttributionUserGestureLimit, out_request->mutable_referrer_chain()); UMA_HISTOGRAM_COUNTS_100( "SafeBrowsing.ReferrerURLChainSize.PPAPIDownloadAttribution",
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service.h b/chrome/browser/safe_browsing/download_protection/download_protection_service.h index 973de09..75cb96dc 100644 --- a/chrome/browser/safe_browsing/download_protection/download_protection_service.h +++ b/chrome/browser/safe_browsing/download_protection/download_protection_service.h
@@ -117,6 +117,8 @@ virtual void CheckPPAPIDownloadRequest( const GURL& requestor_url, const GURL& initiating_frame_url, + const content::GlobalRenderFrameHostId& + initiating_outermost_main_frame_id, content::WebContents* web_contents, const base::FilePath& default_file_path, const std::vector<base::FilePath::StringType>& alternate_extensions, @@ -304,6 +306,8 @@ void AddReferrerChainToPPAPIClientDownloadRequest( content::WebContents* web_contents, const GURL& initiating_frame_url, + const content::GlobalRenderFrameHostId& + initiating_outermost_main_frame_id, const GURL& initiating_main_frame_url, SessionID tab_id, bool has_user_gesture,
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc index f9531006..441e683 100644 --- a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc +++ b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc
@@ -101,6 +101,7 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/download_item_utils.h" +#include "content/public/browser/global_routing_id.h" #include "content/public/browser/page_navigator.h" #include "content/public/test/browser_task_environment.h" #include "content/public/test/navigation_simulator.h" @@ -2512,7 +2513,8 @@ std::vector<base::FilePath::StringType> alternate_extensions{ FILE_PATH_LITERAL(".jpeg")}; download_service_->CheckPPAPIDownloadRequest( - GURL("http://example.com/foo"), GURL(), nullptr, default_file_path, + GURL("http://example.com/foo"), GURL(), + content::GlobalRenderFrameHostId(), nullptr, default_file_path, alternate_extensions, profile(), base::BindOnce(&DownloadProtectionServiceTest::SyncCheckDoneCallback, base::Unretained(this))); @@ -2546,7 +2548,8 @@ SetExtendedReportingPreference(true); RunLoop run_loop; download_service_->CheckPPAPIDownloadRequest( - GURL("http://example.com/foo"), GURL(), /*web_contents=*/nullptr, + GURL("http://example.com/foo"), GURL(), + content::GlobalRenderFrameHostId(), /*web_contents=*/nullptr, default_file_path, alternate_extensions, profile(), base::BindOnce(&DownloadProtectionServiceTest::CheckDoneCallback, base::Unretained(this), run_loop.QuitClosure())); @@ -2568,7 +2571,8 @@ SetExtendedReportingPreference(false); RunLoop run_loop; download_service_->CheckPPAPIDownloadRequest( - GURL("http://example.com/foo"), GURL(), nullptr, default_file_path, + GURL("http://example.com/foo"), GURL(), + content::GlobalRenderFrameHostId(), nullptr, default_file_path, alternate_extensions, profile(), base::BindOnce(&DownloadProtectionServiceTest::CheckDoneCallback, base::Unretained(this), run_loop.QuitClosure())); @@ -2588,7 +2592,8 @@ RunLoop run_loop; download_service_->CheckPPAPIDownloadRequest( - GURL("http://example.com/foo"), GURL(), nullptr, default_file_path, + GURL("http://example.com/foo"), GURL(), + content::GlobalRenderFrameHostId(), nullptr, default_file_path, alternate_extensions, profile(), base::BindOnce(&DownloadProtectionServiceTest::CheckDoneCallback, base::Unretained(this), run_loop.QuitClosure())); @@ -2607,7 +2612,8 @@ .WillRepeatedly(Return(false)); RunLoop run_loop; download_service_->CheckPPAPIDownloadRequest( - GURL("http://example.com/foo"), GURL(), nullptr, default_file_path, + GURL("http://example.com/foo"), GURL(), + content::GlobalRenderFrameHostId(), nullptr, default_file_path, alternate_extensions, profile(), base::BindOnce(&DownloadProtectionServiceTest::CheckDoneCallback, base::Unretained(this), run_loop.QuitClosure())); @@ -2626,7 +2632,8 @@ .WillRepeatedly(Return(false)); RunLoop run_loop; download_service_->CheckPPAPIDownloadRequest( - GURL("http://example.com/foo"), GURL(), nullptr, default_file_path, + GURL("http://example.com/foo"), GURL(), + content::GlobalRenderFrameHostId(), nullptr, default_file_path, alternate_extensions, profile(), base::BindOnce(&DownloadProtectionServiceTest::CheckDoneCallback, base::Unretained(this), run_loop.QuitClosure())); @@ -2645,7 +2652,8 @@ download_service_->download_request_timeout_ms_ = 0; RunLoop run_loop; download_service_->CheckPPAPIDownloadRequest( - GURL("http://example.com/foo"), GURL(), nullptr, default_file_path, + GURL("http://example.com/foo"), GURL(), + content::GlobalRenderFrameHostId(), nullptr, default_file_path, alternate_extensions, profile(), base::BindOnce(&DownloadProtectionServiceTest::CheckDoneCallback, base::Unretained(this), run_loop.QuitClosure())); @@ -2674,8 +2682,8 @@ const GURL kRequestorUrl("http://example.com/foo"); RunLoop run_loop; download_service_->CheckPPAPIDownloadRequest( - kRequestorUrl, GURL(), nullptr, default_file_path, alternate_extensions, - profile(), + kRequestorUrl, GURL(), content::GlobalRenderFrameHostId(), nullptr, + default_file_path, alternate_extensions, profile(), base::BindOnce(&DownloadProtectionServiceTest::CheckDoneCallback, base::Unretained(this), run_loop.QuitClosure())); run_loop.Run(); @@ -2704,8 +2712,9 @@ std::vector<base::FilePath::StringType> alternate_extensions{ FILE_PATH_LITERAL(".tmp"), FILE_PATH_LITERAL(".asdfasdf")}; download_service_->CheckPPAPIDownloadRequest( - GURL("http://example.com/foo"), GURL(), web_contents.get(), - default_file_path, alternate_extensions, profile(), + GURL("http://example.com/foo"), GURL(), + content::GlobalRenderFrameHostId(), web_contents.get(), default_file_path, + alternate_extensions, profile(), base::BindOnce(&DownloadProtectionServiceTest::SyncCheckDoneCallback, base::Unretained(this))); ASSERT_TRUE(IsResult(DownloadCheckResult::ALLOWLISTED_BY_POLICY));
diff --git a/chrome/browser/safe_browsing/download_protection/ppapi_download_request.cc b/chrome/browser/safe_browsing/download_protection/ppapi_download_request.cc index 8b37f98..1ffea9a 100644 --- a/chrome/browser/safe_browsing/download_protection/ppapi_download_request.cc +++ b/chrome/browser/safe_browsing/download_protection/ppapi_download_request.cc
@@ -20,6 +20,7 @@ #include "components/sessions/content/session_tab_helper.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/global_routing_id.h" #include "content/public/browser/web_contents.h" #include "google_apis/google_api_keys.h" #include "net/base/escape.h" @@ -40,6 +41,7 @@ PPAPIDownloadRequest::PPAPIDownloadRequest( const GURL& requestor_url, const GURL& initiating_frame_url, + const content::GlobalRenderFrameHostId& initiating_outermost_main_frame_id, content::WebContents* web_contents, const base::FilePath& default_file_path, const std::vector<base::FilePath::StringType>& alternate_extensions, @@ -49,6 +51,7 @@ scoped_refptr<SafeBrowsingDatabaseManager> database_manager) : requestor_url_(requestor_url), initiating_frame_url_(initiating_frame_url), + initiating_outermost_main_frame_id_(initiating_outermost_main_frame_id), initiating_main_frame_url_( web_contents ? web_contents->GetLastCommittedURL() : GURL()), tab_id_(sessions::SessionTabHelper::IdForTab(web_contents)), @@ -208,8 +211,8 @@ } service_->AddReferrerChainToPPAPIClientDownloadRequest( - web_contents_, initiating_frame_url_, initiating_main_frame_url_, tab_id_, - has_user_gesture_, &request); + web_contents_, initiating_frame_url_, initiating_outermost_main_frame_id_, + initiating_main_frame_url_, tab_id_, has_user_gesture_, &request); if (!request.SerializeToString(&client_download_request_data_)) { // More of an internal error than anything else. Note that the UNKNOWN
diff --git a/chrome/browser/safe_browsing/download_protection/ppapi_download_request.h b/chrome/browser/safe_browsing/download_protection/ppapi_download_request.h index 4f2c5657..9ddafab 100644 --- a/chrome/browser/safe_browsing/download_protection/ppapi_download_request.h +++ b/chrome/browser/safe_browsing/download_protection/ppapi_download_request.h
@@ -13,6 +13,7 @@ #include "base/memory/weak_ptr.h" #include "chrome/browser/safe_browsing/download_protection/download_protection_util.h" #include "components/sessions/core/session_id.h" +#include "content/public/browser/global_routing_id.h" #include "content/public/browser/web_contents_observer.h" #include "url/gurl.h" @@ -64,6 +65,8 @@ PPAPIDownloadRequest( const GURL& requestor_url, const GURL& initiating_frame_url, + const content::GlobalRenderFrameHostId& + initiating_outermost_main_frame_id, content::WebContents* web_contents, const base::FilePath& default_file_path, const std::vector<base::FilePath::StringType>& alternate_extensions, @@ -138,6 +141,9 @@ // URL of the frame that hosts the PPAPI plugin. const GURL initiating_frame_url_; + // The id of the initiating outermost main frame. + const content::GlobalRenderFrameHostId initiating_outermost_main_frame_id_; + // URL of the tab that contains the initialting_frame. const GURL initiating_main_frame_url_;
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc index 2be08ce..07dbe2b6 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/download_protection/download_protection_service.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" +#include "chrome/browser/safe_browsing/test_safe_browsing_navigation_observer_manager.h" #include "chrome/browser/safe_browsing/test_safe_browsing_service.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -30,8 +31,10 @@ #include "content/public/browser/browser_context.h" #include "content/public/browser/download_item_utils.h" #include "content/public/browser/download_manager.h" +#include "content/public/browser/global_routing_id.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" +#include "content/public/test/prerender_test_util.h" #include "content/public/test/test_navigation_observer.h" #include "content/public/test/test_utils.h" #include "net/dns/mock_host_resolver.h" @@ -51,8 +54,15 @@ const char kMultiFrameTestURL[] = "/safe_browsing/download_protection/navigation_observer/" "navigation_observer_multi_frame_tests.html"; +const char kSubFrameTestURL[] = + "/safe_browsing/download_protection/navigation_observer/" + "iframe.html"; const char kRedirectURL[] = "/safe_browsing/download_protection/navigation_observer/redirect.html"; +const char kEmptyURL[] = "/empty.html"; +const char kBasicIframeURL[] = "/iframe.html"; +// This is the src of the iframe in iframe.html above. +const char kInitialSubframeUrl[] = "/title1.html"; // Please update |kShortDataURL| too if you're changing |kDownloadDataURL|. const char kDownloadDataURL[] = "data:application/octet-stream;base64,a2poYWxrc2hkbGtoYXNka2xoYXNsa2RoYWxra" @@ -153,89 +163,21 @@ std::vector<DownloadItem*> items_seen_; }; -class InnerContentsCreationObserver : public content::WebContentsObserver { - public: - InnerContentsCreationObserver( - content::WebContents* web_contents, - base::RepeatingCallback<void(content::WebContents*)> - on_inner_contents_created) - : content::WebContentsObserver(web_contents), - on_inner_contents_created_(on_inner_contents_created) {} - - // WebContentsObserver: - void InnerWebContentsCreated( - content::WebContents* inner_web_contents) override { - on_inner_contents_created_.Run(inner_web_contents); - } - - private: - base::RepeatingCallback<void(content::WebContents*)> - on_inner_contents_created_; -}; - -// Test class to help create SafeBrowsingNavigationObservers for each -// WebContents before they are actually installed through AttachTabHelper. -class TestNavigationObserverManager - : public SafeBrowsingNavigationObserverManager, - public TabStripModelObserver { - public: - explicit TestNavigationObserverManager(Browser* browser) - : SafeBrowsingNavigationObserverManager(browser->profile()->GetPrefs()) { - browser->tab_strip_model()->AddObserver(this); - } - - void ObserveContents(content::WebContents* contents) { - ASSERT_TRUE(contents); - Profile* profile = - Profile::FromBrowserContext(contents->GetBrowserContext()); - auto observer = std::make_unique<SafeBrowsingNavigationObserver>( - contents, HostContentSettingsMapFactory::GetForProfile(profile), - safe_browsing::SafeBrowsingNavigationObserverManagerFactory:: - GetForBrowserContext(profile)); - observer->SetObserverManagerForTesting(this); - observer_list_.push_back(std::move(observer)); - inner_contents_creation_observers_.push_back( - std::make_unique<InnerContentsCreationObserver>( - contents, - base::BindRepeating(&TestNavigationObserverManager::ObserveContents, - // Unretained is safe because this object owns - // inner_contents_creation_observers_ - base::Unretained(this)))); - } - - // TabStripModelObserver: - void OnTabStripModelChanged( - TabStripModel* tab_strip_model, - const TabStripModelChange& change, - const TabStripSelectionChange& selection) override { - if (change.type() != TabStripModelChange::kInserted) - return; - - for (const TabStripModelChange::ContentsWithIndex& tab : - change.GetInsert()->contents) { - ObserveContents(tab.contents); - } - } - - TestNavigationObserverManager(const TestNavigationObserverManager&) = delete; - TestNavigationObserverManager& operator=( - const TestNavigationObserverManager&) = delete; - - ~TestNavigationObserverManager() override = default; - - private: - std::vector<std::unique_ptr<SafeBrowsingNavigationObserver>> observer_list_; - std::vector<std::unique_ptr<InnerContentsCreationObserver>> - inner_contents_creation_observers_; -}; - class SBNavigationObserverBrowserTest : public InProcessBrowserTest { public: - SBNavigationObserverBrowserTest() { + SBNavigationObserverBrowserTest() + : prerender_helper_( + base::BindRepeating(&SBNavigationObserverBrowserTest::web_contents, + base::Unretained(this))) { scoped_feature_list_.InitAndDisableFeature( kOmitNonUserGesturesFromReferrerChain); } + void SetUp() override { + prerender_helper_.SetUp(embedded_test_server()); + InProcessBrowserTest::SetUp(); + } + void SetUpOnMainThread() override { // Disable Safe Browsing service so we can directly control when // SafeBrowsingNavigationObserverManager and SafeBrowsingNavigationObserver @@ -245,12 +187,16 @@ ASSERT_TRUE(embedded_test_server()->Start()); host_resolver()->AddRule("*", "127.0.0.1"); observer_manager_ = - std::make_unique<TestNavigationObserverManager>(browser()); + std::make_unique<TestSafeBrowsingNavigationObserverManager>(browser()); observer_manager_->ObserveContents( browser()->tab_strip_model()->GetActiveWebContents()); ASSERT_TRUE(InitialSetup()); } + content::WebContents* web_contents() { + return browser()->tab_strip_model()->GetActiveWebContents(); + } + bool InitialSetup() { if (!browser()) return false; @@ -470,15 +416,21 @@ ReferrerChain* referrer_chain) { SessionID download_tab_id = sessions::SessionTabHelper::IdForTab( content::DownloadItemUtils::GetWebContents(download)); + content::RenderFrameHost* rfh = + content::DownloadItemUtils::GetRenderFrameHost(download); + content::GlobalRenderFrameHostId outermost_main_frame_id; + if (rfh) + outermost_main_frame_id = rfh->GetOutermostMainFrame()->GetGlobalId(); + auto result = observer_manager_->IdentifyReferrerChainByEventURL( - download->GetURL(), download_tab_id, + download->GetURL(), download_tab_id, outermost_main_frame_id, 2, // kDownloadAttributionUserGestureLimit referrer_chain); if (result == SafeBrowsingNavigationObserverManager::NAVIGATION_EVENT_NOT_FOUND) { DCHECK_EQ(0, referrer_chain->size()); - observer_manager_->IdentifyReferrerChainByWebContents( - content::DownloadItemUtils::GetWebContents(download), + observer_manager_->IdentifyReferrerChainByRenderFrameHost( + rfh, 2, // kDownloadAttributionUserGestureLimit referrer_chain); } @@ -486,12 +438,25 @@ void IdentifyReferrerChainForWebContents(content::WebContents* web_contents, ReferrerChain* referrer_chain) { - observer_manager_->IdentifyReferrerChainByWebContents( - web_contents, + observer_manager_->IdentifyReferrerChainByRenderFrameHost( + // We will assume the primary main frame here. + web_contents->GetMainFrame(), 2, // kDownloadAttributionUserGestureLimit referrer_chain); } + void IdentifyReferrerChainByEventURL( + const GURL& event_url, + SessionID event_tab_id, // Invalid if tab id is unknown or not available. + const content::GlobalRenderFrameHostId& + event_outermost_main_frame_id, // Can also be Invalid. + ReferrerChain* out_referrer_chain) { + observer_manager_->IdentifyReferrerChainByEventURL( + event_url, event_tab_id, event_outermost_main_frame_id, + 2, // user_gesture_count_limit + out_referrer_chain); + } + // Identify referrer chain of a PPAPI download and populate |referrer_chain|. void IdentifyReferrerChainForPPAPIDownload( const GURL& initiating_frame_url, @@ -502,7 +467,8 @@ observer_manager_->OnUserGestureConsumed(web_contents); EXPECT_LE(observer_manager_->IdentifyReferrerChainByHostingPage( initiating_frame_url, web_contents->GetLastCommittedURL(), - tab_id, has_user_gesture, + web_contents->GetMainFrame()->GetGlobalId(), tab_id, + has_user_gesture, 2, // kDownloadAttributionUserGestureLimit referrer_chain), SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_REFERRER); @@ -557,27 +523,44 @@ out_referrer_chain); } + NavigationEvent* GetNavigationEvent(size_t index) { + return observer_manager_->navigation_event_list() + ->navigation_events()[index] + .get(); + } + + absl::optional<size_t> FindNavigationEventIndex( + const GURL& target_url, + content::GlobalRenderFrameHostId outermost_main_frame_id) { + return observer_manager_->navigation_event_list()->FindNavigationEvent( + base::Time::Now(), target_url, GURL(), SessionID::InvalidValue(), + outermost_main_frame_id, + (observer_manager_->navigation_event_list()->NavigationEventsSize() - + 1)); + } + void FindAndAddNavigationToReferrerChain(ReferrerChain* referrer_chain, const GURL& target_url) { - size_t nav_event_index = - observer_manager_->navigation_event_list()->FindNavigationEvent( - base::Time::Now(), target_url, GURL(), SessionID::InvalidValue(), - (observer_manager_->navigation_event_list() - ->NavigationEventsSize() - - 1)); - if (static_cast<int>(nav_event_index) != -1) { + auto nav_event_index = FindNavigationEventIndex( + target_url, content::GlobalRenderFrameHostId()); + if (nav_event_index) { auto* nav_event = observer_manager_->navigation_event_list()->GetNavigationEvent( - nav_event_index); + *nav_event_index); observer_manager_->AddToReferrerChain(referrer_chain, nav_event, GURL(), ReferrerChainEntry::EVENT_URL); } } protected: - std::unique_ptr<TestNavigationObserverManager> observer_manager_; + std::unique_ptr<TestSafeBrowsingNavigationObserverManager> observer_manager_; + + content::test::PrerenderTestHelper& prerender_helper() { + return prerender_helper_; + } private: + content::test::PrerenderTestHelper prerender_helper_; base::test::ScopedFeatureList scoped_feature_list_; }; @@ -2570,6 +2553,279 @@ } IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, + NewWindowAndNavigateSubframe) { + std::string test_server_ip(embedded_test_server()->host_port_pair().host()); + auto main_frame_url = embedded_test_server()->GetURL(kMultiFrameTestURL); + auto new_window_url = embedded_test_server()->GetURL(kBasicIframeURL); + auto new_window_subframe_url = embedded_test_server()->GetURL(kEmptyURL); + auto initial_subframe_url = + embedded_test_server()->GetURL(kInitialSubframeUrl); + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); + + auto initiator_outermost_main_frame_id = + web_contents()->GetMainFrame()->GetGlobalId(); + + auto* initial_web_contents = web_contents(); + + ui_test_utils::UrlLoadObserver url_observer( + new_window_url, content::NotificationService::AllSources()); + ASSERT_TRUE( + ExecJs(web_contents()->GetMainFrame(), + content::JsReplace("var w = window.open($1, 'New Window');", + new_window_url))); + url_observer.Wait(); + const int kExpectedNumberOfNavigations = 1; + + content::TestNavigationObserver navigation_observer( + web_contents(), kExpectedNumberOfNavigations); + ASSERT_TRUE( + ExecJs(initial_web_contents->GetMainFrame(), + content::JsReplace("w.document.querySelector('IFRAME').src = $1;", + new_window_subframe_url))); + navigation_observer.Wait(); + EXPECT_EQ(new_window_subframe_url, navigation_observer.last_navigation_url()); + + auto target_main_frame_id = web_contents()->GetMainFrame()->GetGlobalId(); + + ReferrerChain referrer_chain; + IdentifyReferrerChainByEventURL( + new_window_url, sessions::SessionTabHelper::IdForTab(web_contents()), + content::GlobalRenderFrameHostId(), &referrer_chain); + + auto index = FindNavigationEventIndex(new_window_url, + content::GlobalRenderFrameHostId()); + ASSERT_TRUE(index); + auto* nav_event = GetNavigationEvent(*index); + EXPECT_EQ(initiator_outermost_main_frame_id, + nav_event->initiator_outermost_main_frame_id); + EXPECT_EQ(target_main_frame_id, nav_event->outermost_main_frame_id); + + EXPECT_EQ(2, referrer_chain.size()); + + referrer_chain.Clear(); + IdentifyReferrerChainByEventURL( + new_window_subframe_url, + sessions::SessionTabHelper::IdForTab(web_contents()), + content::GlobalRenderFrameHostId(), &referrer_chain); + EXPECT_EQ(4, referrer_chain.size()); + VerifyReferrerChainEntry( + new_window_subframe_url, // url + // TODO(crbug.com/1300014): this should be |new_window_url|. + GURL(), // main_frame_url + ReferrerChainEntry::EVENT_URL, // type + test_server_ip, // ip_address + initial_subframe_url, // referrer_url + new_window_url, // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects + ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, + referrer_chain.Get(0)); + + VerifyReferrerChainEntry( + initial_subframe_url, // url + new_window_url, // main_frame_url + ReferrerChainEntry::CLIENT_REDIRECT, // type + test_server_ip, // ip_address + GURL(), // referrer_url + new_window_url, // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects + ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, + referrer_chain.Get(1)); + + VerifyReferrerChainEntry( + new_window_url, // url + GURL(), // main_frame_url + ReferrerChainEntry::CLIENT_REDIRECT, // type + test_server_ip, // ip_address + main_frame_url, // referrer_url + GURL(), // referrer_main_frame_url + true, // is_retargeting + std::vector<GURL>(), // server redirects + ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, + referrer_chain.Get(2)); + + VerifyReferrerChainEntry(main_frame_url, // url + GURL(), // main_frame_url + ReferrerChainEntry::CLIENT_REDIRECT, // type + test_server_ip, // ip_address + GURL(), // referrer_url + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects + ReferrerChainEntry::BROWSER_INITIATED, + referrer_chain.Get(3)); + + index = FindNavigationEventIndex(new_window_subframe_url, + content::GlobalRenderFrameHostId()); + ASSERT_TRUE(index); + nav_event = GetNavigationEvent(*index); + EXPECT_EQ(web_contents()->GetMainFrame()->GetGlobalId(), + nav_event->outermost_main_frame_id); + + // If the initial main frame runs JS to initiate this subframe navigation, the + // the navigation request's initiator frame is in the current frame tree, + // not the frame in which the JS ran. + EXPECT_EQ(web_contents()->GetMainFrame()->GetGlobalId(), + nav_event->initiator_outermost_main_frame_id); +} + +// This is similar to PrerenderReferrerChains, but navigates rather than +// initiating the prerender to ensure that the referrer chains match. +IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, + ReferrerChainsMatchPrerender) { + std::string test_server_ip(embedded_test_server()->host_port_pair().host()); + auto main_frame_url = embedded_test_server()->GetURL(kMultiFrameTestURL); + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); + + auto next_url = embedded_test_server()->GetURL(kSubFrameTestURL); + content::TestNavigationObserver observer(web_contents(), 1); + ASSERT_TRUE(ExecJs(web_contents(), + content::JsReplace("window.location = $1;", next_url))); + observer.Wait(); + + ReferrerChain referrer_chain; + IdentifyReferrerChainByEventURL( + next_url, sessions::SessionTabHelper::IdForTab(web_contents()), + web_contents()->GetMainFrame()->GetGlobalId(), &referrer_chain); + + EXPECT_EQ(2, referrer_chain.size()); + + VerifyReferrerChainEntry( + next_url, // url + GURL(), // main_frame_url + ReferrerChainEntry::EVENT_URL, // type + test_server_ip, // ip_address + main_frame_url, // referrer_url + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects + ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, + referrer_chain.Get(0)); + + VerifyReferrerChainEntry(main_frame_url, // url + GURL(), // main_frame_url + ReferrerChainEntry::CLIENT_REDIRECT, // type + test_server_ip, // ip_address + GURL(), // referrer_url + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects + ReferrerChainEntry::BROWSER_INITIATED, + referrer_chain.Get(1)); +} + +IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, + PrerenderReferrerChains) { + std::string test_server_ip(embedded_test_server()->host_port_pair().host()); + auto main_frame_url = embedded_test_server()->GetURL(kMultiFrameTestURL); + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); + + auto prerendered_url = embedded_test_server()->GetURL(kSubFrameTestURL); + auto host_id = prerender_helper().AddPrerender(prerendered_url); + prerender_helper().WaitForPrerenderLoadCompletion(prerendered_url); + + // The prerendered URL (iframe.html) will now be loaded twice within the + // WebContents. Once as the main frame of the prerendered page and once as a + // subframe of the primary page. Since the prerender was initiated after + // loading the primary page, it will be the most recent navigation event. + + // Should find the event corresponding to the prerendered page. By passing an + // invalid RFH id, FindNavigationEvent does not attempt to match within a + // given outermost main frame but will instead match the most recent matching + // navigation event. + auto index_a = FindNavigationEventIndex(prerendered_url, + content::GlobalRenderFrameHostId()); + + // Since we're supplying the id for the primary page's outermost main frame, + // we should find the event for the primary page. + auto index_b = FindNavigationEventIndex( + prerendered_url, web_contents()->GetMainFrame()->GetGlobalId()); + + // Ensure that these indices are valid and not equal. + EXPECT_TRUE(index_a && index_b); + EXPECT_NE(*index_a, *index_b); + + auto* prerendered_main_frame_host = + prerender_helper().GetPrerenderedMainFrameHost(host_id); + auto index_c = FindNavigationEventIndex( + prerendered_url, + prerendered_main_frame_host->GetOutermostMainFrame()->GetGlobalId()); + + // By explicitly supplying the outermost frame id for the prerendered page, we + // should also get the event corresponding to the prerendered page. + EXPECT_TRUE(index_c); + EXPECT_EQ(*index_a, *index_c); + + // Build a full referrer chain for the prerendered page. + ReferrerChain referrer_chain; + IdentifyReferrerChainByEventURL( + prerendered_url, sessions::SessionTabHelper::IdForTab(web_contents()), + prerendered_main_frame_host->GetOutermostMainFrame()->GetGlobalId(), + &referrer_chain); + + EXPECT_EQ(2, referrer_chain.size()); + + VerifyReferrerChainEntry( + prerendered_url, // url + GURL(), // main_frame_url + ReferrerChainEntry::EVENT_URL, // type + test_server_ip, // ip_address + main_frame_url, // referrer_url + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects + ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, + referrer_chain.Get(0)); + + VerifyReferrerChainEntry(main_frame_url, // url + GURL(), // main_frame_url + ReferrerChainEntry::CLIENT_REDIRECT, // type + test_server_ip, // ip_address + GURL(), // referrer_url + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects + ReferrerChainEntry::BROWSER_INITIATED, + referrer_chain.Get(1)); + + content::test::PrerenderHostObserver host_observer(*web_contents(), host_id); + prerender_helper().NavigatePrimaryPage(prerendered_url); + host_observer.WaitForActivation(); + + // Build a full referrer chain for the prerendered page following activation. + referrer_chain.Clear(); + IdentifyReferrerChainByEventURL( + prerendered_url, sessions::SessionTabHelper::IdForTab(web_contents()), + web_contents()->GetMainFrame()->GetGlobalId(), &referrer_chain); + + EXPECT_EQ(2, referrer_chain.size()); + + VerifyReferrerChainEntry( + prerendered_url, // url + GURL(), // main_frame_url + ReferrerChainEntry::EVENT_URL, // type + test_server_ip, // ip_address + main_frame_url, // referrer_url + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects + ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, + referrer_chain.Get(0)); + + VerifyReferrerChainEntry(main_frame_url, // url + GURL(), // main_frame_url + ReferrerChainEntry::CLIENT_REDIRECT, // type + test_server_ip, // ip_address + GURL(), // referrer_url + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects + ReferrerChainEntry::BROWSER_INITIATED, + referrer_chain.Get(1)); +} + +IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, NavigateBackwardForward) { ASSERT_TRUE(ui_test_utils::NavigateToURL( browser(), embedded_test_server()->GetURL(kSingleFrameTestURL)));
diff --git a/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc b/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc index ab45dc8..ad9f27d 100644 --- a/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc +++ b/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc
@@ -33,6 +33,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/download_item_utils.h" #include "content/public/browser/download_manager.h" +#include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" using content::BrowserContext; @@ -169,6 +170,7 @@ void AndroidTelemetryService::FillReferrerChain( content::WebContents* web_contents, + content::RenderFrameHost* rfh, ClientSafeBrowsingReportRequest* report) { if (!SafeBrowsingNavigationObserverManager::IsEnabledAndReady( profile_->GetPrefs(), g_browser_process->safe_browsing_service())) { @@ -188,8 +190,8 @@ : nullptr; SafeBrowsingNavigationObserverManager::AttributionResult result = observer_manager - ? observer_manager->IdentifyReferrerChainByWebContents( - web_contents, kAndroidTelemetryUserGestureLimit, + ? observer_manager->IdentifyReferrerChainByRenderFrameHost( + rfh, kAndroidTelemetryUserGestureLimit, report->mutable_referrer_chain()) : SafeBrowsingNavigationObserverManager::NAVIGATION_EVENT_NOT_FOUND; @@ -229,7 +231,12 @@ // Fill referrer chain. content::WebContents* web_contents = content::DownloadItemUtils::GetWebContents(item); - FillReferrerChain(web_contents, report.get()); + content::RenderFrameHost* rfh = + content::DownloadItemUtils::GetRenderFrameHost(item); + if (!rfh && web_contents) + rfh = web_contents->GetMainFrame(); + + FillReferrerChain(web_contents, rfh, report.get()); // Fill DownloadItemInfo ClientSafeBrowsingReportRequest::DownloadItemInfo*
diff --git a/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.h b/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.h index e5e1d42..ce28c701 100644 --- a/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.h +++ b/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.h
@@ -20,6 +20,7 @@ class PrefService; namespace content { +class RenderFrameHost; class WebContents; } @@ -88,8 +89,9 @@ bool CanSendPing(download::DownloadItem* item); // Fill the referrer chain in |report| with the actual referrer chain for the - // given |web_contents|, as well as recent navigations. + // given |rfh|, as well as recent navigations. void FillReferrerChain(content::WebContents* web_contents, + content::RenderFrameHost* rfh, ClientSafeBrowsingReportRequest* report); // Sets the relevant fields in an instance of
diff --git a/chrome/browser/safe_browsing/test_safe_browsing_navigation_observer_manager.cc b/chrome/browser/safe_browsing/test_safe_browsing_navigation_observer_manager.cc new file mode 100644 index 0000000..c8750d6 --- /dev/null +++ b/chrome/browser/safe_browsing/test_safe_browsing_navigation_observer_manager.cc
@@ -0,0 +1,76 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/safe_browsing/test_safe_browsing_navigation_observer_manager.h" + +#include <memory> + +#include "build/build_config.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" +#include "chrome/browser/ui/browser.h" +#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace safe_browsing { + +InnerContentsCreationObserver::InnerContentsCreationObserver( + content::WebContents* web_contents, + base::RepeatingCallback<void(content::WebContents*)> + on_inner_contents_created) + : content::WebContentsObserver(web_contents), + on_inner_contents_created_(on_inner_contents_created) {} + +InnerContentsCreationObserver::~InnerContentsCreationObserver() = default; + +// WebContentsObserver: +void InnerContentsCreationObserver::InnerWebContentsCreated( + content::WebContents* inner_web_contents) { + on_inner_contents_created_.Run(inner_web_contents); +} + +TestSafeBrowsingNavigationObserverManager:: + TestSafeBrowsingNavigationObserverManager(Browser* browser) + : SafeBrowsingNavigationObserverManager(browser->profile()->GetPrefs()) { + browser->tab_strip_model()->AddObserver(this); +} +TestSafeBrowsingNavigationObserverManager:: + ~TestSafeBrowsingNavigationObserverManager() = default; + +void TestSafeBrowsingNavigationObserverManager::ObserveContents( + content::WebContents* contents) { + ASSERT_TRUE(contents); + Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); + auto observer = std::make_unique<SafeBrowsingNavigationObserver>( + contents, HostContentSettingsMapFactory::GetForProfile(profile), + safe_browsing::SafeBrowsingNavigationObserverManagerFactory:: + GetForBrowserContext(profile)); + observer->SetObserverManagerForTesting(this); + observer_list_.push_back(std::move(observer)); + inner_contents_creation_observers_.push_back( + std::make_unique<InnerContentsCreationObserver>( + contents, + base::BindRepeating( + &TestSafeBrowsingNavigationObserverManager::ObserveContents, + // Unretained is safe because this object owns + // inner_contents_creation_observers_ + base::Unretained(this)))); +} + +// TabStripModelObserver: +void TestSafeBrowsingNavigationObserverManager::OnTabStripModelChanged( + TabStripModel* tab_strip_model, + const TabStripModelChange& change, + const TabStripSelectionChange& selection) { + if (change.type() != TabStripModelChange::kInserted) + return; + + for (const TabStripModelChange::ContentsWithIndex& tab : + change.GetInsert()->contents) { + ObserveContents(tab.contents); + } +} + +} // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/test_safe_browsing_navigation_observer_manager.h b/chrome/browser/safe_browsing/test_safe_browsing_navigation_observer_manager.h new file mode 100644 index 0000000..68e91d500 --- /dev/null +++ b/chrome/browser/safe_browsing/test_safe_browsing_navigation_observer_manager.h
@@ -0,0 +1,68 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SAFE_BROWSING_TEST_SAFE_BROWSING_NAVIGATION_OBSERVER_MANAGER_H_ +#define CHROME_BROWSER_SAFE_BROWSING_TEST_SAFE_BROWSING_NAVIGATION_OBSERVER_MANAGER_H_ + +#include "chrome/browser/ui/tabs/tab_strip_model_observer.h" +#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer.h" +#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h" + +class Browser; + +namespace safe_browsing { + +class InnerContentsCreationObserver : public content::WebContentsObserver { + public: + InnerContentsCreationObserver( + content::WebContents* web_contents, + base::RepeatingCallback<void(content::WebContents*)> + on_inner_contents_created); + + ~InnerContentsCreationObserver() override; + + // WebContentsObserver: + void InnerWebContentsCreated( + content::WebContents* inner_web_contents) override; + + private: + base::RepeatingCallback<void(content::WebContents*)> + on_inner_contents_created_; +}; + +// Test class to help create SafeBrowsingNavigationObservers for each +// WebContents before they are actually installed through AttachTabHelper. +class TestSafeBrowsingNavigationObserverManager + : public SafeBrowsingNavigationObserverManager, + public TabStripModelObserver { + public: + explicit TestSafeBrowsingNavigationObserverManager(Browser* browser); + TestSafeBrowsingNavigationObserverManager( + const TestSafeBrowsingNavigationObserverManager&) = delete; + TestSafeBrowsingNavigationObserverManager& operator=( + const TestSafeBrowsingNavigationObserverManager&) = delete; + + ~TestSafeBrowsingNavigationObserverManager() override; + + void ObserveContents(content::WebContents* contents); + + // TabStripModelObserver: + void OnTabStripModelChanged( + TabStripModel* tab_strip_model, + const TabStripModelChange& change, + const TabStripSelectionChange& selection) override; + + NavigationEventList* navigation_event_list() { + return SafeBrowsingNavigationObserverManager::navigation_event_list(); + } + + private: + std::vector<std::unique_ptr<SafeBrowsingNavigationObserver>> observer_list_; + std::vector<std::unique_ptr<InnerContentsCreationObserver>> + inner_contents_creation_observers_; +}; + +} // namespace safe_browsing + +#endif // CHROME_BROWSER_SAFE_BROWSING_TEST_SAFE_BROWSING_NAVIGATION_OBSERVER_MANAGER_H_
diff --git a/chrome/browser/safe_browsing/threat_details_unittest.cc b/chrome/browser/safe_browsing/threat_details_unittest.cc index 22fd3f1..ac6295e 100644 --- a/chrome/browser/safe_browsing/threat_details_unittest.cc +++ b/chrome/browser/safe_browsing/threat_details_unittest.cc
@@ -213,14 +213,16 @@ class MockReferrerChainProvider : public ReferrerChainProvider { public: - virtual ~MockReferrerChainProvider() {} - MOCK_METHOD3(IdentifyReferrerChainByWebContents, - AttributionResult(content::WebContents* web_contents, + virtual ~MockReferrerChainProvider() = default; + MOCK_METHOD3(IdentifyReferrerChainByRenderFrameHost, + AttributionResult(content::RenderFrameHost* rfh, int user_gesture_count_limit, ReferrerChain* out_referrer_chain)); - MOCK_METHOD4(IdentifyReferrerChainByEventURL, + MOCK_METHOD5(IdentifyReferrerChainByEventURL, AttributionResult(const GURL& event_url, SessionID event_tab_id, + const content::GlobalRenderFrameHostId& + outermost_event_main_frame_id, int user_gesture_count_limit, ReferrerChain* out_referrer_chain)); MOCK_METHOD3(IdentifyReferrerChainByPendingEventURL, @@ -563,7 +565,8 @@ returned_referrer_chain.Add()->set_url(kReferrerURL); returned_referrer_chain.Add()->set_url(kSecondRedirectURL); EXPECT_CALL(*referrer_chain_provider_, - IdentifyReferrerChainByWebContents(web_contents(), _, _)) + IdentifyReferrerChainByRenderFrameHost( + web_contents()->GetMainFrame(), _, _)) .WillOnce(DoAll(SetArgPointee<2>(returned_referrer_chain), Return(ReferrerChainProvider::SUCCESS)));
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 2267662..1bf5e2e 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2777,6 +2777,13 @@ "webui/settings/ash/calculator/size_calculator.h", "webui/settings/ash/os_apps_page/app_notification_handler.cc", "webui/settings/ash/os_apps_page/app_notification_handler.h", + "webui/settings/ash/search/per_session_settings_user_action_tracker.cc", + "webui/settings/ash/search/per_session_settings_user_action_tracker.h", + "webui/settings/ash/search/search_concept.h", + "webui/settings/ash/search/search_handler.cc", + "webui/settings/ash/search/search_handler.h", + "webui/settings/ash/search/search_tag_registry.cc", + "webui/settings/ash/search/search_tag_registry.h", "webui/settings/chromeos/about_section.cc", "webui/settings/chromeos/about_section.h", "webui/settings/chromeos/accessibility_handler.cc", @@ -2890,13 +2897,6 @@ "webui/settings/chromeos/quick_unlock_handler.h", "webui/settings/chromeos/reset_section.cc", "webui/settings/chromeos/reset_section.h", - "webui/settings/chromeos/search/per_session_settings_user_action_tracker.cc", - "webui/settings/chromeos/search/per_session_settings_user_action_tracker.h", - "webui/settings/chromeos/search/search_concept.h", - "webui/settings/chromeos/search/search_handler.cc", - "webui/settings/chromeos/search/search_handler.h", - "webui/settings/chromeos/search/search_tag_registry.cc", - "webui/settings/chromeos/search/search_tag_registry.h", "webui/settings/chromeos/search_section.cc", "webui/settings/chromeos/search_section.h", "webui/settings/chromeos/server_printer_url_util.cc", @@ -3024,7 +3024,7 @@ "//chrome/browser/ui/webui/nearby_share:mojom", "//chrome/browser/ui/webui/nearby_share/public/mojom", "//chrome/browser/ui/webui/settings/ash/os_apps_page/mojom", - "//chrome/browser/ui/webui/settings/chromeos/search:mojo_bindings", + "//chrome/browser/ui/webui/settings/ash/search:mojo_bindings", "//chrome/browser/web_applications", "//chrome/services/file_util/public/cpp", "//chromeos/assistant:buildflags",
diff --git a/chrome/browser/ui/app_list/search/os_settings_provider.cc b/chrome/browser/ui/app_list/search/os_settings_provider.cc index 5f346e1..8e0d739d 100644 --- a/chrome/browser/ui/app_list/search/os_settings_provider.cc +++ b/chrome/browser/ui/app_list/search/os_settings_provider.cc
@@ -21,10 +21,10 @@ #include "chrome/browser/ui/app_list/search/common/icon_constants.h" #include "chrome/browser/ui/app_list/search/search_tags_util.h" #include "chrome/browser/ui/settings_window_manager_chromeos.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/hierarchy.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_handler.h" #include "chrome/browser/web_applications/web_app_id_constants.h" #include "chrome/common/chrome_features.h" #include "components/services/app_service/public/cpp/app_registry_cache.h"
diff --git a/chrome/browser/ui/app_list/search/os_settings_provider.h b/chrome/browser/ui/app_list/search/os_settings_provider.h index 7449024a..bae525f 100644 --- a/chrome/browser/ui/app_list/search/os_settings_provider.h +++ b/chrome/browser/ui/app_list/search/os_settings_provider.h
@@ -13,7 +13,7 @@ #include "chrome/browser/apps/app_service/app_service_proxy_forward.h" #include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/search/search_provider.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom.h" +#include "chrome/browser/ui/webui/settings/ash/search/search.mojom.h" #include "components/services/app_service/public/cpp/app_registry_cache.h" #include "components/services/app_service/public/cpp/icon_types.h" #include "components/services/app_service/public/mojom/types.mojom.h"
diff --git a/chrome/browser/ui/views/extensions/extension_popup.cc b/chrome/browser/ui/views/extensions/extension_popup.cc index fcad195..13283dd8 100644 --- a/chrome/browser/ui/views/extensions/extension_popup.cc +++ b/chrome/browser/ui/views/extensions/extension_popup.cc
@@ -31,6 +31,32 @@ constexpr gfx::Size ExtensionPopup::kMinSize; constexpr gfx::Size ExtensionPopup::kMaxSize; +// A helper class to scope the observation of DevToolsAgentHosts. We can't just +// use base::ScopedObservation here because that requires a specific source +// object, where as DevToolsAgentHostObservers are added to a singleton list. +// The `observer_` passed into this object will be registered as an observer +// for this object's lifetime. +class ExtensionPopup::ScopedDevToolsAgentHostObservation { + public: + ScopedDevToolsAgentHostObservation( + content::DevToolsAgentHostObserver* observer) + : observer_(observer) { + content::DevToolsAgentHost::AddObserver(observer_); + } + + ScopedDevToolsAgentHostObservation( + const ScopedDevToolsAgentHostObservation&) = delete; + ScopedDevToolsAgentHostObservation& operator=( + const ScopedDevToolsAgentHostObservation&) = delete; + + ~ScopedDevToolsAgentHostObservation() { + content::DevToolsAgentHost::RemoveObserver(observer_); + } + + private: + content::DevToolsAgentHostObserver* observer_; +}; + // static void ExtensionPopup::ShowPopup( std::unique_ptr<extensions::ExtensionViewHost> host, @@ -64,8 +90,6 @@ } ExtensionPopup::~ExtensionPopup() { - content::DevToolsAgentHost::RemoveObserver(this); - // The ExtensionPopup may close before it was ever shown. If so, indicate such // through the callback. if (shown_callback_) @@ -167,10 +191,11 @@ extension_host_observation_.Reset(); host_.reset(); - // Stop observing the registry immediately to prevent any subsequent - // notifications, since Widget::Close is asynchronous. + // Stop observing the registry and devtools immediately to prevent any + // subsequent notifications, since Widget::Close is asynchronous. DCHECK(extension_registry_observation_.IsObserving()); extension_registry_observation_.Reset(); + scoped_devtools_observation_.reset(); GetWidget()->Close(); } @@ -192,18 +217,14 @@ void ExtensionPopup::DevToolsAgentHostAttached( content::DevToolsAgentHost* agent_host) { + DCHECK(host_); if (host_->host_contents() == agent_host->GetWebContents()) show_action_ = PopupShowAction::kShowAndInspect; } void ExtensionPopup::DevToolsAgentHostDetached( content::DevToolsAgentHost* agent_host) { - // If the extension's page is open it will be closed when the extension - // is uninstalled, and if DevTools are attached, we will be notified here. - // But because OnExtensionUnloaded was already called, |host_| is - // no longer valid. - if (!host_) - return; + DCHECK(host_); if (host_->host_contents() == agent_host->GetWebContents()) show_action_ = PopupShowAction::kShow; } @@ -244,7 +265,8 @@ // See comments in OnWidgetActivationChanged(). set_close_on_deactivate(false); - content::DevToolsAgentHost::AddObserver(this); + scoped_devtools_observation_ = + std::make_unique<ScopedDevToolsAgentHostObservation>(this); host_->browser()->tab_strip_model()->AddObserver(this); // Listen for the containing view calling window.close();
diff --git a/chrome/browser/ui/views/extensions/extension_popup.h b/chrome/browser/ui/views/extensions/extension_popup.h index 48e8c9cf..532d052 100644 --- a/chrome/browser/ui/views/extensions/extension_popup.h +++ b/chrome/browser/ui/views/extensions/extension_popup.h
@@ -121,6 +121,8 @@ void OnExtensionHostShouldClose(extensions::ExtensionHost* host) override; private: + class ScopedDevToolsAgentHostObservation; + ExtensionPopup(std::unique_ptr<extensions::ExtensionViewHost> host, views::View* anchor_view, views::BubbleBorder::Arrow arrow, @@ -149,6 +151,9 @@ PopupShowAction show_action_; ShowPopupCallback shown_callback_; + + std::unique_ptr<ScopedDevToolsAgentHostObservation> + scoped_devtools_observation_; }; #endif // CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_POPUP_H_
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc index c8d4205..11de087 100644 --- a/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc +++ b/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc
@@ -857,8 +857,8 @@ // there are no other buttons at the end. ProfileMenuViewBase::ActionableItem::kEditProfileButton}; -// TODO(crbug.com/1298490): flaky on Windows. -#if BUILDFLAG(IS_WIN) +// TODO(crbug.com/1298490): flaky on Windows and Mac +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) #define MAYBE_ProfileMenuClickTest_SyncPaused \ DISABLED_ProfileMenuClickTest_SyncPaused #else
diff --git a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc index 9a42c3bd..b6f9760970 100644 --- a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc +++ b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
@@ -104,13 +104,6 @@ this, controller->browser()->tab_menu_model_delegate(), controller->model_, controller->tabstrip_->GetModelIndexOf(tab)); - // If IPH is showing, continue into the menu. IsCommandIdAlerted() - // is called on |menu_runner_| construction, and we check - // |tab_groups_promo_handle_| there. So we must do this first. - tab_groups_promo_handle_ = - controller->browser()->window()->CloseFeaturePromoAndContinue( - feature_engagement::kIPHDesktopTabGroupsNewGroupFeature); - // Because we use "new" badging for feature promos, we cannot use system- // native context menus. (See crbug.com/1109256.) const int run_flags = @@ -143,11 +136,9 @@ bool IsCommandIdAlerted(int command_id) const override { return command_id == TabStripModel::CommandAddToNewGroup && - tab_groups_promo_handle_; - } - - void MenuClosed(ui::SimpleMenuModel*) override { - tab_groups_promo_handle_.Release(); + controller_->GetBrowser()->window()->IsFeaturePromoActive( + feature_engagement::kIPHDesktopTabGroupsNewGroupFeature, + /* include_continued_promos =*/true); } bool GetAcceleratorForCommandId(int command_id, @@ -184,9 +175,6 @@ // A pointer back to our hosting controller, for command state information. raw_ptr<BrowserTabStripController> controller_; - - // Handle we keep if showing menu IPH for tab groups. - FeaturePromoController::PromoHandle tab_groups_promo_handle_; }; ////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/views/tabs/tab_container.cc b/chrome/browser/ui/views/tabs/tab_container.cc index 3889c63..7ddc358 100644 --- a/chrome/browser/ui/views/tabs/tab_container.cc +++ b/chrome/browser/ui/views/tabs/tab_container.cc
@@ -5,8 +5,11 @@ #include "chrome/browser/ui/views/tabs/tab_container.h" #include "base/bits.h" +#include "base/containers/adapters.h" #include "chrome/browser/ui/layout_constants.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/tabs/tab.h" +#include "chrome/browser/ui/views/tabs/tab_drag_context.h" #include "chrome/browser/ui/views/tabs/tab_group_header.h" #include "chrome/browser/ui/views/tabs/tab_group_highlight.h" #include "chrome/browser/ui/views/tabs/tab_group_underline.h" @@ -237,9 +240,11 @@ } TabContainer::TabContainer(TabStripController* controller, - TabHoverCardController* hover_card_controller) + TabHoverCardController* hover_card_controller, + TabDragContext* drag_context) : controller_(controller), hover_card_controller_(hover_card_controller), + drag_context_(drag_context), bounds_animator_(this), layout_helper_(std::make_unique<TabStripLayoutHelper>( controller, @@ -256,6 +261,11 @@ RemoveAllChildViews(); } +void TabContainer::SetAvailableWidthCallback( + base::RepeatingCallback<int()> available_width_callback) { + available_width_callback_ = available_width_callback; +} + Tab* TabContainer::AddTab(std::unique_ptr<Tab> tab, int model_index, TabPinned pinned) { @@ -332,7 +342,7 @@ group_views->second->UpdateBounds(); } -int TabContainer::GetModelIndexOf(const TabSlotView* slot_view) { +int TabContainer::GetModelIndexOf(const TabSlotView* slot_view) const { return tabs_view_model_.GetIndexOfView(slot_view); } @@ -477,6 +487,20 @@ PreferredSizeChanged(); } +int TabContainer::CalculateAvailableWidthForTabs() const { + return override_available_width_for_tabs_.value_or( + GetAvailableWidthForTabContainer()); +} + +int TabContainer::GetAvailableWidthForTabContainer() const { + // Falls back to views::View::GetAvailableSize() when + // |available_width_callback_| is not defined, e.g. when tab scrolling is + // disabled. + return available_width_callback_ + ? available_width_callback_.Run() + : parent()->GetAvailableSize(this).width().value(); +} + void TabContainer::SnapToIdealBounds() { for (int i = 0; i < GetTabCount(); ++i) GetTabAtModelIndex(i)->SetBoundsRect(tabs_view_model_.ideal_bounds(i)); @@ -551,6 +575,31 @@ override_available_width_for_tabs_.reset(); } +void TabContainer::SetTabSlotVisibility() { + bool last_tab_visible = false; + absl::optional<tab_groups::TabGroupId> last_tab_group = absl::nullopt; + std::vector<Tab*> tabs = layout_helper()->GetTabs(); + for (Tab* tab : base::Reversed(tabs)) { + absl::optional<tab_groups::TabGroupId> current_group = tab->group(); + if (current_group != last_tab_group && last_tab_group.has_value()) { + TabGroupViews* group_view = + group_views().at(last_tab_group.value()).get(); + group_view->header()->SetVisible(last_tab_visible); + group_view->underline()->SetVisible(last_tab_visible); + } + last_tab_visible = ShouldTabBeVisible(tab); + last_tab_group = tab->closing() ? absl::nullopt : current_group; + + // Collapsed tabs disappear once they've reached their minimum size. This + // is different than very small non-collapsed tabs, because in that case + // the tab (and its favicon) must still be visible. + bool is_collapsed = (current_group.has_value() && + controller_->IsGroupCollapsed(current_group.value()) && + tab->bounds().width() <= TabStyle::GetTabOverlap()); + tab->SetVisible(is_collapsed ? false : last_tab_visible); + } +} + void TabContainer::OnTabWillBeRemovedAt(int model_index, bool was_active) { // The tab at |model_index| has already been removed from the model, but is // still in |tabs_view_model_|. Index math with care! @@ -767,9 +816,67 @@ return nullptr; } +bool TabContainer::ShouldTabBeVisible(const Tab* tab) const { + // When the tabstrip is scrollable, it can grow to accommodate any number of + // tabs, so tabs can never become clipped. + // N.B. Tabs can still be not-visible because they're in a collapsed group, + // but that's handled elsewhere. + // N.B. This is separate from the tab being potentially scrolled offscreen - + // this solely determines whether the tab should be clipped for the + // pre-scrolling overflow behavior. + if (base::FeatureList::IsEnabled(features::kScrollableTabStrip)) + return true; + + // Detached tabs should always be invisible (as they close). + if (tab->detached()) + return false; + + // If the tab would be clipped by the trailing edge of the strip, even if the + // tabstrip were resized to its greatest possible width, it shouldn't be + // visible. + int right_edge = tab->bounds().right(); + const int tabstrip_right = tab->dragging() + ? drag_context_->GetTabDragAreaWidth() + : GetAvailableWidthForTabContainer(); + if (right_edge > tabstrip_right) + return false; + + // Non-clipped dragging tabs should always be visible. + if (tab->dragging()) + return true; + + // Let all non-clipped closing tabs be visible. These will probably finish + // closing before the user changes the active tab, so there's little reason to + // try and make the more complex logic below apply. + if (tab->closing()) + return true; + + // Now we need to check whether the tab isn't currently clipped, but could + // become clipped if we changed the active tab, widening either this tab or + // the tabstrip portion before it. + + // Pinned tabs don't change size when activated, so any tab in the pinned tab + // region is safe. + if (tab->data().pinned) + return true; + + // If the active tab is on or before this tab, we're safe. + if (controller_->GetActiveIndex() <= GetModelIndexOf(tab)) + return true; + + // We need to check what would happen if the active tab were to move to this + // tab or before. If animating, we want to use the target bounds in this + // calculation. + if (bounds_animator_.IsAnimating()) + right_edge = bounds_animator_.GetTargetBounds(tab).right(); + return (right_edge + layout_helper_->active_tab_width() - + layout_helper_->inactive_tab_width()) <= tabstrip_right; +} + bool TabContainer::IsValidModelIndex(int model_index) const { return controller_->IsValidIndex(model_index); } BEGIN_METADATA(TabContainer, views::View) +ADD_READONLY_PROPERTY_METADATA(int, AvailableWidthForTabContainer) END_METADATA
diff --git a/chrome/browser/ui/views/tabs/tab_container.h b/chrome/browser/ui/views/tabs/tab_container.h index ce85e76..aafd9aa 100644 --- a/chrome/browser/ui/views/tabs/tab_container.h +++ b/chrome/browser/ui/views/tabs/tab_container.h
@@ -22,16 +22,21 @@ class TabStrip; class TabGroupHeader; class TabHoverCardController; +class TabDragContext; // A View that contains a sequence of Tabs for the TabStrip. class TabContainer : public views::View, public views::ViewTargeterDelegate { public: METADATA_HEADER(TabContainer); - TabContainer(TabStripController* controller_, - TabHoverCardController* hover_card_controller_); + TabContainer(TabStripController* controller, + TabHoverCardController* hover_card_controller, + TabDragContext* drag_context); ~TabContainer() override; + void SetAvailableWidthCallback( + base::RepeatingCallback<int()> available_width_callback); + Tab* AddTab(std::unique_ptr<Tab> tab, int model_index, TabPinned pinned); void MoveTab(Tab* tab, int from_model_index, int to_model_index); @@ -51,7 +56,7 @@ void UpdateTabGroupVisuals(tab_groups::TabGroupId group_id); - int GetModelIndexOf(const TabSlotView* slot_view); + int GetModelIndexOf(const TabSlotView* slot_view) const; views::ViewModelT<Tab>* tabs_view_model() { return &tabs_view_model_; } @@ -80,6 +85,14 @@ // currently set in ideal_bounds. void AnimateToIdealBounds(); + // Calculates the width that can be occupied by the tabs in the container. + // This can differ from GetAvailableWidthForTabContainer() when in tab closing + // mode. + int CalculateAvailableWidthForTabs() const; + + // Returns the total width available for the TabContainer's use. + int GetAvailableWidthForTabContainer() const; + // Teleports the tabs to their ideal bounds. // NOTE: this does *not* invoke UpdateIdealBounds, it uses the bounds // currently set in ideal_bounds. @@ -91,6 +104,10 @@ void EnterTabClosingMode(absl::optional<int> override_width); void ExitTabClosingMode(); + // Sets the visibility state of all tabs and group headers (if any) based on + // ShouldTabBeVisible(). + void SetTabSlotVisibility(); + bool in_tab_close() { return in_tab_close_; } absl::optional<int> override_available_width_for_tabs() { return override_available_width_for_tabs_; @@ -144,6 +161,13 @@ // If no tabs are hit, returns null. Tab* FindTabHitByPoint(const gfx::Point& point); + // Returns true if the tab is not partly or fully clipped (due to overflow), + // and the tab couldn't become partly clipped due to changing the selected tab + // (for example, if currently the strip has the last tab selected, and + // changing that to the first tab would cause |tab| to be pushed over enough + // to clip). + bool ShouldTabBeVisible(const Tab* tab) const; + bool IsValidModelIndex(int model_index) const; std::map<tab_groups::TabGroupId, std::unique_ptr<TabGroupViews>> group_views_; @@ -162,6 +186,8 @@ TabHoverCardController* hover_card_controller_; + TabDragContext* drag_context_; + // Responsible for animating tabs in response to model changes. views::BoundsAnimator bounds_animator_; @@ -178,6 +204,8 @@ // true, remove animations preserve current tab bounds, making tabs move more // predictably in case the user wants to perform more mouse-based actions. bool in_tab_close_ = false; + + base::RepeatingCallback<int()> available_width_callback_; }; #endif // CHROME_BROWSER_UI_VIEWS_TABS_TAB_CONTAINER_H_
diff --git a/chrome/browser/ui/views/tabs/tab_container_unittest.cc b/chrome/browser/ui/views/tabs/tab_container_unittest.cc index c6d1bb0..b484f5fa 100644 --- a/chrome/browser/ui/views/tabs/tab_container_unittest.cc +++ b/chrome/browser/ui/views/tabs/tab_container_unittest.cc
@@ -22,7 +22,8 @@ tab_strip_controller_ = std::make_unique<FakeBaseTabStripController>(); tab_container_ = std::make_unique<TabContainer>( - tab_strip_controller_.get(), nullptr /*hover_card_controller_*/); + tab_strip_controller_.get(), nullptr /*hover_card_controller*/, + nullptr /*drag_context*/); tab_controller_ = std::make_unique<FakeTabController>(); }
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc index 11d1440..d8cf19d4 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
@@ -871,7 +871,7 @@ GURL domain_url; // Use committed URL to determine if no page has yet loaded, since the title // can be blank for some web pages. - if (tab->data().last_committed_url.is_empty()) { + if (!tab->data().last_committed_url.is_valid()) { domain_url = tab->data().visible_url; title = tab->data().IsCrashed() ? l10n_util::GetStringUTF16(IDS_HOVER_CARD_CRASHED_TITLE)
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc b/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc index 57e9261..703ce1f 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc
@@ -333,7 +333,7 @@ const Tab* intended_tab) { // Make sure the hover card isn't accidentally shown if it's already visible // or if the anchor is gone or changed. - if (hover_card_ || !TargetTabIsValid() || target_tab_ != intended_tab) + if (hover_card_ || target_tab_ != intended_tab || !TargetTabIsValid()) return; CreateHoverCard(target_tab_); @@ -544,8 +544,13 @@ } bool TabHoverCardController::TargetTabIsValid() const { + // There are a bunch of conditions under which a tab may no longer be valid, + // including no longer belonging to the same tabstrip, being dragged or + // detached, or just not being visible. We need to be vigilant about invalid + // tabs due to e.g. crbug.com/1295601. return target_tab_ && tab_strip_->GetModelIndexOf(target_tab_) >= 0 && - !target_tab_->closing(); + !target_tab_->closing() && !target_tab_->detached() && + !target_tab_->dragging() && target_tab_->GetVisible(); } void TabHoverCardController::OnCardFullyVisible() {
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index 4dafa99..3c0a63f 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -383,8 +383,9 @@ // 2) If the tabstrip is wider than the tab strip region (and thus is // scrollable), returning the tabstrip width allows tabs to be dragged // anywhere within the tabstrip, not just in the leftmost region of it. - return std::max(tab_strip_->GetAvailableWidthForTabStrip(), - tab_strip_->width()); + return std::max( + tab_strip_->tab_container_->GetAvailableWidthForTabContainer(), + tab_strip_->width()); } int TabDragAreaBeginX() const override { @@ -523,7 +524,7 @@ ->SetVisible(true); } - tab_strip_->SetTabSlotVisibility(); + tab_strip_->tab_container_->SetTabSlotVisibility(); tab_strip_->SchedulePaint(); } @@ -571,7 +572,7 @@ view->SetBoundsRect(new_bounds); } } - tab_strip_->SetTabSlotVisibility(); + tab_strip_->tab_container_->SetTabSlotVisibility(); // The rightmost tab may have moved, which would change the tabstrip's // preferred width. tab_strip_->PreferredSizeChanged(); @@ -782,10 +783,11 @@ TabStrip::TabStrip(std::unique_ptr<TabStripController> controller) : controller_(std::move(controller)), hover_card_controller_(std::make_unique<TabHoverCardController>(this)), + drag_context_(std::make_unique<TabDragContextImpl>(this)), tab_container_(AddChildView( std::make_unique<TabContainer>(controller_.get(), - hover_card_controller_.get()))), - drag_context_(std::make_unique<TabDragContextImpl>(this)) { + hover_card_controller_.get(), + drag_context_.get()))) { // TODO(pbos): This is probably incorrect, the background of individual tabs // depend on their selected state. This should probably be pushed down into // tabs. @@ -823,7 +825,7 @@ void TabStrip::SetAvailableWidthCallback( base::RepeatingCallback<int()> available_width_callback) { - available_width_callback_ = available_width_callback; + tab_container_->SetAvailableWidthCallback(available_width_callback); } // static @@ -1003,7 +1005,8 @@ // If the tab strip won't be scrollable after the current tabstrip animations // complete, scroll animation wouldn't be meaningful. - if (ideal_bounds(GetTabCount() - 1).right() <= GetAvailableWidthForTabStrip()) + if (ideal_bounds(GetTabCount() - 1).right() <= + tab_container_->GetAvailableWidthForTabContainer()) return; if (tab_scrolling_animation_) @@ -1171,63 +1174,6 @@ ShiftGroupRelative(group, 1); } -bool TabStrip::ShouldTabBeVisible(const Tab* tab) const { - // When the tabstrip is scrollable, it can grow to accommodate any number of - // tabs, so tabs can never become clipped. - // N.B. Tabs can still be not-visible because they're in a collapsed group, - // but that's handled elsewhere. - // N.B. This is separate from the tab being potentially scrolled offscreen - - // this solely determines whether the tab should be clipped for the - // pre-scrolling overflow behavior. - if (base::FeatureList::IsEnabled(features::kScrollableTabStrip)) - return true; - - // Detached tabs should always be invisible (as they close). - if (tab->detached()) - return false; - - // If the tab would be clipped by the trailing edge of the strip, even if the - // tabstrip were resized to its greatest possible width, it shouldn't be - // visible. - int right_edge = tab->bounds().right(); - const int tabstrip_right = tab->dragging() - ? drag_context_->GetTabDragAreaWidth() - : GetAvailableWidthForTabStrip(); - if (right_edge > tabstrip_right) - return false; - - // Non-clipped dragging tabs should always be visible. - if (tab->dragging()) - return true; - - // Let all non-clipped closing tabs be visible. These will probably finish - // closing before the user changes the active tab, so there's little reason to - // try and make the more complex logic below apply. - if (tab->closing()) - return true; - - // Now we need to check whether the tab isn't currently clipped, but could - // become clipped if we changed the active tab, widening either this tab or - // the tabstrip portion before it. - - // Pinned tabs don't change size when activated, so any tab in the pinned tab - // region is safe. - if (tab->data().pinned) - return true; - - // If the active tab is on or before this tab, we're safe. - if (controller_->GetActiveIndex() <= GetModelIndexOf(tab)) - return true; - - // We need to check what would happen if the active tab were to move to this - // tab or before. If animating, we want to use the target bounds in this - // calculation. - if (IsAnimating()) - right_edge = tab_container_->bounds_animator().GetTargetBounds(tab).right(); - return (right_edge + GetActiveTabWidth() - GetInactiveTabWidth()) <= - tabstrip_right; -} - bool TabStrip::ShouldDrawStrokes() const { // If the controller says we can't draw strokes, don't. if (!controller_->CanDrawStrokes()) @@ -1812,7 +1758,14 @@ } /////////////////////////////////////////////////////////////////////////////// -// TabStrip, views::AccessiblePaneView overrides: +// TabStrip, views::View overrides: + +views::SizeBounds TabStrip::GetAvailableSize(const views::View* child) const { + // We can only reach here if SetAvailableWidthCallback() was never called, + // e.g. if tab scrolling is disabled. Defer to our parent. + DCHECK(child == tab_container_); + return parent()->GetAvailableSize(this); +} void TabStrip::Layout() { if (base::FeatureList::IsEnabled(features::kScrollableTabStrip)) { @@ -1823,23 +1776,25 @@ // It should never be smaller than its minimum width. const int min_width = GetMinimumSize().width(); // If it can, it should fit within the tab strip region. - const int available_width = available_width_callback_.Run(); + const int available_width = + tab_container_->GetAvailableWidthForTabContainer(); // It should be as wide as possible subject to the above constraints. const int width = std::min(max_width, std::max(min_width, available_width)); SetBounds(0, 0, width, GetLayoutConstant(TAB_HEIGHT)); - SetTabSlotVisibility(); + tab_container_->SetTabSlotVisibility(); } tab_container_->SetBounds(0, 0, width(), height()); if (IsAnimating()) { // Hide tabs that have animated at least partially out of the clip region. - SetTabSlotVisibility(); + tab_container_->SetTabSlotVisibility(); return; } // Only do a layout if our size or the available width changed. - const int available_width = GetAvailableWidthForTabStrip(); + const int available_width = + tab_container_->GetAvailableWidthForTabContainer(); if (last_layout_size_ == size() && last_available_width_ == available_width) return; if (drag_context_->IsDragSessionActive()) @@ -2125,7 +2080,7 @@ } void TabStrip::CompleteAnimationAndLayout() { - last_available_width_ = GetAvailableWidthForTabStrip(); + last_available_width_ = tab_container_->GetAvailableWidthForTabContainer(); last_layout_size_ = size(); tab_container_->bounds_animator().Cancel(); @@ -2135,36 +2090,10 @@ UpdateIdealBounds(); tab_container_->SnapToIdealBounds(); - SetTabSlotVisibility(); + tab_container_->SetTabSlotVisibility(); SchedulePaint(); } -void TabStrip::SetTabSlotVisibility() { - bool last_tab_visible = false; - absl::optional<tab_groups::TabGroupId> last_tab_group = absl::nullopt; - std::vector<Tab*> tabs = tab_container_->layout_helper()->GetTabs(); - for (Tab* tab : base::Reversed(tabs)) { - absl::optional<tab_groups::TabGroupId> current_group = tab->group(); - if (current_group != last_tab_group && last_tab_group.has_value()) { - TabGroupViews* group_view = - tab_container_->group_views().at(last_tab_group.value()).get(); - group_view->header()->SetVisible(last_tab_visible); - group_view->underline()->SetVisible(last_tab_visible); - } - last_tab_visible = ShouldTabBeVisible(tab); - last_tab_group = tab->closing() ? absl::nullopt : current_group; - - // Collapsed tabs disappear once they've reached their minimum size. This - // is different than very small non-collapsed tabs, because in that case - // the tab (and its favicon) must still be visible. - bool is_collapsed = - (current_group.has_value() && - controller()->IsGroupCollapsed(current_group.value()) && - tab->bounds().width() <= TabStyle::GetTabOverlap()); - tab->SetVisible(is_collapsed ? false : last_tab_visible); - } -} - int TabStrip::GetActiveTabWidth() const { return tab_container_->layout_helper()->active_tab_width(); } @@ -2659,23 +2588,13 @@ // Update |last_available_width_| in case there is a different amount of // available width than there was in the last layout (e.g. if the tabstrip // is currently hidden). - last_available_width_ = GetAvailableWidthForTabStrip(); + last_available_width_ = tab_container_->GetAvailableWidthForTabContainer(); - const int available_width_for_tabs = CalculateAvailableWidthForTabs(); + const int available_width_for_tabs = + tab_container_->CalculateAvailableWidthForTabs(); tab_container_->layout_helper()->UpdateIdealBounds(available_width_for_tabs); } -int TabStrip::CalculateAvailableWidthForTabs() const { - return tab_container_->override_available_width_for_tabs().value_or( - GetAvailableWidthForTabStrip()); -} - -int TabStrip::GetAvailableWidthForTabStrip() const { - return available_width_callback_ - ? available_width_callback_.Run() - : parent()->GetAvailableSize(this).width().value(); -} - void TabStrip::StartResizeLayoutAnimation() { PrepareForAnimation(); UpdateIdealBounds(); @@ -2821,5 +2740,4 @@ ADD_READONLY_PROPERTY_METADATA(float, HoverOpacityForRadialHighlight) ADD_READONLY_PROPERTY_METADATA(int, ActiveTabWidth) ADD_READONLY_PROPERTY_METADATA(int, InactiveTabWidth) -ADD_READONLY_PROPERTY_METADATA(int, AvailableWidthForTabStrip) END_METADATA
diff --git a/chrome/browser/ui/views/tabs/tab_strip.h b/chrome/browser/ui/views/tabs/tab_strip.h index 22b9b3d..21183fb 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.h +++ b/chrome/browser/ui/views/tabs/tab_strip.h
@@ -189,13 +189,6 @@ // Attempts to move the specified group to the right. void ShiftGroupRight(const tab_groups::TabGroupId& group); - // Returns true if the tab is not partly or fully clipped (due to overflow), - // and the tab couldn't become partly clipped due to changing the selected tab - // (for example, if currently the strip has the last tab selected, and - // changing that to the first tab would cause |tab| to be pushed over enough - // to clip). - bool ShouldTabBeVisible(const Tab* tab) const; - // Returns whether or not strokes should be drawn around and under the tabs. bool ShouldDrawStrokes() const; @@ -326,6 +319,7 @@ void MouseMovedOutOfHost() override; // views::View: + views::SizeBounds GetAvailableSize(const View* child) const override; void Layout() override; void ChildPreferredSizeChanged(views::View* child) override; gfx::Size GetMinimumSize() const override; @@ -438,10 +432,6 @@ // Invoked from Layout if the size changes or layout is really needed. void CompleteAnimationAndLayout(); - // Sets the visibility state of all tabs and group headers (if any) based on - // ShouldTabBeVisible(). - void SetTabSlotVisibility(); - // Returns the current width of the active tab. int GetActiveTabWidth() const; @@ -523,13 +513,6 @@ // use this information for other purposes - see AnimateToIdealBounds. void UpdateIdealBounds(); - // Calculates the width that can be occupied by the tabs in the strip. This - // can differ from GetAvailableWidthForTabStrip() when in tab closing mode. - int CalculateAvailableWidthForTabs() const; - - // Returns the total width available for the TabStrip's use. - int GetAvailableWidthForTabStrip() const; - // Starts various types of TabStrip animations. void StartResizeLayoutAnimation(); void StartPinnedTabAnimation(); @@ -583,11 +566,11 @@ std::unique_ptr<TabHoverCardController> hover_card_controller_; + std::unique_ptr<TabDragContextImpl> drag_context_; + // The View parent for the tabs and the various group views. TabContainer* tab_container_; - base::RepeatingCallback<int()> available_width_callback_; - // Responsible for animating the scroll of the tab strip. std::unique_ptr<gfx::LinearAnimation> tab_scrolling_animation_; @@ -649,8 +632,6 @@ base::BindRepeating(&TabStrip::OnTouchUiChanged, base::Unretained(this))); - std::unique_ptr<TabDragContextImpl> drag_context_; - TabContextMenuController context_menu_controller_{this}; };
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_mac_win_linux.cc b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_mac_win_linux.cc index 711d2b6..00a8eb7 100644 --- a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_mac_win_linux.cc +++ b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_mac_win_linux.cc
@@ -88,7 +88,7 @@ CheckNavigateToAppSettingsFromChromeAppsWorks) { helper_.InstallCreateShortcutWindowed("SiteA"); helper_.CheckAppInListWindowed("SiteA"); - helper_.LaunchAppSettingsFromChromeApps("SiteA"); + helper_.OpenAppSettingsFromChromeApps("SiteA"); helper_.CheckBrowserNavigationIsAppSettings("SiteA"); helper_.UninstallFromMenu("SiteA"); helper_.CheckAppNotInList("SiteA"); @@ -99,12 +99,20 @@ helper_.InstallCreateShortcutWindowed("SiteA"); helper_.CheckAppInListWindowed("SiteA"); helper_.LaunchFromChromeApps("SiteA"); - helper_.LaunchAppSettingsFromAppMenu("SiteA"); + helper_.OpenAppSettingsFromAppMenu("SiteA"); helper_.CheckBrowserNavigationIsAppSettings("SiteA"); helper_.UninstallFromMenu("SiteA"); helper_.CheckAppNotInList("SiteA"); } +IN_PROC_BROWSER_TEST_F(WebAppIntegrationBrowserTestMacWinLinux, + CheckUninstallFromAppSettingsWorks) { + helper_.InstallCreateShortcutWindowed("SiteA"); + helper_.CheckAppInListWindowed("SiteA"); + helper_.UninstallFromAppSettings("SiteA"); + helper_.CheckAppNotInList("SiteA"); +} + // Generated tests: IN_PROC_BROWSER_TEST_F(
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc index 4a29e926..e5820a7 100644 --- a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc +++ b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
@@ -76,6 +76,7 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/test/test_navigation_observer.h" +#include "content/public/test/test_utils.h" #include "content/public/test/test_web_ui.h" #include "extensions/browser/extension_dialog_auto_confirm.h" #include "net/dns/mock_host_resolver.h" @@ -303,6 +304,18 @@ : absl::make_optional<AppState>(it->second); } +#if !BUILDFLAG(IS_CHROMEOS) +AppManagementPageHandler CreateAppManagementPageHandler(Profile* profile) { + mojo::PendingReceiver<app_management::mojom::Page> page; + mojo::Remote<app_management::mojom::PageHandler> handler; + static auto delegate = + WebAppSettingsUI::CreateAppManagementPageHandlerDelegate(profile); + return AppManagementPageHandler(handler.BindNewPipeAndPassReceiver(), + page.InitWithNewPipeAndPassRemote(), profile, + *delegate); +} +#endif + } // anonymous namespace BrowserState::BrowserState( @@ -819,7 +832,7 @@ AfterStateChangeAction(); } -void WebAppIntegrationTestDriver::LaunchAppSettingsFromAppMenu( +void WebAppIntegrationTestDriver::OpenAppSettingsFromAppMenu( const std::string& site_mode) { #if !BUILDFLAG(IS_CHROMEOS) BeforeStateChangeAction(__FUNCTION__); @@ -857,7 +870,7 @@ #endif } -void WebAppIntegrationTestDriver::LaunchAppSettingsFromChromeApps( +void WebAppIntegrationTestDriver::OpenAppSettingsFromChromeApps( const std::string& site_mode) { #if !BUILDFLAG(IS_CHROMEOS) BeforeStateChangeAction(__FUNCTION__); @@ -1011,13 +1024,7 @@ sync_bridge.SetAppUserDisplayMode(app_id, blink::mojom::DisplayMode::kBrowser, true); #else - mojo::PendingReceiver<app_management::mojom::Page> page; - mojo::Remote<app_management::mojom::PageHandler> handler; - auto delegate = - WebAppSettingsUI::CreateAppManagementPageHandlerDelegate(profile()); - AppManagementPageHandler app_management_page_handler( - handler.BindNewPipeAndPassReceiver(), page.InitWithNewPipeAndPassRemote(), - profile(), *delegate); + auto app_management_page_handler = CreateAppManagementPageHandler(profile()); app_management_page_handler.SetWindowMode(app_id, apps::mojom::WindowMode::kBrowser); #endif @@ -1038,13 +1045,7 @@ sync_bridge.SetAppUserDisplayMode( app_id, blink::mojom::DisplayMode::kStandalone, true); #else - mojo::PendingReceiver<app_management::mojom::Page> page; - mojo::Remote<app_management::mojom::PageHandler> handler; - auto delegate = - WebAppSettingsUI::CreateAppManagementPageHandlerDelegate(profile()); - AppManagementPageHandler app_management_page_handler( - handler.BindNewPipeAndPassReceiver(), page.InitWithNewPipeAndPassRemote(), - profile(), *delegate); + auto app_management_page_handler = CreateAppManagementPageHandler(profile()); app_management_page_handler.SetWindowMode(app_id, apps::mojom::WindowMode::kWindow); #endif @@ -1131,6 +1132,44 @@ AfterStateChangeAction(); } +void WebAppIntegrationTestDriver::UninstallFromAppSettings( + const std::string& site_mode) { +#if !BUILDFLAG(IS_CHROMEOS) + BeforeStateChangeAction(__FUNCTION__); + absl::optional<AppState> app_state = GetAppBySiteMode( + before_state_change_action_state_.get(), profile(), site_mode); + ASSERT_TRUE(app_state.has_value()) + << "No app installed for site: " << site_mode; + auto app_id = app_state->id; + WebAppTestUninstallObserver uninstall_observer(profile()); + uninstall_observer.BeginListening({app_id}); + + auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + if (web_contents->GetURL() != + GURL("chrome://app-settings/" + app_state->id)) { + OpenAppSettingsFromChromeApps(site_mode); + CheckBrowserNavigationIsAppSettings("SiteA"); + } + + web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + content::WebContentsDestroyedWatcher destroyed_watcher(web_contents); + + extensions::ScopedTestDialogAutoConfirm auto_confirm( + extensions::ScopedTestDialogAutoConfirm::ACCEPT); + auto app_management_page_handler = CreateAppManagementPageHandler(profile()); + app_management_page_handler.Uninstall(app_id); + + uninstall_observer.Wait(); + + // Wait for app settings page to be closed. + destroyed_watcher.Wait(); + + AfterStateChangeAction(); +#else + NOTREACHED() << "Not implemented on Chrome OS."; +#endif +} + void WebAppIntegrationTestDriver::UninstallFromMenu( const std::string& site_mode) { BeforeStateChangeAction(__FUNCTION__); @@ -1990,16 +2029,10 @@ before_state_change_action_state_.get(), profile(), site_mode); ASSERT_TRUE(app_state.has_value()) << "No app installed for site: " << site_mode; - mojo::PendingReceiver<app_management::mojom::Page> page; - mojo::Remote<app_management::mojom::PageHandler> handler; - auto delegate = - WebAppSettingsUI::CreateAppManagementPageHandlerDelegate(profile()); base::RunLoop run_loop; web_app::SetRunOnOsLoginOsHooksChangedCallbackForTesting( run_loop.QuitClosure()); - AppManagementPageHandler app_management_page_handler( - handler.BindNewPipeAndPassReceiver(), page.InitWithNewPipeAndPassRemote(), - profile(), *delegate); + auto app_management_page_handler = CreateAppManagementPageHandler(profile()); app_management_page_handler.SetRunOnOsLoginMode(app_state->id, login_mode); run_loop.Run(); #endif
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h index f6643e4..995e9df 100644 --- a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h +++ b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h
@@ -166,8 +166,8 @@ void LaunchFromLaunchIcon(const std::string& site_mode); void LaunchFromMenuOption(const std::string& site_mode); void LaunchFromShortcut(const std::string& site_mode); - void LaunchAppSettingsFromChromeApps(const std::string& site_mode); - void LaunchAppSettingsFromAppMenu(const std::string& site_mode); + void OpenAppSettingsFromChromeApps(const std::string& site_mode); + void OpenAppSettingsFromAppMenu(const std::string& site_mode); void NavigateBrowser(const std::string& site_mode); void NavigatePwaSiteATo(const std::string& site_mode); void NavigateNotfoundUrl(); @@ -184,6 +184,7 @@ void SyncTurnOn(); void UninstallFromList(const std::string& site_mode); void UninstallFromMenu(const std::string& site_mode); + void UninstallFromAppSettings(const std::string& site_mode); void UninstallPolicyApp(const std::string& site_mode); void UninstallFromOs(const std::string& site_mode);
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/BUILD.gn b/chrome/browser/ui/webui/settings/ash/search/BUILD.gn similarity index 87% rename from chrome/browser/ui/webui/settings/chromeos/search/BUILD.gn rename to chrome/browser/ui/webui/settings/ash/search/BUILD.gn index 0065095..58ce0fb 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search/BUILD.gn +++ b/chrome/browser/ui/webui/settings/ash/search/BUILD.gn
@@ -15,7 +15,7 @@ ] public_deps = [ - "../constants:mojom", + "//chrome/browser/ui/webui/settings/chromeos/constants:mojom", "//mojo/public/mojom/base", ] }
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/OWNERS b/chrome/browser/ui/webui/settings/ash/search/OWNERS similarity index 100% rename from chrome/browser/ui/webui/settings/chromeos/search/OWNERS rename to chrome/browser/ui/webui/settings/ash/search/OWNERS
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/per_session_settings_user_action_tracker.cc b/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.cc similarity index 97% rename from chrome/browser/ui/webui/settings/chromeos/search/per_session_settings_user_action_tracker.cc rename to chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.cc index 7f568b2..6d0272a 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search/per_session_settings_user_action_tracker.cc +++ b/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.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 "chrome/browser/ui/webui/settings/chromeos/search/per_session_settings_user_action_tracker.h" +#include "chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.h" #include "base/metrics/histogram_functions.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/per_session_settings_user_action_tracker.h b/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.h similarity index 88% rename from chrome/browser/ui/webui/settings/chromeos/search/per_session_settings_user_action_tracker.h rename to chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.h index da5c3706..932a617 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search/per_session_settings_user_action_tracker.h +++ b/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.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 CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_PER_SESSION_SETTINGS_USER_ACTION_TRACKER_H_ -#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_PER_SESSION_SETTINGS_USER_ACTION_TRACKER_H_ +#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_SEARCH_PER_SESSION_SETTINGS_USER_ACTION_TRACKER_H_ +#define CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_SEARCH_PER_SESSION_SETTINGS_USER_ACTION_TRACKER_H_ #include "base/time/time.h" #include "mojo/public/cpp/bindings/pending_receiver.h" @@ -64,4 +64,4 @@ } // namespace settings } // namespace chromeos -#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_PER_SESSION_SETTINGS_USER_ACTION_TRACKER_H_ +#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_SEARCH_PER_SESSION_SETTINGS_USER_ACTION_TRACKER_H_
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/per_session_settings_user_action_tracker_unittest.cc b/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker_unittest.cc similarity index 98% rename from chrome/browser/ui/webui/settings/chromeos/search/per_session_settings_user_action_tracker_unittest.cc rename to chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker_unittest.cc index 74f716e..96640f1 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search/per_session_settings_user_action_tracker_unittest.cc +++ b/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker_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 "chrome/browser/ui/webui/settings/chromeos/search/per_session_settings_user_action_tracker.h" +#include "chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search.mojom b/chrome/browser/ui/webui/settings/ash/search/search.mojom similarity index 98% rename from chrome/browser/ui/webui/settings/chromeos/search/search.mojom rename to chrome/browser/ui/webui/settings/ash/search/search.mojom index d63ae03..a3c098d 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search/search.mojom +++ b/chrome/browser/ui/webui/settings/ash/search/search.mojom
@@ -6,7 +6,7 @@ import "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom"; import "chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom"; -import "chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom"; +import "chrome/browser/ui/webui/settings/ash/search/search_result_icon.mojom"; import "mojo/public/mojom/base/string16.mojom"; // Describes the type of settings result.
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search_concept.h b/chrome/browser/ui/webui/settings/ash/search/search_concept.h similarity index 88% rename from chrome/browser/ui/webui/settings/chromeos/search/search_concept.h rename to chrome/browser/ui/webui/settings/ash/search/search_concept.h index 156e6c81..45a35d1 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search/search_concept.h +++ b/chrome/browser/ui/webui/settings/ash/search/search_concept.h
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_CONCEPT_H_ -#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_CONCEPT_H_ +#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_SEARCH_SEARCH_CONCEPT_H_ +#define CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_SEARCH_SEARCH_CONCEPT_H_ +#include "chrome/browser/ui/webui/settings/ash/search/search.mojom.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_result_icon.mojom.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_identifier.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom.h" namespace chromeos { namespace settings { @@ -71,4 +71,4 @@ } // namespace settings } // namespace chromeos -#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_CONCEPT_H_ +#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_SEARCH_SEARCH_CONCEPT_H_
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc b/chrome/browser/ui/webui/settings/ash/search/search_handler.cc similarity index 97% rename from chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc rename to chrome/browser/ui/webui/settings/ash/search/search_handler.cc index 34fc3c59..f8fb158 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc +++ b/chrome/browser/ui/webui/settings/ash/search/search_handler.cc
@@ -2,16 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/webui/settings/chromeos/search/search_handler.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_handler.h" #include <algorithm> #include "base/strings/string_number_conversions.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_concept.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_result_icon.mojom.h" #include "chrome/browser/ui/webui/settings/chromeos/hierarchy.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom.h" #include "chrome/grit/generated_resources.h" #include "chromeos/components/local_search_service/public/cpp/local_search_service_proxy.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h b/chrome/browser/ui/webui/settings/ash/search/search_handler.h similarity index 91% rename from chrome/browser/ui/webui/settings/chromeos/search/search_handler.h rename to chrome/browser/ui/webui/settings/ash/search/search_handler.h index 3dbffcf..28effd6 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h +++ b/chrome/browser/ui/webui/settings/ash/search/search_handler.h
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_HANDLER_H_ +#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_SEARCH_SEARCH_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_SEARCH_SEARCH_HANDLER_H_ #include <vector> #include "base/gtest_prod_util.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" +#include "chrome/browser/ui/webui/settings/ash/search/search.mojom.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chromeos/components/local_search_service/public/cpp/local_search_service_proxy.h" #include "chromeos/components/local_search_service/public/mojom/index.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" @@ -119,4 +119,4 @@ } // namespace settings } // namespace chromeos -#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_HANDLER_H_ +#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_SEARCH_SEARCH_HANDLER_H_
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc b/chrome/browser/ui/webui/settings/ash/search/search_handler_unittest.cc similarity index 97% rename from chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc rename to chrome/browser/ui/webui/settings/ash/search/search_handler_unittest.cc index c298276..757f81f12 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/ash/search/search_handler_unittest.cc
@@ -2,16 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/webui/settings/chromeos/search/search_handler.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_handler.h" #include "base/no_destructor.h" #include "base/strings/utf_string_conversions.h" #include "base/test/task_environment.h" +#include "chrome/browser/ui/webui/settings/ash/search/search.mojom-test-utils.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h" #include "chrome/browser/ui/webui/settings/chromeos/fake_hierarchy.h" #include "chrome/browser/ui/webui/settings/chromeos/fake_os_settings_sections.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom-test-utils.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/grit/generated_resources.h" #include "chromeos/components/local_search_service/public/cpp/local_search_service_proxy.h" #include "mojo/public/cpp/bindings/remote.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom b/chrome/browser/ui/webui/settings/ash/search/search_result_icon.mojom similarity index 100% rename from chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom rename to chrome/browser/ui/webui/settings/ash/search/search_result_icon.mojom
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.cc b/chrome/browser/ui/webui/settings/ash/search/search_tag_registry.cc similarity index 97% rename from chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.cc rename to chrome/browser/ui/webui/settings/ash/search/search_tag_registry.cc index 1772dcb..17de7c6 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.cc +++ b/chrome/browser/ui/webui/settings/ash/search/search_tag_registry.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 "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include <algorithm> #include <sstream> @@ -10,7 +10,7 @@ #include "base/feature_list.h" #include "base/strings/string_number_conversions.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_concept.h" #include "chromeos/components/local_search_service/public/cpp/local_search_service_proxy.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h b/chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h similarity index 94% rename from chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h rename to chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h index 46e9e2b..d9f00d5 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h +++ b/chrome/browser/ui/webui/settings/ash/search/search_tag_registry.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 CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_TAG_REGISTRY_H_ -#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_TAG_REGISTRY_H_ +#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_SEARCH_SEARCH_TAG_REGISTRY_H_ +#define CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_SEARCH_SEARCH_TAG_REGISTRY_H_ #include <unordered_map> #include <utility> @@ -79,6 +79,7 @@ // returned by the LocalSearchService. If no metadata is available, null // is returned. const SearchConcept* GetTagMetadata(const std::string& result_id) const; + private: FRIEND_TEST_ALL_PREFIXES(SearchTagRegistryTest, AddAndRemove); @@ -108,4 +109,4 @@ } // namespace settings } // namespace chromeos -#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_TAG_REGISTRY_H_ +#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_SEARCH_SEARCH_TAG_REGISTRY_H_
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry_unittest.cc b/chrome/browser/ui/webui/settings/ash/search/search_tag_registry_unittest.cc similarity index 96% rename from chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry_unittest.cc rename to chrome/browser/ui/webui/settings/ash/search/search_tag_registry_unittest.cc index 5611dab7..bd4e862 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry_unittest.cc +++ b/chrome/browser/ui/webui/settings/ash/search/search_tag_registry_unittest.cc
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "base/no_destructor.h" #include "base/test/task_environment.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_concept.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h" #include "chrome/grit/generated_resources.h" #include "chromeos/components/local_search_service/public/mojom/index.mojom.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/user_action_recorder.mojom b/chrome/browser/ui/webui/settings/ash/search/user_action_recorder.mojom similarity index 100% rename from chrome/browser/ui/webui/settings/chromeos/search/user_action_recorder.mojom rename to chrome/browser/ui/webui/settings/ash/search/user_action_recorder.mojom
diff --git a/chrome/browser/ui/webui/settings/chromeos/BUILD.gn b/chrome/browser/ui/webui/settings/chromeos/BUILD.gn index c86ea04..0fc7523 100644 --- a/chrome/browser/ui/webui/settings/chromeos/BUILD.gn +++ b/chrome/browser/ui/webui/settings/chromeos/BUILD.gn
@@ -5,8 +5,8 @@ group("mojom_js") { public_deps = [ "constants:mojom_js", - "search:mojo_bindings_js", "//chrome/browser/ui/webui/nearby_share/public/mojom:mojom_js", + "//chrome/browser/ui/webui/settings/ash/search:mojo_bindings_js", "//ui/webui/resources/cr_components/app_management:mojo_bindings_js", ] }
diff --git a/chrome/browser/ui/webui/settings/chromeos/about_section.cc b/chrome/browser/ui/webui/settings/chromeos/about_section.cc index f676a04f..55e65de 100644 --- a/chrome/browser/ui/webui/settings/chromeos/about_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/about_section.cc
@@ -19,8 +19,8 @@ #include "chrome/browser/obsolete_system/obsolete_system.h" #include "chrome/browser/ui/webui/management/management_ui.h" #include "chrome/browser/ui/webui/settings/about_handler.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/chromeos/device_name_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/browser/ui/webui/version/version_ui.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/channel_info.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc b/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc index 4933f39..165f9e5 100644 --- a/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc
@@ -21,9 +21,9 @@ #include "chrome/browser/extensions/extension_service.h" #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/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/captions_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/chromeos/switch_access_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/tts_handler.h" #include "chrome/browser/ui/webui/settings/font_handler.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/apps_section.cc b/chrome/browser/ui/webui/settings/chromeos/apps_section.cc index 4774000..77ab8af 100644 --- a/chrome/browser/ui/webui/settings/chromeos/apps_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/apps_section.cc
@@ -19,10 +19,10 @@ #include "chrome/browser/ash/plugin_vm/plugin_vm_pref_names.h" #include "chrome/browser/ash/plugin_vm/plugin_vm_util.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/chromeos/android_apps_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/guest_os_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/chrome_features.h" #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc b/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc index c108923..cc4a119 100644 --- a/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc
@@ -10,12 +10,12 @@ #include "base/metrics/histogram_functions.h" #include "base/no_destructor.h" #include "chrome/browser/ui/webui/chromeos/bluetooth_shared_load_time_data_provider.h" +#include "chrome/browser/ui/webui/settings/ash/search/search.mojom.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_result_icon.mojom.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/chromeos/bluetooth_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/webui_url_constants.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc b/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc index 21fa9f10..75d0089 100644 --- a/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc
@@ -16,9 +16,9 @@ #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/chromeos/crostini_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/guest_os_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/date_time_section.cc b/chrome/browser/ui/webui/settings/chromeos/date_time_section.cc index 9c65bcd..5280753 100644 --- a/chrome/browser/ui/webui/settings/chromeos/date_time_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/date_time_section.cc
@@ -12,8 +12,8 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ash/system/timezone_util.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/chromeos/date_time_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_section.cc b/chrome/browser/ui/webui/settings/chromeos/device_section.cc index 486d5062..7be9b02 100644 --- a/chrome/browser/ui/webui/settings/chromeos/device_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/device_section.cc
@@ -16,13 +16,13 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ash/login/demo_mode/demo_session.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/chromeos/device_display_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/device_power_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_features_util.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/chrome_features.h" #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/files_section.cc b/chrome/browser/ui/webui/settings/chromeos/files_section.cc index ff4ff98..7f1bd7b 100644 --- a/chrome/browser/ui/webui/settings/chromeos/files_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/files_section.cc
@@ -9,7 +9,7 @@ #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/ui/webui/chromeos/smb_shares/smb_handler.h" #include "chrome/browser/ui/webui/chromeos/smb_shares/smb_shares_localized_strings_provider.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/hierarchy.h b/chrome/browser/ui/webui/settings/chromeos/hierarchy.h index 8ca5a79..9051051 100644 --- a/chrome/browser/ui/webui/settings/chromeos/hierarchy.h +++ b/chrome/browser/ui/webui/settings/chromeos/hierarchy.h
@@ -10,10 +10,10 @@ #include <utility> #include <vector> +#include "chrome/browser/ui/webui/settings/ash/search/search.mojom.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_identifier.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace chromeos {
diff --git a/chrome/browser/ui/webui/settings/chromeos/internet_section.cc b/chrome/browser/ui/webui/settings/chromeos/internet_section.cc index caab949..0982b45 100644 --- a/chrome/browser/ui/webui/settings/chromeos/internet_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/internet_section.cc
@@ -14,9 +14,9 @@ #include "base/no_destructor.h" #include "base/strings/stringprintf.h" #include "chrome/browser/ui/webui/chromeos/cellular_setup/cellular_setup_localized_strings_provider.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h" #include "chrome/browser/ui/webui/settings/chromeos/internet_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/chrome_features.h" #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/kerberos_section.cc b/chrome/browser/ui/webui/settings/chromeos/kerberos_section.cc index 4bda75a..caa6029e 100644 --- a/chrome/browser/ui/webui/settings/chromeos/kerberos_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/kerberos_section.cc
@@ -6,8 +6,8 @@ #include "base/no_destructor.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/chromeos/kerberos_accounts_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/grit/generated_resources.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/languages_section.cc b/chrome/browser/ui/webui/settings/chromeos/languages_section.cc index 943f7d3..6bc185f2 100644 --- a/chrome/browser/ui/webui/settings/chromeos/languages_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/languages_section.cc
@@ -10,8 +10,8 @@ #include "base/no_destructor.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_features_util.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/languages_handler.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc b/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc index 767f6c3..bfb0598d 100644 --- a/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc
@@ -23,8 +23,8 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/ash/session_controller_client_impl.h" #include "chrome/browser/ui/webui/nearby_share/shared_resources.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc b/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc index f7af139b..7ee91f9 100644 --- a/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc +++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc
@@ -7,10 +7,10 @@ #include "base/bind.h" #include "base/feature_list.h" #include "chrome/browser/ui/webui/settings/ash/os_apps_page/app_notification_handler.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_handler.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/chromeos/hierarchy.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/chromeos/settings_user_action_tracker.h" #include "content/public/browser/web_ui_data_source.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_section.h b/chrome/browser/ui/webui/settings/chromeos/os_settings_section.h index 6ea23f8..49119bbf 100644 --- a/chrome/browser/ui/webui/settings/chromeos/os_settings_section.h +++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_section.h
@@ -11,10 +11,10 @@ #include "base/containers/span.h" #include "base/gtest_prod_util.h" #include "base/values.h" +#include "chrome/browser/ui/webui/settings/ash/search/search.mojom.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_concept.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h" class Profile;
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc b/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc index 79eebde..e781f7bd 100644 --- a/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc
@@ -18,11 +18,11 @@ #include "chrome/browser/nearby_sharing/nearby_sharing_service_impl.h" #include "chrome/browser/ui/webui/managed_ui_handler.h" #include "chrome/browser/ui/webui/settings/ash/os_apps_page/app_notification_handler.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.h" #include "chrome/browser/ui/webui/settings/chromeos/pref_names.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/settings_user_action_tracker.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/webui_url_constants.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h b/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h index 28600c2..b49fbf7 100644 --- a/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h +++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h
@@ -13,7 +13,7 @@ #include "chrome/browser/ui/webui/nearby_share/nearby_share.mojom.h" #include "chrome/browser/ui/webui/nearby_share/public/mojom/nearby_share_settings.mojom.h" #include "chrome/browser/ui/webui/settings/ash/os_apps_page/mojom/app_notification_handler.mojom-forward.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/user_action_recorder.mojom-forward.h" +#include "chrome/browser/ui/webui/settings/ash/search/user_action_recorder.mojom-forward.h" #include "chrome/browser/ui/webui/webui_load_timer.h" #include "chromeos/services/bluetooth_config/public/mojom/cros_bluetooth_config.mojom-forward.h" #include "chromeos/services/cellular_setup/public/mojom/cellular_setup.mojom-forward.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/people_section.cc b/chrome/browser/ui/webui/settings/chromeos/people_section.cc index 11229c41a..546d5217 100644 --- a/chrome/browser/ui/webui/settings/chromeos/people_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/people_section.cc
@@ -27,12 +27,12 @@ #include "chrome/browser/supervised_user/supervised_user_service.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/webui/chromeos/sync/os_sync_handler.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/chromeos/account_manager_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_features_util.h" #include "chrome/browser/ui/webui/settings/chromeos/parental_controls_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/people_handler.h" #include "chrome/browser/ui/webui/settings/profile_info_handler.h" #include "chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc b/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc index ed47d5f..9d508f3 100644 --- a/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc
@@ -12,11 +12,11 @@ #include "base/no_destructor.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_features_util.h" #include "chrome/browser/ui/webui/settings/chromeos/personalization_hub_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/chromeos/wallpaper_handler.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/chrome_features.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/printing_section.cc b/chrome/browser/ui/webui/settings/chromeos/printing_section.cc index 0ac876f..fd472f7 100644 --- a/chrome/browser/ui/webui/settings/chromeos/printing_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/printing_section.cc
@@ -5,8 +5,8 @@ #include "chrome/browser/ui/webui/settings/chromeos/printing_section.h" #include "base/no_destructor.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/chrome_features.h" #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc b/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc index e79dfa7..84b5ed8 100644 --- a/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc
@@ -15,10 +15,10 @@ #include "chrome/browser/ash/login/quick_unlock/quick_unlock_utils.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/chromeos/metrics_consent_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_features_util.h" #include "chrome/browser/ui/webui/settings/chromeos/peripheral_data_access_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/settings_secure_dns_handler.h" #include "chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h" #include "chrome/browser/ui/webui/webui_util.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/reset_section.cc b/chrome/browser/ui/webui/settings/chromeos/reset_section.cc index 3f14606..ef7fcfff 100644 --- a/chrome/browser/ui/webui/settings/chromeos/reset_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/reset_section.cc
@@ -6,7 +6,7 @@ #include "base/no_destructor.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/reset_settings_handler.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/grit/chromium_strings.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/search_section.cc b/chrome/browser/ui/webui/settings/chromeos/search_section.cc index 60150addd..d3c2fdaf 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/search_section.cc
@@ -15,8 +15,8 @@ #include "chrome/browser/ash/assistant/assistant_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h" +#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/search_engines_handler.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/settings_user_action_tracker.h b/chrome/browser/ui/webui/settings/chromeos/settings_user_action_tracker.h index f05770d..ff57567 100644 --- a/chrome/browser/ui/webui/settings/chromeos/settings_user_action_tracker.h +++ b/chrome/browser/ui/webui/settings/chromeos/settings_user_action_tracker.h
@@ -8,9 +8,9 @@ #include <memory> #include "base/gtest_prod_util.h" +#include "chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.h" +#include "chrome/browser/ui/webui/settings/ash/search/user_action_recorder.mojom.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/per_session_settings_user_action_tracker.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/user_action_recorder.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/settings_user_action_tracker_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/settings_user_action_tracker_unittest.cc index 0adb5d6..9641684 100644 --- a/chrome/browser/ui/webui/settings/chromeos/settings_user_action_tracker_unittest.cc +++ b/chrome/browser/ui/webui/settings/chromeos/settings_user_action_tracker_unittest.cc
@@ -6,12 +6,12 @@ #include "base/test/metrics/histogram_tester.h" #include "base/values.h" +#include "chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.h" +#include "chrome/browser/ui/webui/settings/ash/search/user_action_recorder.mojom.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom.h" #include "chrome/browser/ui/webui/settings/chromeos/fake_hierarchy.h" #include "chrome/browser/ui/webui/settings/chromeos/fake_os_settings_section.h" #include "chrome/browser/ui/webui/settings/chromeos/fake_os_settings_sections.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/per_session_settings_user_action_tracker.h" -#include "chrome/browser/ui/webui/settings/chromeos/search/user_action_recorder.mojom.h" #include "testing/gtest/include/gtest/gtest.h" namespace chromeos {
diff --git a/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc b/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc index 2b3d729..56aa0c6 100644 --- a/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc +++ b/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc
@@ -8,6 +8,7 @@ #include <utility> #include "base/bind.h" +#include "base/check.h" #include "base/rand_util.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/net/secure_dns_config.h" @@ -25,6 +26,7 @@ #include "net/dns/public/doh_provider_entry.h" #include "net/dns/public/secure_dns_mode.h" #include "net/dns/public/util.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/base/l10n/l10n_util.h" namespace secure_dns = chrome_browser_net::secure_dns; @@ -190,15 +192,12 @@ probe_callback_id_ = args[0].GetString(); const std::string& doh_config = args[1].GetString(); - - net::DnsConfigOverrides overrides; - overrides.search = std::vector<std::string>(); - overrides.attempts = 1; - overrides.secure_dns_mode = net::SecureDnsMode::kSecure; - secure_dns::ApplyConfig(&overrides, doh_config); DCHECK(!runner_); - runner_ = std::make_unique<chrome_browser_net::DnsProbeRunner>( - overrides, network_context_getter_); + absl::optional<net::DnsOverHttpsConfig> parsed = + net::DnsOverHttpsConfig::FromString(doh_config); + DCHECK(parsed.has_value()); // `doh_config` must be valid. + runner_ = + secure_dns::MakeProbeRunner(std::move(*parsed), network_context_getter_); runner_->RunProbe(base::BindOnce(&SecureDnsHandler::OnProbeComplete, base::Unretained(this))); }
diff --git a/chrome/browser/webauthn/android/java/res/layout-sw600dp/cablev2_error.xml b/chrome/browser/webauthn/android/java/res/layout-sw600dp/cablev2_error.xml index bc238c4..2bf14e9 100644 --- a/chrome/browser/webauthn/android/java/res/layout-sw600dp/cablev2_error.xml +++ b/chrome/browser/webauthn/android/java/res/layout-sw600dp/cablev2_error.xml
@@ -3,87 +3,97 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android" +<ScrollView + xmlns:a="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" a:layout_width="match_parent" a:layout_height="match_parent" - a:gravity="center" - a:orientation="vertical"> + a:fillViewport="true" + a:scrollbars="none"> <LinearLayout a:layout_width="match_parent" - a:layout_weight="2" - a:layout_height="0dp" - a:layout_marginTop="70dp" - a:orientation="vertical" - a:gravity="center"> + a:layout_height="wrap_content" + a:gravity="center" + a:orientation="vertical"> - <TextView - a:id="@+id/error_title" - a:textSize="36sp" + <LinearLayout a:layout_width="match_parent" - a:layout_height="wrap_content" - a:layout_marginTop="104dp" - a:gravity="center_horizontal" - a:text="@string/cablev2_error_title"/> + a:layout_weight="2" + a:layout_height="0dp" + a:layout_marginTop="70dp" + a:orientation="vertical" + a:gravity="center"> - <!-- This is a semantically-meaningless picture of a sad tab that - screen readers can ignore. Thus contentDescription is null. --> - <ImageView - a:layout_width="210dp" - a:layout_height="128dp" - a:layout_marginTop="52dp" - a:layout_marginBottom="35dp" - a:contentDescription="@null" - a:gravity="center_horizontal" - a:src="@drawable/error_icon"/> + <TextView + a:id="@+id/error_title" + a:textSize="36sp" + a:layout_width="match_parent" + a:layout_height="wrap_content" + a:layout_marginTop="104dp" + a:gravity="center_horizontal" + a:text="@string/cablev2_error_title"/> - <TextView - a:id="@+id/error_description" - style="@style/TextAppearance.TextMedium.Secondary" - a:layout_marginTop="4dp" - a:layout_marginLeft="40dp" - a:layout_marginRight="40dp" - a:layout_width="wrap_content" - a:layout_height="wrap_content" - a:gravity="center_horizontal"/> + <!-- This is a semantically-meaningless picture of a sad tab that + screen readers can ignore. Thus contentDescription is null. --> + <ImageView + a:layout_width="210dp" + a:layout_height="128dp" + a:layout_marginTop="52dp" + a:layout_marginBottom="35dp" + a:contentDescription="@null" + a:gravity="center_horizontal" + a:src="@drawable/error_icon"/> - <TextView - a:id="@+id/error_code" - style="@style/TextAppearance.TextMedium.Disabled" - a:layout_marginTop="4dp" - a:layout_marginLeft="40dp" - a:layout_marginRight="40dp" - a:layout_width="wrap_content" - a:layout_height="wrap_content" - a:gravity="center_horizontal"/> + <TextView + a:id="@+id/error_description" + style="@style/TextAppearance.TextMedium.Secondary" + a:layout_marginTop="4dp" + a:layout_marginLeft="40dp" + a:layout_marginRight="40dp" + a:layout_width="wrap_content" + a:layout_height="wrap_content" + a:gravity="center_horizontal"/> - <!-- not shown by default. The visibility is toggled by code when needed --> - <org.chromium.ui.widget.ButtonCompat - a:id="@+id/error_settings_button" - style="@style/TextButton" - a:layout_width="wrap_content" - a:layout_height="wrap_content" - a:gravity="center_horizontal" - a:layout_marginTop="20dp" - a:visibility="invisible" - a:text="@string/qr_code_open_settings_label"/> + <TextView + a:id="@+id/error_code" + style="@style/TextAppearance.TextMedium.Disabled" + a:layout_marginTop="4dp" + a:layout_marginLeft="40dp" + a:layout_marginRight="40dp" + a:layout_width="wrap_content" + a:layout_height="wrap_content" + a:gravity="center_horizontal"/> - </LinearLayout> + <!-- not shown by default. The visibility is toggled by code when needed --> + <org.chromium.ui.widget.ButtonCompat + a:id="@+id/error_settings_button" + style="@style/TextButton" + a:layout_width="wrap_content" + a:layout_height="wrap_content" + a:gravity="center_horizontal" + a:layout_marginTop="20dp" + a:visibility="invisible" + a:text="@string/qr_code_open_settings_label"/> - <LinearLayout - a:layout_width="match_parent" - a:layout_height="0dp" - a:layout_weight="1" - a:gravity="bottom|center"> + </LinearLayout> - <org.chromium.ui.widget.ButtonCompat - a:id="@+id/error_close" - style="@style/TextButton" - a:layout_width="wrap_content" - a:layout_height="wrap_content" - a:gravity="bottom|center" - a:layout_marginBottom="20dp" - a:text="@string/cablev2_error_close"/> + <LinearLayout + a:layout_width="match_parent" + a:layout_height="0dp" + a:layout_weight="1" + a:gravity="bottom|center"> - </LinearLayout> -</LinearLayout> + <org.chromium.ui.widget.ButtonCompat + a:id="@+id/error_close" + style="@style/TextButton" + a:layout_width="wrap_content" + a:layout_height="wrap_content" + a:gravity="bottom|center" + a:layout_marginBottom="20dp" + a:text="@string/cablev2_error_close"/> + + </LinearLayout> + </LinearLayout> + +</ScrollView>
diff --git a/chrome/browser/webauthn/android/java/res/layout-sw600dp/cablev2_spinner.xml b/chrome/browser/webauthn/android/java/res/layout-sw600dp/cablev2_spinner.xml index f7703322..f1e31ca 100644 --- a/chrome/browser/webauthn/android/java/res/layout-sw600dp/cablev2_spinner.xml +++ b/chrome/browser/webauthn/android/java/res/layout-sw600dp/cablev2_spinner.xml
@@ -3,56 +3,66 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" + +<ScrollView + xmlns:a="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" a:layout_width="match_parent" a:layout_height="match_parent" - a:orientation="vertical" - a:gravity="center" - xmlns:tools="http://schemas.android.com/tools"> + a:fillViewport="true" + a:scrollbars="none"> - <TextView + <LinearLayout a:layout_width="match_parent" a:layout_height="wrap_content" - a:layout_marginTop="-104dp" - a:layout_marginLeft="24dp" - a:layout_marginRight="24dp" - a:gravity="center_horizontal" - a:text="@string/cablev2_serverlink_connecting_to_your_device" - a:textSize="36sp" /> + a:orientation="vertical" + a:gravity="center"> - <RelativeLayout - a:layout_width="wrap_content" - a:layout_height="wrap_content" - a:layoutDirection="ltr" - a:layout_marginTop="52dp" - a:layout_marginLeft="24dp" - a:layout_marginRight="24dp" - a:layout_gravity="center_horizontal"> - <ImageView - a:id="@+id/spinner" - a:contentDescription="@null" + <TextView + a:layout_width="match_parent" + a:layout_height="wrap_content" + a:layout_marginTop="-104dp" + a:layout_marginLeft="24dp" + a:layout_marginRight="24dp" + a:gravity="center_horizontal" + a:text="@string/cablev2_serverlink_connecting_to_your_device" + a:textSize="36sp" /> + + <RelativeLayout a:layout_width="wrap_content" a:layout_height="wrap_content" - a:layout_gravity="center" - a:layout_centerInParent="true" - a:layout_centerVertical="true" /> - <ImageView - a:contentDescription="@null" - a:layout_height="wrap_content" + a:layoutDirection="ltr" + a:layout_marginTop="52dp" + a:layout_marginLeft="24dp" + a:layout_marginRight="24dp" + a:layout_gravity="center_horizontal"> + <ImageView + a:id="@+id/spinner" + a:contentDescription="@null" + a:layout_width="wrap_content" + a:layout_height="wrap_content" + a:layout_gravity="center" + a:layout_centerInParent="true" + a:layout_centerVertical="true" /> + <ImageView + a:contentDescription="@null" + a:layout_height="wrap_content" + a:layout_width="wrap_content" + a:src="@drawable/ic_lock_googblue_48dp" + a:layout_centerInParent="true" + a:layout_centerVertical="true" /> + </RelativeLayout> + + <TextView + a:id="@+id/status_text" a:layout_width="wrap_content" - a:src="@drawable/ic_lock_googblue_48dp" - a:layout_centerInParent="true" - a:layout_centerVertical="true" /> - </RelativeLayout> + a:layout_height="wrap_content" + a:layout_marginTop="4dp" + a:layout_marginBottom="16dp" + a:layout_gravity="center_horizontal" + a:padding="0px" + a:textSize="24sp" /> - <TextView - a:id="@+id/status_text" - a:layout_width="wrap_content" - a:layout_height="wrap_content" - a:layout_marginTop="4dp" - a:layout_gravity="center_horizontal" - a:padding="0px" - a:textSize="24sp" /> + </LinearLayout> -</LinearLayout> +</ScrollView>
diff --git a/chrome/browser/webauthn/android/java/res/layout/cablev2_error.xml b/chrome/browser/webauthn/android/java/res/layout/cablev2_error.xml index 70e6c1a7..ede138dc 100644 --- a/chrome/browser/webauthn/android/java/res/layout/cablev2_error.xml +++ b/chrome/browser/webauthn/android/java/res/layout/cablev2_error.xml
@@ -3,77 +3,87 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android" +<ScrollView + xmlns:a="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" a:layout_width="match_parent" a:layout_height="match_parent" - a:gravity="center" - a:orientation="vertical"> - - <TextView - a:id="@+id/error_title" - style="@style/TextAppearance.Headline.Primary" - a:layout_width="match_parent" - a:layout_height="wrap_content" - a:layout_marginTop="104dp" - a:gravity="center_horizontal" - a:text="@string/cablev2_error_title"/> - - <!-- This is a semantically-meaningless picture of a sad tab that - screen readers can ignore. Thus contentDescription is null. --> - <ImageView - a:layout_width="210dp" - a:layout_height="128dp" - a:layout_marginTop="52dp" - a:layout_marginBottom="35dp" - a:contentDescription="@null" - a:gravity="center_horizontal" - a:src="@drawable/error_icon"/> - - <TextView - a:id="@+id/error_description" - style="@style/TextAppearance.TextMedium.Secondary" - a:layout_marginTop="4dp" - a:layout_marginLeft="40dp" - a:layout_marginRight="40dp" - a:layout_width="wrap_content" - a:layout_height="wrap_content" - a:gravity="center_horizontal"/> - - <TextView - a:id="@+id/error_code" - style="@style/TextAppearance.TextMedium.Disabled" - a:layout_marginTop="4dp" - a:layout_marginLeft="40dp" - a:layout_marginRight="40dp" - a:layout_width="wrap_content" - a:layout_height="wrap_content" - a:gravity="center_horizontal"/> - - <!-- not shown by default. The visibility is toggled by code when needed --> - <org.chromium.ui.widget.ButtonCompat - a:id="@+id/error_settings_button" - style="@style/TextButton" - a:layout_width="wrap_content" - a:layout_height="wrap_content" - a:gravity="center_horizontal" - a:layout_marginTop="20dp" - a:visibility="invisible" - a:text="@string/qr_code_open_settings_label"/> + a:fillViewport="true" + a:scrollbars="none"> <LinearLayout a:layout_width="match_parent" - a:layout_height="0dp" - a:layout_weight="1" - a:gravity="bottom|center"> + a:layout_height="wrap_content" + a:gravity="center" + a:orientation="vertical"> - <org.chromium.ui.widget.ButtonCompat - a:id="@+id/error_close" - style="@style/TextButton" + <TextView + a:id="@+id/error_title" + style="@style/TextAppearance.Headline.Primary" + a:layout_width="match_parent" + a:layout_height="wrap_content" + a:layout_marginTop="104dp" + a:gravity="center_horizontal" + a:text="@string/cablev2_error_title"/> + + <!-- This is a semantically-meaningless picture of a sad tab that + screen readers can ignore. Thus contentDescription is null. --> + <ImageView + a:layout_width="210dp" + a:layout_height="128dp" + a:layout_marginTop="52dp" + a:layout_marginBottom="35dp" + a:contentDescription="@null" + a:gravity="center_horizontal" + a:src="@drawable/error_icon"/> + + <TextView + a:id="@+id/error_description" + style="@style/TextAppearance.TextMedium.Secondary" + a:layout_marginTop="4dp" + a:layout_marginLeft="40dp" + a:layout_marginRight="40dp" a:layout_width="wrap_content" a:layout_height="wrap_content" - a:gravity="bottom|center" - a:layout_marginBottom="20dp" - a:text="@string/cablev2_error_close"/> + a:gravity="center_horizontal"/> + <TextView + a:id="@+id/error_code" + style="@style/TextAppearance.TextMedium.Disabled" + a:layout_marginTop="4dp" + a:layout_marginLeft="40dp" + a:layout_marginRight="40dp" + a:layout_width="wrap_content" + a:layout_height="wrap_content" + a:gravity="center_horizontal"/> + + <!-- not shown by default. The visibility is toggled by code when needed --> + <org.chromium.ui.widget.ButtonCompat + a:id="@+id/error_settings_button" + style="@style/TextButton" + a:layout_width="wrap_content" + a:layout_height="wrap_content" + a:gravity="center_horizontal" + a:layout_marginTop="20dp" + a:visibility="invisible" + a:text="@string/qr_code_open_settings_label"/> + + <LinearLayout + a:layout_width="match_parent" + a:layout_height="0dp" + a:layout_weight="1" + a:gravity="bottom|center"> + + <org.chromium.ui.widget.ButtonCompat + a:id="@+id/error_close" + style="@style/TextButton" + a:layout_width="wrap_content" + a:layout_height="wrap_content" + a:gravity="bottom|center" + a:layout_marginBottom="20dp" + a:text="@string/cablev2_error_close"/> + + </LinearLayout> </LinearLayout> -</LinearLayout> + +</ScrollView>
diff --git a/chrome/browser/webauthn/android/java/res/layout/cablev2_spinner.xml b/chrome/browser/webauthn/android/java/res/layout/cablev2_spinner.xml index 0c9420d..abbd458 100644 --- a/chrome/browser/webauthn/android/java/res/layout/cablev2_spinner.xml +++ b/chrome/browser/webauthn/android/java/res/layout/cablev2_spinner.xml
@@ -3,55 +3,64 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" +<ScrollView + xmlns:a="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" a:layout_width="match_parent" a:layout_height="match_parent" - a:orientation="vertical" - xmlns:tools="http://schemas.android.com/tools"> + a:fillViewport="true" + a:scrollbars="none"> - <TextView + <LinearLayout a:layout_width="match_parent" a:layout_height="wrap_content" - a:layout_marginTop="104dp" - a:layout_marginLeft="24dp" - a:layout_marginRight="24dp" - a:gravity="center_horizontal" - a:text="@string/cablev2_serverlink_connecting_to_your_device" - a:textSize="24sp" /> + a:orientation="vertical"> - <RelativeLayout - a:layout_width="wrap_content" - a:layout_height="wrap_content" - a:layoutDirection="ltr" - a:layout_marginTop="52dp" - a:layout_marginLeft="24dp" - a:layout_marginRight="24dp" - a:layout_gravity="center_horizontal"> - <ImageView - a:id="@+id/spinner" - a:contentDescription="@null" + <TextView + a:layout_width="match_parent" + a:layout_height="wrap_content" + a:layout_marginTop="104dp" + a:layout_marginLeft="24dp" + a:layout_marginRight="24dp" + a:gravity="center_horizontal" + a:text="@string/cablev2_serverlink_connecting_to_your_device" + a:textSize="24sp" /> + + <RelativeLayout a:layout_width="wrap_content" a:layout_height="wrap_content" - a:layout_gravity="center" - a:layout_centerInParent="true" - a:layout_centerVertical="true" /> - <ImageView - a:contentDescription="@null" - a:layout_height="wrap_content" + a:layoutDirection="ltr" + a:layout_marginTop="52dp" + a:layout_marginLeft="24dp" + a:layout_marginRight="24dp" + a:layout_gravity="center_horizontal"> + <ImageView + a:id="@+id/spinner" + a:contentDescription="@null" + a:layout_width="wrap_content" + a:layout_height="wrap_content" + a:layout_gravity="center" + a:layout_centerInParent="true" + a:layout_centerVertical="true" /> + <ImageView + a:contentDescription="@null" + a:layout_height="wrap_content" + a:layout_width="wrap_content" + a:src="@drawable/ic_lock_googblue_48dp" + a:layout_centerInParent="true" + a:layout_centerVertical="true" /> + </RelativeLayout> + + <TextView + a:id="@+id/status_text" a:layout_width="wrap_content" - a:src="@drawable/ic_lock_googblue_48dp" - a:layout_centerInParent="true" - a:layout_centerVertical="true" /> - </RelativeLayout> + a:layout_height="wrap_content" + a:layout_marginTop="4dp" + a:layout_marginBottom="16dp" + a:layout_gravity="center_horizontal" + a:padding="0px" + a:textSize="14sp" /> - <TextView - a:id="@+id/status_text" - a:layout_width="wrap_content" - a:layout_height="wrap_content" - a:layout_marginTop="4dp" - a:layout_gravity="center_horizontal" - a:padding="0px" - a:textSize="14sp" /> + </LinearLayout> -</LinearLayout> +</ScrollView>
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 13304b3..96116ede 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1645725546-03a3f2a67e880246435a3a270215ca8761470300.profdata +chrome-win32-main-1645736298-0bbb2e587ea8d357893033f7560c7f635d8bdf91.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 40c2ced..e05b36e 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1645725546-41e700cf464c36c3bdc664410054cc53cd6bbb0a.profdata +chrome-win64-main-1645736298-1f88af4fba2e513be7f01a82d64e31bce7ea806d.profdata
diff --git a/chrome/renderer/DEPS b/chrome/renderer/DEPS index 066439c..8a70ec3 100644 --- a/chrome/renderer/DEPS +++ b/chrome/renderer/DEPS
@@ -28,7 +28,7 @@ "+components/feed/feed_feature_list.h", "+components/grit", "+components/guest_view/renderer", - "+components/history_clusters/core/features.h", + "+components/history_clusters/core/config.h", "+components/metrics/child_call_stack_profile_collector.h", "+components/nacl/common", "+components/nacl/renderer",
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 2292fe1..6ba41fd 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -81,7 +81,7 @@ #include "components/error_page/common/localized_error.h" #include "components/feed/buildflags.h" #include "components/grit/components_scaled_resources.h" -#include "components/history_clusters/core/features.h" +#include "components/history_clusters/core/config.h" #include "components/network_hints/renderer/web_prescient_networking_impl.h" #include "components/no_state_prefetch/common/prerender_url_loader_throttle.h" #include "components/no_state_prefetch/renderer/no_state_prefetch_client.h" @@ -585,8 +585,9 @@ const bool search_result_extractor_enabled = base::FeatureList::IsEnabled(features::kContinuousSearch); #else + history_clusters::OverrideWithFinch(RenderThread::Get()->GetLocale()); const bool search_result_extractor_enabled = - history_clusters::IsJourneysEnabled(RenderThread::Get()->GetLocale()); + history_clusters::GetConfig().is_journeys_enabled; #endif if (render_frame->IsMainFrame() && search_result_extractor_enabled) { continuous_search::SearchResultExtractorImpl::Create(render_frame);
diff --git a/chrome/renderer/media/flash_embed_rewrite.cc b/chrome/renderer/media/flash_embed_rewrite.cc index 9d99c1b1..416af5b 100644 --- a/chrome/renderer/media/flash_embed_rewrite.cc +++ b/chrome/renderer/media/flash_embed_rewrite.cc
@@ -56,8 +56,8 @@ std::string path = corrected_url.path(); path.replace(path.find("/v/"), 3, "/embed/"); - url::Replacements<char> r; - r.SetPath(path.c_str(), url::Component(0, path.length())); + GURL::Replacements r; + r.SetPathStr(path); return corrected_url.ReplaceComponents(r); } @@ -73,8 +73,8 @@ int replace_length = path.find("/swf/video/") == 0 ? 11 : 5; path.replace(0, replace_length, "/embed/video/"); - url::Replacements<char> r; - r.SetPath(path.c_str(), url::Component(0, path.length())); + GURL::Replacements r; + r.SetPathStr(path); return url.ReplaceComponents(r); }
diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn index abfdfcd..bce8795 100644 --- a/chrome/test/android/BUILD.gn +++ b/chrome/test/android/BUILD.gn
@@ -274,7 +274,6 @@ "javatests/src/org/chromium/chrome/test/util/MenuUtils.java", "javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java", "javatests/src/org/chromium/chrome/test/util/OmniboxTestUtils.java", - "javatests/src/org/chromium/chrome/test/util/OverviewModeBehaviorWatcher.java", "javatests/src/org/chromium/chrome/test/util/RecentTabsPageTestUtils.java", "javatests/src/org/chromium/chrome/test/util/SadTabRule.java", "javatests/src/org/chromium/chrome/test/util/TabStripUtils.java",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OverviewModeBehaviorWatcher.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OverviewModeBehaviorWatcher.java deleted file mode 100644 index 5b04acf..0000000 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OverviewModeBehaviorWatcher.java +++ /dev/null
@@ -1,75 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.test.util; - -import org.hamcrest.Matchers; - -import org.chromium.base.test.util.Criteria; -import org.chromium.base.test.util.CriteriaHelper; -import org.chromium.chrome.browser.compositor.layouts.EmptyOverviewModeObserver; -import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; -import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior.OverviewModeObserver; -import org.chromium.content_public.browser.test.util.TestThreadUtils; - -/** - * Checks and waits for certain overview mode events to happen. Can be used to block test threads - * until certain overview mode state criteria are met. - */ -public class OverviewModeBehaviorWatcher { - private final OverviewModeBehavior mOverviewModeBehavior; - private final OverviewModeObserver mOverviewModeObserver; - private boolean mWaitingForShow; - private boolean mWaitingForHide; - - /** - * Creates an instance of an {@link OverviewModeBehaviorWatcher}. Note that at this point - * it will be registered for overview mode events. - * - * @param behavior The {@link OverviewModeBehavior} to watch. - * @param waitForShow Whether or not to wait for overview mode to finish showing. - * @param waitForHide Whether or not to wait for overview mode to finish hiding. - */ - public OverviewModeBehaviorWatcher(OverviewModeBehavior behavior, boolean waitForShow, - boolean waitForHide) { - mOverviewModeBehavior = behavior; - mOverviewModeObserver = new EmptyOverviewModeObserver() { - @Override - public void onOverviewModeFinishedShowing() { - mWaitingForShow = false; - } - - @Override - public void onOverviewModeFinishedHiding() { - mWaitingForHide = false; - } - }; - - TestThreadUtils.runOnUiThreadBlocking( - () -> mOverviewModeBehavior.addOverviewModeObserver(mOverviewModeObserver)); - - mWaitingForShow = waitForShow; - mWaitingForHide = waitForHide; - } - - /** - * Blocks until all of the expected events have occurred. Once the events of this class - * are met it will always return immediately from {@link #waitForBehavior()}. - */ - public void waitForBehavior() { - try { - CriteriaHelper.pollUiThread(() -> { - Criteria.checkThat( - "OverviewModeObserver#onOverviewModeFinishedShowing() not called.", - mWaitingForShow, Matchers.is(false)); - Criteria.checkThat( - "OverviewModeObserver#onOverviewModeFinishedHiding() not called.", - mWaitingForHide, Matchers.is(false)); - }); - } finally { - TestThreadUtils.runOnUiThreadBlocking( - () -> mOverviewModeBehavior.removeOverviewModeObserver(mOverviewModeObserver)); - } - } -}
diff --git a/chrome/test/data/pdf/page_change_test.js b/chrome/test/data/pdf/page_change_test.js index 28c63da..806ffff3 100644 --- a/chrome/test/data/pdf/page_change_test.js +++ b/chrome/test/data/pdf/page_change_test.js
@@ -24,12 +24,23 @@ simulateFormFocusChange(false); } - /** @return {number} */ function getCurrentPage() { return getViewer().viewport.getMostVisiblePage(); } +function getAllPossibleKeyModifiers() { + const modifiers = ['shift', 'ctrl', 'alt', 'meta']; + modifiers.push( + ['shift', 'ctrl'], ['shift', 'alt'], ['shift', 'meta'], ['ctrl', 'alt'], + ['ctrl', 'meta'], ['alt', 'meta']); + modifiers.push( + ['shift', 'ctrl', 'alt'], ['shift', 'ctrl', 'meta'], + ['shift', 'alt', 'meta'], ['ctrl', 'alt', 'meta']); + modifiers.push(['shift', 'ctrl', 'alt', 'meta']); + return modifiers; +} + const tests = [ /** * Test that the left/right arrows change page back and forth. @@ -68,16 +79,30 @@ }, /** - * Test that when the document.documentElement is in fit to page, pressing - * page up/page down changes page back/forth. + * Test that when the PDF Viewer is in fit-to-page mode: + * - Pressing page up/page down changes page back/forth. + * - Pressing any modifiers + page up/page down does not. */ function testPageDownInFitPage() { getViewer().viewport.fitToPage(); + // Modifiers + Page down -> Does not change the page. + const modifiers = getAllPossibleKeyModifiers(); + for (const mods of modifiers) { + pressAndReleaseKeyOn(document.documentElement, 34, mods, 'PageDown'); + chrome.test.assertEq(0, getCurrentPage()); + } + // Page down -> Go to page 2. pressAndReleaseKeyOn(document.documentElement, 34, '', 'PageDown'); chrome.test.assertEq(1, getCurrentPage()); + // Modifiers + Page up -> Does not change the page. + for (const mods of modifiers) { + pressAndReleaseKeyOn(document.documentElement, 33, mods, 'PageUp'); + chrome.test.assertEq(1, getCurrentPage()); + } + // Page up -> Back to page 1. pressAndReleaseKeyOn(document.documentElement, 33, '', 'PageUp'); chrome.test.assertEq(0, getCurrentPage());
diff --git a/chrome/test/data/webui/new_tab_page/modules/modules_test.ts b/chrome/test/data/webui/new_tab_page/modules/modules_test.ts index d18733a..e8488d3 100644 --- a/chrome/test/data/webui/new_tab_page/modules/modules_test.ts +++ b/chrome/test/data/webui/new_tab_page/modules/modules_test.ts
@@ -138,6 +138,9 @@ }, ]); + callbackRouterRemote.setDisabledModules(false, []); + await callbackRouterRemote.$.flushForTesting(); + // Assert. const modules = Array.from(modulesElement.shadowRoot!.querySelectorAll('#modules')); @@ -163,6 +166,157 @@ ModuleWrapperElement) .module.element); }); + + test('modules can be disabled and restored', async () => { + // Arrange. + let restoreCalled = false; + const moduleArray = []; + for (let i = 0; i < 3; ++i) { + let module = createElement(); + moduleArray.push(module); + } + const fooDescriptor = new ModuleDescriptorV2( + 'foo', 'foo', ModuleHeight.SHORT, async () => createElement()); + const barDescriptor = new ModuleDescriptorV2( + 'bar', 'bar', ModuleHeight.SHORT, async () => createElement()); + const bazDescriptor = new ModuleDescriptorV2( + 'baz', 'baz', ModuleHeight.SHORT, async () => createElement()); + moduleRegistry.setResultFor( + 'getDescriptors', [fooDescriptor, barDescriptor, bazDescriptor]); + + // Act. + const modulesElement = await createModulesElement([ + { + descriptor: fooDescriptor, + element: moduleArray[0]!, + }, + { + descriptor: barDescriptor, + element: moduleArray[1]!, + }, + { + descriptor: bazDescriptor, + element: moduleArray[2]!, + } + ]); + + callbackRouterRemote.setDisabledModules(false, []); + await callbackRouterRemote.$.flushForTesting(); + + // Assert. + const modules = + Array.from(modulesElement.shadowRoot!.querySelectorAll('#modules')); + const moduleWrappers = + modulesElement.shadowRoot!.querySelectorAll('ntp-module-wrapper'); + const moduleWrapperContainers = + modulesElement.shadowRoot!.querySelectorAll('.module-container'); + let shortModuleSiblingsContainers = + modulesElement.shadowRoot!.querySelectorAll( + '.short-module-siblings-container'); + assertEquals(3, moduleWrappers.length); + assertEquals(3, moduleWrapperContainers.length); + assertEquals(1, shortModuleSiblingsContainers.length); + assertEquals(modules[0]!.children[0], shortModuleSiblingsContainers[0]); + assertEquals( + moduleArray[0], + (shortModuleSiblingsContainers[0]!.children[0]!.children[0] as + ModuleWrapperElement) + .module.element); + assertEquals( + moduleArray[1], + (shortModuleSiblingsContainers[0]!.children[1]!.children[0] as + ModuleWrapperElement) + .module.element); + assertNotStyle(moduleWrappers[0]!, 'display', 'none'); + assertNotStyle(moduleWrapperContainers[0]!, 'display', 'none'); + assertFalse(modulesElement.$.removeModuleToast.open); + + // Act. + moduleWrappers[0]!.dispatchEvent(new CustomEvent('disable-module', { + bubbles: true, + composed: true, + detail: { + message: 'Foo', + restoreCallback: () => { + restoreCalled = true; + }, + }, + })); + + // Assert. + assertDeepEquals(['foo', true], handler.getArgs('setModuleDisabled')[0]); + + // Act. + callbackRouterRemote.setDisabledModules(false, ['foo']); + await callbackRouterRemote.$.flushForTesting(); + + // Assert. + shortModuleSiblingsContainers = + modulesElement.shadowRoot!.querySelectorAll( + '.short-module-siblings-container'); + assertEquals(1, shortModuleSiblingsContainers.length); + assertEquals(modules[0]!.children[1], shortModuleSiblingsContainers[0]); + assertEquals( + moduleArray[1], + (shortModuleSiblingsContainers[0]!.children[0]!.children[0] as + ModuleWrapperElement) + .module.element); + assertEquals( + moduleArray[2], + (shortModuleSiblingsContainers[0]!.children[1]!.children[0] as + ModuleWrapperElement) + .module.element); + assertNotStyle(moduleWrappers[0]!, 'display', 'none'); + assertStyle(moduleWrapperContainers[0]!, 'display', 'none'); + assertTrue(modulesElement.$.removeModuleToast.open); + assertEquals( + 'Foo', modulesElement.$.removeModuleToastMessage.textContent!.trim()); + assertEquals(1, metrics.count('NewTabPage.Modules.Disabled', 'foo')); + assertEquals( + 1, metrics.count('NewTabPage.Modules.Disabled.ModuleRequest', 'foo')); + assertFalse(restoreCalled); + + // Act. + modulesElement.$.undoRemoveModuleButton.click(); + + // // Assert. + assertDeepEquals(['foo', false], handler.getArgs('setModuleDisabled')[1]); + + // Act. + callbackRouterRemote.setDisabledModules(false, []); + await callbackRouterRemote.$.flushForTesting(); + + // Assert. + shortModuleSiblingsContainers = + modulesElement.shadowRoot!.querySelectorAll( + '.short-module-siblings-container'); + assertEquals(1, shortModuleSiblingsContainers.length); + assertEquals(modules[0]!.children[0], shortModuleSiblingsContainers[0]); + assertEquals( + moduleArray[0], + (shortModuleSiblingsContainers[0]!.children[0]!.children[0] as + ModuleWrapperElement) + .module.element); + assertEquals( + moduleArray[1], + (shortModuleSiblingsContainers[0]!.children[1]!.children[0] as + ModuleWrapperElement) + .module.element); + assertNotStyle(moduleWrappers[0]!, 'display', 'none'); + assertNotStyle(moduleWrapperContainers[0]!, 'display', 'none'); + assertFalse(modulesElement.$.removeModuleToast.open); + assertTrue(restoreCalled); + assertEquals(1, metrics.count('NewTabPage.Modules.Enabled', 'foo')); + assertEquals(1, metrics.count('NewTabPage.Modules.Enabled.Toast', 'foo')); + + // // Act. + window.dispatchEvent(new KeyboardEvent('keydown', { + key: 'z', + ctrlKey: true, + })); + + // Assert: no crash. + }); }); test('modules can be dismissed and restored', async () => {
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn index d52f574..46317f5 100644 --- a/chrome/test/data/webui/settings/chromeos/BUILD.gn +++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -18,14 +18,14 @@ js_library("fake_user_action_recorder") { deps = [ - "//chrome/browser/ui/webui/settings/chromeos/search:mojo_bindings_js_library_for_compile", + "//chrome/browser/ui/webui/settings/ash/search:mojo_bindings_js_library_for_compile", "//ui/webui/resources/js:cr", ] } js_library("fake_settings_search_handler") { deps = [ - "//chrome/browser/ui/webui/settings/chromeos/search:mojo_bindings_js_library_for_compile", + "//chrome/browser/ui/webui/settings/ash/search:mojo_bindings_js_library_for_compile", "//ui/webui/resources/js:cr", ] }
diff --git a/chrome/test/ppapi/ppapi_filechooser_browsertest.cc b/chrome/test/ppapi/ppapi_filechooser_browsertest.cc index 154bd7d9..685fbf2 100644 --- a/chrome/test/ppapi/ppapi_filechooser_browsertest.cc +++ b/chrome/test/ppapi/ppapi_filechooser_browsertest.cc
@@ -19,6 +19,7 @@ #include "chrome/test/ppapi/ppapi_test_select_file_dialog_factory.h" #include "components/safe_browsing/buildflags.h" #include "components/services/quarantine/test_support.h" +#include "content/public/browser/global_routing_id.h" #include "content/public/test/browser_test.h" #include "ppapi/shared_impl/test_utils.h" @@ -54,6 +55,8 @@ void CheckPPAPIDownloadRequest( const GURL& requestor_url, const GURL& initiating_frame_url_unused, + const content::GlobalRenderFrameHostId& + initiating_outermost_main_frame_id, content::WebContents* web_contents_unused, const base::FilePath& default_file_path, const std::vector<base::FilePath::StringType>& alternate_extensions,
diff --git a/chrome/updater/win/task_scheduler_unittest.cc b/chrome/updater/win/task_scheduler_unittest.cc index d0d65c1..574aed5 100644 --- a/chrome/updater/win/task_scheduler_unittest.cc +++ b/chrome/updater/win/task_scheduler_unittest.cc
@@ -4,6 +4,7 @@ #include "chrome/updater/win/task_scheduler.h" +#include <lmsname.h> #include <mstask.h> #include <security.h> #include <shlobj.h> @@ -70,6 +71,7 @@ EXPECT_TRUE(task_scheduler_->DeleteTask(kTaskName1)); EXPECT_TRUE(task_scheduler_->DeleteTask(kTaskName2)); ASSERT_FALSE(IsProcessRunning(kTestProcessExecutableName)); + EXPECT_TRUE(IsServiceRunning(SERVICE_SCHEDULE)); } void TearDown() override {
diff --git a/chrome/updater/win/win_util.cc b/chrome/updater/win/win_util.cc index 2d0d834..01ee3d0 100644 --- a/chrome/updater/win/win_util.cc +++ b/chrome/updater/win/win_util.cc
@@ -677,4 +677,33 @@ msi_installer.value(), L"\" /log \"", msi_installer.value(), L".log\""}); } +bool IsServiceRunning(const std::wstring& service_name) { + ScopedScHandle scm(::OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT)); + if (!scm.IsValid()) { + LOG(ERROR) << "::OpenSCManager failed. service_name: " << service_name + << ", error: " << std::hex << HRESULTFromLastError(); + return false; + } + + ScopedScHandle service( + ::OpenService(scm.Get(), service_name.c_str(), SERVICE_QUERY_STATUS)); + if (!service.IsValid()) { + LOG(ERROR) << "::OpenService failed. service_name: " << service_name + << ", error: " << std::hex << HRESULTFromLastError(); + return false; + } + + SERVICE_STATUS status = {0}; + if (!::QueryServiceStatus(service.Get(), &status)) { + LOG(ERROR) << "::QueryServiceStatus failed. service_name: " << service_name + << ", error: " << std::hex << HRESULTFromLastError(); + return false; + } + + VLOG(1) << "IsServiceRunning. service_name: " << service_name + << ", status: " << std::hex << status.dwCurrentState; + return status.dwCurrentState == SERVICE_RUNNING || + status.dwCurrentState == SERVICE_START_PENDING; +} + } // namespace updater
diff --git a/chrome/updater/win/win_util.h b/chrome/updater/win/win_util.h index bcc7e61..55899a0 100644 --- a/chrome/updater/win/win_util.h +++ b/chrome/updater/win/win_util.h
@@ -37,6 +37,27 @@ namespace updater { +class ScHandleTraits { + public: + using Handle = SC_HANDLE; + + ScHandleTraits() = delete; + ScHandleTraits(const ScHandleTraits&) = delete; + ScHandleTraits& operator=(const ScHandleTraits&) = delete; + + static bool CloseHandle(SC_HANDLE handle) { + return ::CloseServiceHandle(handle) != FALSE; + } + + static bool IsHandleValid(SC_HANDLE handle) { return handle != nullptr; } + + static SC_HANDLE NullHandle() { return nullptr; } +}; + +using ScopedScHandle = + base::win::GenericScopedHandle<ScHandleTraits, + base::win::DummyVerifierTraits>; + class ProcessFilterName : public base::ProcessFilter { public: explicit ProcessFilterName(const std::wstring& process_name); @@ -199,6 +220,9 @@ std::wstring BuildMsiCommandLine(const std::wstring& arguments, const base::FilePath& msi_installer); +// Returns `true` if the service specified is currently running or starting. +bool IsServiceRunning(const std::wstring& service_name); + } // namespace updater #endif // CHROME_UPDATER_WIN_WIN_UTIL_H_
diff --git a/chromecast/cast_core/BUILD.gn b/chromecast/cast_core/BUILD.gn index fb98901e3..8ef9c5e 100644 --- a/chromecast/cast_core/BUILD.gn +++ b/chromecast/cast_core/BUILD.gn
@@ -16,6 +16,7 @@ "//chromecast/browser:browser", "//chromecast/browser:prefs_simple", "//chromecast/browser:simple_main_parts", + "//chromecast/cast_core/grpc:grpc_factory_linux", "//chromecast/cast_core/runtime/browser:browser_simple", "//chromecast/cast_core/runtime/renderer", "//chromecast/utility:simple_client", @@ -40,6 +41,7 @@ ":all_unit_tests", "//chromecast/browser:prefs_simple", "//chromecast/browser:simple_main_parts", + "//chromecast/cast_core/grpc:grpc_factory_linux", "//chromecast/cast_core/runtime/browser:browser_simple", "//chromecast/cast_core/runtime/renderer", "//mojo/core/test:run_all_unittests",
diff --git a/chromecast/cast_core/grpc/BUILD.gn b/chromecast/cast_core/grpc/BUILD.gn index a235ce2..83cf12da 100644 --- a/chromecast/cast_core/grpc/BUILD.gn +++ b/chromecast/cast_core/grpc/BUILD.gn
@@ -5,6 +5,26 @@ import("//chromecast/chromecast.gni") import("//third_party/cast_core/public/src/proto/proto.gni") +cast_source_set("grpc_factory") { + sources = [ + "grpc_server_builder.cc", + "grpc_server_builder.h", + ] + + public_deps = [ "//third_party/grpc:grpc++" ] +} + +cast_source_set("grpc_factory_linux") { + sources = [ "grpc_factory_linux.cc" ] + + deps = [ + ":grpc_factory", + "//base", + "//third_party/abseil-cpp:absl", + "//third_party/grpc:grpc++", + ] +} + cast_source_set("grpc") { sources = [ "cancellable_reactor.h", @@ -30,6 +50,7 @@ ] public_deps = [ + ":grpc_factory", "//base", "//third_party/abseil-cpp:absl", "//third_party/grpc:grpc++",
diff --git a/chromecast/cast_core/grpc/grpc_factory.h b/chromecast/cast_core/grpc/grpc_factory.h new file mode 100644 index 0000000..dd4baf4 --- /dev/null +++ b/chromecast/cast_core/grpc/grpc_factory.h
@@ -0,0 +1,20 @@ +#ifndef THIRD_PARTY_CASTLITE_COMMON_GRPC_GRPC_FACTORY_H_ +#define THIRD_PARTY_CASTLITE_COMMON_GRPC_GRPC_FACTORY_H_ + +#include "chromecast/cast_core/grpc/grpc_server_builder.h" + +namespace cast { +namespace utils { + +// This class holds a set of factory methods that should be overridden per +// specific platform (ie Android, Linux etc). +class GrpcFactory { + public: + // Creates an instance of GrpcServerBuilder. + static std::unique_ptr<GrpcServerBuilder> CreateServerBuilder(); +}; + +} // namespace utils +} // namespace cast + +#endif // THIRD_PARTY_CASTLITE_COMMON_GRPC_GRPC_FACTORY_H_
diff --git a/chromecast/cast_core/grpc/grpc_factory_linux.cc b/chromecast/cast_core/grpc/grpc_factory_linux.cc new file mode 100644 index 0000000..ebc79d5 --- /dev/null +++ b/chromecast/cast_core/grpc/grpc_factory_linux.cc
@@ -0,0 +1,58 @@ +#include "base/sequence_checker.h" +#include "chromecast/cast_core/grpc/grpc_factory.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace cast { +namespace utils { + +namespace { + +// Linux implementation of the |GrpcServerBuilder|. +class GrpcServerBuilderLinux : public GrpcServerBuilder { + public: + GrpcServerBuilderLinux() { server_builder_.emplace(); } + ~GrpcServerBuilderLinux() override = default; + + // Implements GrpcServerBuilder APIs. + GrpcServerBuilder& AddListeningPort( + const std::string& endpoint, + std::shared_ptr<grpc::ServerCredentials> creds, + int* selected_port = nullptr) override { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(server_builder_); + DCHECK(creds); + server_builder_->AddListeningPort(endpoint, std::move(creds), + selected_port); + return *this; + } + + GrpcServerBuilder& RegisterCallbackGenericService( + grpc::CallbackGenericService* service) override { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(server_builder_); + DCHECK(service); + server_builder_->RegisterCallbackGenericService(service); + return *this; + } + + std::unique_ptr<grpc::Server> BuildAndStart() override { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(server_builder_) << "gRPC server was already built"; + auto server = std::move(server_builder_).value().BuildAndStart(); + server_builder_.reset(); + return server; + } + + private: + SEQUENCE_CHECKER(sequence_checker_); + absl::optional<grpc::ServerBuilder> server_builder_; +}; + +} // namespace + +std::unique_ptr<GrpcServerBuilder> GrpcFactory::CreateServerBuilder() { + return std::make_unique<GrpcServerBuilderLinux>(); +} + +} // namespace utils +} // namespace cast
diff --git a/chromecast/cast_core/grpc/grpc_server.cc b/chromecast/cast_core/grpc/grpc_server.cc index c5222c3..9bcc73bb 100644 --- a/chromecast/cast_core/grpc/grpc_server.cc +++ b/chromecast/cast_core/grpc/grpc_server.cc
@@ -12,6 +12,8 @@ #include "base/task/thread_pool.h" #include "base/time/time.h" #include "chromecast/cast_core/grpc/grpc_call_options.h" +#include "chromecast/cast_core/grpc/grpc_factory.h" +#include "chromecast/cast_core/grpc/grpc_server_builder.h" namespace cast { namespace utils { @@ -67,9 +69,10 @@ DCHECK(!server_) << "Server is already running"; DCHECK(server_reactor_tracker_) << "Server was alreadys shutdown"; - server_ = grpc::ServerBuilder() - .AddListeningPort(std::string(endpoint), - grpc::InsecureServerCredentials()) + auto builder = GrpcFactory::CreateServerBuilder(); + server_ = builder + ->AddListeningPort(std::string(endpoint), + grpc::InsecureServerCredentials()) .RegisterCallbackGenericService(this) .BuildAndStart(); DCHECK(server_) << "Failed to start server";
diff --git a/chromecast/cast_core/grpc/grpc_server_builder.cc b/chromecast/cast_core/grpc/grpc_server_builder.cc new file mode 100644 index 0000000..dc44f36 --- /dev/null +++ b/chromecast/cast_core/grpc/grpc_server_builder.cc
@@ -0,0 +1,13 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromecast/cast_core/grpc/grpc_server_builder.h" + +namespace cast { +namespace utils { + +GrpcServerBuilder::~GrpcServerBuilder() = default; + +} // namespace utils +} // namespace cast
diff --git a/chromecast/cast_core/grpc/grpc_server_builder.h b/chromecast/cast_core/grpc/grpc_server_builder.h new file mode 100644 index 0000000..1bc08bf --- /dev/null +++ b/chromecast/cast_core/grpc/grpc_server_builder.h
@@ -0,0 +1,43 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMECAST_CAST_CORE_GRPC_GRPC_SERVER_BUILDER_H_ +#define CHROMECAST_CAST_CORE_GRPC_GRPC_SERVER_BUILDER_H_ + +#include <grpcpp/grpcpp.h> + +#include <memory> +#include <string> + +namespace cast { +namespace utils { + +// An grpc::Server builder interface which enables injection of additional logic +// to the vanilla grpc::ServerBuilder. For example, enabling gRPC on Android via +// IPC binder. +class GrpcServerBuilder { + public: + virtual ~GrpcServerBuilder(); + + // Create an instance of GrpcServerBuilder. May be overridden per platform. + static std::unique_ptr<GrpcServerBuilder> Create(); + + // Adds a gRPC server listening port. + virtual GrpcServerBuilder& AddListeningPort( + const std::string& endpoint, + std::shared_ptr<grpc::ServerCredentials> creds, + int* selected_port = nullptr) = 0; + + // Registers a generic service that uses the callback API. + virtual GrpcServerBuilder& RegisterCallbackGenericService( + grpc::CallbackGenericService* service) = 0; + + // Builds and starts the gRPC server. + virtual std::unique_ptr<grpc::Server> BuildAndStart() = 0; +}; + +} // namespace utils +} // namespace cast + +#endif // CHROMECAST_CAST_CORE_GRPC_GRPC_SERVER_BUILDER_H_
diff --git a/chromeos/dbus/userdataauth/fake_userdataauth_client.cc b/chromeos/dbus/userdataauth/fake_userdataauth_client.cc index 40190730..81a0352 100644 --- a/chromeos/dbus/userdataauth/fake_userdataauth_client.cc +++ b/chromeos/dbus/userdataauth/fake_userdataauth_client.cc
@@ -16,6 +16,7 @@ #include "base/strings/stringprintf.h" #include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" +#include "chromeos/dbus/cryptohome/UserDataAuth.pb.h" #include "chromeos/dbus/cryptohome/rpc.pb.h" namespace chromeos { @@ -303,6 +304,169 @@ ReturnProtobufMethodCallback(reply, std::move(callback)); } +void FakeUserDataAuthClient::PrepareGuestVault( + const ::user_data_auth::PrepareGuestVaultRequest& request, + PrepareGuestVaultCallback callback) { + ::user_data_auth::PrepareGuestVaultReply reply; + + cryptohome::AccountIdentifier account; + account.set_account_id(kGuestUserName); + reply.set_sanitized_username(GetStubSanitizedUsername(account)); + + ReturnProtobufMethodCallback(reply, std::move(callback)); +} + +void FakeUserDataAuthClient::PrepareEphemeralVault( + const ::user_data_auth::PrepareEphemeralVaultRequest& request, + PrepareEphemeralVaultCallback callback) { + ::user_data_auth::PrepareEphemeralVaultReply reply; + + cryptohome::AccountIdentifier account; + auto auth_session = auth_sessions_.find(request.auth_session_id()); + if (auth_session == auth_sessions_.end()) { + LOG(ERROR) << "AuthSession not found"; + reply.set_sanitized_username(std::string()); + reply.set_error(::user_data_auth::CryptohomeErrorCode:: + CRYPTOHOME_INVALID_AUTH_SESSION_TOKEN); + } else { + account = auth_session->second.account; + reply.set_sanitized_username(GetStubSanitizedUsername(account)); + if (!auth_session->second.authenticated) { + LOG(ERROR) << "AuthSession is not authenticated"; + reply.set_error(::user_data_auth::CryptohomeErrorCode:: + CRYPTOHOME_ERROR_INVALID_ARGUMENT); + } + } + + ReturnProtobufMethodCallback(reply, std::move(callback)); +} + +void FakeUserDataAuthClient::CreatePersistentUser( + const ::user_data_auth::CreatePersistentUserRequest& request, + CreatePersistentUserCallback callback) { + ::user_data_auth::CreatePersistentUserReply reply; + + auto auth_session = auth_sessions_.find(request.auth_session_id()); + if (auth_session == auth_sessions_.end()) { + LOG(ERROR) << "AuthSession not found"; + reply.set_sanitized_username(std::string()); + reply.set_error(::user_data_auth::CryptohomeErrorCode:: + CRYPTOHOME_INVALID_AUTH_SESSION_TOKEN); + } else if (UserExists(auth_session->second.account)) { + LOG(ERROR) << "User already exists" + << GetStubSanitizedUsername(auth_session->second.account); + reply.set_error(::user_data_auth::CryptohomeErrorCode:: + CRYPTOHOME_ERROR_MOUNT_MOUNT_POINT_BUSY); + } else { + auth_session->second.authenticated = true; + AddExistingUser(auth_session->second.account); + } + + ReturnProtobufMethodCallback(reply, std::move(callback)); +} + +void FakeUserDataAuthClient::PreparePersistentVault( + const ::user_data_auth::PreparePersistentVaultRequest& request, + PreparePersistentVaultCallback callback) { + ::user_data_auth::PreparePersistentVaultReply reply; + + auto error = ::user_data_auth::CryptohomeErrorCode::CRYPTOHOME_ERROR_NOT_SET; + auto* authenticated_auth_session = + GetAuthenticatedAuthSession(request.auth_session_id(), &error); + + if (authenticated_auth_session == nullptr) { + reply.set_error(error); + } else if (!UserExists(authenticated_auth_session->account)) { + reply.set_error(::user_data_auth::CryptohomeErrorCode:: + CRYPTOHOME_ERROR_ACCOUNT_NOT_FOUND); + } + + ReturnProtobufMethodCallback(reply, std::move(callback)); +} + +void FakeUserDataAuthClient::InvalidateAuthSession( + const ::user_data_auth::InvalidateAuthSessionRequest& request, + InvalidateAuthSessionCallback callback) { + ::user_data_auth::InvalidateAuthSessionReply reply; + auto auth_session = auth_sessions_.find(request.auth_session_id()); + if (auth_session == auth_sessions_.end()) { + LOG(ERROR) << "AuthSession not found"; + reply.set_error(::user_data_auth::CryptohomeErrorCode:: + CRYPTOHOME_INVALID_AUTH_SESSION_TOKEN); + } else { + auth_sessions_.erase(auth_session); + } + ReturnProtobufMethodCallback(reply, std::move(callback)); +} + +void FakeUserDataAuthClient::ExtendAuthSession( + const ::user_data_auth::ExtendAuthSessionRequest& request, + ExtendAuthSessionCallback callback) { + ::user_data_auth::ExtendAuthSessionReply reply; + + auto error = ::user_data_auth::CryptohomeErrorCode::CRYPTOHOME_ERROR_NOT_SET; + GetAuthenticatedAuthSession(request.auth_session_id(), &error); + reply.set_error(error); + + ReturnProtobufMethodCallback(reply, std::move(callback)); +} + +void FakeUserDataAuthClient::AddAuthFactor( + const ::user_data_auth::AddAuthFactorRequest& request, + AddAuthFactorCallback callback) { + ::user_data_auth::AddAuthFactorReply reply; + + auto error = ::user_data_auth::CryptohomeErrorCode::CRYPTOHOME_ERROR_NOT_SET; + GetAuthenticatedAuthSession(request.auth_session_id(), &error); + reply.set_error(error); + + ReturnProtobufMethodCallback(reply, std::move(callback)); +} + +void FakeUserDataAuthClient::AuthenticateAuthFactor( + const ::user_data_auth::AuthenticateAuthFactorRequest& request, + AuthenticateAuthFactorCallback callback) { + last_authenticate_auth_factor_request_ = request; + ::user_data_auth::AuthenticateAuthFactorReply reply; + + const std::string auth_session_id = request.auth_session_id(); + const auto auth_session = auth_sessions_.find(auth_session_id); + if (auth_session == auth_sessions_.end()) { + LOG(ERROR) << "AuthSession not found"; + reply.set_error(::user_data_auth::CryptohomeErrorCode:: + CRYPTOHOME_INVALID_AUTH_SESSION_TOKEN); + } else if (auth_session->second.authenticated) { + LOG(WARNING) << "AuthSession is already authenticated"; + } else { + auth_session->second.authenticated = true; + } + ReturnProtobufMethodCallback(reply, std::move(callback)); +} + +void FakeUserDataAuthClient::UpdateAuthFactor( + const ::user_data_auth::UpdateAuthFactorRequest& request, + UpdateAuthFactorCallback callback) { + ::user_data_auth::UpdateAuthFactorReply reply; + + auto error = ::user_data_auth::CryptohomeErrorCode::CRYPTOHOME_ERROR_NOT_SET; + GetAuthenticatedAuthSession(request.auth_session_id(), &error); + reply.set_error(error); + + ReturnProtobufMethodCallback(reply, std::move(callback)); +} + +void FakeUserDataAuthClient::RemoveAuthFactor( + const ::user_data_auth::RemoveAuthFactorRequest& request, + RemoveAuthFactorCallback callback) { + ::user_data_auth::RemoveAuthFactorReply reply; + + auto error = ::user_data_auth::CryptohomeErrorCode::CRYPTOHOME_ERROR_NOT_SET; + GetAuthenticatedAuthSession(request.auth_session_id(), &error); + reply.set_error(error); + + ReturnProtobufMethodCallback(reply, std::move(callback)); +} + void FakeUserDataAuthClient::WaitForServiceToBeAvailable( chromeos::WaitForServiceToBeAvailableCallback callback) { if (service_is_available_ || service_reported_not_available_) { @@ -424,6 +588,29 @@ return base::PathExists(GetUserProfileDir(account_id)); } +const FakeUserDataAuthClient::AuthSessionData* +FakeUserDataAuthClient::GetAuthenticatedAuthSession( + const std::string& auth_session_id, + ::user_data_auth::CryptohomeErrorCode* error) const { + auto auth_session = auth_sessions_.find(auth_session_id); + + // Check if the token refers to a valid AuthSession. + if (auth_session == auth_sessions_.end()) { + LOG(ERROR) << "AuthSession not found"; + *error = ::user_data_auth::CryptohomeErrorCode:: + CRYPTOHOME_INVALID_AUTH_SESSION_TOKEN; + } + + // Check if the AuthSession is properly authenticated. + if (!auth_session->second.authenticated) { + LOG(ERROR) << "AuthSession is not authenticated"; + *error = ::user_data_auth::CryptohomeErrorCode:: + CRYPTOHOME_ERROR_INVALID_ARGUMENT; + } + + return &auth_session->second; +} + void FakeUserDataAuthClient::AddExistingUser( const cryptohome::AccountIdentifier& account_id) { existing_users_.insert(account_id);
diff --git a/chromeos/dbus/userdataauth/fake_userdataauth_client.h b/chromeos/dbus/userdataauth/fake_userdataauth_client.h index a6908e9..c5e4bba 100644 --- a/chromeos/dbus/userdataauth/fake_userdataauth_client.h +++ b/chromeos/dbus/userdataauth/fake_userdataauth_client.h
@@ -95,6 +95,35 @@ AuthenticateAuthSessionCallback callback) override; void AddCredentials(const ::user_data_auth::AddCredentialsRequest& request, AddCredentialsCallback callback) override; + void PrepareGuestVault( + const ::user_data_auth::PrepareGuestVaultRequest& request, + PrepareGuestVaultCallback callback) override; + void PrepareEphemeralVault( + const ::user_data_auth::PrepareEphemeralVaultRequest& request, + PrepareEphemeralVaultCallback callback) override; + void CreatePersistentUser( + const ::user_data_auth::CreatePersistentUserRequest& request, + CreatePersistentUserCallback callback) override; + void PreparePersistentVault( + const ::user_data_auth::PreparePersistentVaultRequest& request, + PreparePersistentVaultCallback callback) override; + void InvalidateAuthSession( + const ::user_data_auth::InvalidateAuthSessionRequest& request, + InvalidateAuthSessionCallback callback) override; + void ExtendAuthSession( + const ::user_data_auth::ExtendAuthSessionRequest& request, + ExtendAuthSessionCallback callback) override; + void AddAuthFactor(const ::user_data_auth::AddAuthFactorRequest& request, + AddAuthFactorCallback callback) override; + void AuthenticateAuthFactor( + const ::user_data_auth::AuthenticateAuthFactorRequest& request, + AuthenticateAuthFactorCallback callback) override; + void UpdateAuthFactor( + const ::user_data_auth::UpdateAuthFactorRequest& request, + UpdateAuthFactorCallback callback) override; + void RemoveAuthFactor( + const ::user_data_auth::RemoveAuthFactorRequest& request, + RemoveAuthFactorCallback callback) override; // Mount() related setter/getters. @@ -177,6 +206,12 @@ return last_authenticate_auth_session_request_.authorization(); } + // AuthenticateAuthFactor() related: + const ::user_data_auth::AuthenticateAuthFactorRequest& + get_last_authenticate_auth_factor_request() { + return last_authenticate_auth_factor_request_; + } + // WaitForServiceToBeAvailable() related: // Changes the behavior of WaitForServiceToBeAvailable(). This method runs @@ -227,6 +262,13 @@ // Check whether user with given id exists bool UserExists(const cryptohome::AccountIdentifier& account_id) const; + // The method takes serialized auth session id and returns an authenticated + // auth session associated with the id. If the session is missing or not + // authenticated, |nullptr| is returned. + const AuthSessionData* GetAuthenticatedAuthSession( + const std::string& auth_session_id, + ::user_data_auth::CryptohomeErrorCode* error) const; + // Mount() related fields. ::user_data_auth::CryptohomeErrorCode cryptohome_error_ = ::user_data_auth::CryptohomeErrorCode::CRYPTOHOME_ERROR_NOT_SET; @@ -277,6 +319,11 @@ ::user_data_auth::AuthenticateAuthSessionRequest last_authenticate_auth_session_request_; + // The AuthenticateAuthFactorRequest passed in for the last + // AuthenticateAuthFactor() call. + ::user_data_auth::AuthenticateAuthFactorRequest + last_authenticate_auth_factor_request_; + // The auth sessions on file. base::flat_map<std::string, AuthSessionData> auth_sessions_;
diff --git a/chromeos/dbus/userdataauth/userdataauth_client.cc b/chromeos/dbus/userdataauth/userdataauth_client.cc index 1b399ae..091fbd37 100644 --- a/chromeos/dbus/userdataauth/userdataauth_client.cc +++ b/chromeos/dbus/userdataauth/userdataauth_client.cc
@@ -235,6 +235,85 @@ std::move(callback)); } + void PrepareGuestVault( + const ::user_data_auth::PrepareGuestVaultRequest& request, + PrepareGuestVaultCallback callback) override { + CallProtoMethod(::user_data_auth::kPrepareGuestVault, + ::user_data_auth::kUserDataAuthInterface, request, + std::move(callback)); + } + + void PrepareEphemeralVault( + const ::user_data_auth::PrepareEphemeralVaultRequest& request, + PrepareEphemeralVaultCallback callback) override { + CallProtoMethod(::user_data_auth::kPrepareEphemeralVault, + ::user_data_auth::kUserDataAuthInterface, request, + std::move(callback)); + } + + void CreatePersistentUser( + const ::user_data_auth::CreatePersistentUserRequest& request, + CreatePersistentUserCallback callback) override { + CallProtoMethod(::user_data_auth::kCreatePersistentUser, + ::user_data_auth::kUserDataAuthInterface, request, + std::move(callback)); + } + + void PreparePersistentVault( + const ::user_data_auth::PreparePersistentVaultRequest& request, + PreparePersistentVaultCallback callback) override { + CallProtoMethod(::user_data_auth::kPreparePersistentVault, + ::user_data_auth::kUserDataAuthInterface, request, + std::move(callback)); + } + + void InvalidateAuthSession( + const ::user_data_auth::InvalidateAuthSessionRequest& request, + InvalidateAuthSessionCallback callback) override { + CallProtoMethod(::user_data_auth::kInvalidateAuthSession, + ::user_data_auth::kUserDataAuthInterface, request, + std::move(callback)); + } + + void ExtendAuthSession( + const ::user_data_auth::ExtendAuthSessionRequest& request, + ExtendAuthSessionCallback callback) override { + CallProtoMethod(::user_data_auth::kExtendAuthSession, + ::user_data_auth::kUserDataAuthInterface, request, + std::move(callback)); + } + + void AddAuthFactor(const ::user_data_auth::AddAuthFactorRequest& request, + AddAuthFactorCallback callback) override { + CallProtoMethod(::user_data_auth::kAddAuthFactor, + ::user_data_auth::kUserDataAuthInterface, request, + std::move(callback)); + } + + void AuthenticateAuthFactor( + const ::user_data_auth::AuthenticateAuthFactorRequest& request, + AuthenticateAuthFactorCallback callback) override { + CallProtoMethod(::user_data_auth::kAuthenticateAuthFactor, + ::user_data_auth::kUserDataAuthInterface, request, + std::move(callback)); + } + + void UpdateAuthFactor( + const ::user_data_auth::UpdateAuthFactorRequest& request, + UpdateAuthFactorCallback callback) override { + CallProtoMethod(::user_data_auth::kUpdateAuthFactor, + ::user_data_auth::kUserDataAuthInterface, request, + std::move(callback)); + } + + void RemoveAuthFactor( + const ::user_data_auth::RemoveAuthFactorRequest& request, + RemoveAuthFactorCallback callback) override { + CallProtoMethod(::user_data_auth::kRemoveAuthFactor, + ::user_data_auth::kUserDataAuthInterface, request, + std::move(callback)); + } + private: // Calls cryptohomed's |method_name| method in |interface_name| interface, // passing in |request| as input with |timeout_ms|. Once the (asynchronous)
diff --git a/chromeos/dbus/userdataauth/userdataauth_client.h b/chromeos/dbus/userdataauth/userdataauth_client.h index 67d9b13f..8d98518e 100644 --- a/chromeos/dbus/userdataauth/userdataauth_client.h +++ b/chromeos/dbus/userdataauth/userdataauth_client.h
@@ -69,6 +69,26 @@ DBusMethodCallback<::user_data_auth::AuthenticateAuthSessionReply>; using AddCredentialsCallback = DBusMethodCallback<::user_data_auth::AddCredentialsReply>; + using PrepareGuestVaultCallback = + DBusMethodCallback<::user_data_auth::PrepareGuestVaultReply>; + using PrepareEphemeralVaultCallback = + DBusMethodCallback<::user_data_auth::PrepareEphemeralVaultReply>; + using CreatePersistentUserCallback = + DBusMethodCallback<::user_data_auth::CreatePersistentUserReply>; + using PreparePersistentVaultCallback = + DBusMethodCallback<::user_data_auth::PreparePersistentVaultReply>; + using InvalidateAuthSessionCallback = + DBusMethodCallback<::user_data_auth::InvalidateAuthSessionReply>; + using ExtendAuthSessionCallback = + DBusMethodCallback<::user_data_auth::ExtendAuthSessionReply>; + using AddAuthFactorCallback = + DBusMethodCallback<::user_data_auth::AddAuthFactorReply>; + using AuthenticateAuthFactorCallback = + DBusMethodCallback<::user_data_auth::AuthenticateAuthFactorReply>; + using UpdateAuthFactorCallback = + DBusMethodCallback<::user_data_auth::UpdateAuthFactorReply>; + using RemoveAuthFactorCallback = + DBusMethodCallback<::user_data_auth::RemoveAuthFactorReply>; // Not copyable or movable. UserDataAuthClient(const UserDataAuthClient&) = delete; @@ -190,6 +210,67 @@ const ::user_data_auth::AddCredentialsRequest& request, AddCredentialsCallback callback) = 0; + // This request is intended to happen when a user wants + // to login to ChromeOS as a guest. + virtual void PrepareGuestVault( + const ::user_data_auth::PrepareGuestVaultRequest& request, + PrepareGuestVaultCallback callback) = 0; + + // This request is intended when a policy (either device or enterprise) + // has enabled ephemeral users. An ephemeral user is created + // in a memory filesystem only and is never actually persisted to disk. + virtual void PrepareEphemeralVault( + const ::user_data_auth::PrepareEphemeralVaultRequest& request, + PrepareEphemeralVaultCallback callback) = 0; + + // This will create user directories needed to store + // keys and download policies. This will usually be called when a new user is + // registering. + virtual void CreatePersistentUser( + const ::user_data_auth::CreatePersistentUserRequest& request, + CreatePersistentUserCallback callback) = 0; + + // This makes available user directories for them to use. + virtual void PreparePersistentVault( + const ::user_data_auth::PreparePersistentVaultRequest& request, + PreparePersistentVaultCallback callback) = 0; + + // This call is used to invalidate an AuthSession + // once the need for one no longer exists. + virtual void InvalidateAuthSession( + const ::user_data_auth::InvalidateAuthSessionRequest& request, + InvalidateAuthSessionCallback callback) = 0; + + // This call is used to extend the duration of + // AuthSession that it should be valid for. + virtual void ExtendAuthSession( + const ::user_data_auth::ExtendAuthSessionRequest& request, + ExtendAuthSessionCallback callback) = 0; + + // This call adds an AuthFactor for a user. The call goes + // through an authenticated AuthSession. + virtual void AddAuthFactor( + const ::user_data_auth::AddAuthFactorRequest& request, + AddAuthFactorCallback callback) = 0; + + // This will Authenticate an existing AuthFactor. + // This call will authenticate an AuthSession. + virtual void AuthenticateAuthFactor( + const ::user_data_auth::AuthenticateAuthFactorRequest& request, + AuthenticateAuthFactorCallback callback) = 0; + + // This call will be used in the case of a user wanting + // to update an AuthFactor. (E.g. Changing pin or password). + virtual void UpdateAuthFactor( + const ::user_data_auth::UpdateAuthFactorRequest& request, + UpdateAuthFactorCallback callback) = 0; + + // This is called when a user wants to remove an + // AuthFactor. + virtual void RemoveAuthFactor( + const ::user_data_auth::RemoveAuthFactorRequest& request, + RemoveAuthFactorCallback callback) = 0; + protected: // Initialize/Shutdown should be used instead. UserDataAuthClient();
diff --git a/components/browsing_topics/OWNERS b/components/browsing_topics/OWNERS new file mode 100644 index 0000000..077aa37f --- /dev/null +++ b/components/browsing_topics/OWNERS
@@ -0,0 +1,2 @@ +yaoxia@chromium.org +jkarlin@chromium.org
diff --git a/components/browsing_topics/common/BUILD.gn b/components/browsing_topics/common/BUILD.gn new file mode 100644 index 0000000..b48c2bc --- /dev/null +++ b/components/browsing_topics/common/BUILD.gn
@@ -0,0 +1,16 @@ +# Copyright 2022 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +component("common") { + output_name = "browsing_topics_common" + + defines = [ "IS_BROWSING_TOPICS_COMMON_IMPL" ] + + sources = [ + "common_types.cc", + "common_types.h", + ] + + deps = [ "//base" ] +}
diff --git a/components/browsing_topics/common/common_types.cc b/components/browsing_topics/common/common_types.cc new file mode 100644 index 0000000..cf7db18c --- /dev/null +++ b/components/browsing_topics/common/common_types.cc
@@ -0,0 +1,23 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/browsing_topics/common/common_types.h" + +namespace browsing_topics { + +ApiUsageContextQueryResult::ApiUsageContextQueryResult() = default; + +ApiUsageContextQueryResult::ApiUsageContextQueryResult( + std::vector<ApiUsageContext> api_usage_contexts) + : success(true), api_usage_contexts(std::move(api_usage_contexts)) {} + +ApiUsageContextQueryResult::ApiUsageContextQueryResult( + ApiUsageContextQueryResult&& other) = default; + +ApiUsageContextQueryResult& ApiUsageContextQueryResult::operator=( + ApiUsageContextQueryResult&& other) = default; + +ApiUsageContextQueryResult::~ApiUsageContextQueryResult() = default; + +} // namespace browsing_topics
diff --git a/components/browsing_topics/common/common_types.h b/components/browsing_topics/common/common_types.h new file mode 100644 index 0000000..2377712 --- /dev/null +++ b/components/browsing_topics/common/common_types.h
@@ -0,0 +1,46 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_BROWSING_TOPICS_COMMON_COMMON_TYPES_H_ +#define COMPONENTS_BROWSING_TOPICS_COMMON_COMMON_TYPES_H_ + +#include <vector> + +#include "base/component_export.h" +#include "base/time/time.h" +#include "base/types/strong_alias.h" + +namespace browsing_topics { + +using HashedHost = base::StrongAlias<class HashedHostTag, int64_t>; +using HashedDomain = base::StrongAlias<class HashedHostTag, int64_t>; + +struct COMPONENT_EXPORT(BROWSING_TOPICS_COMMON) ApiUsageContext { + HashedDomain hashed_context_domain; + HashedHost hashed_top_host; + base::Time time; +}; + +struct COMPONENT_EXPORT(BROWSING_TOPICS_COMMON) ApiUsageContextQueryResult { + ApiUsageContextQueryResult(); + explicit ApiUsageContextQueryResult( + std::vector<ApiUsageContext> api_usage_contexts); + + ApiUsageContextQueryResult(const ApiUsageContextQueryResult&) = delete; + ApiUsageContextQueryResult& operator=(const ApiUsageContextQueryResult&) = + delete; + + ApiUsageContextQueryResult(ApiUsageContextQueryResult&&); + ApiUsageContextQueryResult& operator=(ApiUsageContextQueryResult&&); + + ~ApiUsageContextQueryResult(); + + bool success = false; + + std::vector<ApiUsageContext> api_usage_contexts; +}; + +} // namespace browsing_topics + +#endif // COMPONENTS_BROWSING_TOPICS_COMMON_COMMON_TYPES_H_
diff --git a/components/history_clusters/core/BUILD.gn b/components/history_clusters/core/BUILD.gn index 836ce2a5..fc926888 100644 --- a/components/history_clusters/core/BUILD.gn +++ b/components/history_clusters/core/BUILD.gn
@@ -20,6 +20,8 @@ static_library("core") { sources = [ "clustering_backend.h", + "config.cc", + "config.h", "features.cc", "features.h", "history_clusters_db_tasks.cc", @@ -87,7 +89,7 @@ source_set("unit_tests") { testonly = true sources = [ - "features_unittest.cc", + "config_unittest.cc", "history_clusters_db_tasks_unittest.cc", "history_clusters_service_unittest.cc", "history_clusters_util_unittest.cc",
diff --git a/components/history_clusters/core/config.cc b/components/history_clusters/core/config.cc new file mode 100644 index 0000000..af42d9e --- /dev/null +++ b/components/history_clusters/core/config.cc
@@ -0,0 +1,66 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/history_clusters/core/config.h" + +#include "base/containers/contains.h" +#include "base/feature_list.h" +#include "base/metrics/field_trial_params.h" +#include "base/strings/string_piece_forward.h" +#include "base/strings/string_split.h" +#include "build/build_config.h" +#include "components/history_clusters/core/features.h" +#include "components/history_clusters/core/on_device_clustering_features.h" +#include "ui/base/l10n/l10n_util.h" + +namespace history_clusters { + +static Config* s_config = nullptr; + +Config::Config() = default; +Config::Config(const Config& other) = default; +Config::~Config() = default; + +// Override any parameters that may be provided by Finch. +void OverrideWithFinch(const std::string& application_locale) { + if (s_config) + return; + + s_config = new Config; + + if (!base::FeatureList::IsEnabled(internal::kJourneys)) { + s_config->is_journeys_enabled = false; + } else { + // Default to "", because defaulting it to a specific locale makes it hard + // to allow all locales, since the FeatureParam code interprets an empty + // string as undefined, and instead returns the default value. + const base::FeatureParam<std::string> kLocaleOrLanguageAllowlist{ + &internal::kJourneys, "JourneysLocaleOrLanguageAllowlist", ""}; + + // Allow comma and colon as delimiters to the language list. + auto allowlist = + base::SplitString(kLocaleOrLanguageAllowlist.Get(), + ",:", base::WhitespaceHandling::TRIM_WHITESPACE, + base::SplitResult::SPLIT_WANT_NONEMPTY); + + // Allow any exact locale matches, and also allow any users where the + // primary language subtag, e.g. "en" from "en-US" to match any element of + // the list. + s_config->is_journeys_enabled = + allowlist.empty() || base::Contains(allowlist, application_locale) || + base::Contains(allowlist, l10n_util::GetLanguage(application_locale)); + } +} + +void ResetConfigForTesting() { + s_config = nullptr; +} + +const Config& GetConfig() { + DCHECK(s_config); + + return *s_config; +} + +} // namespace history_clusters \ No newline at end of file
diff --git a/components/history_clusters/core/config.h b/components/history_clusters/core/config.h new file mode 100644 index 0000000..4ce487cb --- /dev/null +++ b/components/history_clusters/core/config.h
@@ -0,0 +1,35 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_HISTORY_CLUSTERS_CORE_CONFIG_H_ +#define COMPONENTS_HISTORY_CLUSTERS_CORE_CONFIG_H_ + +#include <string> + +namespace history_clusters { + +// The default configuration. Always use |GetConfig()| to get the current +// configuration. +struct Config { + // + bool is_journeys_enabled = false; + + Config(); + Config(const Config& other); + ~Config(); +}; + +// Gets the current configuration. OverrideWithFinch() must have been called +// before GetConfig() is called. +const Config& GetConfig(); + +// Override any parameters that may be provided by Finch. +void OverrideWithFinch(const std::string& application_locale); + +// Resets the static config object for testing. +void ResetConfigForTesting(); + +} // namespace history_clusters + +#endif // COMPONENTS_HISTORY_CLUSTERS_CORE_CONFIG_H_ \ No newline at end of file
diff --git a/components/history_clusters/core/config_unittest.cc b/components/history_clusters/core/config_unittest.cc new file mode 100644 index 0000000..f056d93 --- /dev/null +++ b/components/history_clusters/core/config_unittest.cc
@@ -0,0 +1,93 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/history_clusters/core/config.h" + +#include "base/test/scoped_feature_list.h" +#include "components/history_clusters/core/features.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace history_clusters { + +TEST(HistoryClustersConfigTest, PlainEnabled) { + const struct { + const std::string locale; + bool expected_is_journeys_enabled; + } kLocaleTestCases[] = {{"", false}, + {"en", false}, + {"fr", false}, + {"zh-TW", false}, + {" random junk ", false}}; + + for (const auto& test : kLocaleTestCases) { + ResetConfigForTesting(); + OverrideWithFinch(test.locale); + + EXPECT_EQ(test.expected_is_journeys_enabled, + GetConfig().is_journeys_enabled) + << test.locale; + } +} + +TEST(HistoryClustersConfigTest, OmniboxAction) { + base::test::ScopedFeatureList features; + features.InitWithFeatures({internal::kJourneys, kOmniboxAction}, {}); + + const struct { + const std::string locale; + bool expected_is_journeys_enabled; + } kLocaleTestCases[] = {{"", true}, + {"en", true}, + {"fr", true}, + {"zh-TW", true}, + {" random junk ", true}}; + + for (const auto& test : kLocaleTestCases) { + ResetConfigForTesting(); + OverrideWithFinch(test.locale); + + EXPECT_EQ(test.expected_is_journeys_enabled, + GetConfig().is_journeys_enabled) + << test.locale; + } +} + +TEST(HistoryClustersConfigTest, LocaleOrLanguageAllowlist) { + base::test::ScopedFeatureList features; + features.InitWithFeaturesAndParameters( + {{ + internal::kJourneys, + // Test that we're tolerant of spaces, colons, whole locales, as well + // as primary language subcodes. + {{"JourneysLocaleOrLanguageAllowlist", "en, fr:de:zh-TW"}}, + }, + {kOmniboxAction, {}}}, + {}); + + const struct { + const std::string locale; + bool expected_is_journeys_enabled; + } kLocaleTestCases[] = {{"", false}, + {"en", true}, + {"en-US", true}, + {"fr", true}, + {" random junk ", false}, + {"de", true}, + {"el", false}, + {"zh-TW", true}, + {"zh", false}, + {"zh-CN", false}}; + + for (const auto& test : kLocaleTestCases) { + ResetConfigForTesting(); + + OverrideWithFinch(test.locale); + + EXPECT_EQ(test.expected_is_journeys_enabled, + GetConfig().is_journeys_enabled) + << test.locale; + } +} + +} // namespace history_clusters
diff --git a/components/history_clusters/core/features.cc b/components/history_clusters/core/features.cc index c234463..8395829 100644 --- a/components/history_clusters/core/features.cc +++ b/components/history_clusters/core/features.cc
@@ -25,30 +25,6 @@ } // namespace -bool IsJourneysEnabled(const std::string& locale) { - if (!base::FeatureList::IsEnabled(internal::kJourneys)) - return false; - - // Allow comma and colon as delimiters to the language list. - auto allowlist = - base::SplitString(kLocaleOrLanguageAllowlist.Get(), - ",:", base::WhitespaceHandling::TRIM_WHITESPACE, - base::SplitResult::SPLIT_WANT_NONEMPTY); - if (allowlist.empty()) - return true; - - // Allow any exact locale matches, and also allow any users where the primary - // language subtag, e.g. "en" from "en-US" to match any element of the list. - return base::Contains(allowlist, locale) || - base::Contains(allowlist, l10n_util::GetLanguage(locale)); -} - -// Default to "", because defaulting it to a specific locale makes it hard to -// allow all locales, since the FeatureParam code interprets an empty string as -// undefined, and instead returns the default value. -const base::FeatureParam<std::string> kLocaleOrLanguageAllowlist{ - &internal::kJourneys, "JourneysLocaleOrLanguageAllowlist", ""}; - const base::FeatureParam<int> kMaxVisitsToCluster{ &internal::kJourneys, "JourneysMaxVisitsToCluster", 1000};
diff --git a/components/history_clusters/core/features.h b/components/history_clusters/core/features.h index 827f4aea..f1fd5453 100644 --- a/components/history_clusters/core/features.h +++ b/components/history_clusters/core/features.h
@@ -13,23 +13,6 @@ // Params & helpers functions -// Returns true if Journeys in the Chrome History WebUI is enabled. -// Callers with access to `HistoryClustersService` should use -// `HistoryClustersService::IsJourneysEnabled` which has precomputed this value -// with the g_browser_process locale. Renderer process callers will have to -// use this function directly. -bool IsJourneysEnabled(const std::string& application_locale); - -// A comma (or colon) separated list of allowed locales and languages for which -// Journeys is enabled. If this string is empty, any application locale or -// language is allowed. If this string is non-empty, then the either the user's -// system locale or primary language subtag must match one of the elements for -// Journeys to be enabled. -// -// For example, "en,zh-TW" would mark English language users from any country, -// and Chinese language users from Taiwan as on the allowlist. -extern const base::FeatureParam<std::string> kLocaleOrLanguageAllowlist; - // The max number of visits to use for each clustering iteration. This limits // the number of visits sent to the clustering backend per batch. extern const base::FeatureParam<int> kMaxVisitsToCluster;
diff --git a/components/history_clusters/core/features_unittest.cc b/components/history_clusters/core/features_unittest.cc deleted file mode 100644 index 663e69aa..0000000 --- a/components/history_clusters/core/features_unittest.cc +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/history_clusters/core/features.h" - -#include "base/test/scoped_feature_list.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace history_clusters { - -TEST(HistoryClustersFeaturesTest, PlainEnabled) { - EXPECT_FALSE(IsJourneysEnabled("")); - EXPECT_FALSE(IsJourneysEnabled("en")); - EXPECT_FALSE(IsJourneysEnabled("fr")); - EXPECT_FALSE(IsJourneysEnabled("zh-TW")); - EXPECT_FALSE(IsJourneysEnabled(" random junk ")); - - base::test::ScopedFeatureList features; - features.InitWithFeatures({internal::kJourneys, kOmniboxAction}, {}); - - EXPECT_TRUE(IsJourneysEnabled("")); - EXPECT_TRUE(IsJourneysEnabled("en")); - EXPECT_TRUE(IsJourneysEnabled("fr")); - EXPECT_TRUE(IsJourneysEnabled("zh-TW")); - EXPECT_TRUE(IsJourneysEnabled(" random junk ")); -} - -TEST(HistoryClustersFeaturesTest, LocaleOrLanguageAllowlist) { - base::test::ScopedFeatureList features; - features.InitWithFeaturesAndParameters( - {{ - internal::kJourneys, - // Test that we're tolerant of spaces, colons, whole locales, as well - // as primary language subcodes. - {{"JourneysLocaleOrLanguageAllowlist", "en, fr:de:zh-TW"}}, - }, - {kOmniboxAction, {}}}, - {}); - - EXPECT_FALSE(IsJourneysEnabled("")); - EXPECT_TRUE(IsJourneysEnabled("en")); - EXPECT_TRUE(IsJourneysEnabled("en-US")); - EXPECT_TRUE(IsJourneysEnabled("fr")); - EXPECT_FALSE(IsJourneysEnabled(" random junk ")); - EXPECT_TRUE(IsJourneysEnabled("de")); - EXPECT_FALSE(IsJourneysEnabled("el")); - EXPECT_TRUE(IsJourneysEnabled("zh-TW")); - EXPECT_FALSE(IsJourneysEnabled("zh")); - EXPECT_FALSE(IsJourneysEnabled("zh-CN")); -} - -} // namespace history_clusters
diff --git a/components/history_clusters/core/history_clusters_service.cc b/components/history_clusters/core/history_clusters_service.cc index 2ac8254..5c07328 100644 --- a/components/history_clusters/core/history_clusters_service.cc +++ b/components/history_clusters/core/history_clusters_service.cc
@@ -30,6 +30,7 @@ #include "components/history/core/browser/history_database.h" #include "components/history/core/browser/history_db_task.h" #include "components/history/core/browser/history_types.h" +#include "components/history_clusters/core/config.h" #include "components/history_clusters/core/features.h" #include "components/history_clusters/core/history_clusters_buildflags.h" #include "components/history_clusters/core/history_clusters_db_tasks.h" @@ -190,10 +191,9 @@ optimization_guide::EntityMetadataProvider* entity_metadata_provider, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, site_engagement::SiteEngagementScoreProvider* engagement_score_provider) - : is_journeys_enabled_( - ::history_clusters::IsJourneysEnabled(application_locale)), - history_service_(history_service), - visit_deletion_observer_(this) { + : history_service_(history_service), visit_deletion_observer_(this) { + InitializeConfig(application_locale); + DCHECK(history_service_); visit_deletion_observer_.AttachToHistoryService(history_service); @@ -207,12 +207,22 @@ HistoryClustersService::~HistoryClustersService() = default; +// static +void HistoryClustersService::InitializeConfig( + const std::string& application_locale) { + OverrideWithFinch(application_locale); +} + base::WeakPtr<HistoryClustersService> HistoryClustersService::GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } void HistoryClustersService::Shutdown() {} +bool HistoryClustersService::IsJourneysEnabled() const { + return GetConfig().is_journeys_enabled; +} + void HistoryClustersService::AddObserver(Observer* obs) { observers_.AddObserver(obs); }
diff --git a/components/history_clusters/core/history_clusters_service.h b/components/history_clusters/core/history_clusters_service.h index f502362..6c079184 100644 --- a/components/history_clusters/core/history_clusters_service.h +++ b/components/history_clusters/core/history_clusters_service.h
@@ -104,7 +104,7 @@ // Returns true if the Journeys feature is enabled for the current application // locale. This is a cached wrapper of `IsJourneysEnabled()` within features.h // that's already evaluated against the g_browser_process application locale. - bool IsJourneysEnabled() const { return is_journeys_enabled_; } + bool IsJourneysEnabled() const; // Used to add and remove observers. void AddObserver(Observer* obs); @@ -174,6 +174,10 @@ // Clears `all_keywords_cache_` and cancels any pending tasks to populate it. void ClearKeywordCache(); + // Initializes the history cluster config object if it has not been already + // initialized. + static void InitializeConfig(const std::string& application_locale); + private: friend class HistoryClustersServiceTestApi; @@ -202,9 +206,6 @@ QueryClustersCallback callback, std::vector<history::Cluster> clusters) const; - // True if the Journeys feature is enabled for the application locale. - const bool is_journeys_enabled_; - // Non-owning pointer, but never nullptr. history::HistoryService* const history_service_;
diff --git a/components/messages/android/messages_feature.cc b/components/messages/android/messages_feature.cc index 081cee51..ede8673 100644 --- a/components/messages/android/messages_feature.cc +++ b/components/messages/android/messages_feature.cc
@@ -35,7 +35,7 @@ "save_password_message_dismiss_duration_ms", 0}; const base::Feature kMessagesForAndroidPermissionUpdate{ - "MessagesForAndroidPermissionUpdate", base::FEATURE_DISABLED_BY_DEFAULT}; + "MessagesForAndroidPermissionUpdate", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kMessagesForAndroidPopupBlocked{ "MessagesForAndroidPopupBlocked", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/components/safe_browsing/content/browser/client_side_detection_host.cc b/components/safe_browsing/content/browser/client_side_detection_host.cc index 5cfb4e65..49a84af 100644 --- a/components/safe_browsing/content/browser/client_side_detection_host.cc +++ b/components/safe_browsing/content/browser/client_side_detection_host.cc
@@ -422,6 +422,9 @@ } current_url_ = navigation_handle->GetURL(); + current_outermost_main_frame_id_ = navigation_handle->GetRenderFrameHost() + ->GetOutermostMainFrame() + ->GetGlobalId(); // Check whether we can cassify the current URL for phishing. classification_request_ = new ShouldClassifyUrlRequest( @@ -554,7 +557,8 @@ if (IsEnhancedProtectionEnabled(*delegate_->GetPrefs()) && base::FeatureList::IsEnabled(kClientSideDetectionReferrerChain)) { - delegate_->AddReferrerChain(verdict.get(), current_url_); + delegate_->AddReferrerChain(verdict.get(), current_url_, + current_outermost_main_frame_id_); } base::UmaHistogramBoolean("SBClientPhishing.LocalModelDetectsPhishing",
diff --git a/components/safe_browsing/content/browser/client_side_detection_host.h b/components/safe_browsing/content/browser/client_side_detection_host.h index 6fbe46f..f3190bcf 100644 --- a/components/safe_browsing/content/browser/client_side_detection_host.h +++ b/components/safe_browsing/content/browser/client_side_detection_host.h
@@ -20,6 +20,7 @@ #include "components/safe_browsing/core/browser/db/database_manager.h" #include "components/safe_browsing/core/browser/safe_browsing_token_fetcher.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" +#include "content/public/browser/global_routing_id.h" #include "content/public/browser/web_contents_observer.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/service_manager/public/cpp/binder_registry.h" @@ -29,6 +30,10 @@ class TickClock; } +namespace content { +struct GlobalRenderFrameHostId; +} + namespace safe_browsing { class ClientPhishingRequest; class ClientSideDetectionService; @@ -58,7 +63,9 @@ virtual scoped_refptr<BaseUIManager> GetSafeBrowsingUIManager() = 0; virtual ClientSideDetectionService* GetClientSideDetectionService() = 0; virtual void AddReferrerChain(ClientPhishingRequest* verdict, - GURL current_url) = 0; + GURL current_url, + const content::GlobalRenderFrameHostId& + current_outermost_main_frame_id) = 0; }; // The caller keeps ownership of the tab object and is responsible for @@ -196,6 +203,8 @@ scoped_refptr<ShouldClassifyUrlRequest> classification_request_; // The current URL GURL current_url_; + // The current outermost main frame's id. + content::GlobalRenderFrameHostId current_outermost_main_frame_id_; // A map from the live RenderFrameHosts to their PhishingDetector. These // correspond to the `phishing_detector_receiver_` in the // PhishingClassifierDelegate.
diff --git a/components/safe_browsing/content/browser/safe_browsing_navigation_observer.cc b/components/safe_browsing/content/browser/safe_browsing_navigation_observer.cc index f01b6ca..422a2e7 100644 --- a/components/safe_browsing/content/browser/safe_browsing_navigation_observer.cc +++ b/components/safe_browsing/content/browser/safe_browsing_navigation_observer.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "base/metrics/histogram_functions.h" #include "base/time/time.h" #include "components/page_info/page_info_ui.h" #include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h" @@ -30,47 +31,19 @@ // SafeBrowsingNavigationObserver::NavigationEvent----------------------------- NavigationEvent::NavigationEvent() - : source_url(), - source_main_frame_url(), - original_request_url(), - source_tab_id(SessionID::InvalidValue()), + : source_tab_id(SessionID::InvalidValue()), target_tab_id(SessionID::InvalidValue()), last_updated(base::Time::Now()), navigation_initiation(ReferrerChainEntry::UNDEFINED), has_committed(false), maybe_launched_by_external_application() {} -NavigationEvent::NavigationEvent(NavigationEvent&& nav_event) - : source_url(std::move(nav_event.source_url)), - source_main_frame_url(std::move(nav_event.source_main_frame_url)), - original_request_url(std::move(nav_event.original_request_url)), - server_redirect_urls(std::move(nav_event.server_redirect_urls)), - source_tab_id(std::move(nav_event.source_tab_id)), - target_tab_id(std::move(nav_event.target_tab_id)), - last_updated(nav_event.last_updated), - navigation_initiation(nav_event.navigation_initiation), - has_committed(nav_event.has_committed), - maybe_launched_by_external_application( - nav_event.maybe_launched_by_external_application) {} - +NavigationEvent::NavigationEvent(NavigationEvent&& nav_event) = default; NavigationEvent::NavigationEvent(const NavigationEvent& nav_event) = default; +NavigationEvent& NavigationEvent::operator=(NavigationEvent&& nav_event) = + default; -NavigationEvent& NavigationEvent::operator=(NavigationEvent&& nav_event) { - source_url = std::move(nav_event.source_url); - source_main_frame_url = std::move(nav_event.source_main_frame_url); - original_request_url = std::move(nav_event.original_request_url); - source_tab_id = nav_event.source_tab_id; - target_tab_id = nav_event.target_tab_id; - last_updated = nav_event.last_updated; - navigation_initiation = nav_event.navigation_initiation; - has_committed = nav_event.has_committed; - maybe_launched_by_external_application = - nav_event.maybe_launched_by_external_application; - server_redirect_urls = std::move(nav_event.server_redirect_urls); - return *this; -} - -NavigationEvent::~NavigationEvent() {} +NavigationEvent::~NavigationEvent() = default; // SafeBrowsingNavigationObserver -------------------------------------------- @@ -109,7 +82,7 @@ content_settings_observation_.Observe(host_content_settings_map); } -SafeBrowsingNavigationObserver::~SafeBrowsingNavigationObserver() {} +SafeBrowsingNavigationObserver::~SafeBrowsingNavigationObserver() = default; void SafeBrowsingNavigationObserver::OnUserInteraction() { GetObserverManager()->RecordUserGestureForWebContents(web_contents()); @@ -151,6 +124,7 @@ nav_event->source_tab_id = sessions::SessionTabHelper::IdForTab(navigation_handle->GetWebContents()); SetNavigationSourceMainFrameUrl(navigation_handle, nav_event.get()); + SetNavigationOutermostMainFrameIds(navigation_handle, nav_event.get()); std::unique_ptr<NavigationEvent> pending_nav_event = std::make_unique<NavigationEvent>(*nav_event); @@ -203,6 +177,25 @@ nav_event->has_committed = navigation_handle->HasCommitted(); nav_event->target_tab_id = sessions::SessionTabHelper::IdForTab(navigation_handle->GetWebContents()); + + // TODO(crbug.com/1254770) Non-MPArch portals cause issues for the outermost + // main frame logic. Since they do not create navigation events for + // activation, there is a an unaccounted-for shift in outermost main frame at + // that point. For now, we will not set outermost main frame ids for portals + // so they will continue to match. In future, once portals have been converted + // to MPArch, this will not be necessary. + if (!web_contents()->IsPortal() && nav_event->is_outermost_main_frame && + nav_event->has_committed) { + auto* rfh = navigation_handle->GetRenderFrameHost(); + // We set the outermost main frame id here rather than in DidStartNavigation + // because in that function, we don't yet have a RenderFrameHost, so if + // we're the outermost main frame, we won't yet have an id. + nav_event->outermost_main_frame_id = + rfh->GetOutermostMainFrame()->GetGlobalId(); + } + DCHECK(web_contents()->IsPortal() || !nav_event->has_committed || + nav_event->outermost_main_frame_id); + nav_event->last_updated = base::Time::Now(); GetObserverManager()->RecordNavigationEvent( @@ -264,6 +257,11 @@ navigation_handle->GetInitiatorProcessID(), navigation_handle->GetInitiatorFrameToken().value()) : nullptr; + + base::UmaHistogramBoolean( + "SafeBrowsing.NavigationObserver.MissingInitiatorRenderFrameHostPortal", + !initiator_frame_host); + // TODO(https://crbug.com/1074422): Handle the case where the initiator // RenderFrameHost is gone. if (initiator_frame_host) { @@ -307,19 +305,38 @@ void SafeBrowsingNavigationObserver::SetNavigationSourceUrl( content::NavigationHandle* navigation_handle, NavigationEvent* nav_event) { - // If there was a URL previously committed in the current RenderFrameHost, - // set it as the source url of this navigation. Otherwise, this is the - // first url going to commit in this frame. - content::RenderFrameHost* current_frame_host = - content::RenderFrameHost::FromID( - navigation_handle->GetPreviousRenderFrameHostId()); // For browser initiated navigation (e.g. from address bar or bookmark), we // don't fill the source_url to prevent attributing navigation to the last // committed navigation. - if (navigation_handle->IsRendererInitiated() && current_frame_host && - current_frame_host->GetLastCommittedURL().is_valid()) { + if (!navigation_handle->IsRendererInitiated()) + return; + + if (navigation_handle->IsInPrerenderedMainFrame()) { + // A prerendered page can only be initiated by the primary page, so we will + // grab the last committed URL from the primary main frame directly. Note + // that this cannot be obtained from the previous RFH since this is empty + // for prerenders. While this differs from the semantics for source_url + // (which is indeed related to the last committed URL in the frame into + // which we are navigating), it matches what source_url would have been had + // we been navigating normally since we will activate in the primary main + // frame. nav_event->source_url = SafeBrowsingNavigationObserverManager::ClearURLRef( - current_frame_host->GetLastCommittedURL()); + navigation_handle->GetWebContents() + ->GetMainFrame() + ->GetLastCommittedURL()); + } else { + // If there was a URL previously committed in the current RenderFrameHost, + // set it as the source url of this navigation. Otherwise, this is the + // first url going to commit in this frame. + content::RenderFrameHost* current_frame_host = + content::RenderFrameHost::FromID( + navigation_handle->GetPreviousRenderFrameHostId()); + if (current_frame_host && + current_frame_host->GetLastCommittedURL().is_valid()) { + nav_event->source_url = + SafeBrowsingNavigationObserverManager::ClearURLRef( + current_frame_host->GetLastCommittedURL()); + } } } @@ -337,6 +354,40 @@ } } +void SafeBrowsingNavigationObserver::SetNavigationOutermostMainFrameIds( + content::NavigationHandle* navigation_handle, + NavigationEvent* nav_event) { + // TODO(crbug.com/1254770) Non-MPArch portals cause issues for the outermost + // main frame logic. Since they do not create navigation events for + // activation, there is a an unaccounted-for shift in outermost main frame at + // that point. For now, we will not set outermost main frame ids for portals + // so they will continue to match. In future, once portals have been converted + // to MPArch, this will not be necessary. + if (web_contents()->IsPortal()) + return; + + auto* outer_rfh = navigation_handle->GetParentFrameOrOuterDocument(); + nav_event->is_outermost_main_frame = !outer_rfh; + + if (outer_rfh) { + nav_event->outermost_main_frame_id = + outer_rfh->GetOutermostMainFrame()->GetGlobalId(); + } + + if (navigation_handle->IsRendererInitiated()) { + auto* initiator_frame_host = + navigation_handle->GetInitiatorFrameToken().has_value() + ? content::RenderFrameHost::FromFrameToken( + navigation_handle->GetInitiatorProcessID(), + navigation_handle->GetInitiatorFrameToken().value()) + : nullptr; + if (initiator_frame_host) { + nav_event->initiator_outermost_main_frame_id = + initiator_frame_host->GetOutermostMainFrame()->GetGlobalId(); + } + } +} + SafeBrowsingNavigationObserverManager* SafeBrowsingNavigationObserver::GetObserverManager() { return observer_manager_;
diff --git a/components/safe_browsing/content/browser/safe_browsing_navigation_observer.h b/components/safe_browsing/content/browser/safe_browsing_navigation_observer.h index 0a3a2662..24c3782 100644 --- a/components/safe_browsing/content/browser/safe_browsing_navigation_observer.h +++ b/components/safe_browsing/content/browser/safe_browsing_navigation_observer.h
@@ -16,6 +16,7 @@ #include "components/content_settings/core/common/content_settings.h" #include "components/safe_browsing/core/common/proto/csd.pb.h" #include "components/sessions/core/session_id.h" +#include "content/public/browser/global_routing_id.h" #include "content/public/browser/web_contents_observer.h" #include "url/gurl.h" @@ -58,6 +59,21 @@ // Which tab this request url is targeting to. SessionID target_tab_id; + // RFH ID of the outermost main frame of the frame which initiated this + // navigation. This can only differ from outermost_main_frame_id if + // |is_outermost_main_frame| is true, however differing values does not imply + // that we're in the outermost main frame (we could be navigating within the + // current RFH). + content::GlobalRenderFrameHostId initiator_outermost_main_frame_id; + + // RFH ID of the outermost main frame of the frame where this navigation takes + // place. If this navigation is occurring in the outermost main frame, then + // this is not known until commit. + content::GlobalRenderFrameHostId outermost_main_frame_id; + + // Whether this navigation is happening in the outermost main frame. + bool is_outermost_main_frame = false; + // When this NavigationEvent was last updated. base::Time last_updated; @@ -174,6 +190,9 @@ void SetNavigationSourceMainFrameUrl( content::NavigationHandle* navigation_handle, NavigationEvent* nav_event); + void SetNavigationOutermostMainFrameIds( + content::NavigationHandle* navigation_handle, + NavigationEvent* nav_event); // Map keyed on NavigationHandle* to keep track of all the ongoing // navigation events. NavigationHandle pointers are owned by
diff --git a/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.cc b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.cc index f864e1ad..a44ffb8 100644 --- a/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.cc +++ b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.cc
@@ -23,6 +23,7 @@ #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/safe_browsing/core/common/utils.h" #include "components/sessions/content/session_tab_helper.h" +#include "content/public/browser/global_routing_id.h" #include "content/public/browser/navigation_details.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" @@ -123,19 +124,20 @@ DCHECK_GT(size_limit_, 0U); } -NavigationEventList::~NavigationEventList() {} +NavigationEventList::~NavigationEventList() = default; -size_t NavigationEventList::FindNavigationEvent( +absl::optional<size_t> NavigationEventList::FindNavigationEvent( const base::Time& last_event_timestamp, const GURL& target_url, const GURL& target_main_frame_url, SessionID target_tab_id, + const content::GlobalRenderFrameHostId& outermost_main_frame_id, size_t start_index) { if (target_url.is_empty() && target_main_frame_url.is_empty()) - return -1; + return absl::nullopt; if (navigation_events_.size() == 0) - return -1; + return absl::nullopt; // If target_url is empty, we should back trace navigation based on its // main frame URL instead. @@ -150,10 +152,24 @@ continue; } - // If tab id is not valid, we only compare url, otherwise we compare both. - if (nav_event->GetDestinationUrl() == search_url && - (!target_tab_id.is_valid() || - nav_event->target_tab_id == target_tab_id)) { + const bool valid_tab_id = + !target_tab_id.is_valid() || nav_event->target_tab_id == target_tab_id; + + const bool potentially_valid_outermost_main_frame_id = + !outermost_main_frame_id || !nav_event->outermost_main_frame_id || + nav_event->is_outermost_main_frame || + nav_event->outermost_main_frame_id == outermost_main_frame_id; + + const bool valid_outermost_main_frame_id = + !outermost_main_frame_id || + nav_event->outermost_main_frame_id == outermost_main_frame_id; + + // If tab id is valid, we require it match the nav event (similar for frame + // tree node id). In all cases, we require that the URLs match. + if (nav_event->GetDestinationUrl() == search_url && valid_tab_id && + potentially_valid_outermost_main_frame_id) { + size_t result_index = current_index; + // If both source_url and source_main_frame_url are empty, we should check // if a retargeting navigation caused this navigation. In this case, we // skip this navigation event and looks for the retargeting navigation @@ -162,28 +178,44 @@ nav_event->source_main_frame_url.is_empty()) { size_t retargeting_nav_event_index = FindRetargetingNavigationEvent( nav_event->last_updated, nav_event->target_tab_id, start_index); - if (static_cast<int>(retargeting_nav_event_index) == -1) - return current_index; - // If there is a server redirection immediately after retargeting, we - // need to adjust our search url to the original request. - auto* retargeting_nav_event = - GetNavigationEvent(retargeting_nav_event_index); - if (!nav_event->server_redirect_urls.empty()) { - // Adjust retargeting navigation event's attributes. - retargeting_nav_event->server_redirect_urls.push_back( - std::move(search_url)); - } else { - // The retargeting_nav_event original request url is unreliable, since - // that navigation can be canceled. - retargeting_nav_event->original_request_url = std::move(search_url); + if (static_cast<int>(retargeting_nav_event_index) != -1) { + // If there is a server redirection immediately after retargeting, we + // need to adjust our search url to the original request. + auto* retargeting_nav_event = + GetNavigationEvent(retargeting_nav_event_index); + if (!nav_event->server_redirect_urls.empty()) { + // Adjust retargeting navigation event's attributes. + retargeting_nav_event->server_redirect_urls.push_back( + std::move(search_url)); + } else { + // The retargeting_nav_event original request url is unreliable, + // since that navigation can be canceled. + retargeting_nav_event->original_request_url = std::move(search_url); + } + result_index = retargeting_nav_event_index; } - return retargeting_nav_event_index; - } else { - return current_index; } + + // We didn't have a strict main frame id match, so we will look for a + // better match first. + if (!valid_outermost_main_frame_id && current_index > 0) { + auto alternate_index = FindNavigationEvent( + last_event_timestamp, target_url, target_main_frame_url, + target_tab_id, outermost_main_frame_id, current_index - 1); + if (alternate_index) { + auto* alternate_event = GetNavigationEvent(*alternate_index); + // Found a strict match. + if (alternate_event->outermost_main_frame_id == + outermost_main_frame_id) { + result_index = *alternate_index; + } + } + } + + return result_index; } } - return -1; + return absl::nullopt; } NavigationEvent* NavigationEventList::FindPendingNavigationEvent( @@ -295,7 +327,7 @@ // static GURL SafeBrowsingNavigationObserverManager::ClearURLRef(const GURL& url) { if (url.has_ref()) { - url::Replacements<char> replacements; + GURL::Replacements replacements; replacements.ClearRef(); return url.ReplaceComponents(replacements); } @@ -444,6 +476,7 @@ SafeBrowsingNavigationObserverManager::IdentifyReferrerChainByEventURL( const GURL& event_url, SessionID event_tab_id, + const content::GlobalRenderFrameHostId& outermost_main_frame_id, int user_gesture_count_limit, ReferrerChain* out_referrer_chain) { SCOPED_UMA_HISTOGRAM_TIMER( @@ -451,20 +484,21 @@ if (!event_url.is_valid()) return INVALID_URL; - size_t nav_event_index = navigation_event_list_.FindNavigationEvent( + auto nav_event_index = navigation_event_list_.FindNavigationEvent( base::Time::Now(), ClearURLRef(event_url), GURL(), event_tab_id, + outermost_main_frame_id, navigation_event_list_.NavigationEventsSize() - 1); - if (static_cast<int>(nav_event_index) == -1) { + if (!nav_event_index) { // We cannot find a single navigation event related to this event. return NAVIGATION_EVENT_NOT_FOUND; } - auto* nav_event = navigation_event_list_.GetNavigationEvent(nav_event_index); + auto* nav_event = navigation_event_list_.GetNavigationEvent(*nav_event_index); AttributionResult result = SUCCESS; AddToReferrerChain(out_referrer_chain, nav_event, GURL(), ReferrerChainEntry::EVENT_URL); int user_gesture_count = 0; - GetRemainingReferrerChain(nav_event_index, user_gesture_count, + GetRemainingReferrerChain(*nav_event_index, user_gesture_count, user_gesture_count_limit, out_referrer_chain, &result); bool omit_non_user_gestures_is_enabled = base::FeatureList::IsEnabled( @@ -525,28 +559,33 @@ } SafeBrowsingNavigationObserverManager::AttributionResult -SafeBrowsingNavigationObserverManager::IdentifyReferrerChainByWebContents( - content::WebContents* web_contents, +SafeBrowsingNavigationObserverManager::IdentifyReferrerChainByRenderFrameHost( + content::RenderFrameHost* render_frame_host, int user_gesture_count_limit, ReferrerChain* out_referrer_chain) { SCOPED_UMA_HISTOGRAM_TIMER( - "SafeBrowsing.NavigationObserver.IdentifyReferrerChainByWebContentsTime"); - if (!web_contents) + "SafeBrowsing.NavigationObserver." + "IdentifyReferrerChainByRenderFrameHostTime"); + if (!render_frame_host) return INVALID_URL; - GURL last_committed_url = web_contents->GetLastCommittedURL(); + GURL last_committed_url = render_frame_host->GetLastCommittedURL(); if (!last_committed_url.is_valid()) return INVALID_URL; + content::WebContents* web_contents = + content::WebContents::FromRenderFrameHost(render_frame_host); bool has_user_gesture = HasUserGesture(web_contents); SessionID tab_id = sessions::SessionTabHelper::IdForTab(web_contents); return IdentifyReferrerChainByHostingPage( - ClearURLRef(last_committed_url), GURL(), tab_id, has_user_gesture, - user_gesture_count_limit, out_referrer_chain); + ClearURLRef(last_committed_url), GURL(), + render_frame_host->GetOutermostMainFrame()->GetGlobalId(), tab_id, + has_user_gesture, user_gesture_count_limit, out_referrer_chain); } SafeBrowsingNavigationObserverManager::AttributionResult SafeBrowsingNavigationObserverManager::IdentifyReferrerChainByHostingPage( const GURL& initiating_frame_url, const GURL& initiating_main_frame_url, + const content::GlobalRenderFrameHostId& initiating_outermost_main_frame_id, SessionID tab_id, bool has_user_gesture, int user_gesture_count_limit, @@ -554,16 +593,22 @@ if (!initiating_frame_url.is_valid()) return INVALID_URL; - int nav_event_index = navigation_event_list_.FindNavigationEvent( + auto* rfh = + content::RenderFrameHost::FromID(initiating_outermost_main_frame_id); + DCHECK(!initiating_outermost_main_frame_id || + (rfh && rfh->GetOutermostMainFrame() == rfh)); + + auto nav_event_index = navigation_event_list_.FindNavigationEvent( base::Time::Now(), ClearURLRef(initiating_frame_url), ClearURLRef(initiating_main_frame_url), tab_id, + initiating_outermost_main_frame_id, navigation_event_list_.NavigationEventsSize() - 1); - if (static_cast<int>(nav_event_index) == -1) { + if (!nav_event_index) { // We cannot find a single navigation event related to this hosting page. return NAVIGATION_EVENT_NOT_FOUND; } - auto* nav_event = navigation_event_list_.GetNavigationEvent(nav_event_index); + auto* nav_event = navigation_event_list_.GetNavigationEvent(*nav_event_index); AttributionResult result = SUCCESS; @@ -580,7 +625,7 @@ ReferrerChainEntry::CLIENT_REDIRECT); } - GetRemainingReferrerChain(nav_event_index, user_gesture_count, + GetRemainingReferrerChain(*nav_event_index, user_gesture_count, user_gesture_count_limit, out_referrer_chain, &result); @@ -629,6 +674,23 @@ source_render_frame_host->GetOutermostMainFrame() ->GetLastCommittedURL()); } + + // TODO(crbug.com/1254770) Non-MPArch portals cause issues for the outermost + // main frame logic. Since they do not create navigation events for + // activation, there is a an unaccounted-for shift in outermost main frame at + // that point. For now, we will not set outermost main frame ids for portals + // so they will continue to match. In future, once portals have been converted + // to MPArch, this will not be necessary. + if (!target_web_contents->IsPortal()) { + if (source_render_frame_host) { + nav_event->initiator_outermost_main_frame_id = + source_render_frame_host->GetOutermostMainFrame()->GetGlobalId(); + } + nav_event->outermost_main_frame_id = target_web_contents->GetMainFrame() + ->GetOutermostMainFrame() + ->GetGlobalId(); + } + nav_event->source_tab_id = sessions::SessionTabHelper::IdForTab(source_web_contents); nav_event->original_request_url = cleaned_target_url; @@ -852,14 +914,17 @@ while (current_user_gesture_count < user_gesture_count_limit) { // Back trace to the next nav_event that was initiated by the user. while (!last_nav_event_traced->IsUserInitiated()) { - last_nav_event_traced_index = navigation_event_list_.FindNavigationEvent( + auto nav_event_index = navigation_event_list_.FindNavigationEvent( last_nav_event_traced->last_updated, last_nav_event_traced->source_url, last_nav_event_traced->source_main_frame_url, last_nav_event_traced->source_tab_id, + last_nav_event_traced->initiator_outermost_main_frame_id, last_nav_event_traced_index - 1); - if (static_cast<int>(last_nav_event_traced_index) == -1) + if (!nav_event_index) return; + + last_nav_event_traced_index = *nav_event_index; last_nav_event_traced = navigation_event_list_.GetNavigationEvent( last_nav_event_traced_index); AddToReferrerChain(out_referrer_chain, last_nav_event_traced, @@ -876,13 +941,16 @@ current_user_gesture_count++; - last_nav_event_traced_index = navigation_event_list_.FindNavigationEvent( + auto nav_event_index = navigation_event_list_.FindNavigationEvent( last_nav_event_traced->last_updated, last_nav_event_traced->source_url, last_nav_event_traced->source_main_frame_url, - last_nav_event_traced->source_tab_id, last_nav_event_traced_index - 1); - if (static_cast<int>(last_nav_event_traced_index) == -1) + last_nav_event_traced->source_tab_id, + last_nav_event_traced->initiator_outermost_main_frame_id, + last_nav_event_traced_index - 1); + if (!nav_event_index) return; + last_nav_event_traced_index = *nav_event_index; last_nav_event_traced = navigation_event_list_.GetNavigationEvent(last_nav_event_traced_index); AddToReferrerChain(out_referrer_chain, last_nav_event_traced,
diff --git a/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h index 7c66e59..05679df 100644 --- a/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h +++ b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h
@@ -17,6 +17,7 @@ #include "components/safe_browsing/core/common/proto/csd.pb.h" #include "components/sessions/core/session_id.h" #include "content/public/browser/web_contents_observer.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/protobuf/src/google/protobuf/repeated_field.h" #include "url/gurl.h" @@ -24,6 +25,7 @@ namespace content { class NavigationHandle; +struct GlobalRenderFrameHostId; } namespace safe_browsing { @@ -70,7 +72,7 @@ // Finds the index of the most recent navigation event that navigated to // |target_url| and its associated |target_main_frame_url| in the tab with - // ID |target_tab_id|. Returns -1 if event is not found. + // ID |target_tab_id|. Returns an empty optional if event is not found. // If navigation happened in the main frame, |target_url| and // |target_main_frame_url| are the same. // If |target_url| is empty, we use its main frame url (a.k.a. @@ -90,12 +92,22 @@ // In this case, FindNavigationEvent() will think url2 in Window B is the // referrer of about::blank in Window C since this navigation is more recent. // However, it does not prevent us to attribute url1 in Window A as the cause - // of all these navigations. Returns -1 if an event is not found. - size_t FindNavigationEvent(const base::Time& last_event_timestamp, - const GURL& target_url, - const GURL& target_main_frame_url, - SessionID target_tab_id, - size_t start_index); + // of all these navigations. Returns an empty optional if an event is not + // found. + // + // If an |outermost_main_frame_id| is supplied, the function attempts to find + // a navigation event per the logic described above with the additional + // constraint that the |outermost_main_frame_id| match. If there is no such + // event, it will return the first main frame event that matches the other + // criteria. And if there is still no matching event, the function will return + // an empty optional. + absl::optional<size_t> FindNavigationEvent( + const base::Time& last_event_timestamp, + const GURL& target_url, + const GURL& target_main_frame_url, + SessionID target_tab_id, + const content::GlobalRenderFrameHostId& outermost_main_frame_id, + size_t start_index); // Finds the the navigation event in the |pending_navigation_events_| map that // has the same destination URL as the |target_url|. If there are multiple @@ -222,6 +234,8 @@ AttributionResult IdentifyReferrerChainByEventURL( const GURL& event_url, SessionID event_tab_id, // Invalid if tab id is unknown or not available. + const content::GlobalRenderFrameHostId& + event_outermost_main_frame_id, // Can also be Invalid. int user_gesture_count_limit, ReferrerChain* out_referrer_chain) override; @@ -239,14 +253,14 @@ int user_gesture_count_limit, ReferrerChain* out_referrer_chain) override; - // Based on the |web_contents| associated with an event, traces back the + // Based on the |render_frame_host| associated with an event, traces back the // observed NavigationEvents in |navigation_event_list_| to identify the // sequence of navigations leading to the event hosting page, with the // coverage limited to |user_gesture_count_limit| number of user gestures. // Then converts these identified NavigationEvents into ReferrerChainEntrys // and appends them to |out_referrer_chain|. - AttributionResult IdentifyReferrerChainByWebContents( - content::WebContents* web_contents, + AttributionResult IdentifyReferrerChainByRenderFrameHost( + content::RenderFrameHost* render_frame_host, int user_gesture_count_limit, ReferrerChain* out_referrer_chain) override; @@ -261,6 +275,8 @@ AttributionResult IdentifyReferrerChainByHostingPage( const GURL& initiating_frame_url, const GURL& initiating_main_frame_url, + const content::GlobalRenderFrameHostId& + initiating_outermost_main_frame_id, SessionID tab_id, bool has_user_gesture, int user_gesture_count_limit, @@ -287,6 +303,11 @@ void AppendRecentNavigations(size_t recent_navigation_count, ReferrerChain* out_referrer_chain); + protected: + NavigationEventList* navigation_event_list() { + return &navigation_event_list_; + } + private: friend class TestNavigationObserverManager; friend class SBNavigationObserverBrowserTest; @@ -303,10 +324,6 @@ typedef std::unordered_map<std::string, std::vector<ResolvedIPAddress>> HostToIpMap; - NavigationEventList* navigation_event_list() { - return &navigation_event_list_; - } - HostToIpMap* host_to_ip_map() { return &host_to_ip_map_; } // Remove stale entries from navigation_event_list_ if they are older than
diff --git a/components/safe_browsing/content/browser/safe_browsing_navigation_observer_unittest.cc b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_unittest.cc index f6b0ebaf..ae9d1500 100644 --- a/components/safe_browsing/content/browser/safe_browsing_navigation_observer_unittest.cc +++ b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_unittest.cc
@@ -15,6 +15,7 @@ #include "components/safe_browsing/core/common/features.h" #include "components/sessions/content/session_tab_helper.h" #include "components/sync_preferences/testing_pref_service_syncable.h" +#include "content/public/browser/global_routing_id.h" #include "content/public/browser/web_contents.h" #include "content/public/test/mock_navigation_handle.h" #include "content/public/test/navigation_simulator.h" @@ -192,10 +193,10 @@ TEST_F(SBNavigationObserverTest, TestNavigationEventList) { NavigationEventList events(3); - EXPECT_EQ(-1, static_cast<int>(events.FindNavigationEvent( - base::Time::Now(), GURL("http://invalid.com"), GURL(), - SessionID::InvalidValue(), - navigation_event_list()->navigation_events().size() - 1))); + EXPECT_FALSE(events.FindNavigationEvent( + base::Time::Now(), GURL("http://invalid.com"), GURL(), + SessionID::InvalidValue(), content::GlobalRenderFrameHostId(), + navigation_event_list()->navigation_events().size() - 1)); EXPECT_EQ(0U, events.CleanUpNavigationEvents()); EXPECT_EQ(0U, events.NavigationEventsSize()); @@ -209,11 +210,13 @@ CreateNavigationEventUniquePtr(GURL("http://foo1.com"), now)); EXPECT_EQ(2U, events.NavigationEventsSize()); // FindNavigationEvent should return the latest matching event. - int index = events.FindNavigationEvent( + auto index = events.FindNavigationEvent( base::Time::Now(), GURL("http://foo1.com"), GURL(), - SessionID::InvalidValue(), events.navigation_events().size() - 1); + SessionID::InvalidValue(), content::GlobalRenderFrameHostId(), + events.navigation_events().size() - 1); + EXPECT_TRUE(index); - EXPECT_EQ(now, events.GetNavigationEvent(index)->last_updated); + EXPECT_EQ(now, events.GetNavigationEvent(*index)->last_updated); // One event should get removed. EXPECT_EQ(1U, events.CleanUpNavigationEvents()); EXPECT_EQ(1U, events.NavigationEventsSize()); @@ -292,10 +295,66 @@ ASSERT_EQ(6U, navigation_event_list()->NavigationEventsSize()); ReferrerChain referrer_chain; navigation_observer_manager_->IdentifyReferrerChainByEventURL( - GURL("http://A.com/"), SessionID::InvalidValue(), 10, &referrer_chain); + GURL("http://A.com/"), SessionID::InvalidValue(), + content::GlobalRenderFrameHostId(), 10, &referrer_chain); ASSERT_EQ(6, referrer_chain.size()); } +TEST_F(SBNavigationObserverTest, TestFindEventInCorrectOutermostFrame) { + NavigationEventList events(4); + + // Add 2 events to the list. + base::Time now = base::Time::Now(); + const int child_id = 1; + const int frame_id_a = 2; + const int frame_id_b = 3; + + auto outermost_main_frame_id_a = + content::GlobalRenderFrameHostId(child_id, frame_id_a); + + auto event_page_a = + CreateNavigationEventUniquePtr(GURL("http://foo1.com"), now); + event_page_a->outermost_main_frame_id = outermost_main_frame_id_a; + events.RecordNavigationEvent(std::move(event_page_a)); + + auto event_subframe_a = CreateNavigationEventUniquePtr( + GURL("http://foo1.com/subframe.html"), now); + event_subframe_a->outermost_main_frame_id = outermost_main_frame_id_a; + events.RecordNavigationEvent(std::move(event_subframe_a)); + + auto outermost_main_frame_id_b = + content::GlobalRenderFrameHostId(child_id, frame_id_b); + + auto event_page_b = + CreateNavigationEventUniquePtr(GURL("http://foo1.com/bar.html"), now); + event_page_b->outermost_main_frame_id = outermost_main_frame_id_b; + events.RecordNavigationEvent(std::move(event_page_b)); + + auto event_subframe_b = CreateNavigationEventUniquePtr( + GURL("http://foo1.com/subframe.html"), now); + event_subframe_b->outermost_main_frame_id = outermost_main_frame_id_b; + events.RecordNavigationEvent(std::move(event_subframe_b)); + + // Should match outermost main frame id, where possible. + EXPECT_EQ( + 1U, *events.FindNavigationEvent( + base::Time::Now(), GURL("http://foo1.com/subframe.html"), GURL(), + SessionID::InvalidValue(), outermost_main_frame_id_a, + events.NavigationEventsSize() - 1)); + EXPECT_EQ( + 3U, *events.FindNavigationEvent( + base::Time::Now(), GURL("http://foo1.com/subframe.html"), GURL(), + SessionID::InvalidValue(), outermost_main_frame_id_b, + events.NavigationEventsSize() - 1)); + + // Should match the most recent if main_frame_id is not given. + EXPECT_EQ( + 3U, *events.FindNavigationEvent( + base::Time::Now(), GURL("http://foo1.com/subframe.html"), GURL(), + SessionID::InvalidValue(), content::GlobalRenderFrameHostId(), + events.NavigationEventsSize() - 1)); +} + TEST_F(SBNavigationObserverTest, BasicNavigationAndCommit) { // Navigation in current tab. NavigateAndCommit(GURL("http://foo/1"), ui::PAGE_TRANSITION_AUTO_BOOKMARK); @@ -414,9 +473,10 @@ // Verifies all stale and invalid navigation events are removed. ASSERT_EQ(2U, navigation_event_list()->NavigationEventsSize()); ASSERT_EQ(1U, navigation_event_list()->PendingNavigationEventsSize()); - EXPECT_EQ(-1, static_cast<int>(navigation_event_list()->FindNavigationEvent( - base::Time::Now(), url_1, GURL(), SessionID::InvalidValue(), - navigation_event_list()->NavigationEventsSize() - 1))); + EXPECT_FALSE(navigation_event_list()->FindNavigationEvent( + base::Time::Now(), url_1, GURL(), SessionID::InvalidValue(), + content::GlobalRenderFrameHostId(), + navigation_event_list()->NavigationEventsSize() - 1)); EXPECT_EQ(nullptr, navigation_event_list()->FindPendingNavigationEvent(url_1)); } @@ -582,7 +642,8 @@ ReferrerChain referrer_chain; navigation_observer_manager_->IdentifyReferrerChainByEventURL( - GURL("http://A.com"), SessionID::InvalidValue(), 10, &referrer_chain); + GURL("http://A.com"), SessionID::InvalidValue(), + content::GlobalRenderFrameHostId(), 10, &referrer_chain); ASSERT_EQ(3, referrer_chain.size()); @@ -659,7 +720,8 @@ ReferrerChain referrer_chain; navigation_observer_manager_->IdentifyReferrerChainByEventURL( - GURL("http://A.com/"), SessionID::InvalidValue(), 10, &referrer_chain); + GURL("http://A.com/"), SessionID::InvalidValue(), + content::GlobalRenderFrameHostId(), 10, &referrer_chain); int utm_counter = 10; GURL expected_current_url = GURL("http://A.com"); @@ -722,7 +784,8 @@ ReferrerChain referrer_chain; navigation_observer_manager_->IdentifyReferrerChainByEventURL( - GURL("http://b.com/"), SessionID::InvalidValue(), 10, &referrer_chain); + GURL("http://b.com/"), SessionID::InvalidValue(), + content::GlobalRenderFrameHostId(), 10, &referrer_chain); ASSERT_EQ(1, referrer_chain.size()); @@ -755,7 +818,8 @@ ReferrerChain referrer_chain; navigation_observer_manager_->IdentifyReferrerChainByEventURL( - GURL("http://b.com/"), SessionID::InvalidValue(), 10, &referrer_chain); + GURL("http://b.com/"), SessionID::InvalidValue(), + content::GlobalRenderFrameHostId(), 10, &referrer_chain); EXPECT_EQ(2, referrer_chain.size()); } @@ -796,8 +860,8 @@ ReferrerChain referrer_chain; navigation_observer_manager_->IdentifyReferrerChainByEventURL( - GURL("http://example.com/c"), SessionID::InvalidValue(), 10, - &referrer_chain); + GURL("http://example.com/c"), SessionID::InvalidValue(), + content::GlobalRenderFrameHostId(), 10, &referrer_chain); ASSERT_EQ(1, referrer_chain.size());
diff --git a/components/safe_browsing/content/browser/threat_details.cc b/components/safe_browsing/content/browser/threat_details.cc index e252991..90f855d 100644 --- a/components/safe_browsing/content/browser/threat_details.cc +++ b/components/safe_browsing/content/browser/threat_details.cc
@@ -897,8 +897,10 @@ return; } - referrer_chain_provider_->IdentifyReferrerChainByWebContents( - web_contents(), kThreatDetailsUserGestureLimit, + // We would have cancelled a prerender if it was blocked, so we can use the + // primary main frame here. + referrer_chain_provider_->IdentifyReferrerChainByRenderFrameHost( + web_contents()->GetMainFrame(), kThreatDetailsUserGestureLimit, report_->mutable_referrer_chain()); }
diff --git a/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc b/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc index 1a58295..0d70d97 100644 --- a/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc +++ b/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc
@@ -33,6 +33,7 @@ #include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/proto/csd.pb.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" +#include "content/public/browser/global_routing_id.h" #include "services/network/public/mojom/cookie_manager.mojom.h" #if BUILDFLAG(FULL_SAFE_BROWSING) #include "components/enterprise/common/proto/connectors.pb.h" @@ -2442,7 +2443,8 @@ ReferrerChain referrer_chain; provider->IdentifyReferrerChainByEventURL( - GURL(url_string), SessionID::InvalidValue(), 2, &referrer_chain); + GURL(url_string), SessionID::InvalidValue(), + content::GlobalRenderFrameHostId(), 2, &referrer_chain); base::ListValue referrer_list; for (const ReferrerChainEntry& entry : referrer_chain) {
diff --git a/components/safe_browsing/core/browser/realtime/url_lookup_service_unittest.cc b/components/safe_browsing/core/browser/realtime/url_lookup_service_unittest.cc index 41d6d88..5617781 100644 --- a/components/safe_browsing/core/browser/realtime/url_lookup_service_unittest.cc +++ b/components/safe_browsing/core/browser/realtime/url_lookup_service_unittest.cc
@@ -70,13 +70,15 @@ class MockReferrerChainProvider : public ReferrerChainProvider { public: virtual ~MockReferrerChainProvider() = default; - MOCK_METHOD3(IdentifyReferrerChainByWebContents, - AttributionResult(content::WebContents* web_contents, + MOCK_METHOD3(IdentifyReferrerChainByRenderFrameHost, + AttributionResult(content::RenderFrameHost* rfh, int user_gesture_count_limit, ReferrerChain* out_referrer_chain)); - MOCK_METHOD4(IdentifyReferrerChainByEventURL, + MOCK_METHOD5(IdentifyReferrerChainByEventURL, AttributionResult(const GURL& event_url, SessionID event_tab_id, + const content::GlobalRenderFrameHostId& + event_outermost_main_frame_id, int user_gesture_count_limit, ReferrerChain* out_referrer_chain)); MOCK_METHOD3(IdentifyReferrerChainByPendingEventURL,
diff --git a/components/safe_browsing/core/browser/referrer_chain_provider.h b/components/safe_browsing/core/browser/referrer_chain_provider.h index e51a742..bef26948 100644 --- a/components/safe_browsing/core/browser/referrer_chain_provider.h +++ b/components/safe_browsing/core/browser/referrer_chain_provider.h
@@ -10,7 +10,8 @@ #include "url/gurl.h" namespace content { -class WebContents; +class RenderFrameHost; +struct GlobalRenderFrameHostId; } namespace safe_browsing { @@ -33,14 +34,15 @@ ATTRIBUTION_FAILURE_TYPE_MAX }; - virtual AttributionResult IdentifyReferrerChainByWebContents( - content::WebContents* web_contents, + virtual AttributionResult IdentifyReferrerChainByRenderFrameHost( + content::RenderFrameHost* render_frame_host, int user_gesture_count_limit, ReferrerChain* out_referrer_chain) = 0; virtual AttributionResult IdentifyReferrerChainByEventURL( const GURL& event_url, SessionID event_tab_id, + const content::GlobalRenderFrameHostId& event_outermost_main_frame_id, int user_gesture_count_limit, ReferrerChain* out_referrer_chain) = 0;
diff --git a/components/safe_browsing/core/common/features.cc b/components/safe_browsing/core/common/features.cc index 7eb74545..b506c2ca 100644 --- a/components/safe_browsing/core/common/features.cc +++ b/components/safe_browsing/core/common/features.cc
@@ -98,7 +98,13 @@ base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kTailoredSecurityIntegration{ - "TailoredSecurityIntegration", base::FEATURE_DISABLED_BY_DEFAULT}; + "TailoredSecurityIntegration", +#if BUILDFLAG(IS_ANDROID) + base::FEATURE_DISABLED_BY_DEFAULT +#else + base::FEATURE_ENABLED_BY_DEFAULT +#endif +}; const base::Feature kOmitNonUserGesturesFromReferrerChain{ "SafeBrowsingOmitNonUserGesturesFromReferrerChain",
diff --git a/components/safe_browsing/core/common/safe_browsing_prefs.cc b/components/safe_browsing/core/common/safe_browsing_prefs.cc index efc273d..f63da778 100644 --- a/components/safe_browsing/core/common/safe_browsing_prefs.cc +++ b/components/safe_browsing/core/common/safe_browsing_prefs.cc
@@ -55,7 +55,7 @@ if (!url.is_valid() || !url.IsStandard()) return GURL(); - url::Replacements<char> replacements; + GURL::Replacements replacements; replacements.ClearUsername(); replacements.ClearPassword(); replacements.ClearQuery();
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn index 2acdb0c..54a46aa 100644 --- a/components/sync/BUILD.gn +++ b/components/sync/BUILD.gn
@@ -129,7 +129,6 @@ sources = [ "base/client_tag_hash_unittest.cc", "base/model_type_unittest.cc", - "base/ordinal_unittest.cc", "base/protobuf_unittest.cc", "base/sync_prefs_unittest.cc", "base/sync_util_unittest.cc", @@ -190,6 +189,7 @@ "model/mutable_data_batch_unittest.cc", "model/processor_entity_tracker_unittest.cc", "model/processor_entity_unittest.cc", + "model/string_ordinal_unittest.cc", "model/sync_change_unittest.cc", "model/sync_data_unittest.cc", "model/sync_error_unittest.cc",
diff --git a/components/sync/base/BUILD.gn b/components/sync/base/BUILD.gn index f7539be..a56ed25b 100644 --- a/components/sync/base/BUILD.gn +++ b/components/sync/base/BUILD.gn
@@ -35,7 +35,6 @@ "logging.h", "model_type.cc", "model_type.h", - "ordinal.h", "passphrase_enums.cc", "passphrase_enums.h", "pref_names.h",
diff --git a/components/sync/base/DEPS b/components/sync/base/DEPS index 395d1e5..2483803f 100644 --- a/components/sync/base/DEPS +++ b/components/sync/base/DEPS
@@ -8,7 +8,4 @@ "+net/base/net_errors.h", "+net/http/http_status_code.h", "+ui/base", - # TODO(crbug.com/1300525): Remove this once ordinal_unittest.cc is moved to - # model/. - "+components/sync/model/string_ordinal.h", ]
diff --git a/components/sync/base/ordinal.h b/components/sync/base/ordinal.h deleted file mode 100644 index 7314f1fe..0000000 --- a/components/sync/base/ordinal.h +++ /dev/null
@@ -1,512 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_SYNC_BASE_ORDINAL_H_ -#define COMPONENTS_SYNC_BASE_ORDINAL_H_ - -#include <stdint.h> - -#include <algorithm> -#include <string> - -#include "base/check_op.h" -#include "base/json/string_escape.h" - -namespace mojo { -template <typename DataViewType, typename T> -struct StructTraits; -} - -namespace syncer { - -namespace mojom { -class StringOrdinalDataView; -} - -// An Ordinal<T> is an object that can be used for ordering. The -// Ordinal<T> class has an unbounded dense strict total order, which -// mean for any Ordinal<T>s a, b and c: -// -// - a < b and b < c implies a < c (transitivity); -// - exactly one of a < b, b < a and a = b holds (trichotomy); -// - if a < b, there is a Ordinal<T> x such that a < x < b (density); -// - there are Ordinals<T> x and y such that x < a < y (unboundedness). -// -// This means that when Ordinal<T> is used for sorting a list, if any -// item changes its position in the list, only its Ordinal<T> value -// has to change to represent the new order, and all the other values -// can stay the same. -// -// An Ordinal<T> is internally represented as an array of bytes, so it -// can be serialized to and deserialized from disk. -// -// The Traits class should look like the following: -// -// // Don't forget to #include <stdint.h> and <stddef.h>. -// struct MyOrdinalTraits { -// // There must be at least two distinct values greater than kZeroDigit -// // and less than kMaxDigit. -// static const uint8_t kZeroDigit = '0'; -// static const uint8_t kMaxDigit = '9'; -// // kMinLength must be positive. -// static const size_t kMinLength = 1; -// }; -// -// An Ordinal<T> is valid iff its corresponding string has at least -// kMinLength characters, does not contain any characters less than -// kZeroDigit or greater than kMaxDigit, is not all zero digits, and -// does not have any unnecessary trailing zero digits. -// -// Note that even if the native char type is signed, strings still -// compare as if their they are unsigned. (This is explicitly in -// C++11 but not in C++98, even though all implementations do so -// anyway in practice.) Thus, it is safe to use any byte range for -// Ordinal<T>s. -template <typename Traits> -class Ordinal { - public: - // Functors for use with STL algorithms and containers. - class LessThanFn { - public: - LessThanFn(); - - bool operator()(const Ordinal<Traits>& lhs, - const Ordinal<Traits>& rhs) const; - }; - - class EqualsFn { - public: - EqualsFn(); - - bool operator()(const Ordinal<Traits>& lhs, - const Ordinal<Traits>& rhs) const; - }; - - // Creates an Ordinal from the given string of bytes. The Ordinal - // may be valid or invalid. - explicit Ordinal(const std::string& bytes); - - // Creates an invalid Ordinal. - Ordinal(); - - // Creates a valid initial Ordinal. This is called to create the first - // element of Ordinal list (i.e. before we have any other values we can - // generate from). - static Ordinal CreateInitialOrdinal(); - - // Returns true iff this Ordinal is valid. This takes constant - // time. - bool IsValid() const; - - // Returns true iff |*this| == |other| or |*this| and |other| - // are both invalid. - bool EqualsOrBothInvalid(const Ordinal& other) const; - - // Returns a printable string representation of the Ordinal suitable - // for logging. - std::string ToDebugString() const; - - // All remaining functions can only be called if IsValid() holds. - // It is an error to call them if IsValid() is false. - - // Order-related functions. - - // Returns true iff |*this| < |other|. - bool LessThan(const Ordinal& other) const; - - // Returns true iff |*this| > |other|. - bool GreaterThan(const Ordinal& other) const; - - // Returns true iff |*this| == |other| (i.e. |*this| < |other| and - // |other| < |*this| are both false). - bool Equals(const Ordinal& other) const; - - // Given |*this| != |other|, returns a Ordinal x such that - // min(|*this|, |other|) < x < max(|*this|, |other|). It is an error - // to call this function when |*this| == |other|. - Ordinal CreateBetween(const Ordinal& other) const; - - // Returns a Ordinal |x| such that |x| < |*this|. - Ordinal CreateBefore() const; - - // Returns a Ordinal |x| such that |*this| < |x|. - Ordinal CreateAfter() const; - - // Returns the string of bytes representing the Ordinal. It is - // guaranteed that an Ordinal constructed from the returned string - // will be valid. - std::string ToInternalValue() const; - - // Use of copy constructor and default assignment for this class is allowed. - - // Constants for Ordinal digits. - static const uint8_t kZeroDigit = Traits::kZeroDigit; - static const uint8_t kMaxDigit = Traits::kMaxDigit; - static const size_t kMinLength = Traits::kMinLength; - static const uint8_t kOneDigit = kZeroDigit + 1; - static const uint8_t kMidDigit = kOneDigit + (kMaxDigit - kOneDigit) / 2; - static const unsigned int kMidDigitValue = kMidDigit - kZeroDigit; - static const unsigned int kMaxDigitValue = kMaxDigit - kZeroDigit; - static const unsigned int kRadix = kMaxDigitValue + 1; - - static_assert(kOneDigit > kZeroDigit, "incorrect ordinal one digit"); - static_assert(kMidDigit > kOneDigit, "incorrect ordinal mid digit"); - static_assert(kMaxDigit > kMidDigit, "incorrect ordinal max digit"); - static_assert(kMinLength > 0, "incorrect ordinal min length"); - static_assert(kMidDigitValue > 1, "incorrect ordinal mid digit"); - static_assert(kMaxDigitValue > kMidDigitValue, "incorrect ordinal max digit"); - static_assert(kRadix == kMaxDigitValue + 1, "incorrect ordinal radix"); - - private: - friend struct mojo::StructTraits<syncer::mojom::StringOrdinalDataView, - Ordinal<Traits>>; - - // Returns true iff the given byte string satisfies the criteria for - // a valid Ordinal. - static bool IsValidOrdinalBytes(const std::string& bytes); - - // Returns the length that bytes.substr(0, length) would be with - // trailing zero digits removed. - static size_t GetLengthWithoutTrailingZeroDigits(const std::string& bytes, - size_t length); - - // Returns the digit at position i, padding with zero digits if - // required. - static uint8_t GetDigit(const std::string& bytes, size_t i); - - // Returns the digit value at position i, padding with 0 if required. - static int GetDigitValue(const std::string& bytes, size_t i); - - // Adds the given value to |bytes| at position i, carrying when - // necessary. Returns the left-most carry. - static int AddDigitValue(std::string* bytes, size_t i, int digit_value); - - // Returns the proper length |bytes| should be resized to, i.e. the - // smallest length such that |bytes| is still greater than - // |lower_bound| and is still valid. |bytes| should be greater than - // |lower_bound|. - static size_t GetProperLength(const std::string& lower_bound, - const std::string& bytes); - - // Compute the midpoint ordinal byte string that is between |start| - // and |end|. - static std::string ComputeMidpoint(const std::string& start, - const std::string& end); - - // Create a Ordinal that is lexigraphically greater than |start| and - // lexigraphically less than |end|. The returned Ordinal will be roughly - // between |start| and |end|. - static Ordinal<Traits> CreateOrdinalBetween(const Ordinal<Traits>& start, - const Ordinal<Traits>& end); - - // The internal byte string representation of the Ordinal. Never - // changes after construction except for assignment. - std::string bytes_; - - // A cache of the result of IsValidOrdinalBytes(bytes_). - bool is_valid_; -}; - -template <typename Traits> -const uint8_t Ordinal<Traits>::kZeroDigit; -template <typename Traits> -const uint8_t Ordinal<Traits>::kMaxDigit; -template <typename Traits> -const size_t Ordinal<Traits>::kMinLength; -template <typename Traits> -const uint8_t Ordinal<Traits>::kOneDigit; -template <typename Traits> -const uint8_t Ordinal<Traits>::kMidDigit; -template <typename Traits> -const unsigned int Ordinal<Traits>::kMidDigitValue; -template <typename Traits> -const unsigned int Ordinal<Traits>::kMaxDigitValue; -template <typename Traits> -const unsigned int Ordinal<Traits>::kRadix; - -template <typename Traits> -Ordinal<Traits>::LessThanFn::LessThanFn() = default; - -template <typename Traits> -bool Ordinal<Traits>::LessThanFn::operator()(const Ordinal<Traits>& lhs, - const Ordinal<Traits>& rhs) const { - return lhs.LessThan(rhs); -} - -template <typename Traits> -Ordinal<Traits>::EqualsFn::EqualsFn() = default; - -template <typename Traits> -bool Ordinal<Traits>::EqualsFn::operator()(const Ordinal<Traits>& lhs, - const Ordinal<Traits>& rhs) const { - return lhs.Equals(rhs); -} - -template <typename Traits> -bool operator==(const Ordinal<Traits>& lhs, const Ordinal<Traits>& rhs) { - return lhs.EqualsOrBothInvalid(rhs); -} - -template <typename Traits> -bool operator!=(const Ordinal<Traits>& lhs, const Ordinal<Traits>& rhs) { - return !(lhs == rhs); -} - -template <typename Traits> -Ordinal<Traits>::Ordinal(const std::string& bytes) - : bytes_(bytes), is_valid_(IsValidOrdinalBytes(bytes_)) {} - -template <typename Traits> -Ordinal<Traits>::Ordinal() : is_valid_(false) {} - -template <typename Traits> -Ordinal<Traits> Ordinal<Traits>::CreateInitialOrdinal() { - std::string bytes(Traits::kMinLength, kZeroDigit); - bytes[0] = kMidDigit; - return Ordinal(bytes); -} - -template <typename Traits> -bool Ordinal<Traits>::IsValid() const { - DCHECK_EQ(IsValidOrdinalBytes(bytes_), is_valid_); - return is_valid_; -} - -template <typename Traits> -bool Ordinal<Traits>::EqualsOrBothInvalid(const Ordinal& other) const { - if (!IsValid() && !other.IsValid()) - return true; - - if (!IsValid() || !other.IsValid()) - return false; - - return Equals(other); -} - -template <typename Traits> -std::string Ordinal<Traits>::ToDebugString() const { - std::string debug_string = - base::EscapeBytesAsInvalidJSONString(bytes_, false /* put_in_quotes */); - if (!is_valid_) { - debug_string = "INVALID[" + debug_string + "]"; - } - return debug_string; -} - -template <typename Traits> -bool Ordinal<Traits>::LessThan(const Ordinal& other) const { - CHECK(IsValid()); - CHECK(other.IsValid()); - return bytes_ < other.bytes_; -} - -template <typename Traits> -bool Ordinal<Traits>::GreaterThan(const Ordinal& other) const { - CHECK(IsValid()); - CHECK(other.IsValid()); - return bytes_ > other.bytes_; -} - -template <typename Traits> -bool Ordinal<Traits>::Equals(const Ordinal& other) const { - CHECK(IsValid()); - CHECK(other.IsValid()); - return bytes_ == other.bytes_; -} - -template <typename Traits> -Ordinal<Traits> Ordinal<Traits>::CreateBetween(const Ordinal& other) const { - CHECK(IsValid()); - CHECK(other.IsValid()); - CHECK(!Equals(other)); - - if (LessThan(other)) { - return CreateOrdinalBetween(*this, other); - } else { - return CreateOrdinalBetween(other, *this); - } -} - -template <typename Traits> -Ordinal<Traits> Ordinal<Traits>::CreateBefore() const { - CHECK(IsValid()); - // Create the smallest valid Ordinal of the appropriate length - // to be the minimum boundary. - const size_t length = bytes_.length(); - std::string start(length, kZeroDigit); - start[length - 1] = kOneDigit; - if (start == bytes_) { - start[length - 1] = kZeroDigit; - start += kOneDigit; - } - - // Even though |start| is already a valid Ordinal that is less - // than |*this|, we don't return it because we wouldn't have much space in - // front of it to insert potential future values. - return CreateBetween(Ordinal(start)); -} - -template <typename Traits> -Ordinal<Traits> Ordinal<Traits>::CreateAfter() const { - CHECK(IsValid()); - // Create the largest valid Ordinal of the appropriate length to be - // the maximum boundary. - std::string end(bytes_.length(), kMaxDigit); - if (end == bytes_) - end += kMaxDigit; - - // Even though |end| is already a valid Ordinal that is greater than - // |*this|, we don't return it because we wouldn't have much space after - // it to insert potential future values. - return CreateBetween(Ordinal(end)); -} - -template <typename Traits> -std::string Ordinal<Traits>::ToInternalValue() const { - CHECK(IsValid()); - return bytes_; -} - -template <typename Traits> -bool Ordinal<Traits>::IsValidOrdinalBytes(const std::string& bytes) { - const size_t length = bytes.length(); - if (length < kMinLength) - return false; - - bool found_non_zero = false; - for (size_t i = 0; i < length; ++i) { - const uint8_t byte = bytes[i]; - if (byte < kZeroDigit || byte > kMaxDigit) - return false; - if (byte > kZeroDigit) - found_non_zero = true; - } - if (!found_non_zero) - return false; - - if (length > kMinLength) { - const uint8_t last_byte = bytes[length - 1]; - if (last_byte == kZeroDigit) - return false; - } - - return true; -} - -template <typename Traits> -size_t Ordinal<Traits>::GetLengthWithoutTrailingZeroDigits( - const std::string& bytes, - size_t length) { - DCHECK(!bytes.empty()); - DCHECK_GT(length, 0U); - - size_t end_position = - bytes.find_last_not_of(static_cast<char>(kZeroDigit), length - 1); - - // If no non kZeroDigit is found then the string is a string of all zeros - // digits so we return 0 as the correct length. - if (end_position == std::string::npos) - return 0; - - return end_position + 1; -} - -template <typename Traits> -uint8_t Ordinal<Traits>::GetDigit(const std::string& bytes, size_t i) { - return (i < bytes.length()) ? bytes[i] : kZeroDigit; -} - -template <typename Traits> -int Ordinal<Traits>::GetDigitValue(const std::string& bytes, size_t i) { - return GetDigit(bytes, i) - kZeroDigit; -} - -template <typename Traits> -int Ordinal<Traits>::AddDigitValue(std::string* bytes, - size_t i, - int digit_value) { - DCHECK_LT(i, bytes->length()); - - for (int j = static_cast<int>(i); j >= 0 && digit_value > 0; --j) { - int byte_j_value = GetDigitValue(*bytes, j) + digit_value; - digit_value = byte_j_value / kRadix; - DCHECK_LE(digit_value, 1); - byte_j_value %= kRadix; - (*bytes)[j] = static_cast<char>(kZeroDigit + byte_j_value); - } - return digit_value; -} - -template <typename Traits> -size_t Ordinal<Traits>::GetProperLength(const std::string& lower_bound, - const std::string& bytes) { - CHECK_GT(bytes, lower_bound); - - size_t drop_length = - GetLengthWithoutTrailingZeroDigits(bytes, bytes.length()); - // See if the |ordinal| can be truncated after its last non-zero - // digit without affecting the ordering. - if (drop_length > kMinLength) { - size_t truncated_length = - GetLengthWithoutTrailingZeroDigits(bytes, drop_length - 1); - - if (truncated_length > 0 && - bytes.compare(0, truncated_length, lower_bound) > 0) - drop_length = truncated_length; - } - return std::max(drop_length, kMinLength); -} - -template <typename Traits> -std::string Ordinal<Traits>::ComputeMidpoint(const std::string& start, - const std::string& end) { - size_t max_size = std::max(start.length(), end.length()) + 1; - std::string midpoint(max_size, kZeroDigit); - - // Perform the operation (start + end) / 2 left-to-right by - // maintaining a "forward carry" which is either 0 or - // kMidDigitValue. AddDigitValue() is in general O(n), but this - // operation is still O(n) despite that; calls to AddDigitValue() - // will overflow at most to the last position where AddDigitValue() - // last overflowed. - int forward_carry = 0; - for (size_t i = 0; i < max_size; ++i) { - const int sum_value = GetDigitValue(start, i) + GetDigitValue(end, i); - const int digit_value = sum_value / 2 + forward_carry; - // AddDigitValue returning a non-zero carry would imply that - // midpoint[0] >= kMaxDigit, which one can show is impossible. - CHECK_EQ(AddDigitValue(&midpoint, i, digit_value), 0); - forward_carry = (sum_value % 2 == 1) ? kMidDigitValue : 0; - } - DCHECK_EQ(forward_carry, 0); - - return midpoint; -} - -template <typename Traits> -Ordinal<Traits> Ordinal<Traits>::CreateOrdinalBetween( - const Ordinal<Traits>& start, - const Ordinal<Traits>& end) { - CHECK(start.IsValid()); - CHECK(end.IsValid()); - CHECK(start.LessThan(end)); - const std::string& start_bytes = start.ToInternalValue(); - const std::string& end_bytes = end.ToInternalValue(); - DCHECK_LT(start_bytes, end_bytes); - - std::string midpoint = ComputeMidpoint(start_bytes, end_bytes); - const size_t proper_length = GetProperLength(start_bytes, midpoint); - midpoint.resize(proper_length, kZeroDigit); - - DCHECK_GT(midpoint, start_bytes); - DCHECK_LT(midpoint, end_bytes); - - Ordinal<Traits> midpoint_ordinal(midpoint); - DCHECK(midpoint_ordinal.IsValid()); - return midpoint_ordinal; -} - -} // namespace syncer - -#endif // COMPONENTS_SYNC_BASE_ORDINAL_H_
diff --git a/components/sync/model/BUILD.gn b/components/sync/model/BUILD.gn index 7f0d2fb..64134bc 100644 --- a/components/sync/model/BUILD.gn +++ b/components/sync/model/BUILD.gn
@@ -52,6 +52,7 @@ "processor_entity_tracker.h", "proxy_model_type_controller_delegate.cc", "proxy_model_type_controller_delegate.h", + "string_ordinal.cc", "string_ordinal.h", "sync_change.cc", "sync_change.h",
diff --git a/components/sync/model/string_ordinal.cc b/components/sync/model/string_ordinal.cc new file mode 100644 index 0000000..6c34584 --- /dev/null +++ b/components/sync/model/string_ordinal.cc
@@ -0,0 +1,278 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/sync/model/string_ordinal.h" + +#include <algorithm> + +#include "base/check.h" +#include "base/check_op.h" +#include "base/json/string_escape.h" + +namespace syncer { + +const uint8_t StringOrdinal::kZeroDigit; +const uint8_t StringOrdinal::kMaxDigit; +const size_t StringOrdinal::kMinLength; +const uint8_t StringOrdinal::kOneDigit; +const uint8_t StringOrdinal::kMidDigit; +const unsigned int StringOrdinal::kMidDigitValue; +const unsigned int StringOrdinal::kMaxDigitValue; +const unsigned int StringOrdinal::kRadix; + +StringOrdinal::LessThanFn::LessThanFn() = default; + +bool StringOrdinal::LessThanFn::operator()(const StringOrdinal& lhs, + const StringOrdinal& rhs) const { + return lhs.LessThan(rhs); +} + +StringOrdinal::EqualsFn::EqualsFn() = default; + +bool StringOrdinal::EqualsFn::operator()(const StringOrdinal& lhs, + const StringOrdinal& rhs) const { + return lhs.Equals(rhs); +} + +bool operator==(const StringOrdinal& lhs, const StringOrdinal& rhs) { + return lhs.EqualsOrBothInvalid(rhs); +} + +bool operator!=(const StringOrdinal& lhs, const StringOrdinal& rhs) { + return !(lhs == rhs); +} + +StringOrdinal::StringOrdinal(const std::string& bytes) + : bytes_(bytes), is_valid_(IsValidOrdinalBytes(bytes_)) {} + +StringOrdinal::StringOrdinal() : is_valid_(false) {} + +StringOrdinal StringOrdinal::CreateInitialOrdinal() { + std::string bytes(kMinLength, kZeroDigit); + bytes[0] = kMidDigit; + return StringOrdinal(bytes); +} + +bool StringOrdinal::IsValid() const { + DCHECK_EQ(IsValidOrdinalBytes(bytes_), is_valid_); + return is_valid_; +} + +bool StringOrdinal::EqualsOrBothInvalid(const StringOrdinal& other) const { + if (!IsValid() && !other.IsValid()) + return true; + + if (!IsValid() || !other.IsValid()) + return false; + + return Equals(other); +} + +std::string StringOrdinal::ToDebugString() const { + std::string debug_string = + base::EscapeBytesAsInvalidJSONString(bytes_, false /* put_in_quotes */); + if (!is_valid_) { + debug_string = "INVALID[" + debug_string + "]"; + } + return debug_string; +} + +bool StringOrdinal::LessThan(const StringOrdinal& other) const { + CHECK(IsValid()); + CHECK(other.IsValid()); + return bytes_ < other.bytes_; +} + +bool StringOrdinal::GreaterThan(const StringOrdinal& other) const { + CHECK(IsValid()); + CHECK(other.IsValid()); + return bytes_ > other.bytes_; +} + +bool StringOrdinal::Equals(const StringOrdinal& other) const { + CHECK(IsValid()); + CHECK(other.IsValid()); + return bytes_ == other.bytes_; +} + +StringOrdinal StringOrdinal::CreateBetween(const StringOrdinal& other) const { + CHECK(IsValid()); + CHECK(other.IsValid()); + CHECK(!Equals(other)); + + if (LessThan(other)) { + return CreateOrdinalBetween(*this, other); + } else { + return CreateOrdinalBetween(other, *this); + } +} + +StringOrdinal StringOrdinal::CreateBefore() const { + CHECK(IsValid()); + // Create the smallest valid StringOrdinal of the appropriate length + // to be the minimum boundary. + const size_t length = bytes_.length(); + std::string start(length, kZeroDigit); + start[length - 1] = kOneDigit; + if (start == bytes_) { + start[length - 1] = kZeroDigit; + start += kOneDigit; + } + + // Even though |start| is already a valid StringOrdinal that is less + // than |*this|, we don't return it because we wouldn't have much space in + // front of it to insert potential future values. + return CreateBetween(StringOrdinal(start)); +} + +StringOrdinal StringOrdinal::CreateAfter() const { + CHECK(IsValid()); + // Create the largest valid StringOrdinal of the appropriate length to be + // the maximum boundary. + std::string end(bytes_.length(), kMaxDigit); + if (end == bytes_) + end += kMaxDigit; + + // Even though |end| is already a valid StringOrdinal that is greater than + // |*this|, we don't return it because we wouldn't have much space after + // it to insert potential future values. + return CreateBetween(StringOrdinal(end)); +} + +std::string StringOrdinal::ToInternalValue() const { + CHECK(IsValid()); + return bytes_; +} + +bool StringOrdinal::IsValidOrdinalBytes(const std::string& bytes) { + const size_t length = bytes.length(); + if (length < kMinLength) + return false; + + bool found_non_zero = false; + for (size_t i = 0; i < length; ++i) { + const uint8_t byte = bytes[i]; + if (byte < kZeroDigit || byte > kMaxDigit) + return false; + if (byte > kZeroDigit) + found_non_zero = true; + } + if (!found_non_zero) + return false; + + if (length > kMinLength) { + const uint8_t last_byte = bytes[length - 1]; + if (last_byte == kZeroDigit) + return false; + } + + return true; +} + +size_t StringOrdinal::GetLengthWithoutTrailingZeroDigits( + const std::string& bytes, + size_t length) { + DCHECK(!bytes.empty()); + DCHECK_GT(length, 0U); + + size_t end_position = + bytes.find_last_not_of(static_cast<char>(kZeroDigit), length - 1); + + // If no non kZeroDigit is found then the string is a string of all zeros + // digits so we return 0 as the correct length. + if (end_position == std::string::npos) + return 0; + + return end_position + 1; +} + +uint8_t StringOrdinal::GetDigit(const std::string& bytes, size_t i) { + return (i < bytes.length()) ? bytes[i] : kZeroDigit; +} + +int StringOrdinal::GetDigitValue(const std::string& bytes, size_t i) { + return GetDigit(bytes, i) - kZeroDigit; +} + +int StringOrdinal::AddDigitValue(std::string* bytes, + size_t i, + int digit_value) { + DCHECK_LT(i, bytes->length()); + + for (int j = static_cast<int>(i); j >= 0 && digit_value > 0; --j) { + int byte_j_value = GetDigitValue(*bytes, j) + digit_value; + digit_value = byte_j_value / kRadix; + DCHECK_LE(digit_value, 1); + byte_j_value %= kRadix; + (*bytes)[j] = static_cast<char>(kZeroDigit + byte_j_value); + } + return digit_value; +} + +size_t StringOrdinal::GetProperLength(const std::string& lower_bound, + const std::string& bytes) { + CHECK_GT(bytes, lower_bound); + + size_t drop_length = + GetLengthWithoutTrailingZeroDigits(bytes, bytes.length()); + // See if the |ordinal| can be truncated after its last non-zero + // digit without affecting the ordering. + if (drop_length > kMinLength) { + size_t truncated_length = + GetLengthWithoutTrailingZeroDigits(bytes, drop_length - 1); + + if (truncated_length > 0 && + bytes.compare(0, truncated_length, lower_bound) > 0) + drop_length = truncated_length; + } + return std::max(drop_length, kMinLength); +} + +std::string StringOrdinal::ComputeMidpoint(const std::string& start, + const std::string& end) { + size_t max_size = std::max(start.length(), end.length()) + 1; + std::string midpoint(max_size, kZeroDigit); + + // Perform the operation (start + end) / 2 left-to-right by + // maintaining a "forward carry" which is either 0 or + // kMidDigitValue. AddDigitValue() is in general O(n), but this + // operation is still O(n) despite that; calls to AddDigitValue() + // will overflow at most to the last position where AddDigitValue() + // last overflowed. + int forward_carry = 0; + for (size_t i = 0; i < max_size; ++i) { + const int sum_value = GetDigitValue(start, i) + GetDigitValue(end, i); + const int digit_value = sum_value / 2 + forward_carry; + // AddDigitValue returning a non-zero carry would imply that + // midpoint[0] >= kMaxDigit, which one can show is impossible. + CHECK_EQ(AddDigitValue(&midpoint, i, digit_value), 0); + forward_carry = (sum_value % 2 == 1) ? kMidDigitValue : 0; + } + DCHECK_EQ(forward_carry, 0); + + return midpoint; +} + +StringOrdinal StringOrdinal::CreateOrdinalBetween(const StringOrdinal& start, + const StringOrdinal& end) { + CHECK(start.IsValid()); + CHECK(end.IsValid()); + CHECK(start.LessThan(end)); + const std::string& start_bytes = start.ToInternalValue(); + const std::string& end_bytes = end.ToInternalValue(); + DCHECK_LT(start_bytes, end_bytes); + + std::string midpoint = ComputeMidpoint(start_bytes, end_bytes); + const size_t proper_length = GetProperLength(start_bytes, midpoint); + midpoint.resize(proper_length, kZeroDigit); + + DCHECK_GT(midpoint, start_bytes); + DCHECK_LT(midpoint, end_bytes); + + StringOrdinal midpoint_ordinal(midpoint); + DCHECK(midpoint_ordinal.IsValid()); + return midpoint_ordinal; +} + +} // namespace syncer
diff --git a/components/sync/model/string_ordinal.h b/components/sync/model/string_ordinal.h index e375759..8e38e24 100644 --- a/components/sync/model/string_ordinal.h +++ b/components/sync/model/string_ordinal.h
@@ -5,29 +5,194 @@ #ifndef COMPONENTS_SYNC_MODEL_STRING_ORDINAL_H_ #define COMPONENTS_SYNC_MODEL_STRING_ORDINAL_H_ -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> +#include <string> -#include "components/sync/base/ordinal.h" +namespace mojo { +template <typename DataViewType, typename T> +struct StructTraits; +} namespace syncer { -// A StringOrdinal is an Ordinal with range 'a'-'z' for printability -// of its internal byte string representation. (Think of -// StringOrdinal as being short for PrintableStringOrdinal.) It -// should be used for data types that want to maintain one or more -// orderings for nodes. +namespace mojom { +class StringOrdinalDataView; +} + +// WARNING, DO NOT USE! Use UniquePosition instead. +// +// +// A StringOrdinal is an object that can be used for ordering. The +// StringOrdinal class has an unbounded dense strict total order, which +// mean for any StringOrdinals a, b and c: +// +// - a < b and b < c implies a < c (transitivity); +// - exactly one of a < b, b < a and a = b holds (trichotomy); +// - if a < b, there is a StringOrdinal x such that a < x < b (density); +// - there are Ordinals<T> x and y such that x < a < y (unboundedness). +// +// This means that when StringOrdinal is used for sorting a list, if any +// item changes its position in the list, only its StringOrdinal value +// has to change to represent the new order, and all the other values +// can stay the same. +// +// A StringOrdinal is internally represented as an array of bytes, so it +// can be serialized to and deserialized from disk. +// +// A StringOrdinal is valid iff its corresponding string has at least +// kMinLength characters, does not contain any characters less than +// kZeroDigit or greater than kMaxDigit, is not all zero digits, and +// does not have any unnecessary trailing zero digits. // // Since StringOrdinals contain only printable characters, it is safe // to store as a string in a protobuf. +class StringOrdinal { + public: + // Functors for use with STL algorithms and containers. + class LessThanFn { + public: + LessThanFn(); -struct StringOrdinalTraits { + bool operator()(const StringOrdinal& lhs, const StringOrdinal& rhs) const; + }; + + class EqualsFn { + public: + EqualsFn(); + + bool operator()(const StringOrdinal& lhs, const StringOrdinal& rhs) const; + }; + + // Creates an StringOrdinal from the given string of bytes. The StringOrdinal + // may be valid or invalid. + explicit StringOrdinal(const std::string& bytes); + + // Creates an invalid StringOrdinal. + StringOrdinal(); + + // Creates a valid initial StringOrdinal. This is called to create the first + // element of StringOrdinal list (i.e. before we have any other values we can + // generate from). + static StringOrdinal CreateInitialOrdinal(); + + // Returns true iff this StringOrdinal is valid. This takes constant + // time. + bool IsValid() const; + + // Returns true iff |*this| == |other| or |*this| and |other| + // are both invalid. + bool EqualsOrBothInvalid(const StringOrdinal& other) const; + + // Returns a printable string representation of the StringOrdinal suitable + // for logging. + std::string ToDebugString() const; + + // All remaining functions can only be called if IsValid() holds. + // It is an error to call them if IsValid() is false. + + // Order-related functions. + + // Returns true iff |*this| < |other|. + bool LessThan(const StringOrdinal& other) const; + + // Returns true iff |*this| > |other|. + bool GreaterThan(const StringOrdinal& other) const; + + // Returns true iff |*this| == |other| (i.e. |*this| < |other| and + // |other| < |*this| are both false). + bool Equals(const StringOrdinal& other) const; + + // Given |*this| != |other|, returns a StringOrdinal x such that + // min(|*this|, |other|) < x < max(|*this|, |other|). It is an error + // to call this function when |*this| == |other|. + StringOrdinal CreateBetween(const StringOrdinal& other) const; + + // Returns a StringOrdinal |x| such that |x| < |*this|. + StringOrdinal CreateBefore() const; + + // Returns a StringOrdinal |x| such that |*this| < |x|. + StringOrdinal CreateAfter() const; + + // Returns the string of bytes representing the StringOrdinal. It is + // guaranteed that an StringOrdinal constructed from the returned string + // will be valid. + std::string ToInternalValue() const; + + // Use of copy constructor and default assignment for this class is allowed. + + // Constants for StringOrdinal digits. static const uint8_t kZeroDigit = 'a'; static const uint8_t kMaxDigit = 'z'; static const size_t kMinLength = 1; + static const uint8_t kOneDigit = kZeroDigit + 1; + static const uint8_t kMidDigit = kOneDigit + (kMaxDigit - kOneDigit) / 2; + static const unsigned int kMidDigitValue = kMidDigit - kZeroDigit; + static const unsigned int kMaxDigitValue = kMaxDigit - kZeroDigit; + static const unsigned int kRadix = kMaxDigitValue + 1; + + static_assert(kOneDigit > kZeroDigit, "incorrect StringOrdinal one digit"); + static_assert(kMidDigit > kOneDigit, "incorrect StringOrdinal mid digit"); + static_assert(kMaxDigit > kMidDigit, "incorrect StringOrdinal max digit"); + static_assert(kMinLength > 0, "incorrect StringOrdinal min length"); + static_assert(kMidDigitValue > 1, "incorrect StringOrdinal mid digit"); + static_assert(kMaxDigitValue > kMidDigitValue, + "incorrect StringOrdinal max digit"); + static_assert(kRadix == kMaxDigitValue + 1, "incorrect StringOrdinal radix"); + + private: + friend struct mojo::StructTraits<syncer::mojom::StringOrdinalDataView, + StringOrdinal>; + + // Returns true iff the given byte string satisfies the criteria for + // a valid StringOrdinal. + static bool IsValidOrdinalBytes(const std::string& bytes); + + // Returns the length that bytes.substr(0, length) would be with + // trailing zero digits removed. + static size_t GetLengthWithoutTrailingZeroDigits(const std::string& bytes, + size_t length); + + // Returns the digit at position i, padding with zero digits if + // required. + static uint8_t GetDigit(const std::string& bytes, size_t i); + + // Returns the digit value at position i, padding with 0 if required. + static int GetDigitValue(const std::string& bytes, size_t i); + + // Adds the given value to |bytes| at position i, carrying when + // necessary. Returns the left-most carry. + static int AddDigitValue(std::string* bytes, size_t i, int digit_value); + + // Returns the proper length |bytes| should be resized to, i.e. the + // smallest length such that |bytes| is still greater than + // |lower_bound| and is still valid. |bytes| should be greater than + // |lower_bound|. + static size_t GetProperLength(const std::string& lower_bound, + const std::string& bytes); + + // Compute the midpoint StringOrdinal byte string that is between |start| + // and |end|. + static std::string ComputeMidpoint(const std::string& start, + const std::string& end); + + // Create a StringOrdinal that is lexigraphically greater than |start| and + // lexigraphically less than |end|. The returned StringOrdinal will be roughly + // between |start| and |end|. + static StringOrdinal CreateOrdinalBetween(const StringOrdinal& start, + const StringOrdinal& end); + + // The internal byte string representation of the StringOrdinal. Never + // changes after construction except for assignment. + std::string bytes_; + + // A cache of the result of IsValidOrdinalBytes(bytes_). + bool is_valid_; }; -using StringOrdinal = Ordinal<StringOrdinalTraits>; +bool operator==(const StringOrdinal& lhs, const StringOrdinal& rhs); + +bool operator!=(const StringOrdinal& lhs, const StringOrdinal& rhs); static_assert(StringOrdinal::kZeroDigit == 'a', "StringOrdinal has incorrect zero digit");
diff --git a/components/sync/base/ordinal_unittest.cc b/components/sync/model/string_ordinal_unittest.cc similarity index 97% rename from components/sync/base/ordinal_unittest.cc rename to components/sync/model/string_ordinal_unittest.cc index 5e782fcb..c8ab190 100644 --- a/components/sync/base/ordinal_unittest.cc +++ b/components/sync/model/string_ordinal_unittest.cc
@@ -2,16 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(crbug.com/1300525): Move this file to model/ and remove this include -// (it's kept now to avoid a presubmit error). None of that is done now to allow -// for a friendlier diff. -#include "components/sync/base/ordinal.h" +#include "components/sync/model/string_ordinal.h" +#include <algorithm> #include <cctype> #include <vector> #include "base/rand_util.h" -#include "components/sync/model/string_ordinal.h" #include "testing/gtest/include/gtest/gtest.h" namespace syncer {
diff --git a/content/DEPS b/content/DEPS index ec3de28..f567a63 100644 --- a/content/DEPS +++ b/content/DEPS
@@ -25,6 +25,7 @@ # as autofill or extensions, and chrome implementation details such as # settings, packaging details, installation or crash reporting. + "+components/browsing_topics/common", "+components/memory_pressure", "+components/power_scheduler", "+components/services/filesystem",
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index d71fa98d..60c1258c 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -62,6 +62,7 @@ "//cc/mojo_embedder", "//cc/paint", "//components/back_forward_cache:enum", + "//components/browsing_topics/common:common", "//components/cbor", "//components/discardable_memory/common", "//components/discardable_memory/service", @@ -401,6 +402,7 @@ "attribution_reporting/attribution_manager.h", "attribution_reporting/attribution_manager_impl.cc", "attribution_reporting/attribution_manager_impl.h", + "attribution_reporting/attribution_observer.h", "attribution_reporting/attribution_page_metrics.cc", "attribution_reporting/attribution_page_metrics.h", "attribution_reporting/attribution_policy.cc", @@ -599,6 +601,8 @@ "browsing_data/storage_partition_code_cache_data_remover.h", "browsing_instance.cc", "browsing_instance.h", + "browsing_topics/browsing_topics_site_data_storage.cc", + "browsing_topics/browsing_topics_site_data_storage.h", "buckets/bucket_context.cc", "buckets/bucket_context.h", "buckets/bucket_host.cc",
diff --git a/content/browser/attribution_reporting/attribution_internals_handler_impl.h b/content/browser/attribution_reporting/attribution_internals_handler_impl.h index a7809e1..e964b72df 100644 --- a/content/browser/attribution_reporting/attribution_internals_handler_impl.h +++ b/content/browser/attribution_reporting/attribution_internals_handler_impl.h
@@ -9,6 +9,7 @@ #include "base/scoped_observation.h" #include "content/browser/attribution_reporting/attribution_internals.mojom.h" #include "content/browser/attribution_reporting/attribution_manager.h" +#include "content/browser/attribution_reporting/attribution_observer.h" #include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/attribution_storage.h" #include "mojo/public/cpp/bindings/pending_receiver.h" @@ -26,7 +27,7 @@ // `AttributionInternalsUI`. class AttributionInternalsHandlerImpl : public mojom::AttributionInternalsHandler, - public AttributionManager::Observer { + public AttributionObserver { public: AttributionInternalsHandlerImpl( WebUI* web_ui, @@ -65,7 +66,7 @@ std::unique_ptr<AttributionManager::Provider> manager_provider); private: - // AttributionManager::Observer: + // AttributionObserver: void OnSourcesChanged() override; void OnReportsChanged() override; void OnSourceDeactivated( @@ -84,7 +85,7 @@ mojo::RemoteSet<mojom::AttributionInternalsObserver> observers_; - base::ScopedObservation<AttributionManager, AttributionManager::Observer> + base::ScopedObservation<AttributionManager, AttributionObserver> manager_observation_{this}; };
diff --git a/content/browser/attribution_reporting/attribution_manager.h b/content/browser/attribution_reporting/attribution_manager.h index fac50c4..49fa1e1 100644 --- a/content/browser/attribution_reporting/attribution_manager.h +++ b/content/browser/attribution_reporting/attribution_manager.h
@@ -8,9 +8,7 @@ #include <vector> #include "base/callback_forward.h" -#include "base/observer_list_types.h" #include "content/browser/attribution_reporting/attribution_report.h" -#include "content/browser/attribution_reporting/attribution_storage.h" namespace base { class Time; @@ -24,12 +22,11 @@ class AttributionTrigger; class AttributionDataHostManager; +class AttributionObserver; class StorableSource; class StoredSource; class WebContents; -struct SendResult; - // Interface that mediates data flow between the network, storage layer, and // blink. class AttributionManager { @@ -48,32 +45,11 @@ virtual AttributionManager* GetManager(WebContents* web_contents) const = 0; }; - class Observer : public base::CheckedObserver { - public: - ~Observer() override = default; - - virtual void OnSourcesChanged() {} - - virtual void OnReportsChanged() {} - - virtual void OnSourceHandled(const StorableSource& source, - StorableSource::Result result) {} - - virtual void OnSourceDeactivated( - const AttributionStorage::DeactivatedSource& source) {} - - virtual void OnReportSent(const AttributionReport& report, - const SendResult& info) {} - - virtual void OnTriggerHandled( - const AttributionStorage::CreateReportResult& result) {} - }; - virtual ~AttributionManager() = default; - virtual void AddObserver(Observer* observer) = 0; + virtual void AddObserver(AttributionObserver* observer) = 0; - virtual void RemoveObserver(Observer* observer) = 0; + virtual void RemoveObserver(AttributionObserver* observer) = 0; // Gets manager responsible for tracking pending data hosts targeting `this`. virtual AttributionDataHostManager* GetDataHostManager() = 0;
diff --git a/content/browser/attribution_reporting/attribution_manager_impl.cc b/content/browser/attribution_reporting/attribution_manager_impl.cc index 4ce26ef..c33f6143 100644 --- a/content/browser/attribution_reporting/attribution_manager_impl.cc +++ b/content/browser/attribution_reporting/attribution_manager_impl.cc
@@ -19,6 +19,7 @@ #include "content/browser/attribution_reporting/attribution_cookie_checker_impl.h" #include "content/browser/attribution_reporting/attribution_data_host_manager_impl.h" #include "content/browser/attribution_reporting/attribution_info.h" +#include "content/browser/attribution_reporting/attribution_observer.h" #include "content/browser/attribution_reporting/attribution_policy.h" #include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/attribution_report_network_sender.h" @@ -241,11 +242,11 @@ std::move(session_only_origin_predicate)); } -void AttributionManagerImpl::AddObserver(Observer* observer) { +void AttributionManagerImpl::AddObserver(AttributionObserver* observer) { observers_.AddObserver(observer); } -void AttributionManagerImpl::RemoveObserver(Observer* observer) { +void AttributionManagerImpl::RemoveObserver(AttributionObserver* observer) { observers_.RemoveObserver(observer); } @@ -278,7 +279,7 @@ if (!manager) return; - for (Observer& observer : manager->observers_) + for (auto& observer : manager->observers_) observer.OnSourceHandled(source, result.status); manager->scheduler_.ScheduleSend(result.min_fake_report_time); @@ -414,7 +415,7 @@ NotifySourceDeactivated(*source); } - for (Observer& observer : observers_) + for (auto& observer : observers_) observer.OnTriggerHandled(result); } @@ -634,23 +635,23 @@ return; } - for (Observer& observer : observers_) + for (auto& observer : observers_) observer.OnReportSent(report, info); } void AttributionManagerImpl::NotifySourcesChanged() { - for (Observer& observer : observers_) + for (auto& observer : observers_) observer.OnSourcesChanged(); } void AttributionManagerImpl::NotifyReportsChanged() { - for (Observer& observer : observers_) + for (auto& observer : observers_) observer.OnReportsChanged(); } void AttributionManagerImpl::NotifySourceDeactivated( const AttributionStorage::DeactivatedSource& source) { - for (Observer& observer : observers_) + for (auto& observer : observers_) observer.OnSourceDeactivated(source); }
diff --git a/content/browser/attribution_reporting/attribution_manager_impl.h b/content/browser/attribution_reporting/attribution_manager_impl.h index 0caf15b..0d54ce14 100644 --- a/content/browser/attribution_reporting/attribution_manager_impl.h +++ b/content/browser/attribution_reporting/attribution_manager_impl.h
@@ -98,8 +98,8 @@ ~AttributionManagerImpl() override; // AttributionManager: - void AddObserver(Observer* observer) override; - void RemoveObserver(Observer* observer) override; + void AddObserver(AttributionObserver* observer) override; + void RemoveObserver(AttributionObserver* observer) override; AttributionDataHostManager* GetDataHostManager() override; void HandleSource(StorableSource source) override; void HandleTrigger(AttributionTrigger trigger) override; @@ -179,7 +179,7 @@ // Holds pending sources and triggers in the order they were received by the // browser. For the time being, they must be processed in this order in order // to ensure that behavioral requirements are met and to ensure that - // `AttributionManager::Observer`s are notified in the correct order, which + // `AttributionObserver`s are notified in the correct order, which // the simulator currently depends on. We may be able to loosen this // requirement in the future so that there are conceptually separate queues // per <source origin, destination origin, reporting origin>. @@ -203,7 +203,7 @@ // is expected to be small, so a `flat_set` is used. base::flat_set<AttributionReport::EventLevelData::Id> reports_being_sent_; - base::ObserverList<Observer> observers_; + base::ObserverList<AttributionObserver> observers_; base::WeakPtrFactory<AttributionManagerImpl> weak_factory_; };
diff --git a/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc b/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc index a5c2fcc..1cea033 100644 --- a/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc +++ b/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc
@@ -28,6 +28,7 @@ #include "base/values.h" #include "build/build_config.h" #include "content/browser/attribution_reporting/attribution_cookie_checker.h" +#include "content/browser/attribution_reporting/attribution_observer.h" #include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/attribution_report_sender.h" #include "content/browser/attribution_reporting/attribution_storage.h" @@ -72,7 +73,7 @@ using Checkpoint = ::testing::MockFunction<void(int step)>; -class MockAttributionManagerObserver : public AttributionManager::Observer { +class MockAttributionObserver : public AttributionObserver { public: MOCK_METHOD(void, OnSourcesChanged, (), (override)); @@ -517,9 +518,9 @@ attribution_manager_->HandleTrigger(DefaultTrigger()); EXPECT_THAT(StoredReports(), SizeIs(1)); - MockAttributionManagerObserver observer; - base::ScopedObservation<AttributionManager, AttributionManager::Observer> - observation(&observer); + MockAttributionObserver observer; + base::ScopedObservation<AttributionManager, AttributionObserver> observation( + &observer); observation.Observe(attribution_manager_.get()); // Ensure that observers are notified after the report is deleted. @@ -610,9 +611,9 @@ TEST_F(AttributionManagerImplTest, QueuedReportSent_ObserversNotified) { base::HistogramTester histograms; - MockAttributionManagerObserver observer; - base::ScopedObservation<AttributionManager, AttributionManager::Observer> - observation(&observer); + MockAttributionObserver observer; + base::ScopedObservation<AttributionManager, AttributionObserver> observation( + &observer); observation.Observe(attribution_manager_.get()); EXPECT_CALL(observer, OnReportSent(ReportSourceIs(SourceEventIdIs(1u)), _)); @@ -655,9 +656,9 @@ } TEST_F(AttributionManagerImplTest, TriggerHandled_ObserversNotified) { - MockAttributionManagerObserver observer; - base::ScopedObservation<AttributionManager, AttributionManager::Observer> - observation(&observer); + MockAttributionObserver observer; + base::ScopedObservation<AttributionManager, AttributionObserver> observation( + &observer); observation.Observe(attribution_manager_.get()); Checkpoint checkpoint; @@ -960,9 +961,9 @@ attribution_manager_->HandleTrigger(DefaultTrigger()); EXPECT_THAT(StoredReports(), SizeIs(1)); - MockAttributionManagerObserver observer; - base::ScopedObservation<AttributionManager, AttributionManager::Observer> - observation(&observer); + MockAttributionObserver observer; + base::ScopedObservation<AttributionManager, AttributionObserver> observation( + &observer); observation.Observe(attribution_manager_.get()); // Ensure that deleting a report notifies observers. @@ -976,9 +977,9 @@ } TEST_F(AttributionManagerImplTest, HandleSource_NotifiesObservers) { - MockAttributionManagerObserver observer; - base::ScopedObservation<AttributionManager, AttributionManager::Observer> - observation(&observer); + MockAttributionObserver observer; + base::ScopedObservation<AttributionManager, AttributionObserver> observation( + &observer); observation.Observe(attribution_manager_.get()); SourceBuilder builder; @@ -1022,9 +1023,9 @@ } TEST_F(AttributionManagerImplTest, HandleTrigger_NotifiesObservers) { - MockAttributionManagerObserver observer; - base::ScopedObservation<AttributionManager, AttributionManager::Observer> - observation(&observer); + MockAttributionObserver observer; + base::ScopedObservation<AttributionManager, AttributionObserver> observation( + &observer); observation.Observe(attribution_manager_.get()); SourceBuilder builder; @@ -1089,9 +1090,9 @@ } TEST_F(AttributionManagerImplTest, ClearData_NotifiesObservers) { - MockAttributionManagerObserver observer; - base::ScopedObservation<AttributionManager, AttributionManager::Observer> - observation(&observer); + MockAttributionObserver observer; + base::ScopedObservation<AttributionManager, AttributionObserver> observation( + &observer); observation.Observe(attribution_manager_.get()); EXPECT_CALL(observer, OnSourcesChanged); @@ -1124,9 +1125,9 @@ attribution_manager_->HandleTrigger(DefaultTrigger()); EXPECT_THAT(StoredReports(), SizeIs(1)); - MockAttributionManagerObserver observer; - base::ScopedObservation<AttributionManager, AttributionManager::Observer> - observation(&observer); + MockAttributionObserver observer; + base::ScopedObservation<AttributionManager, AttributionObserver> observation( + &observer); observation.Observe(attribution_manager_.get()); EXPECT_CALL(observer, OnReportSent(_, Field(&SendResult::status, @@ -1411,9 +1412,9 @@ TEST_F(AttributionManagerImplTest, HandleSource_NotifiesObservers_SourceHandled) { - MockAttributionManagerObserver observer; - base::ScopedObservation<AttributionManager, AttributionManager::Observer> - observation(&observer); + MockAttributionObserver observer; + base::ScopedObservation<AttributionManager, AttributionObserver> observation( + &observer); observation.Observe(attribution_manager_.get()); const StorableSource source = SourceBuilder().Build();
diff --git a/content/browser/attribution_reporting/attribution_observer.h b/content/browser/attribution_reporting/attribution_observer.h new file mode 100644 index 0000000..e14d3295 --- /dev/null +++ b/content/browser/attribution_reporting/attribution_observer.h
@@ -0,0 +1,50 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_OBSERVER_H_ +#define CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_OBSERVER_H_ + +#include "base/observer_list_types.h" +#include "content/browser/attribution_reporting/attribution_storage.h" +#include "content/browser/attribution_reporting/storable_source.h" + +namespace content { + +class AttributionReport; + +struct SendResult; + +// Observes events in the Attribution Reporting API. Observers are registered on +// `AttributionManager`. +class AttributionObserver : public base::CheckedObserver { + public: + ~AttributionObserver() override = default; + + // Called when sources in storage change. + virtual void OnSourcesChanged() {} + + // Called when reports in storage change. + virtual void OnReportsChanged() {} + + // Called when a source is registered, regardless of success. + virtual void OnSourceHandled(const StorableSource& source, + StorableSource::Result result) {} + + // Called when a source is deactivated. + virtual void OnSourceDeactivated( + const AttributionStorage::DeactivatedSource& source) {} + + // Called when a report is sent, regardless of success, but not for attempts + // that will be retried. + virtual void OnReportSent(const AttributionReport& report, + const SendResult& info) {} + + // Called when a trigger is registered, regardless of success. + virtual void OnTriggerHandled( + const AttributionStorage::CreateReportResult& result) {} +}; + +} // namespace content + +#endif // CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_OBSERVER_H_
diff --git a/content/browser/attribution_reporting/attribution_test_utils.cc b/content/browser/attribution_reporting/attribution_test_utils.cc index 9c56b04..9b11a0d 100644 --- a/content/browser/attribution_reporting/attribution_test_utils.cc +++ b/content/browser/attribution_reporting/attribution_test_utils.cc
@@ -18,6 +18,7 @@ #include "base/strings/string_number_conversions.h" #include "base/task/task_runner_util.h" #include "base/test/bind.h" +#include "content/browser/attribution_reporting/attribution_observer.h" #include "content/browser/attribution_reporting/rate_limit_result.h" #include "url/gurl.h" @@ -170,11 +171,11 @@ MockAttributionManager::~MockAttributionManager() = default; -void MockAttributionManager::AddObserver(Observer* observer) { +void MockAttributionManager::AddObserver(AttributionObserver* observer) { observers_.AddObserver(observer); } -void MockAttributionManager::RemoveObserver(Observer* observer) { +void MockAttributionManager::RemoveObserver(AttributionObserver* observer) { observers_.RemoveObserver(observer); } @@ -183,37 +184,37 @@ } void MockAttributionManager::NotifySourcesChanged() { - for (Observer& observer : observers_) + for (auto& observer : observers_) observer.OnSourcesChanged(); } void MockAttributionManager::NotifyReportsChanged() { - for (Observer& observer : observers_) + for (auto& observer : observers_) observer.OnReportsChanged(); } void MockAttributionManager::NotifySourceDeactivated( const DeactivatedSource& source) { - for (Observer& observer : observers_) + for (auto& observer : observers_) observer.OnSourceDeactivated(source); } void MockAttributionManager::NotifySourceHandled( const StorableSource& source, StorableSource::Result result) { - for (Observer& observer : observers_) + for (auto& observer : observers_) observer.OnSourceHandled(source, result); } void MockAttributionManager::NotifyReportSent(const AttributionReport& report, const SendResult& info) { - for (Observer& observer : observers_) + for (auto& observer : observers_) observer.OnReportSent(report, info); } void MockAttributionManager::NotifyTriggerHandled( const AttributionStorage::CreateReportResult& result) { - for (Observer& observer : observers_) + for (auto& observer : observers_) observer.OnTriggerHandled(result); }
diff --git a/content/browser/attribution_reporting/attribution_test_utils.h b/content/browser/attribution_reporting/attribution_test_utils.h index 0caff1cd..84de4407 100644 --- a/content/browser/attribution_reporting/attribution_test_utils.h +++ b/content/browser/attribution_reporting/attribution_test_utils.h
@@ -43,6 +43,7 @@ namespace content { class AggregatableHistogramContribution; +class AttributionObserver; class AttributionTrigger; struct AggregatableAttribution; @@ -289,8 +290,8 @@ base::OnceClosure done), (override)); - void AddObserver(Observer* observer) override; - void RemoveObserver(Observer* observer) override; + void AddObserver(AttributionObserver* observer) override; + void RemoveObserver(AttributionObserver* observer) override; AttributionDataHostManager* GetDataHostManager() override; void NotifySourcesChanged(); @@ -308,7 +309,7 @@ private: std::unique_ptr<AttributionDataHostManager> data_host_manager_; - base::ObserverList<Observer, /*check_empty=*/true> observers_; + base::ObserverList<AttributionObserver, /*check_empty=*/true> observers_; }; // Helper class to construct a StorableSource for tests using default data.
diff --git a/content/browser/browsing_topics/OWNERS b/content/browser/browsing_topics/OWNERS new file mode 100644 index 0000000..bb1b03b --- /dev/null +++ b/content/browser/browsing_topics/OWNERS
@@ -0,0 +1 @@ +file://components/browsing_topics/OWNERS
diff --git a/content/browser/browsing_topics/browsing_topics_site_data_storage.cc b/content/browser/browsing_topics/browsing_topics_site_data_storage.cc new file mode 100644 index 0000000..c6ef8ea --- /dev/null +++ b/content/browser/browsing_topics/browsing_topics_site_data_storage.cc
@@ -0,0 +1,269 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/browsing_topics/browsing_topics_site_data_storage.h" + +#include "base/files/file_util.h" +#include "base/metrics/histogram_functions.h" +#include "sql/database.h" +#include "sql/recovery.h" +#include "sql/statement.h" +#include "sql/transaction.h" +#include "third_party/blink/public/common/features.h" + +namespace content { + +namespace { + +// Version number of the database. +const int kCurrentVersionNumber = 1; + +void RecordInitializationStatus(bool successful) { + base::UmaHistogramBoolean("BrowsingTopics.SiteDataStorage.InitStatus", + successful); +} + +} // namespace + +BrowsingTopicsSiteDataStorage::BrowsingTopicsSiteDataStorage( + const base::FilePath& path_to_database) + : path_to_database_(path_to_database) { + DETACH_FROM_SEQUENCE(sequence_checker_); +} + +BrowsingTopicsSiteDataStorage::~BrowsingTopicsSiteDataStorage() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} + +void BrowsingTopicsSiteDataStorage::ExpireDataBefore(base::Time end_time) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (!LazyInit()) + return; + + static constexpr char kDeleteApiUsageSql[] = + // clang-format off + "DELETE FROM browsing_topics_api_usages " + "WHERE last_usage_time < ?"; + // clang-format on + + sql::Statement delete_api_usage_statement( + db_->GetCachedStatement(SQL_FROM_HERE, kDeleteApiUsageSql)); + delete_api_usage_statement.BindTime(0, end_time); + + delete_api_usage_statement.Run(); +} + +browsing_topics::ApiUsageContextQueryResult +BrowsingTopicsSiteDataStorage::GetBrowsingTopicsApiUsage(base::Time begin_time, + base::Time end_time) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (!LazyInit()) + return {}; + + // Expire data before `begin_time`, as they are no longer needed. + ExpireDataBefore(begin_time); + + static constexpr char kGetApiUsageSql[] = + // clang-format off + "SELECT hashed_context_domain,hashed_top_host,last_usage_time " + "FROM browsing_topics_api_usages " + "WHERE last_usage_time>=? AND last_usage_time<? " + "ORDER BY last_usage_time DESC " + "LIMIT ?"; + // clang-format on + + sql::Statement statement( + db_->GetCachedStatement(SQL_FROM_HERE, kGetApiUsageSql)); + + statement.BindTime(0, begin_time); + statement.BindTime(1, end_time); + statement.BindInt( + 2, + blink::features:: + kBrowsingTopicsMaxNumberOfApiUsageContextEntriesToLoadPerEpoch.Get()); + + std::vector<browsing_topics::ApiUsageContext> contexts; + while (statement.Step()) { + browsing_topics::ApiUsageContext usage_context; + usage_context.hashed_context_domain = + browsing_topics::HashedDomain(statement.ColumnInt64(0)); + usage_context.hashed_top_host = + browsing_topics::HashedHost(statement.ColumnInt64(1)); + usage_context.time = statement.ColumnTime(2); + + contexts.push_back(std::move(usage_context)); + } + + if (!statement.Succeeded()) + return {}; + + return browsing_topics::ApiUsageContextQueryResult(std::move(contexts)); +} + +void BrowsingTopicsSiteDataStorage::OnBrowsingTopicsApiUsed( + const browsing_topics::HashedHost& hashed_top_host, + const base::flat_set<browsing_topics::HashedDomain>& + hashed_context_domains) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (!LazyInit()) + return; + + sql::Transaction transaction(db_.get()); + if (!transaction.Begin()) + return; + + base::Time current_time = base::Time::Now(); + + for (const browsing_topics::HashedDomain& hashed_context_domain : + hashed_context_domains) { + static constexpr char kInsertApiUsageSql[] = + // clang-format off + "INSERT OR REPLACE INTO browsing_topics_api_usages " + "(hashed_context_domain,hashed_top_host,last_usage_time) " + "VALUES (?,?,?)"; + // clang-format on + + sql::Statement insert_api_usage_statement( + db_->GetCachedStatement(SQL_FROM_HERE, kInsertApiUsageSql)); + insert_api_usage_statement.BindInt64(0, hashed_context_domain.value()); + insert_api_usage_statement.BindInt64(1, hashed_top_host.value()); + insert_api_usage_statement.BindTime(2, current_time); + + if (!insert_api_usage_statement.Run()) + return; + } + + transaction.Commit(); +} + +bool BrowsingTopicsSiteDataStorage::LazyInit() { + if (db_init_status_ != InitStatus::kUnattempted) + return db_init_status_ == InitStatus::kSuccess; + + db_ = std::make_unique<sql::Database>(sql::DatabaseOptions{ + .exclusive_locking = true, .page_size = 4096, .cache_size = 32}); + db_->set_histogram_tag("BrowsingTopics"); + + // base::Unretained is safe here because this BrowsingTopicsSiteDataStorage + // owns the sql::Database instance that stores and uses the callback. So, + // `this` is guaranteed to outlive the callback. + db_->set_error_callback( + base::BindRepeating(&BrowsingTopicsSiteDataStorage::DatabaseErrorCallback, + base::Unretained(this))); + + if (!db_->Open(path_to_database_)) { + HandleInitializationFailure(); + return false; + } + + // TODO(yaoxia): measure metrics for the DB file size to have some idea if it + // gets too big. + + if (!InitializeTables()) { + HandleInitializationFailure(); + return false; + } + + db_init_status_ = InitStatus::kSuccess; + RecordInitializationStatus(true); + return true; +} + +bool BrowsingTopicsSiteDataStorage::InitializeTables() { + sql::Transaction transaction(db_.get()); + if (!transaction.Begin()) + return false; + + if (!meta_table_.Init(db_.get(), kCurrentVersionNumber, + kCurrentVersionNumber)) { + return false; + } + + if (!CreateSchema()) + return false; + + // This is the first code version. No database version is expected to be + // smaller. Fail when this happens. + if (meta_table_.GetVersionNumber() < kCurrentVersionNumber) + return false; + + if (!transaction.Commit()) + return false; + + // This is possible with code reverts. The DB will never work until Chrome + // is re-upgraded. Assume the user will continue using this Chrome version + // and raze the DB to get the feature working. + if (meta_table_.GetVersionNumber() > kCurrentVersionNumber) { + db_->Raze(); + meta_table_.Reset(); + return InitializeTables(); + } + + return true; +} + +bool BrowsingTopicsSiteDataStorage::CreateSchema() { + static constexpr char kBrowsingTopicsApiUsagesTableSql[] = + // clang-format off + "CREATE TABLE IF NOT EXISTS browsing_topics_api_usages(" + "hashed_context_domain INTEGER NOT NULL," + "hashed_top_host INTEGER NOT NULL," + "last_usage_time INTEGER NOT NULL," + "PRIMARY KEY (hashed_context_domain,hashed_top_host))"; + // clang-format on + if (!db_->Execute(kBrowsingTopicsApiUsagesTableSql)) + return false; + + static constexpr char kLastUsageTimeIndexSql[] = + // clang-format off + "CREATE INDEX IF NOT EXISTS last_usage_time_idx " + "ON browsing_topics_api_usages(last_usage_time)"; + // clang-format on + if (!db_->Execute(kLastUsageTimeIndexSql)) + return false; + + return true; +} + +void BrowsingTopicsSiteDataStorage::HandleInitializationFailure() { + db_.reset(); + db_init_status_ = InitStatus::kFailure; + RecordInitializationStatus(false); +} + +void BrowsingTopicsSiteDataStorage::DatabaseErrorCallback( + int extended_error, + sql::Statement* stmt) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Attempt to recover a corrupt database. + if (sql::Recovery::ShouldRecover(extended_error)) { + // Prevent reentrant calls. + db_->reset_error_callback(); + + // After this call, the |db_| handle is poisoned so that future calls will + // return errors until the handle is re-opened. + sql::Recovery::RecoverDatabaseWithMetaVersion(db_.get(), path_to_database_); + + // The DLOG(FATAL) below is intended to draw immediate attention to errors + // in newly-written code. Database corruption is generally a result of OS or + // hardware issues, not coding errors at the client level, so displaying the + // error would probably lead to confusion. The ignored call signals the + // test-expectation framework that the error was handled. + std::ignore = sql::Database::IsExpectedSqliteError(extended_error); + return; + } + + // The default handling is to assert on debug and to ignore on release. + if (!sql::Database::IsExpectedSqliteError(extended_error)) + DLOG(FATAL) << db_->GetErrorMessage(); + + // Consider the database closed if we did not attempt to recover so we did not + // produce further errors. + db_init_status_ = InitStatus::kFailure; +} + +} // namespace content
diff --git a/content/browser/browsing_topics/browsing_topics_site_data_storage.h b/content/browser/browsing_topics/browsing_topics_site_data_storage.h new file mode 100644 index 0000000..5e0815c3 --- /dev/null +++ b/content/browser/browsing_topics/browsing_topics_site_data_storage.h
@@ -0,0 +1,103 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_BROWSING_TOPICS_BROWSING_TOPICS_SITE_DATA_STORAGE_H_ +#define CONTENT_BROWSER_BROWSING_TOPICS_BROWSING_TOPICS_SITE_DATA_STORAGE_H_ + +#include <string> + +#include "base/containers/flat_set.h" +#include "base/files/file_path.h" +#include "base/memory/weak_ptr.h" +#include "base/sequence_checker.h" +#include "base/thread_annotations.h" +#include "components/browsing_topics/common/common_types.h" +#include "content/common/content_export.h" +#include "sql/meta_table.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace sql { +class Database; +class Statement; +} // namespace sql + +namespace content { + +class CONTENT_EXPORT BrowsingTopicsSiteDataStorage { + public: + explicit BrowsingTopicsSiteDataStorage( + const base::FilePath& path_to_database); + + BrowsingTopicsSiteDataStorage(const BrowsingTopicsSiteDataStorage&) = delete; + BrowsingTopicsSiteDataStorage& operator=( + const BrowsingTopicsSiteDataStorage&) = delete; + BrowsingTopicsSiteDataStorage(BrowsingTopicsSiteDataStorage&&) = delete; + BrowsingTopicsSiteDataStorage& operator=(BrowsingTopicsSiteDataStorage&&) = + delete; + + ~BrowsingTopicsSiteDataStorage(); + + // Expire all data before the given time. + void ExpireDataBefore(base::Time time); + + // Get all browsing topics `ApiUsageContext` with its `last_usage_time` within + // [`begin_time`, `end_time`). Note that it's possible for a usage to occur + // within the specified time range, and a more recent usage has renewed its + // `last_usage_time`, so that the corresponding context is not retrieved in + // this query. In practice, this method will be called with + // `end_time` being very close to the current time, so the amount of missed + // data should be negligible. This query also deletes all data with + // last_usage_time (non-inclusive) less than `begin_time`. + browsing_topics::ApiUsageContextQueryResult GetBrowsingTopicsApiUsage( + base::Time begin_time, + base::Time end_time); + + // Persist the browsing topics api usage context to storage. Called when the + // usage is detected in a context on a page. + void OnBrowsingTopicsApiUsed( + const browsing_topics::HashedHost& hashed_top_host, + const base::flat_set<browsing_topics::HashedDomain>& + hashed_context_domains); + + private: + enum class InitStatus { + kUnattempted = 0, // `LazyInit()` has not yet been called. + kSuccess = 1, // `LazyInit()` succeeded. + kFailure = 2, // `LazyInit()` failed. + }; + + // Initializes the database if necessary, and returns whether the database is + // open. + bool LazyInit() VALID_CONTEXT_REQUIRED(sequence_checker_); + + bool InitializeTables() VALID_CONTEXT_REQUIRED(sequence_checker_); + bool CreateSchema() VALID_CONTEXT_REQUIRED(sequence_checker_); + + void HandleInitializationFailure() VALID_CONTEXT_REQUIRED(sequence_checker_); + + void DatabaseErrorCallback(int extended_error, sql::Statement* stmt); + + const base::FilePath path_to_database_; + + // Current status of the database initialization. Tracks what stage |this| is + // at for lazy initialization, and used as a signal for if the database is + // closed. This is initialized in the first call to LazyInit() to avoid doing + // additional work in the constructor. + InitStatus db_init_status_ GUARDED_BY_CONTEXT(sequence_checker_){ + InitStatus::kUnattempted}; + + // May be null if the database: + // - could not be opened + // - table/index initialization failed + std::unique_ptr<sql::Database> db_ GUARDED_BY_CONTEXT(sequence_checker_); + + sql::MetaTable meta_table_ GUARDED_BY_CONTEXT(sequence_checker_); + + SEQUENCE_CHECKER(sequence_checker_); + base::WeakPtrFactory<BrowsingTopicsSiteDataStorage> weak_factory_{this}; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_BROWSING_TOPICS_BROWSING_TOPICS_SITE_DATA_STORAGE_H_
diff --git a/content/browser/browsing_topics/browsing_topics_site_data_storage_unittest.cc b/content/browser/browsing_topics/browsing_topics_site_data_storage_unittest.cc new file mode 100644 index 0000000..76e8d204 --- /dev/null +++ b/content/browser/browsing_topics/browsing_topics_site_data_storage_unittest.cc
@@ -0,0 +1,481 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/browsing_topics/browsing_topics_site_data_storage.h" + +#include <functional> +#include <memory> + +#include "base/bind.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/memory/raw_ptr.h" +#include "base/path_service.h" +#include "base/run_loop.h" +#include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" +#include "base/test/task_environment.h" +#include "base/time/time.h" +#include "sql/database.h" +#include "sql/statement.h" +#include "sql/test/scoped_error_expecter.h" +#include "sql/test/test_helpers.h" +#include "sql/transaction.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/features.h" +#include "url/gurl.h" + +namespace content { + +namespace { + +int VersionFromMetaTable(sql::Database& db) { + // Get version. + sql::Statement s( + db.GetUniqueStatement("SELECT value FROM meta WHERE key='version'")); + if (!s.Step()) + return 0; + return s.ColumnInt(0); +} + +} // namespace + +class BrowsingTopicsSiteDataStorageTest : public testing::Test { + public: + BrowsingTopicsSiteDataStorageTest() + : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {} + + void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); } + + void TearDown() override { EXPECT_TRUE(temp_dir_.Delete()); } + + base::FilePath DbPath() const { + return temp_dir_.GetPath().AppendASCII("TestBrowsingTopicsSiteData.db"); + } + + base::FilePath GetSqlFilePath(base::StringPiece sql_filename) { + base::FilePath file_path; + base::PathService::Get(base::DIR_SOURCE_ROOT, &file_path); + file_path = file_path.AppendASCII("content/test/data/browsing_topics/"); + file_path = file_path.AppendASCII(sql_filename); + EXPECT_TRUE(base::PathExists(file_path)); + return file_path; + } + + size_t CountApiUsagesEntries(sql::Database& db) { + static const char kCountSQL[] = + "SELECT COUNT(*) FROM browsing_topics_api_usages"; + sql::Statement s(db.GetUniqueStatement(kCountSQL)); + EXPECT_TRUE(s.Step()); + return s.ColumnInt(0); + } + + void OpenDatabase() { + topics_storage_.reset(); + topics_storage_ = std::make_unique<BrowsingTopicsSiteDataStorage>(DbPath()); + } + + void CloseDatabase() { topics_storage_.reset(); } + + BrowsingTopicsSiteDataStorage* topics_storage() { + return topics_storage_.get(); + } + + protected: + base::ScopedTempDir temp_dir_; + std::unique_ptr<BrowsingTopicsSiteDataStorage> topics_storage_; + base::test::SingleThreadTaskEnvironment task_environment_; +}; + +TEST_F(BrowsingTopicsSiteDataStorageTest, + DatabaseInitialized_TablesAndIndexesLazilyInitialized) { + base::HistogramTester histograms; + + OpenDatabase(); + CloseDatabase(); + + // An unused BrowsingTopicsSiteDataStorage instance should not create the + // database. + EXPECT_FALSE(base::PathExists(DbPath())); + + // DB init UMA should not be recorded. + histograms.ExpectTotalCount("BrowsingTopics.SiteDataStorage.InitStatus", 0); + + OpenDatabase(); + // Trigger the lazy-initialization. + topics_storage()->GetBrowsingTopicsApiUsage( + /*begin_time=*/base::Time(), /*end_time=*/base::Time()); + CloseDatabase(); + + EXPECT_TRUE(base::PathExists(DbPath())); + + sql::Database db; + EXPECT_TRUE(db.Open(DbPath())); + + // [browsing_topics_api_usages], [meta]. + EXPECT_EQ(2u, sql::test::CountSQLTables(&db)); + + EXPECT_EQ(1, VersionFromMetaTable(db)); + + // [sqlite_autoindex_browsing_topics_api_usages_1], [last_usage_time_idx], + // and [sqlite_autoindex_meta_1]. + EXPECT_EQ(3u, sql::test::CountSQLIndices(&db)); + + // `hashed_context_domain`, `hashed_top_host`, and `last_usage_time`. + EXPECT_EQ(3u, + sql::test::CountTableColumns(&db, "browsing_topics_api_usages")); + + EXPECT_EQ(0u, CountApiUsagesEntries(db)); + + histograms.ExpectUniqueSample("BrowsingTopics.SiteDataStorage.InitStatus", + true, /*expected_bucket_count=*/1); +} + +TEST_F(BrowsingTopicsSiteDataStorageTest, LoadFromFile_CurrentVersion_Success) { + base::HistogramTester histograms; + + ASSERT_TRUE( + sql::test::CreateDatabaseFromSQL(DbPath(), GetSqlFilePath("v1.sql"))); + + OpenDatabase(); + // Trigger the lazy-initialization. + topics_storage()->GetBrowsingTopicsApiUsage( + /*begin_time=*/base::Time(), /*end_time=*/base::Time()); + CloseDatabase(); + + sql::Database db; + EXPECT_TRUE(db.Open(DbPath())); + EXPECT_EQ(2u, sql::test::CountSQLTables(&db)); + EXPECT_EQ(1, VersionFromMetaTable(db)); + EXPECT_EQ(1u, CountApiUsagesEntries(db)); + + histograms.ExpectUniqueSample("BrowsingTopics.SiteDataStorage.InitStatus", + true, /*expected_bucket_count=*/1); +} + +TEST_F(BrowsingTopicsSiteDataStorageTest, LoadFromFile_VersionTooOld_Failure) { + base::HistogramTester histograms; + + ASSERT_TRUE(sql::test::CreateDatabaseFromSQL( + DbPath(), GetSqlFilePath("v0.init_too_old.sql"))); + + OpenDatabase(); + // Trigger the lazy-initialization. + topics_storage()->GetBrowsingTopicsApiUsage( + /*begin_time=*/base::Time(), /*end_time=*/base::Time()); + CloseDatabase(); + + // Expect that the initialization was unsuccessful. The original database was + // unaffected. + sql::Database db; + EXPECT_TRUE(db.Open(DbPath())); + EXPECT_EQ(2u, sql::test::CountSQLTables(&db)); + EXPECT_EQ(0, VersionFromMetaTable(db)); + EXPECT_EQ(1u, CountApiUsagesEntries(db)); + + histograms.ExpectUniqueSample("BrowsingTopics.SiteDataStorage.InitStatus", + false, /*expected_bucket_count=*/1); +} + +TEST_F(BrowsingTopicsSiteDataStorageTest, LoadFromFile_VersionTooNew_Failure) { + base::HistogramTester histograms; + + ASSERT_TRUE(sql::test::CreateDatabaseFromSQL( + DbPath(), GetSqlFilePath("v1.init_too_new.sql"))); + + OpenDatabase(); + // Trigger the lazy-initialization. + topics_storage()->GetBrowsingTopicsApiUsage( + /*begin_time=*/base::Time(), /*end_time=*/base::Time()); + CloseDatabase(); + + // Expect that the initialization was successful. The original database was + // razed and re-initialized. + sql::Database db; + EXPECT_TRUE(db.Open(DbPath())); + EXPECT_EQ(2u, sql::test::CountSQLTables(&db)); + EXPECT_EQ(1, VersionFromMetaTable(db)); + EXPECT_EQ(0u, CountApiUsagesEntries(db)); + + histograms.ExpectUniqueSample("BrowsingTopics.SiteDataStorage.InitStatus", + true, /*expected_bucket_count=*/1); +} + +TEST_F(BrowsingTopicsSiteDataStorageTest, OnBrowsingTopicsApiUsed_SingleEntry) { + OpenDatabase(); + topics_storage()->OnBrowsingTopicsApiUsed( + /*hashed_top_host=*/browsing_topics::HashedHost(123), + /*hashed_context_domains=*/{browsing_topics::HashedDomain(456)}); + CloseDatabase(); + + sql::Database db; + EXPECT_TRUE(db.Open(DbPath())); + EXPECT_EQ(1u, CountApiUsagesEntries(db)); + + const char kGetAllEntriesSql[] = + "SELECT hashed_context_domain, hashed_top_host, last_usage_time FROM " + "browsing_topics_api_usages"; + sql::Statement s(db.GetUniqueStatement(kGetAllEntriesSql)); + EXPECT_TRUE(s.Step()); + + int64_t hashed_context_domain = s.ColumnInt64(0); + int64_t hashed_top_host = s.ColumnInt64(1); + base::Time time = s.ColumnTime(2); + + EXPECT_EQ(hashed_context_domain, 456); + EXPECT_EQ(hashed_top_host, 123); + EXPECT_EQ(time, base::Time::Now()); + + EXPECT_FALSE(s.Step()); +} + +TEST_F(BrowsingTopicsSiteDataStorageTest, + OnBrowsingTopicsApiUsed_MultipleEntries) { + OpenDatabase(); + topics_storage()->OnBrowsingTopicsApiUsed( + /*hashed_top_host=*/browsing_topics::HashedHost(123), + /*hashed_context_domains=*/{browsing_topics::HashedDomain(123)}); + + task_environment_.FastForwardBy(base::Seconds(1)); + + topics_storage()->OnBrowsingTopicsApiUsed( + /*hashed_top_host=*/browsing_topics::HashedHost(123), + /*hashed_context_domains=*/{browsing_topics::HashedDomain(456), + browsing_topics::HashedDomain(789)}); + topics_storage()->OnBrowsingTopicsApiUsed( + /*hashed_top_host=*/browsing_topics::HashedHost(456), + /*hashed_context_domains=*/{browsing_topics::HashedDomain(789)}); + CloseDatabase(); + + sql::Database db; + EXPECT_TRUE(db.Open(DbPath())); + EXPECT_EQ(4u, CountApiUsagesEntries(db)); + + const char kGetAllEntriesSql[] = + "SELECT hashed_context_domain, hashed_top_host, last_usage_time FROM " + "browsing_topics_api_usages " + "ORDER BY last_usage_time, hashed_top_host, hashed_context_domain"; + + sql::Statement s(db.GetUniqueStatement(kGetAllEntriesSql)); + + { + EXPECT_TRUE(s.Step()); + + int64_t hashed_context_domain = s.ColumnInt64(0); + int64_t hashed_top_host = s.ColumnInt64(1); + base::Time time = s.ColumnTime(2); + + EXPECT_EQ(hashed_context_domain, 123); + EXPECT_EQ(hashed_top_host, 123); + EXPECT_EQ(time, base::Time::Now() - base::Seconds(1)); + } + + { + EXPECT_TRUE(s.Step()); + + int64_t hashed_context_domain = s.ColumnInt64(0); + int64_t hashed_top_host = s.ColumnInt64(1); + base::Time time = s.ColumnTime(2); + + EXPECT_EQ(hashed_context_domain, 456); + EXPECT_EQ(hashed_top_host, 123); + EXPECT_EQ(time, base::Time::Now()); + } + + { + EXPECT_TRUE(s.Step()); + + int64_t hashed_context_domain = s.ColumnInt64(0); + int64_t hashed_top_host = s.ColumnInt64(1); + base::Time time = s.ColumnTime(2); + + EXPECT_EQ(hashed_context_domain, 789u); + EXPECT_EQ(hashed_top_host, 123); + EXPECT_EQ(time, base::Time::Now()); + } + + { + EXPECT_TRUE(s.Step()); + + int64_t hashed_context_domain = s.ColumnInt64(0); + int64_t hashed_top_host = s.ColumnInt64(1); + base::Time time = s.ColumnTime(2); + + EXPECT_EQ(hashed_context_domain, 789u); + EXPECT_EQ(hashed_top_host, 456); + EXPECT_EQ(time, base::Time::Now()); + } + + EXPECT_FALSE(s.Step()); +} + +TEST_F(BrowsingTopicsSiteDataStorageTest, GetBrowsingTopicsApiUsage) { + OpenDatabase(); + + topics_storage()->OnBrowsingTopicsApiUsed( + /*hashed_top_host=*/browsing_topics::HashedHost(123), + /*hashed_context_domains=*/{browsing_topics::HashedDomain(123)}); + + task_environment_.FastForwardBy(base::Seconds(1)); + + topics_storage()->OnBrowsingTopicsApiUsed( + /*hashed_top_host=*/browsing_topics::HashedHost(123), + /*hashed_context_domains=*/{browsing_topics::HashedDomain(456)}); + + task_environment_.FastForwardBy(base::Seconds(1)); + + browsing_topics::ApiUsageContextQueryResult result = + topics_storage()->GetBrowsingTopicsApiUsage( + /*begin_time=*/base::Time::Now() - base::Seconds(2), + /*end_time=*/base::Time::Now()); + CloseDatabase(); + + EXPECT_TRUE(result.success); + EXPECT_EQ(result.api_usage_contexts.size(), 2u); + + EXPECT_EQ(result.api_usage_contexts[0].hashed_top_host, + browsing_topics::HashedHost(123)); + EXPECT_EQ(result.api_usage_contexts[0].hashed_context_domain, + browsing_topics::HashedDomain(456)); + EXPECT_EQ(result.api_usage_contexts[0].time, + base::Time::Now() - base::Seconds(1)); + + EXPECT_EQ(result.api_usage_contexts[1].hashed_top_host, + browsing_topics::HashedHost(123)); + EXPECT_EQ(result.api_usage_contexts[1].hashed_context_domain, + browsing_topics::HashedDomain(123)); + EXPECT_EQ(result.api_usage_contexts[1].time, + base::Time::Now() - base::Seconds(2)); +} + +TEST_F(BrowsingTopicsSiteDataStorageTest, + GetBrowsingTopicsApiUsage_AutoExpireDataBeforeBeginTime) { + OpenDatabase(); + + topics_storage()->OnBrowsingTopicsApiUsed( + /*hashed_top_host=*/browsing_topics::HashedHost(123), + /*hashed_context_domains=*/{browsing_topics::HashedDomain(123)}); + + task_environment_.FastForwardBy(base::Seconds(1)); + + topics_storage()->OnBrowsingTopicsApiUsed( + /*hashed_top_host=*/browsing_topics::HashedHost(123), + /*hashed_context_domains=*/{browsing_topics::HashedDomain(456)}); + + task_environment_.FastForwardBy(base::Seconds(1)); + + browsing_topics::ApiUsageContextQueryResult result = + topics_storage()->GetBrowsingTopicsApiUsage( + /*begin_time=*/base::Time::Now() - base::Seconds(1), + /*end_time=*/base::Time::Now()); + CloseDatabase(); + + EXPECT_TRUE(result.success); + EXPECT_EQ(result.api_usage_contexts.size(), 1u); + EXPECT_EQ(result.api_usage_contexts[0].hashed_top_host, + browsing_topics::HashedHost(123)); + EXPECT_EQ(result.api_usage_contexts[0].hashed_context_domain, + browsing_topics::HashedDomain(456)); + EXPECT_EQ(result.api_usage_contexts[0].time, + base::Time::Now() - base::Seconds(1)); + + // The `GetBrowsingTopicsApiUsage()` should have deleted the first inserted + // entry. + sql::Database db; + EXPECT_TRUE(db.Open(DbPath())); + EXPECT_EQ(1u, CountApiUsagesEntries(db)); +} + +TEST_F(BrowsingTopicsSiteDataStorageTest, ExpireDataBefore) { + OpenDatabase(); + + topics_storage()->OnBrowsingTopicsApiUsed( + /*hashed_top_host=*/browsing_topics::HashedHost(123), + /*hashed_context_domains=*/{browsing_topics::HashedDomain(123)}); + + task_environment_.FastForwardBy(base::Seconds(1)); + + topics_storage()->OnBrowsingTopicsApiUsed( + /*hashed_top_host=*/browsing_topics::HashedHost(123), + /*hashed_context_domains=*/{browsing_topics::HashedDomain(456)}); + + task_environment_.FastForwardBy(base::Seconds(1)); + + topics_storage()->ExpireDataBefore(base::Time::Now() - base::Seconds(1)); + CloseDatabase(); + + sql::Database db; + EXPECT_TRUE(db.Open(DbPath())); + EXPECT_EQ(1u, CountApiUsagesEntries(db)); + + // The `ExpireDataBefore()` should have deleted the first inserted entry. + const char kGetAllEntriesSql[] = + "SELECT hashed_context_domain, hashed_top_host, last_usage_time FROM " + "browsing_topics_api_usages"; + sql::Statement s(db.GetUniqueStatement(kGetAllEntriesSql)); + EXPECT_TRUE(s.Step()); + + int64_t hashed_context_domain = s.ColumnInt64(0); + int64_t hashed_top_host = s.ColumnInt64(1); + base::Time time = s.ColumnTime(2); + + EXPECT_EQ(hashed_context_domain, 456); + EXPECT_EQ(hashed_top_host, 123); + EXPECT_EQ(time, base::Time::Now() - base::Seconds(1)); + + EXPECT_FALSE(s.Step()); +} + +class BrowsingTopicsSiteDataStorageMaxEntriesToLoadTest + : public BrowsingTopicsSiteDataStorageTest { + public: + BrowsingTopicsSiteDataStorageMaxEntriesToLoadTest() { + feature_list_.InitAndEnableFeatureWithParameters( + blink::features::kBrowsingTopics, + {{"max_number_of_api_usage_context_entries_to_load_per_epoch", "1"}}); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +TEST_F(BrowsingTopicsSiteDataStorageMaxEntriesToLoadTest, MaxEntriesToLoad) { + OpenDatabase(); + + topics_storage()->OnBrowsingTopicsApiUsed( + /*hashed_top_host=*/browsing_topics::HashedHost(123), + /*hashed_context_domains=*/{browsing_topics::HashedDomain(123)}); + + task_environment_.FastForwardBy(base::Seconds(1)); + + topics_storage()->OnBrowsingTopicsApiUsed( + /*hashed_top_host=*/browsing_topics::HashedHost(123), + /*hashed_context_domains=*/{browsing_topics::HashedDomain(456)}); + + task_environment_.FastForwardBy(base::Seconds(1)); + + browsing_topics::ApiUsageContextQueryResult result = + topics_storage()->GetBrowsingTopicsApiUsage( + /*begin_time=*/base::Time::Now() - base::Seconds(2), + /*end_time=*/base::Time::Now()); + CloseDatabase(); + + // Only the latest entry is loaded; the storage should still have two entries. + EXPECT_TRUE(result.success); + EXPECT_EQ(result.api_usage_contexts.size(), 1u); + + EXPECT_EQ(result.api_usage_contexts[0].hashed_top_host, + browsing_topics::HashedHost(123)); + EXPECT_EQ(result.api_usage_contexts[0].hashed_context_domain, + browsing_topics::HashedDomain(456)); + EXPECT_EQ(result.api_usage_contexts[0].time, + base::Time::Now() - base::Seconds(1)); + + sql::Database db; + EXPECT_TRUE(db.Open(DbPath())); + EXPECT_EQ(2u, CountApiUsagesEntries(db)); +} + +} // namespace content
diff --git a/content/browser/file_system_access/safe_move_helper.cc b/content/browser/file_system_access/safe_move_helper.cc index bea27b8..414e39f 100644 --- a/content/browser/file_system_access/safe_move_helper.cc +++ b/content/browser/file_system_access/safe_move_helper.cc
@@ -16,6 +16,7 @@ #include "components/services/quarantine/quarantine.h" #include "content/browser/file_system_access/file_system_access_error.h" #include "content/public/browser/content_browser_client.h" +#include "content/public/browser/global_routing_id.h" #include "content/public/common/content_client.h" #include "crypto/secure_hash.h" #include "mojo/public/cpp/bindings/callback_helpers.h" @@ -197,12 +198,18 @@ return; } + content::GlobalRenderFrameHostId outermost_main_frame_id; + auto* rfh = content::RenderFrameHost::FromID(context_.frame_id); + if (rfh) + outermost_main_frame_id = rfh->GetOutermostMainFrame()->GetGlobalId(); + auto item = std::make_unique<FileSystemAccessWriteItem>(); item->target_file_path = dest_url().path(); item->full_path = source_url().path(); item->sha256_hash = hash; item->size = size; item->frame_url = context_.url; + item->outermost_main_frame_id = outermost_main_frame_id; item->has_user_gesture = has_transient_user_activation_; manager_->permission_context()->PerformAfterWriteChecks( std::move(item), context_.frame_id,
diff --git a/content/public/browser/file_system_access_write_item.h b/content/public/browser/file_system_access_write_item.h index 5d8591d..cd6a4fe 100644 --- a/content/public/browser/file_system_access_write_item.h +++ b/content/public/browser/file_system_access_write_item.h
@@ -11,6 +11,7 @@ #include "base/files/file_path.h" #include "base/memory/raw_ptr.h" #include "content/common/content_export.h" +#include "content/public/browser/global_routing_id.h" #include "url/gurl.h" #include "url/origin.h" @@ -40,6 +41,10 @@ // URL of the frame in which the write operation took place. GURL frame_url; + + // id of the outermost main frame in which the write operation took place. + GlobalRenderFrameHostId outermost_main_frame_id; + // True iff the frame had a transient user activation when the writer was // created. bool has_user_gesture = false;
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc index bda9909..b86bdbc 100644 --- a/content/public/test/render_view_test.cc +++ b/content/public/test/render_view_test.cc
@@ -850,7 +850,7 @@ ->DidFinishSameDocumentNavigation( is_new_navigation ? blink::kWebStandardCommit : blink::kWebHistoryInertCommit, - false /* is_synchronously_committed */, + true /* is_synchronously_committed */, blink::mojom::SameDocumentNavigationType::kFragment, false /* is_client_redirect */); }
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index f20d944..717ec6b3 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -74,8 +74,6 @@ "gpu_benchmarking_extension.h", "in_process_renderer_thread.cc", "in_process_renderer_thread.h", - "internal_document_state_data.cc", - "internal_document_state_data.h", "media/audio_decoder.cc", "media/audio_decoder.h", "media/batching_media_log.cc",
diff --git a/content/renderer/document_state.cc b/content/renderer/document_state.cc index 7e46571..961fcf2 100644 --- a/content/renderer/document_state.cc +++ b/content/renderer/document_state.cc
@@ -4,18 +4,17 @@ #include "content/renderer/document_state.h" +#include "content/renderer/navigation_state.h" + namespace content { -DocumentState::DocumentState() : was_load_data_with_base_url_request_(false) {} +DocumentState::DocumentState() {} DocumentState::~DocumentState() {} -std::unique_ptr<DocumentState> DocumentState::Clone() { - std::unique_ptr<DocumentState> new_document_state(new DocumentState()); - new_document_state->set_was_load_data_with_base_url_request( - was_load_data_with_base_url_request_); - new_document_state->set_data_url(data_url_); - return new_document_state; +void DocumentState::set_navigation_state( + std::unique_ptr<NavigationState> navigation_state) { + navigation_state_ = std::move(navigation_state); } } // namespace content
diff --git a/content/renderer/document_state.h b/content/renderer/document_state.h index ea522fb..3a2d552 100644 --- a/content/renderer/document_state.h +++ b/content/renderer/document_state.h
@@ -15,10 +15,12 @@ namespace content { -// The RenderView stores an instance of this class in the "extra data" of each -// WebDocumentLoader (see RenderView::DidCreateDataSource). -class CONTENT_EXPORT DocumentState : public blink::WebDocumentLoader::ExtraData, - public base::SupportsUserData { +class NavigationState; + +// RenderFrameImpl stores an instance of this class in the "extra data" of each +// WebDocumentLoader. +class CONTENT_EXPORT DocumentState + : public blink::WebDocumentLoader::ExtraData { public: DocumentState(); ~DocumentState() override; @@ -28,10 +30,6 @@ return static_cast<DocumentState*>(document_loader->GetExtraData()); } - // Returns a copy of the DocumentState. This is a shallow copy, - // user data is not copied. - std::unique_ptr<DocumentState> Clone(); - // For LoadDataWithBaseURL navigations, |was_load_data_with_base_url_request_| // is set to true and |data_url_| is set to the data URL of the navigation. // Otherwise, |was_load_data_with_base_url_request_| is false and |data_url_| @@ -51,9 +49,39 @@ const GURL& data_url() const { return data_url_; } void set_data_url(const GURL& data_url) { data_url_ = data_url; } + // True if the user agent was overridden for this page. + bool is_overriding_user_agent() const { return is_overriding_user_agent_; } + void set_is_overriding_user_agent(bool state) { + is_overriding_user_agent_ = state; + } + + // True if we have to reset the scroll and scale state of the page + // after the provisional load has been committed. + bool must_reset_scroll_and_scale_state() const { + return must_reset_scroll_and_scale_state_; + } + void set_must_reset_scroll_and_scale_state(bool state) { + must_reset_scroll_and_scale_state_ = state; + } + + // This is a fake navigation request id, which we send to the browser process + // together with metrics. Note that renderer does not actually issue a request + // for navigation (browser does it instead), but still reports metrics for it. + // See content::mojom::ResourceLoadInfo. + int request_id() const { return request_id_; } + void set_request_id(int request_id) { request_id_ = request_id; } + + NavigationState* navigation_state() { return navigation_state_.get(); } + void set_navigation_state(std::unique_ptr<NavigationState> navigation_state); + void clear_navigation_state() { navigation_state_.reset(); } + private: - bool was_load_data_with_base_url_request_; + bool was_load_data_with_base_url_request_ = false; GURL data_url_; + bool is_overriding_user_agent_ = false; + bool must_reset_scroll_and_scale_state_ = false; + int request_id_ = -1; + std::unique_ptr<NavigationState> navigation_state_; }; } // namespace content
diff --git a/content/renderer/internal_document_state_data.cc b/content/renderer/internal_document_state_data.cc deleted file mode 100644 index 906d61ab..0000000 --- a/content/renderer/internal_document_state_data.cc +++ /dev/null
@@ -1,62 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/renderer/internal_document_state_data.h" - -#include "base/memory/ptr_util.h" -#include "content/renderer/document_state.h" -#include "content/renderer/navigation_state.h" -#include "third_party/blink/public/web/web_document_loader.h" - -namespace content { - -namespace { - -// Key InternalDocumentStateData is stored under in DocumentState. -const char kUserDataKey[] = "InternalDocumentStateData"; - -} - -InternalDocumentStateData::InternalDocumentStateData() - : is_overriding_user_agent_(false), - must_reset_scroll_and_scale_state_(false) {} - -// static -InternalDocumentStateData* InternalDocumentStateData::FromDocumentLoader( - blink::WebDocumentLoader* document_loader) { - return FromDocumentState( - static_cast<DocumentState*>(document_loader->GetExtraData())); -} - -// static -InternalDocumentStateData* InternalDocumentStateData::FromDocumentState( - DocumentState* ds) { - if (!ds) - return nullptr; - InternalDocumentStateData* data = static_cast<InternalDocumentStateData*>( - ds->GetUserData(&kUserDataKey)); - if (!data) { - data = new InternalDocumentStateData; - ds->SetUserData(&kUserDataKey, base::WrapUnique(data)); - } - return data; -} - -InternalDocumentStateData::~InternalDocumentStateData() { -} - -void InternalDocumentStateData::CopyFrom(InternalDocumentStateData* other) { - is_overriding_user_agent_ = other->is_overriding_user_agent_; - must_reset_scroll_and_scale_state_ = - other->must_reset_scroll_and_scale_state_; - effective_connection_type_ = other->effective_connection_type_; - request_id_ = other->request_id_; -} - -void InternalDocumentStateData::set_navigation_state( - std::unique_ptr<NavigationState> navigation_state) { - navigation_state_ = std::move(navigation_state); -} - -} // namespace content
diff --git a/content/renderer/internal_document_state_data.h b/content/renderer/internal_document_state_data.h deleted file mode 100644 index 515e000..0000000 --- a/content/renderer/internal_document_state_data.h +++ /dev/null
@@ -1,85 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_RENDERER_INTERNAL_DOCUMENT_STATE_DATA_H_ -#define CONTENT_RENDERER_INTERNAL_DOCUMENT_STATE_DATA_H_ - -#include <memory> - -#include "base/supports_user_data.h" -#include "net/nqe/effective_connection_type.h" -#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h" -#include "url/gurl.h" - -namespace blink { -class WebDocumentLoader; -} - -namespace content { - -class DocumentState; -class NavigationState; - -// Stores internal state per WebDocumentLoader. -class InternalDocumentStateData : public base::SupportsUserData::Data { - public: - InternalDocumentStateData(); - - InternalDocumentStateData(const InternalDocumentStateData&) = delete; - InternalDocumentStateData& operator=(const InternalDocumentStateData&) = - delete; - - ~InternalDocumentStateData() override; - - static InternalDocumentStateData* FromDocumentLoader( - blink::WebDocumentLoader* document_loader); - static InternalDocumentStateData* FromDocumentState(DocumentState* ds); - - void CopyFrom(InternalDocumentStateData* other); - - // True if the user agent was overridden for this page. - bool is_overriding_user_agent() const { return is_overriding_user_agent_; } - void set_is_overriding_user_agent(bool state) { - is_overriding_user_agent_ = state; - } - - // True if we have to reset the scroll and scale state of the page - // after the provisional load has been committed. - bool must_reset_scroll_and_scale_state() const { - return must_reset_scroll_and_scale_state_; - } - void set_must_reset_scroll_and_scale_state(bool state) { - must_reset_scroll_and_scale_state_ = state; - } - - net::EffectiveConnectionType effective_connection_type() const { - return effective_connection_type_; - } - void set_effective_connection_type( - net::EffectiveConnectionType effective_connection_type) { - effective_connection_type_ = effective_connection_type; - } - - // This is a fake navigation request id, which we send to the browser process - // together with metrics. Note that renderer does not actually issue a request - // for navigation (browser does it instead), but still reports metrics for it. - // See content::mojom::ResourceLoadInfo. - int request_id() const { return request_id_; } - void set_request_id(int request_id) { request_id_ = request_id; } - - NavigationState* navigation_state() { return navigation_state_.get(); } - void set_navigation_state(std::unique_ptr<NavigationState> navigation_state); - - private: - bool is_overriding_user_agent_; - bool must_reset_scroll_and_scale_state_; - net::EffectiveConnectionType effective_connection_type_ = - net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN; - int request_id_ = -1; - std::unique_ptr<NavigationState> navigation_state_; -}; - -} // namespace content - -#endif // CONTENT_RENDERER_INTERNAL_DOCUMENT_STATE_DATA_H_
diff --git a/content/renderer/navigation_state.cc b/content/renderer/navigation_state.cc index fc7ddc7..d459902 100644 --- a/content/renderer/navigation_state.cc +++ b/content/renderer/navigation_state.cc
@@ -9,7 +9,6 @@ #include "base/memory/ptr_util.h" #include "content/common/frame_messages.mojom.h" -#include "content/renderer/internal_document_state_data.h" #include "third_party/blink/public/common/navigation/navigation_params.h" #include "third_party/blink/public/mojom/commit_result/commit_result.mojom.h" @@ -43,13 +42,6 @@ /*was_initiated_in_this_frame=*/true)); } -// static -NavigationState* NavigationState::FromDocumentLoader( - blink::WebDocumentLoader* document_loader) { - return InternalDocumentStateData::FromDocumentLoader(document_loader) - ->navigation_state(); -} - bool NavigationState::WasWithinSameDocument() { return was_within_same_document_; }
diff --git a/content/renderer/navigation_state.h b/content/renderer/navigation_state.h index f1661d94..cba58a9f 100644 --- a/content/renderer/navigation_state.h +++ b/content/renderer/navigation_state.h
@@ -13,12 +13,10 @@ #include "third_party/blink/public/mojom/navigation/navigation_params.mojom.h" namespace blink { -class WebDocumentLoader; - namespace mojom { enum class CommitResult; } -} +} // namespace blink namespace content { @@ -39,9 +37,6 @@ static std::unique_ptr<NavigationState> CreateForSynchronousCommit(); - static NavigationState* FromDocumentLoader( - blink::WebDocumentLoader* document_loader); - // True iff the frame's navigation was within the same document. bool WasWithinSameDocument();
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index f45c6d7ad..345f6880 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -86,7 +86,6 @@ #include "content/renderer/effective_connection_type_helper.h" #include "content/renderer/frame_owner_properties_converter.h" #include "content/renderer/gpu_benchmarking_extension.h" -#include "content/renderer/internal_document_state_data.h" #include "content/renderer/media/media_permission_dispatcher.h" #include "content/renderer/mhtml_handle_writer.h" #include "content/renderer/mojo/blink_interface_registry_impl.h" @@ -370,7 +369,7 @@ bool is_main_frame, bool is_in_fenced_frame_tree) { NavigationState* navigation_state = - NavigationState::FromDocumentLoader(document_loader); + DocumentState::FromDocumentLoader(document_loader)->navigation_state(); ui::PageTransition default_transition = navigation_state->IsForSynchronousCommit() ? ui::PAGE_TRANSITION_LINK @@ -877,8 +876,8 @@ std::unique_ptr<DocumentState> BuildDocumentState() { std::unique_ptr<DocumentState> document_state = std::make_unique<DocumentState>(); - InternalDocumentStateData::FromDocumentState(document_state.get()) - ->set_navigation_state(NavigationState::CreateForSynchronousCommit()); + document_state->set_navigation_state( + NavigationState::CreateForSynchronousCommit()); return document_state; } @@ -893,18 +892,16 @@ bool was_initiated_in_this_frame, bool is_main_frame) { std::unique_ptr<DocumentState> document_state(new DocumentState()); - InternalDocumentStateData* internal_data = - InternalDocumentStateData::FromDocumentState(document_state.get()); DCHECK(!common_params.navigation_start.is_null()); DCHECK(!common_params.url.SchemeIs(url::kJavaScriptScheme)); - internal_data->set_is_overriding_user_agent( + document_state->set_is_overriding_user_agent( commit_params.is_overriding_user_agent); - internal_data->set_must_reset_scroll_and_scale_state( + document_state->set_must_reset_scroll_and_scale_state( common_params.navigation_type == blink::mojom::NavigationType::RELOAD_ORIGINAL_REQUEST_URL); - internal_data->set_request_id(request_id); + document_state->set_request_id(request_id); // If this is a loadDataWithBaseURL request, save the commit URL so that we // can send a DidCommit message with the URL that was originally sent by the @@ -915,11 +912,9 @@ if (load_data) document_state->set_data_url(common_params.url); - InternalDocumentStateData::FromDocumentState(document_state.get()) - ->set_navigation_state(NavigationState::Create( - common_params.Clone(), commit_params.Clone(), - std::move(commit_callback), std::move(navigation_client), - was_initiated_in_this_frame)); + document_state->set_navigation_state(NavigationState::Create( + common_params.Clone(), commit_params.Clone(), std::move(commit_callback), + std::move(navigation_client), was_initiated_in_this_frame)); return document_state; } @@ -3156,19 +3151,13 @@ if (common_params->initiator_origin) initiator_origin = common_params->initiator_origin.value(); - DocumentState* original_document_state = + DocumentState* document_state = DocumentState::FromDocumentLoader(frame_->GetDocumentLoader()); - std::unique_ptr<DocumentState> document_state = - original_document_state->Clone(); - InternalDocumentStateData* internal_data = - InternalDocumentStateData::FromDocumentState(document_state.get()); - internal_data->CopyFrom( - InternalDocumentStateData::FromDocumentState(original_document_state)); // This is a same-document navigation coming from the browser process (as // opposed to a fragment link click, which would have been handled // synchronously in the renderer process), therefore // |was_initiated_in_this_frame| must be false. - internal_data->set_navigation_state(NavigationState::Create( + document_state->set_navigation_state(NavigationState::Create( std::move(common_params), std::move(commit_params), mojom::NavigationClient::CommitNavigationCallback(), nullptr, false /* was_initiated_in_this_frame */)); @@ -3177,7 +3166,7 @@ commit_status = frame_->CommitSameDocumentNavigation( url, load_type, item_for_history_navigation, is_client_redirect, started_with_transient_activation, initiator_origin, - is_browser_initiated, std::move(document_state)); + is_browser_initiated); // The load of the URL can result in this frame being removed. Use a // WeakPtr as an easy way to detect whether this has occured. If so, this @@ -3752,9 +3741,9 @@ navigation_commit_state_ = NavigationCommitState::kDidCommit; WebDocumentLoader* document_loader = frame_->GetDocumentLoader(); - InternalDocumentStateData* internal_data = - InternalDocumentStateData::FromDocumentLoader(document_loader); - NavigationState* navigation_state = internal_data->navigation_state(); + DocumentState* document_state = + DocumentState::FromDocumentLoader(document_loader); + NavigationState* navigation_state = document_state->navigation_state(); DCHECK(!navigation_state->WasWithinSameDocument()); TRACE_EVENT2("navigation,benchmark,rail", @@ -3905,10 +3894,14 @@ UpdateEncoding(frame_, frame_->View()->PageEncoding().Utf8()); NotifyObserversOfNavigationCommit(transition); + + document_state->clear_navigation_state(); } void RenderFrameImpl::DidCommitDocumentReplacementNavigation( blink::WebDocumentLoader* document_loader) { + DocumentState::FromDocumentLoader(document_loader) + ->set_navigation_state(NavigationState::CreateForSynchronousCommit()); // TODO(https://crbug.com/855189): figure out which of the following observer // calls are necessary, if any. for (auto& observer : observers_) @@ -4049,11 +4042,13 @@ "RenderFrameImpl::didFinishSameDocumentNavigation", "id", routing_id_); WebDocumentLoader* document_loader = frame_->GetDocumentLoader(); - InternalDocumentStateData* data = - InternalDocumentStateData::FromDocumentLoader(document_loader); - if (is_synchronously_committed) - data->set_navigation_state(NavigationState::CreateForSynchronousCommit()); - data->navigation_state()->set_was_within_same_document(true); + DocumentState* document_state = + DocumentState::FromDocumentLoader(document_loader); + if (is_synchronously_committed) { + document_state->set_navigation_state( + NavigationState::CreateForSynchronousCommit()); + } + document_state->navigation_state()->set_was_within_same_document(true); ui::PageTransition transition = GetTransitionType( document_loader, IsMainFrame(), GetWebView()->IsFencedFrameRoot()); @@ -4075,10 +4070,13 @@ // If we end up reusing this WebRequest (for example, due to a #ref click), // we don't want the transition type to persist. Just clear it. - data->navigation_state()->set_transition_type(ui::PAGE_TRANSITION_LINK); + document_state->navigation_state()->set_transition_type( + ui::PAGE_TRANSITION_LINK); for (auto& observer : observers_) observer.DidFinishSameDocumentNavigation(); + + document_state->clear_navigation_state(); } void RenderFrameImpl::WillFreezePage() { @@ -4516,11 +4514,10 @@ const WebLocalFrame* main_frame = web_view->MainFrame()->ToWebLocalFrame(); WebDocumentLoader* document_loader = main_frame->GetDocumentLoader(); - InternalDocumentStateData* internal_data = - document_loader - ? InternalDocumentStateData::FromDocumentLoader(document_loader) - : nullptr; - return internal_data && internal_data->is_overriding_user_agent(); + DocumentState* document_state = + document_loader ? DocumentState::FromDocumentLoader(document_loader) + : nullptr; + return document_state && document_state->is_overriding_user_agent(); } blink::WebString RenderFrameImpl::DoNotTrackValue() { @@ -4632,10 +4629,9 @@ WebDocumentLoader* document_loader = frame_->GetDocumentLoader(); const WebURLResponse& response = document_loader->GetResponse(); - InternalDocumentStateData* internal_data = - InternalDocumentStateData::FromDocumentLoader( - frame_->GetDocumentLoader()); - NavigationState* navigation_state = internal_data->navigation_state(); + DocumentState* document_state = + DocumentState::FromDocumentLoader(frame_->GetDocumentLoader()); + NavigationState* navigation_state = document_state->navigation_state(); auto params = mojom::DidCommitProvisionalLoadParams::New(); params->http_status_code = response.HttpStatusCode(); @@ -4753,7 +4749,7 @@ // Send the user agent override back. params->is_overriding_user_agent = - internal_data->is_overriding_user_agent(); + document_state->is_overriding_user_agent(); params->history_list_was_cleared = navigation_state->commit_params().should_clear_history_list; @@ -4799,7 +4795,7 @@ requires_universal_access); } } - params->request_id = internal_data->request_id(); + params->request_id = document_state->request_id(); params->unload_start = GetWebFrame()->Performance().UnloadStart(); params->unload_end = GetWebFrame()->Performance().UnloadEnd(); @@ -4812,7 +4808,8 @@ void RenderFrameImpl::UpdateNavigationHistory( blink::WebHistoryCommitType commit_type) { NavigationState* navigation_state = - NavigationState::FromDocumentLoader(frame_->GetDocumentLoader()); + DocumentState::FromDocumentLoader(frame_->GetDocumentLoader()) + ->navigation_state(); const blink::mojom::CommitNavigationParams& commit_params = navigation_state->commit_params(); @@ -4847,10 +4844,9 @@ void RenderFrameImpl::UpdateStateForCommit( blink::WebHistoryCommitType commit_type, ui::PageTransition transition) { - InternalDocumentStateData* internal_data = - InternalDocumentStateData::FromDocumentLoader( - frame_->GetDocumentLoader()); - NavigationState* navigation_state = internal_data->navigation_state(); + DocumentState* document_state = + DocumentState::FromDocumentLoader(frame_->GetDocumentLoader()); + NavigationState* navigation_state = document_state->navigation_state(); // We need to update the last committed session history entry with state for // the previous page. Do this before updating the current history item. @@ -4858,9 +4854,9 @@ UpdateNavigationHistory(commit_type); - if (internal_data->must_reset_scroll_and_scale_state()) { + if (document_state->must_reset_scroll_and_scale_state()) { GetWebView()->ResetScrollAndScaleState(); - internal_data->set_must_reset_scroll_and_scale_state(false); + document_state->set_must_reset_scroll_and_scale_state(false); } if (!frame_->Parent()) { // Only for top frames. RenderThreadImpl* render_thread_impl = RenderThreadImpl::current(); @@ -4933,7 +4929,8 @@ std::move(params), std::move(same_document_params)); } else { NavigationState* navigation_state = - NavigationState::FromDocumentLoader(frame_->GetDocumentLoader()); + DocumentState::FromDocumentLoader(frame_->GetDocumentLoader()) + ->navigation_state(); if (navigation_state->has_navigation_client()) { navigation_state->RunCommitNavigationCallback( std::move(params), std::move(interface_params));
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index 7e4d769..b915910 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc
@@ -50,6 +50,7 @@ #include "content/renderer/accessibility/render_accessibility_impl.h" #include "content/renderer/accessibility/render_accessibility_manager.h" #include "content/renderer/agent_scheduling_group.h" +#include "content/renderer/document_state.h" #include "content/renderer/navigation_state.h" #include "content/renderer/render_frame_proxy.h" #include "content/renderer/render_process.h" @@ -278,6 +279,32 @@ return interfaces; } +// Helper that collects the CommonNavigationParams off of WebDocumentLoader's +// NavigationState during commit. The NavigationState is cleared when commit +// notifications are done, so any assertions about the CommonNavigationParams +// post-commit require the CommonNavigationParams to be stored manually. +class CommonParamsFrameLoadWaiter : public FrameLoadWaiter { + public: + explicit CommonParamsFrameLoadWaiter(RenderFrameImpl* frame) + : FrameLoadWaiter(frame), frame_(frame) {} + + const blink::mojom::CommonNavigationParamsPtr& common_params() { + return common_params_; + } + + private: + void DidCommitProvisionalLoad(ui::PageTransition transition) override { + NavigationState* navigation_state = + DocumentState::FromDocumentLoader( + frame_->GetWebFrame()->GetDocumentLoader()) + ->navigation_state(); + common_params_ = navigation_state->common_params().Clone(); + } + + blink::mojom::CommonNavigationParamsPtr common_params_; + const RenderFrameImpl* frame_; +}; + } // namespace class RenderViewImplTest : public RenderViewTest { @@ -333,7 +360,7 @@ web_view_->EnableDeviceEmulation(params); } - void GoToOffsetWithParams( + blink::mojom::CommonNavigationParamsPtr GoToOffsetWithParams( int offset, const blink::PageState& state, blink::mojom::CommonNavigationParamsPtr common_params, @@ -342,6 +369,10 @@ blink::WebView* webview = web_view_; int pending_offset = offset + webview->HistoryBackListCount(); + // The load actually happens asynchronously, so we pump messages to process + // the pending continuation. + CommonParamsFrameLoadWaiter waiter(frame()); + commit_params->page_state = state.ToEncodedData(); commit_params->nav_entry_id = pending_offset + 1; commit_params->pending_history_list_offset = pending_offset; @@ -352,9 +383,8 @@ 1; frame()->Navigate(std::move(common_params), std::move(commit_params)); - // The load actually happens asynchronously, so we pump messages to process - // the pending continuation. - FrameLoadWaiter(frame()).Wait(); + waiter.Wait(); + return waiter.common_params()->Clone(); } template <class T> @@ -2632,16 +2662,14 @@ // recorded at an appropriate time and is passed in the corresponding message. TEST_F(RenderViewImplTest, RendererNavigationStartTransmittedToBrowser) { base::TimeTicks lower_bound_navigation_start(base::TimeTicks::Now()); - FrameLoadWaiter waiter(frame()); + CommonParamsFrameLoadWaiter waiter(frame()); frame()->LoadHTMLStringForTesting("hello world", GURL("data:text/html,"), "UTF-8", GURL(), false /* replace_current_item */); waiter.Wait(); - NavigationState* navigation_state = NavigationState::FromDocumentLoader( - frame()->GetWebFrame()->GetDocumentLoader()); - EXPECT_FALSE(navigation_state->common_params().navigation_start.is_null()); + EXPECT_FALSE(waiter.common_params()->navigation_start.is_null()); EXPECT_LE(lower_bound_navigation_start, - navigation_state->common_params().navigation_start); + waiter.common_params()->navigation_start); } // Checks that a browser-initiated navigation in an initial document that was @@ -2651,13 +2679,11 @@ TEST_F(RenderViewImplTest, BrowserNavigationStart) { auto common_params = MakeCommonNavigationParams(-base::Seconds(1)); - FrameLoadWaiter waiter(frame()); + CommonParamsFrameLoadWaiter waiter(frame()); frame()->Navigate(common_params.Clone(), DummyCommitNavigationParams()); waiter.Wait(); - NavigationState* navigation_state = NavigationState::FromDocumentLoader( - frame()->GetWebFrame()->GetDocumentLoader()); EXPECT_EQ(common_params->navigation_start, - navigation_state->common_params().navigation_start); + waiter.common_params()->navigation_start); } // Sanity check for the Navigation Timing API |navigationStart| override. We @@ -2688,13 +2714,11 @@ ExecuteJavaScriptForTests("document.title = 'Hi!';"); auto common_params = MakeCommonNavigationParams(-base::Seconds(1)); - FrameLoadWaiter waiter(frame()); + CommonParamsFrameLoadWaiter waiter(frame()); frame()->Navigate(common_params.Clone(), DummyCommitNavigationParams()); waiter.Wait(); - NavigationState* navigation_state = NavigationState::FromDocumentLoader( - frame()->GetWebFrame()->GetDocumentLoader()); EXPECT_EQ(common_params->navigation_start, - navigation_state->common_params().navigation_start); + waiter.common_params()->navigation_start); } TEST_F(RenderViewImplTest, NavigationStartForReload) { @@ -2712,15 +2736,13 @@ // The browser navigation_start should not be used because beforeunload will // be fired during Navigate. - FrameLoadWaiter waiter(frame()); + CommonParamsFrameLoadWaiter waiter(frame()); frame()->Navigate(common_params.Clone(), DummyCommitNavigationParams()); waiter.Wait(); // The browser navigation_start is always used. - NavigationState* navigation_state = NavigationState::FromDocumentLoader( - frame()->GetWebFrame()->GetDocumentLoader()); EXPECT_EQ(common_params->navigation_start, - navigation_state->common_params().navigation_start); + waiter.common_params()->navigation_start); } TEST_F(RenderViewImplTest, NavigationStartForSameProcessHistoryNavigation) { @@ -2739,14 +2761,13 @@ common_params_back->transition = ui::PAGE_TRANSITION_FORWARD_BACK; common_params_back->navigation_type = blink::mojom::NavigationType::HISTORY_DIFFERENT_DOCUMENT; - GoToOffsetWithParams(-1, back_state, common_params_back.Clone(), - DummyCommitNavigationParams()); - NavigationState* navigation_state = NavigationState::FromDocumentLoader( - frame()->GetWebFrame()->GetDocumentLoader()); + auto final_common_params = + GoToOffsetWithParams(-1, back_state, common_params_back.Clone(), + DummyCommitNavigationParams()); // The browser navigation_start is always used. EXPECT_EQ(common_params_back->navigation_start, - navigation_state->common_params().navigation_start); + final_common_params->navigation_start); // Go forward. auto common_params_forward = blink::CreateCommonNavigationParams(); @@ -2755,12 +2776,11 @@ common_params_forward->transition = ui::PAGE_TRANSITION_FORWARD_BACK; common_params_forward->navigation_type = blink::mojom::NavigationType::HISTORY_DIFFERENT_DOCUMENT; - GoToOffsetWithParams(1, forward_state, common_params_forward.Clone(), - DummyCommitNavigationParams()); - navigation_state = NavigationState::FromDocumentLoader( - frame()->GetWebFrame()->GetDocumentLoader()); + auto final_common_params2 = + GoToOffsetWithParams(-1, back_state, common_params_back.Clone(), + DummyCommitNavigationParams()); EXPECT_EQ(common_params_forward->navigation_start, - navigation_state->common_params().navigation_start); + final_common_params2->navigation_start); } TEST_F(RenderViewImplTest, NavigationStartForCrossProcessHistoryNavigation) { @@ -2777,14 +2797,12 @@ commit_params->pending_history_list_offset = 1; commit_params->current_history_list_offset = 0; commit_params->current_history_list_length = 1; - FrameLoadWaiter waiter(frame()); + CommonParamsFrameLoadWaiter waiter(frame()); frame()->Navigate(common_params.Clone(), std::move(commit_params)); waiter.Wait(); - NavigationState* navigation_state = NavigationState::FromDocumentLoader( - frame()->GetWebFrame()->GetDocumentLoader()); EXPECT_EQ(common_params->navigation_start, - navigation_state->common_params().navigation_start); + waiter.common_params()->navigation_start); } TEST_F(RenderViewImplTest, PreferredSizeZoomed) {
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 3f9bed0..678fa48b 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -446,6 +446,7 @@ "//base/third_party/dynamic_annotations", "//build:chromeos_buildflags", "//cc:test_support", + "//components/browsing_topics/common:common", "//components/network_session_configurator/common:common", "//components/services/storage", "//components/startup_metric_utils/browser", @@ -1995,6 +1996,7 @@ "../browser/browsing_data/browsing_data_remover_impl_unittest.cc", "../browser/browsing_data/clear_site_data_handler_unittest.cc", "../browser/browsing_data/same_site_data_remover_impl_unittest.cc", + "../browser/browsing_topics/browsing_topics_site_data_storage_unittest.cc", "../browser/buckets/bucket_manager_host_unittest.cc", "../browser/byte_stream_unittest.cc", "../browser/cache_storage/cache_storage_blob_to_disk_cache_unittest.cc", @@ -2446,6 +2448,7 @@ "data/", "//media/test/data/", "//content/test/data/attribution_reporting/databases/", + "//content/test/data/browsing_topics/", ] }
diff --git a/content/test/attribution_simulator_impl.cc b/content/test/attribution_simulator_impl.cc index 19fccc5..f73df3ec 100644 --- a/content/test/attribution_simulator_impl.cc +++ b/content/test/attribution_simulator_impl.cc
@@ -22,8 +22,8 @@ #include "content/browser/attribution_reporting/attribution_cookie_checker.h" #include "content/browser/attribution_reporting/attribution_default_random_generator.h" #include "content/browser/attribution_reporting/attribution_insecure_random_generator.h" -#include "content/browser/attribution_reporting/attribution_manager.h" #include "content/browser/attribution_reporting/attribution_manager_impl.h" +#include "content/browser/attribution_reporting/attribution_observer.h" #include "content/browser/attribution_reporting/attribution_random_generator.h" #include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/attribution_report_sender.h" @@ -142,7 +142,7 @@ // Registers sources and triggers in the `AttributionManagerImpl` and records // rejected sources in a JSON list. -class AttributionEventHandler : public AttributionManager::Observer { +class AttributionEventHandler : public AttributionObserver { public: AttributionEventHandler(AttributionManagerImpl* manager, base::Value::ListStorage& rejected_sources, @@ -175,7 +175,7 @@ } private: - // AttributionManager::Observer: + // AttributionObserver: void OnSourceHandled(const StorableSource& source, StorableSource::Result result) override { @@ -234,7 +234,7 @@ rejected_triggers_.push_back(std::move(dict)); } - base::ScopedObservation<AttributionManager, AttributionManager::Observer> + base::ScopedObservation<AttributionManagerImpl, AttributionObserver> observation_{this}; base::raw_ptr<AttributionManagerImpl> manager_;
diff --git a/content/test/data/browsing_topics/v0.init_too_old.sql b/content/test/data/browsing_topics/v0.init_too_old.sql new file mode 100644 index 0000000..6229824 --- /dev/null +++ b/content/test/data/browsing_topics/v0.init_too_old.sql
@@ -0,0 +1,20 @@ +PRAGMA foreign_keys=OFF; + +BEGIN TRANSACTION; + +CREATE TABLE browsing_topics_api_usages ( +hashed_context_domain INTEGER NOT NULL, +hashed_top_host INTEGER NOT NULL, +last_usage_time INTEGER NOT NULL, +PRIMARY KEY (hashed_context_domain, hashed_top_host)); + +CREATE INDEX last_usage_time_idx ON browsing_topics_api_usages(last_usage_time); + +CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); + +INSERT INTO meta VALUES('version','0'); +INSERT INTO meta VALUES('last_compatible_version','1'); + +INSERT INTO browsing_topics_api_usages VALUES (111, 222, 333); + +COMMIT;
diff --git a/content/test/data/browsing_topics/v1.init_too_new.sql b/content/test/data/browsing_topics/v1.init_too_new.sql new file mode 100644 index 0000000..825043b --- /dev/null +++ b/content/test/data/browsing_topics/v1.init_too_new.sql
@@ -0,0 +1,20 @@ +PRAGMA foreign_keys=OFF; + +BEGIN TRANSACTION; + +CREATE TABLE browsing_topics_api_usages ( +hashed_context_domain INTEGER NOT NULL, +hashed_top_host INTEGER NOT NULL, +last_usage_time INTEGER NOT NULL, +PRIMARY KEY (hashed_context_domain, hashed_top_host)); + +CREATE INDEX last_usage_time_idx ON browsing_topics_api_usages(last_usage_time); + +CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); + +INSERT INTO meta VALUES('version','2'); +INSERT INTO meta VALUES('last_compatible_version','1'); + +INSERT INTO browsing_topics_api_usages VALUES (111, 222, 333); + +COMMIT;
diff --git a/content/test/data/browsing_topics/v1.sql b/content/test/data/browsing_topics/v1.sql new file mode 100644 index 0000000..10d6373 --- /dev/null +++ b/content/test/data/browsing_topics/v1.sql
@@ -0,0 +1,20 @@ +PRAGMA foreign_keys=OFF; + +BEGIN TRANSACTION; + +CREATE TABLE browsing_topics_api_usages ( +hashed_context_domain INTEGER NOT NULL, +hashed_top_host INTEGER NOT NULL, +last_usage_time INTEGER NOT NULL, +PRIMARY KEY (hashed_context_domain, hashed_top_host)); + +CREATE INDEX last_usage_time_idx ON browsing_topics_api_usages(last_usage_time); + +CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); + +INSERT INTO meta VALUES('version','1'); +INSERT INTO meta VALUES('last_compatible_version','1'); + +INSERT INTO browsing_topics_api_usages VALUES (111, 222, 333); + +COMMIT;
diff --git a/content/test/data/gpu/pixel_webgpu_import_video_frame_offscreen_canvas.html b/content/test/data/gpu/pixel_webgpu_import_video_frame_offscreen_canvas.html new file mode 100644 index 0000000..3197c77e --- /dev/null +++ b/content/test/data/gpu/pixel_webgpu_import_video_frame_offscreen_canvas.html
@@ -0,0 +1,61 @@ +<!DOCTYPE html> +<html> +<head> + <title>WebGPU importExternalTexture videoFrame test</title> + <style type="text/css"> + .nomargin { + margin: 0px auto; + } + </style> + <script type="text/javascript" src="pixel_webgpu_util.js"></script> + <script type="text/javascript" src="webcodecs/webcodecs_common.js"></script> + <script type="text/javascript"> + var g_swapsBeforeAck = 15; + + async function main() { + let cnv = document.getElementById('placeholder'); + let offscreen = cnv.transferControlToOffscreen(); + let ctx = offscreen.getContext('2d'); + const gpuCanvas = document.getElementById('canvas_webgpu'); + const [gpuDevice, gpuContext] = await webGpuUtils.init(gpuCanvas); + + if (!gpuDevice || !gpuContext) { + console.error("Failed to initialize WebGPU - skipping test"); + domAutomationController.send("FAILURE"); + return; + } + + let source = await createFrameSource("hw_decoder", cnv.width, cnv.height); + if (!source) { + console.error("Cannot get valid video frame - skipping test"); + domAutomationController.send("FAILURE"); + return; + } + + let frame = await source.getNextFrame(); + ctx.drawImage(frame, 0, 0, cnv.width, cnv.height); + + const renderCallback = function() { + webGpuUtils.importExternalTextureTest(gpuDevice, gpuContext, frame); + frame.close(); + waitForFinish(); + }; + + window.requestAnimationFrame(renderCallback); + } + + function waitForFinish() { + if (g_swapsBeforeAck == 0) { + domAutomationController.send("SUCCESS"); + } else { + g_swapsBeforeAck--; + window.requestAnimationFrame(waitForFinish); + } + } + </script> +</head> +<body onload="main()"> + <canvas id="placeholder" width="200" height="200" class="nomargin"></canvas> + <canvas id="canvas_webgpu" width="200" height="200" class="nomargin"></canvas> +</body> +</html>
diff --git a/content/test/gpu/gpu_tests/pixel_test_pages.py b/content/test/gpu/gpu_tests/pixel_test_pages.py index 48e7283..64bbd5e 100644 --- a/content/test/gpu/gpu_tests/pixel_test_pages.py +++ b/content/test/gpu/gpu_tests/pixel_test_pages.py
@@ -364,6 +364,20 @@ base_name + '_WebGPUImportVideoFrame', test_rect=[0, 0, 400, 200], browser_args=webgpu_args), + PixelTestPage('pixel_webgpu_import_video_frame.html', + base_name + '_WebGPUImportVideoFrameUnaccelerated', + test_rect=[0, 0, 400, 200], + browser_args=webgpu_args + + [cba.DISABLE_ACCELERATED_2D_CANVAS]), + PixelTestPage('pixel_webgpu_import_video_frame_offscreen_canvas.html', + base_name + '_WebGPUImportVideoFrameOffscreenCanvas', + test_rect=[0, 0, 400, 200], + browser_args=webgpu_args), + PixelTestPage( + 'pixel_webgpu_import_video_frame_offscreen_canvas.html', + base_name + '_WebGPUImportVideoFrameUnacceleratedOffscreenCanvas', + test_rect=[0, 0, 400, 200], + browser_args=webgpu_args + [cba.DISABLE_ACCELERATED_2D_CANVAS]), PixelTestPage('pixel_webgpu_webgl_teximage2d.html', base_name + '_WebGPUWebGLTexImage2D', test_rect=[0, 0, 400, 200],
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt index cea9dee..c2ecf78 100644 --- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -267,6 +267,9 @@ # always run on Windows RS3 or above. crbug.com/1066979 [ win ] Pixel_Canvas2DRedBoxHdr10 [ Failure ] +# Failure on win10 capturing a VideoFrame from unaccelerated OffscreenCanvas clears the source canvas +crbug.com/1300550 [ win ] Pixel_WebGPUImportVideoFrameUnacceleratedOffscreenCanvas [ Failure ] + # Flakes on gpu-fyi-try-chromeos-kevin and Fuchsia x64, produces notably different image. crbug.com/1086687 [ chromeos chromeos-board-kevin ] Pixel_PrecisionRoundedCorner [ Failure ] @@ -328,6 +331,10 @@ # Pixel_WebGPUImportVideoFrame hangs on Windows FYI bots crbug.com/1274796 [ win skia-renderer-gl ] Pixel_WebGPUImportVideoFrame [ Failure ] +# Crashes on gpu-fyi-win10-nvidia-rel-32 +crbug.com/1300670 [ win nvidia-0x2184 passthrough ] Pixel_WebGPUImportVideoFrameUnaccelerated [ Failure ] +crbug.com/1300670 [ win nvidia-0x2184 passthrough ] Pixel_WebGPUImportVideoFrameOffscreenCanvas [ Failure ] + # Pixel_Video_Media_Stream_Incompatible_Stride flakes with SkiaRenderer GL crbug.com/1213542 [ skia-renderer-gl linux nvidia-0x1cb3 ] Pixel_Video_Media_Stream_Incompatible_Stride [ RetryOnFailure ] crbug.com/1213542 [ skia-renderer-gl linux nvidia-0x2184 passthrough ] Pixel_Video_Media_Stream_Incompatible_Stride [ RetryOnFailure ]
diff --git a/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt index a1209d2..192387d 100644 --- a/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt
@@ -136,6 +136,11 @@ crbug.com/852089 [ fuchsia ] TraceTest_WebGPU* [ Skip ] crbug.com/852089 [ win7 ] TraceTest_WebGPU* [ Skip ] +# Tests that crash on gpu-fyi-win10-nvidia-rel-32 +crbug.com/1300670 [ win nvidia-0x2184 ] TraceTest_WebGPUImportVideoFrameUnacceleratedOffscreenCanvas [ Failure ] +crbug.com/1300670 [ win nvidia-0x2184 ] TraceTest_WebGPUImportVideoFrameOffscreenCanvas [ Failure ] +crbug.com/1300670 [ win nvidia-0x2184 ] TraceTest_WebGPUImportVideoFrameUnaccelerated [ Failure ] + ############################### # Temporary Skip Expectations # ###############################
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt index 1e961de..213e5da 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -745,6 +745,7 @@ crbug.com/1152588 [ linux amd-0x7340 ] conformance2/rendering/multisampling-fragment-evaluation.html [ Failure ] crbug.com/1283514 [ linux amd-0x7340 angle-opengl ] conformance2/textures/misc/angle-stuck-depth-textures.html [ Failure ] crbug.com/1283514 [ linux amd-0x7340 angle-opengl ] deqp/functional/gles3/fboinvalidate/whole.html [ Failure ] +crbug.com/1300683 [ linux amd-0x7340 angle-opengl passthrough ] deqp/functional/gles3/fborender/recreate_depth_stencil.html [ RetryOnFailure ] #################### # Android failures #
diff --git a/extensions/browser/app_window/app_window.h b/extensions/browser/app_window/app_window.h index 43343a5..676bf55 100644 --- a/extensions/browser/app_window/app_window.h +++ b/extensions/browser/app_window/app_window.h
@@ -248,7 +248,10 @@ const GURL& initial_url() const { return initial_url_; } bool is_hidden() const { return is_hidden_; } + // Calls to this should always be guarded by a nullptr check as this can + // return nullptr if the extension is no longer installed. const Extension* GetExtension() const; + NativeAppWindow* GetBaseWindow(); gfx::NativeWindow GetNativeWindow();
diff --git a/gpu/config/gpu_finch_features.cc b/gpu/config/gpu_finch_features.cc index e73186c..e2885365 100644 --- a/gpu/config/gpu_finch_features.cc +++ b/gpu/config/gpu_finch_features.cc
@@ -324,8 +324,10 @@ return false; // DrDc is supported on android MediaPlayer and MCVD path only when - // AImageReader is enabled. - if (!IsAImageReaderEnabled()) + // AImageReader is enabled. Also DrDc requires AImageReader max size to be + // at least 2 for each gpu thread. Hence DrDc is disabled on devices which has + // only 1 image. + if (!IsAImageReaderEnabled() || LimitAImageReaderMaxSizeToOne()) return false; // Check block list against build info. @@ -341,8 +343,10 @@ bool IsUsingThreadSafeMediaForWebView() { #if BUILDFLAG(IS_ANDROID) - // SurfaceTexture can't be thread-safe. - if (!IsAImageReaderEnabled()) + // SurfaceTexture can't be thread-safe. Also thread safe media code currently + // requires AImageReader max size to be at least 2 since one image could be + // accessed by each gpu thread in webview. + if (!IsAImageReaderEnabled() || LimitAImageReaderMaxSizeToOne()) return false; // Not yet compatible with Vulkan.
diff --git a/infra/config/generated/cq-builders.md b/infra/config/generated/cq-builders.md index 7aacc44..e769ab2 100644 --- a/infra/config/generated/cq-builders.md +++ b/infra/config/generated/cq-builders.md
@@ -391,6 +391,7 @@ Path regular expressions: * [`//tools/clang/scripts/update.py`](https://cs.chromium.org/search?q=+file:tools/clang/scripts/update.py) + * [`//DEPS`](https://cs.chromium.org/chromium/src/DEPS) * [win-updater-try-builder-dbg](https://ci.chromium.org/p/chromium/builders/try/win-updater-try-builder-dbg) ([definition](https://cs.chromium.org/search?q=+file:/try.star$+""win-updater-try-builder-dbg"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""win-updater-try-builder-dbg""))
diff --git a/infra/config/generated/cq-usage/full.cfg b/infra/config/generated/cq-usage/full.cfg index 1f45f8e..d887804a 100644 --- a/infra/config/generated/cq-usage/full.cfg +++ b/infra/config/generated/cq-usage/full.cfg
@@ -510,6 +510,7 @@ name: "chromium/try/reclient-config-deployment-verifier" disable_reuse: true location_regexp: ".+/[+]/tools/clang/scripts/update.py" + location_regexp: ".+/[+]/DEPS" } builders { name: "chromium/try/win-libfuzzer-asan-rel"
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg index 9210b3c..581be9d2 100644 --- a/infra/config/generated/luci/commit-queue.cfg +++ b/infra/config/generated/luci/commit-queue.cfg
@@ -1762,6 +1762,7 @@ name: "chromium/try/reclient-config-deployment-verifier" disable_reuse: true location_regexp: ".+/[+]/tools/clang/scripts/update.py" + location_regexp: ".+/[+]/DEPS" } builders { name: "chromium/try/tricium-metrics-analysis"
diff --git a/infra/config/subprojects/chromium/try/presubmit.star b/infra/config/subprojects/chromium/try/presubmit.star index 1153f312..5fe3eb4 100644 --- a/infra/config/subprojects/chromium/try/presubmit.star +++ b/infra/config/subprojects/chromium/try/presubmit.star
@@ -105,7 +105,10 @@ ], }, tryjob = try_.job( - location_regexp = [r".+/[+]/tools/clang/scripts/update.py"], + location_regexp = [ + r".+/[+]/tools/clang/scripts/update.py", + r".+/[+]/DEPS", + ], ), )
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_egtest.mm b/ios/chrome/browser/safe_browsing/safe_browsing_egtest.mm index adc37065..731f6d1 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_egtest.mm +++ b/ios/chrome/browser/safe_browsing/safe_browsing_egtest.mm
@@ -12,7 +12,6 @@ #include "components/strings/grit/components_strings.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_earl_grey.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_earl_grey_ui.h" -#import "ios/chrome/browser/ui/tab_switcher/tab_grid/features.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h"
diff --git a/ios/chrome/browser/ui/popup_menu/BUILD.gn b/ios/chrome/browser/ui/popup_menu/BUILD.gn index a77fda1..916ea98 100644 --- a/ios/chrome/browser/ui/popup_menu/BUILD.gn +++ b/ios/chrome/browser/ui/popup_menu/BUILD.gn
@@ -27,6 +27,7 @@ "resources:popup_menu_new_incognito_tab", "resources:popup_menu_new_tab", "resources:popup_menu_new_window", + "resources:popup_menu_open_tabs", "resources:popup_menu_paste_and_go", "resources:popup_menu_qr_scanner", "resources:popup_menu_read_later", @@ -43,6 +44,7 @@ "resources:popup_menu_text_zoom", "resources:popup_menu_translate", "resources:popup_menu_voice_search", + "resources:popup_menu_web", "//base", "//components/bookmarks/browser", "//components/bookmarks/common",
diff --git a/ios/chrome/browser/ui/popup_menu/request_desktop_mobile_site_egtest.mm b/ios/chrome/browser/ui/popup_menu/request_desktop_mobile_site_egtest.mm index 1590337..0b562b9 100644 --- a/ios/chrome/browser/ui/popup_menu/request_desktop_mobile_site_egtest.mm +++ b/ios/chrome/browser/ui/popup_menu/request_desktop_mobile_site_egtest.mm
@@ -8,7 +8,6 @@ #include "components/version_info/version_info.h" #import "ios/chrome/browser/ui/popup_menu/popup_menu_constants.h" #import "ios/chrome/browser/ui/settings/settings_table_view_controller_constants.h" -#import "ios/chrome/browser/ui/tab_switcher/tab_grid/features.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
diff --git a/ios/chrome/browser/ui/popup_menu/resources/BUILD.gn b/ios/chrome/browser/ui/popup_menu/resources/BUILD.gn index cdd05e9..bba625b 100644 --- a/ios/chrome/browser/ui/popup_menu/resources/BUILD.gn +++ b/ios/chrome/browser/ui/popup_menu/resources/BUILD.gn
@@ -248,3 +248,19 @@ "popup_menu_enterprise_icon.imageset/popup_menu_enterprise_icon@3x.png", ] } + +imageset("popup_menu_open_tabs") { + sources = [ + "popup_menu_open_tabs.imageset/Contents.json", + "popup_menu_open_tabs.imageset/popup_menu_open_tabs@2x.png", + "popup_menu_open_tabs.imageset/popup_menu_open_tabs@3x.png", + ] +} + +imageset("popup_menu_web") { + sources = [ + "popup_menu_web.imageset/Contents.json", + "popup_menu_web.imageset/popup_menu_web@2x.png", + "popup_menu_web.imageset/popup_menu_web@3x.png", + ] +}
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_open_tabs.imageset/Contents.json b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_open_tabs.imageset/Contents.json new file mode 100644 index 0000000..67e70d3 --- /dev/null +++ b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_open_tabs.imageset/Contents.json
@@ -0,0 +1,18 @@ +{ + "images": [ + { + "idiom": "universal", + "scale": "2x", + "filename": "popup_menu_open_tabs@2x.png" + }, + { + "idiom": "universal", + "scale": "3x", + "filename": "popup_menu_open_tabs@3x.png" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +}
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_open_tabs.imageset/popup_menu_open_tabs@2x.png b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_open_tabs.imageset/popup_menu_open_tabs@2x.png new file mode 100644 index 0000000..51981e4a --- /dev/null +++ b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_open_tabs.imageset/popup_menu_open_tabs@2x.png Binary files differ
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_open_tabs.imageset/popup_menu_open_tabs@3x.png b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_open_tabs.imageset/popup_menu_open_tabs@3x.png new file mode 100644 index 0000000..de9bfe2 --- /dev/null +++ b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_open_tabs.imageset/popup_menu_open_tabs@3x.png Binary files differ
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_web.imageset/Contents.json b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_web.imageset/Contents.json new file mode 100644 index 0000000..2d856b9 --- /dev/null +++ b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_web.imageset/Contents.json
@@ -0,0 +1,18 @@ +{ + "images": [ + { + "idiom": "universal", + "scale": "2x", + "filename": "popup_menu_web@2x.png" + }, + { + "idiom": "universal", + "scale": "3x", + "filename": "popup_menu_web@3x.png" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +}
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_web.imageset/popup_menu_web@2x.png b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_web.imageset/popup_menu_web@2x.png new file mode 100644 index 0000000..8b6b03a --- /dev/null +++ b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_web.imageset/popup_menu_web@2x.png Binary files differ
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_web.imageset/popup_menu_web@3x.png b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_web.imageset/popup_menu_web@3x.png new file mode 100644 index 0000000..a66ef44f --- /dev/null +++ b/ios/chrome/browser/ui/popup_menu/resources/popup_menu_web.imageset/popup_menu_web@3x.png Binary files differ
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm index c2ef9f24..64ccd71 100644 --- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm +++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
@@ -764,7 +764,7 @@ initWithType:ItemTypeSuggestedActionSearchWeb]; searchWebItem.title = l10n_util::GetNSString(IDS_IOS_TABS_SEARCH_SUGGESTED_ACTION_SEARCH_WEB); - searchWebItem.image = [[UIImage imageNamed:@"popup_menu_search"] + searchWebItem.image = [[UIImage imageNamed:@"popup_menu_web"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; [model addItem:searchWebItem toSectionWithIdentifier:SectionIdentifierSuggestedActions]; @@ -775,7 +775,7 @@ initWithType:ItemTypeSuggestedActionSearchOpenTabs]; searchOpenTabsItem.title = l10n_util::GetNSString( IDS_IOS_TABS_SEARCH_SUGGESTED_ACTION_SEARCH_OPEN_TABS); - searchOpenTabsItem.image = [[UIImage imageNamed:@"popup_menu_search"] + searchOpenTabsItem.image = [[UIImage imageNamed:@"popup_menu_open_tabs"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; [model addItem:searchOpenTabsItem toSectionWithIdentifier:SectionIdentifierSuggestedActions];
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm b/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm index 480407a..0e1ad26 100644 --- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm +++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm
@@ -247,8 +247,7 @@ IDS_IOS_GOOGLE_SERVICES_SETTINGS_ALLOW_SIGNIN_TEXT detailStringID: IDS_IOS_GOOGLE_SERVICES_SETTINGS_ALLOW_SIGNIN_DETAIL - status:GetStatusForSigninPolicy() - controllable:IsSigninControllableByUser()]; + status:GetStatusForSigninPolicy()]; } #pragma mark - Load non personalized section @@ -362,8 +361,7 @@ IDS_IOS_GOOGLE_SERVICES_SETTINGS_AUTOCOMPLETE_SEARCHES_AND_URLS_TEXT detailStringID: IDS_IOS_GOOGLE_SERVICES_SETTINGS_AUTOCOMPLETE_SEARCHES_AND_URLS_DETAIL - status:self.autocompleteSearchPreference.value - controllable:self.autocompleteSearchPreference.value]; + status:self.autocompleteSearchPreference.value]; [items addObject:autocompleteItem]; } else { SyncSwitchItem* autocompleteItem = [self @@ -382,8 +380,7 @@ IDS_IOS_GOOGLE_SERVICES_SETTINGS_SAFE_BROWSING_TEXT detailStringID: IDS_IOS_GOOGLE_SERVICES_SETTINGS_SAFE_BROWSING_DETAIL - status:self.safeBrowsingPreference.value - controllable:self.safeBrowsingPreference.value]; + status:self.safeBrowsingPreference.value]; [items addObject:safeBrowsingManagedItem]; } else { SyncSwitchItem* safeBrowsingItem = [self @@ -405,8 +402,7 @@ IDS_IOS_GOOGLE_SERVICES_SETTINGS_IMPROVE_CHROME_TEXT detailStringID: IDS_IOS_GOOGLE_SERVICES_SETTINGS_IMPROVE_CHROME_DETAIL - status:self.sendDataUsagePreference - controllable:self.sendDataUsagePreference]; + status:self.sendDataUsagePreference]; [items addObject:improveChromeItem]; } else { SyncSwitchItem* improveChromeItem = [self @@ -425,8 +421,7 @@ IDS_IOS_GOOGLE_SERVICES_SETTINGS_BETTER_SEARCH_AND_BROWSING_TEXT detailStringID: IDS_IOS_GOOGLE_SERVICES_SETTINGS_BETTER_SEARCH_AND_BROWSING_DETAIL - status:self.anonymizedDataCollectionPreference - controllable:self.anonymizedDataCollectionPreference]; + status:self.anonymizedDataCollectionPreference]; betterSearchAndBrowsingItem.accessibilityIdentifier = kBetterSearchAndBrowsingItemAccessibilityID; [items addObject:betterSearchAndBrowsingItem]; @@ -448,8 +443,7 @@ tableViewInfoButtonItemType:TrackPricesOnTabsItemType textStringID:IDS_IOS_TRACK_PRICES_ON_TABS detailStringID:IDS_IOS_TRACK_PRICES_ON_TABS_DESCRIPTION - status:self.trackPricesOnTabsPreference - controllable:self.trackPricesOnTabsPreference]; + status:self.trackPricesOnTabsPreference]; trackPricesOnTabsItem.accessibilityIdentifier = kTrackPricesOnTabsItemAccessibilityID; [items addObject:trackPricesOnTabsItem]; @@ -502,8 +496,7 @@ - (TableViewInfoButtonItem*)tableViewInfoButtonItemType:(NSInteger)itemType textStringID:(int)textStringID detailStringID:(int)detailStringID - status:(BOOL)status - controllable:(BOOL)controllable { + status:(BOOL)status { TableViewInfoButtonItem* managedItem = [[TableViewInfoButtonItem alloc] initWithType:itemType]; managedItem.text = GetNSString(textStringID); @@ -514,14 +507,11 @@ managedItem.tintColor = [UIColor colorNamed:kGrey300Color]; } - // When there is no knob (not controllable), then set the color opacity to - // 40%. - if (!controllable) { - managedItem.textColor = - [[UIColor colorNamed:kTextPrimaryColor] colorWithAlphaComponent:0.4f]; - managedItem.detailTextColor = - [[UIColor colorNamed:kTextSecondaryColor] colorWithAlphaComponent:0.4f]; - } + // This item is not controllable, then set the color opacity to 40%. + managedItem.textColor = + [[UIColor colorNamed:kTextPrimaryColor] colorWithAlphaComponent:0.4f]; + managedItem.detailTextColor = + [[UIColor colorNamed:kTextSecondaryColor] colorWithAlphaComponent:0.4f]; managedItem.accessibilityHint = l10n_util::GetNSString(IDS_IOS_TOGGLE_SETTING_MANAGED_ACCESSIBILITY_HINT); return managedItem;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.mm index 7192b4b..757623b 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.mm
@@ -11,7 +11,6 @@ #include "base/notreached.h" #import "ios/chrome/browser/commerce/price_alert_util.h" #import "ios/chrome/browser/ui/elements/top_aligned_image_view.h" -#import "ios/chrome/browser/ui/tab_switcher/tab_grid/features.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h"
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_context_menu_helper.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_context_menu_helper.mm index d07096f..1bed922f 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_context_menu_helper.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_context_menu_helper.mm
@@ -13,7 +13,6 @@ #import "ios/chrome/browser/ui/menu/action_factory.h" #import "ios/chrome/browser/ui/menu/tab_context_menu_delegate.h" #import "ios/chrome/browser/ui/ntp/ntp_util.h" -#import "ios/chrome/browser/ui/tab_switcher/tab_grid/features.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_item.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_menu_actions_data_source.h"
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 9660038..9efbac13 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
@@ -888,7 +888,8 @@ - (void)didSelectSearchRecentTabsInSuggestedActionsViewController: (SuggestedActionsViewController*)viewController { - // TODO(crbug.com/1297859): Log the user action. + base::RecordAction( + base::UserMetricsAction("TabsSearch.SuggestedActions.RecentTabs")); [self.suggestedActionsDelegate searchRecentTabsForText:self.searchText]; }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/suggested_actions/suggested_actions_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/suggested_actions/suggested_actions_view_controller.mm index da94278..882fdac 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/suggested_actions/suggested_actions_view_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/suggested_actions/suggested_actions_view_controller.mm
@@ -105,7 +105,7 @@ initWithType:ItemTypeSuggestedActionSearchWeb]; searchWebItem.title = l10n_util::GetNSString(IDS_IOS_TABS_SEARCH_SUGGESTED_ACTION_SEARCH_WEB); - searchWebItem.image = [[UIImage imageNamed:@"popup_menu_search"] + searchWebItem.image = [[UIImage imageNamed:@"popup_menu_web"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; [model addItem:searchWebItem toSectionWithIdentifier:kSectionIdentifierSuggestedActions];
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 2052733b..867144b 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,7 +5,6 @@ #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_bottom_toolbar.h" #include "base/strings/sys_string_conversions.h" -#import "ios/chrome/browser/ui/tab_switcher/tab_grid/features.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_constants.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_new_tab_button.h"
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm index 4970926..25fded0 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
@@ -8,7 +8,6 @@ #import "base/test/ios/wait_util.h" #import "components/bookmarks/common/bookmark_pref_names.h" #import "ios/chrome/browser/ui/start_surface/start_surface_features.h" -#import "ios/chrome/browser/ui/tab_switcher/tab_grid/features.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_constants.h" #include "ios/chrome/grit/ios_strings.h"
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_transition_egtest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_transition_egtest.mm index fa7a5ad..6afa7e3 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_transition_egtest.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_transition_egtest.mm
@@ -7,7 +7,6 @@ #include "base/bind.h" #include "base/strings/sys_string_conversions.h" -#import "ios/chrome/browser/ui/tab_switcher/tab_grid/features.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
diff --git a/ios/chrome/browser/web/error_page_egtest.mm b/ios/chrome/browser/web/error_page_egtest.mm index 39e40106..186e1c2a 100644 --- a/ios/chrome/browser/web/error_page_egtest.mm +++ b/ios/chrome/browser/web/error_page_egtest.mm
@@ -9,7 +9,6 @@ #include "base/bind.h" #import "base/test/ios/wait_util.h" -#import "ios/chrome/browser/ui/tab_switcher/tab_grid/features.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h"
diff --git a/ios/web/public/webui/web_ui_ios.h b/ios/web/public/webui/web_ui_ios.h index 8eba45f..e7671cd 100644 --- a/ios/web/public/webui/web_ui_ios.h +++ b/ios/web/public/webui/web_ui_ios.h
@@ -42,18 +42,23 @@ virtual void AddMessageHandler( std::unique_ptr<WebUIIOSMessageHandler> handler) = 0; + // TODO(crbug.com/1300095): new version of DeprecatedMessageCallback2 that + // takes base::Value::List as a parameter needs to be introduced. Afterwards + // existing callers of RegisterDeprecatedMessageCallback() should be migrated + // to the new RegisterMessageCallback() (not the one below) version. + // // Used by WebUIIOSMessageHandlers. If the given message is already // registered, the call has no effect. - using MessageCallback = + using DeprecatedMessageCallback2 = base::RepeatingCallback<void(base::Value::ConstListView)>; virtual void RegisterMessageCallback(const std::string& message, - MessageCallback callback) = 0; + DeprecatedMessageCallback2 callback) = 0; - // Always use RegisterMessageCallback() above in new code. - // - // TODO(crbug.com/1243386): Existing callers of - // RegisterDeprecatedMessageCallback() should be migrated to - // RegisterMessageCallback() if possible. + // TODO(crbug.com/1300095): new version of DeprecatedMessageCallback that + // takes base::Value::List as a parameter needs to be introduced. Afterwards + // existing callers of RegisterDeprecatedMessageCallback() should be migrated + // to the new RegisterMessageCallback() (not the one above) version if + // possible. // // Used by WebUIIOSMessageHandlers. If the given message is already // registered, the call has no effect.
diff --git a/ios/web/webui/web_ui_ios_impl.h b/ios/web/webui/web_ui_ios_impl.h index 27aab67..ed2dabf 100644 --- a/ios/web/webui/web_ui_ios_impl.h +++ b/ios/web/webui/web_ui_ios_impl.h
@@ -37,12 +37,8 @@ void SetController(std::unique_ptr<WebUIIOSController> controller) override; void AddMessageHandler( std::unique_ptr<WebUIIOSMessageHandler> handler) override; - using MessageCallback = - base::RepeatingCallback<void(base::Value::ConstListView)>; void RegisterMessageCallback(const std::string& message, - MessageCallback callback) override; - using DeprecatedMessageCallback = - base::RepeatingCallback<void(const base::ListValue*)>; + DeprecatedMessageCallback2 callback) override; void RegisterDeprecatedMessageCallback( const std::string& message, const DeprecatedMessageCallback& callback) override; @@ -69,8 +65,9 @@ void ExecuteJavascript(const std::u16string& javascript); // A map of message name -> message handling callback. - using MessageCallbackMap = std::map<std::string, MessageCallback>; - MessageCallbackMap message_callbacks_; + using DeprecatedMessageCallback2Map = + std::map<std::string, DeprecatedMessageCallback2>; + DeprecatedMessageCallback2Map deprecated_message_callbacks_2_; // A map of message name -> message handling callback. using DeprecatedMessageCallbackMap =
diff --git a/ios/web/webui/web_ui_ios_impl.mm b/ios/web/webui/web_ui_ios_impl.mm index e051dc3..edf4161 100644 --- a/ios/web/webui/web_ui_ios_impl.mm +++ b/ios/web/webui/web_ui_ios_impl.mm
@@ -108,9 +108,10 @@ GetJavascriptCall("cr.webUIListenerCallback", modified_args)); } -void WebUIIOSImpl::RegisterMessageCallback(const std::string& message, - MessageCallback callback) { - message_callbacks_.emplace(message, std::move(callback)); +void WebUIIOSImpl::RegisterMessageCallback( + const std::string& message, + DeprecatedMessageCallback2 callback) { + deprecated_message_callbacks_2_.emplace(message, std::move(callback)); } void WebUIIOSImpl::RegisterDeprecatedMessageCallback( @@ -153,19 +154,20 @@ return; // Look up the callback for this message. - MessageCallbackMap::const_iterator callback = - message_callbacks_.find(message); - if (callback != message_callbacks_.end()) { + auto deprecated_message_callback_2_it = + deprecated_message_callbacks_2_.find(message); + if (deprecated_message_callback_2_it != + deprecated_message_callbacks_2_.end()) { // Forward this message and content on. - callback->second.Run(args.GetListDeprecated()); + deprecated_message_callback_2_it->second.Run(args.GetListDeprecated()); + return; } // Look up the deprecated callback for this message. - DeprecatedMessageCallbackMap::const_iterator deprecated_callback = - deprecated_message_callbacks_.find(message); - if (deprecated_callback != deprecated_message_callbacks_.end()) { + auto deprecated_callback_it = deprecated_message_callbacks_.find(message); + if (deprecated_callback_it != deprecated_message_callbacks_.end()) { // Forward this message and content on. - deprecated_callback->second.Run(&base::Value::AsListValue(args)); + deprecated_callback_it->second.Run(&base::Value::AsListValue(args)); } }
diff --git a/media/audio/audio_debug_recording_helper.cc b/media/audio/audio_debug_recording_helper.cc index b7d5328..24d55f9c 100644 --- a/media/audio/audio_debug_recording_helper.cc +++ b/media/audio/audio_debug_recording_helper.cc
@@ -13,6 +13,7 @@ #include "base/memory/ptr_util.h" #include "base/task/single_thread_task_runner.h" #include "media/audio/audio_debug_file_writer.h" +#include "media/base/audio_bus.h" namespace media {
diff --git a/media/base/audio_parameters.cc b/media/base/audio_parameters.cc index 401d8034..f60b3a2 100644 --- a/media/base/audio_parameters.cc +++ b/media/base/audio_parameters.cc
@@ -6,10 +6,22 @@ #include <sstream> +#include "media/base/audio_bus.h" #include "media/base/limits.h" namespace media { +static_assert(AudioBus::kChannelAlignment == kParametersAlignment, + "Audio buffer parameters struct alignment not same as AudioBus"); +static_assert(sizeof(AudioInputBufferParameters) % + AudioBus::kChannelAlignment == + 0, + "AudioInputBufferParameters not aligned"); +static_assert(sizeof(AudioOutputBufferParameters) % + AudioBus::kChannelAlignment == + 0, + "AudioOutputBufferParameters not aligned"); + const char* FormatToString(AudioParameters::Format format) { switch (format) { case AudioParameters::AUDIO_PCM_LINEAR:
diff --git a/media/base/audio_parameters.h b/media/base/audio_parameters.h index 256bc29..2b8c5f8f 100644 --- a/media/base/audio_parameters.h +++ b/media/base/audio_parameters.h
@@ -13,7 +13,6 @@ #include "base/numerics/checked_math.h" #include "base/time/time.h" #include "build/build_config.h" -#include "media/base/audio_bus.h" #include "media/base/audio_latency.h" #include "media/base/audio_point.h" #include "media/base/channel_layout.h" @@ -27,19 +26,18 @@ // size as sizeof(Audio{Input,Output}BufferParameters) + #(bytes in audio // buffer) without using packing. Also align Audio{Input,Output}BufferParameters // instead of in Audio{Input,Output}Buffer to be able to calculate size like so. -// Use a macro for the alignment value that's the same as +// Use a constexpr for the alignment value that's the same as // AudioBus::kChannelAlignment, since MSVC doesn't accept the latter to be used. #if BUILDFLAG(IS_WIN) #pragma warning(push) #pragma warning(disable : 4324) // Disable warning for added padding. #endif -#define PARAMETERS_ALIGNMENT 16 -static_assert(AudioBus::kChannelAlignment == PARAMETERS_ALIGNMENT, - "Audio buffer parameters struct alignment not same as AudioBus"); +constexpr int kParametersAlignment = 16; + // ****WARNING****: Do not change the field types or ordering of these fields // without checking that alignment is correct. The structs may be concurrently // accessed by both 32bit and 64bit process in shmem. http://crbug.com/781095. -struct MEDIA_SHMEM_EXPORT ALIGNAS(PARAMETERS_ALIGNMENT) +struct MEDIA_SHMEM_EXPORT ALIGNAS(kParametersAlignment) AudioInputBufferParameters { double volume; int64_t capture_time_us; // base::TimeTicks in microseconds. @@ -47,7 +45,7 @@ uint32_t id; bool key_pressed; }; -struct MEDIA_SHMEM_EXPORT ALIGNAS(PARAMETERS_ALIGNMENT) +struct MEDIA_SHMEM_EXPORT ALIGNAS(kParametersAlignment) AudioOutputBufferParameters { int64_t delay_us; // base::TimeDelta in microseconds. int64_t delay_timestamp_us; // base::TimeTicks in microseconds. @@ -55,20 +53,10 @@ uint32_t bitstream_data_size; uint32_t bitstream_frames; }; -#undef PARAMETERS_ALIGNMENT #if BUILDFLAG(IS_WIN) #pragma warning(pop) #endif -static_assert(sizeof(AudioInputBufferParameters) % - AudioBus::kChannelAlignment == - 0, - "AudioInputBufferParameters not aligned"); -static_assert(sizeof(AudioOutputBufferParameters) % - AudioBus::kChannelAlignment == - 0, - "AudioOutputBufferParameters not aligned"); - struct MEDIA_SHMEM_EXPORT AudioInputBuffer { AudioInputBufferParameters params; int8_t audio[1]; @@ -94,6 +82,8 @@ base::TimeDelta starting_capacity_for_encrypted; }; +class AudioParameters; + // These convenience function safely computes the size required for // |shared_memory_count| AudioInputBuffers, with enough memory for AudioBus // data, using |paremeters| (or alternatively |channels| and |frames|). The
diff --git a/media/gpu/windows/d3d11_h265_accelerator.cc b/media/gpu/windows/d3d11_h265_accelerator.cc index 4398c0f..d1a2f1fe 100644 --- a/media/gpu/windows/d3d11_h265_accelerator.cc +++ b/media/gpu/windows/d3d11_h265_accelerator.cc
@@ -154,6 +154,8 @@ int i = 0; for (auto& it : ref_pic_list) { + if (!it) + continue; D3D11H265Picture* our_ref_pic = it->AsD3D11H265Picture(); if (!our_ref_pic) continue; @@ -415,6 +417,8 @@ } while (0) for (auto& it : ref_pic_list0) { + if (!it) + continue; auto poc = it->pic_order_cnt_val_; auto idx = poc_index_into_ref_pic_list_[poc]; if (idx < 0) { @@ -438,6 +442,8 @@ } } for (auto& it : ref_pic_list1) { + if (!it) + continue; auto poc = it->pic_order_cnt_val_; auto idx = poc_index_into_ref_pic_list_[poc]; if (idx < 0) {
diff --git a/media/mojo/services/gpu_mojo_media_client.cc b/media/mojo/services/gpu_mojo_media_client.cc index 8f83a4d..40cdaff8 100644 --- a/media/mojo/services/gpu_mojo_media_client.cc +++ b/media/mojo/services/gpu_mojo_media_client.cc
@@ -13,7 +13,6 @@ #include "build/chromeos_buildflags.h" #include "gpu/ipc/service/gpu_channel.h" #include "media/audio/audio_features.h" -#include "media/audio/audio_opus_encoder.h" #include "media/base/audio_decoder.h" #include "media/base/cdm_factory.h" #include "media/base/media_switches.h" @@ -119,14 +118,7 @@ scoped_refptr<base::SequencedTaskRunner> task_runner) { if (!base::FeatureList::IsEnabled(features::kPlatformAudioEncoder)) return nullptr; - // TODO(crbug.com/1259883) Right now Opus encoder is all we have, later on - // we'll create a real platform encoder here. - auto opus_encoder = std::make_unique<AudioOpusEncoder>(); - auto encoding_runner = base::ThreadPool::CreateSequencedTaskRunner( - {base::TaskPriority::USER_BLOCKING}); - return std::make_unique<OffloadingAudioEncoder>(std::move(opus_encoder), - std::move(encoding_runner), - std::move(task_runner)); + return nullptr; } VideoDecoderType GpuMojoMediaClient::GetDecoderImplementationType() {
diff --git a/media/webrtc/audio_processor.h b/media/webrtc/audio_processor.h index ec08d2ce..1349be27 100644 --- a/media/webrtc/audio_processor.h +++ b/media/webrtc/audio_processor.h
@@ -7,6 +7,7 @@ #include <memory> +#include "base/callback.h" #include "base/component_export.h" #include "base/files/file.h" #include "base/memory/scoped_refptr.h"
diff --git a/net/BUILD.gn b/net/BUILD.gn index bc26f50..203d3a9 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -2209,7 +2209,16 @@ allow_circular_includes_from = [ "//net/dns:test_support" ] - data = [ "data/" ] + # Data dependencies shared with suites other than net_unittests. + data = [ + "data/cert_net_fetcher_impl_unittest/", + "data/dns/", + "data/ov_name_constraints/", + "data/parse_certificate_unittest/", + "data/ssl/", + "data/url_request_unittest/", + "data/websocket/", + ] if (is_mac) { frameworks = [ "Security.framework" ] @@ -4563,7 +4572,30 @@ ] } - data = [] + data = [ + "data/cache_tests/", + "data/certificate_policies_unittest/", + "data/cert_issuer_source_aia_unittest/", + "data/cert_issuer_source_static_unittest/", + "data/crl_unittest/", + "data/embedded_test_server/", + "data/file_stream_unittest/", + "data/filter_unittests/", + "data/gencerts/", + "data/name_constraints_unittest/", + "data/ocsp_unittest/", + "data/pac_file_fetcher_unittest/", + "data/path_builder_unittest/", + "data/quic_http_response_cache_data/", + "data/quic_http_response_cache_data_with_push/", + "data/spdy_tests/", + "data/test.html", + "data/trial_comparison_cert_verifier_unittest/", + "data/url_fetcher_impl_unittest/", + "data/verify_certificate_chain_unittest/", + "data/verify_name_match_unittest/", + "data/verify_signed_data_unittest/", + ] data_deps = [ "third_party/nist-pkits/", "//testing/buildbot/filters:net_unittests_filters", @@ -4891,6 +4923,10 @@ "//base:i18n", "//net", ] + data = [ + "fuzzer_data", + "fuzzer_dictionaries", + ] allow_circular_includes_from = [ "//net/dns:fuzzer_test_support" ] } }
diff --git a/net/tools/quic/quic_simple_client_bin.cc b/net/tools/quic/quic_simple_client_bin.cc index 9233b80..d55bd2ab0 100644 --- a/net/tools/quic/quic_simple_client_bin.cc +++ b/net/tools/quic/quic_simple_client_bin.cc
@@ -34,6 +34,8 @@ // quic_client http://www.example.com #include "base/logging.h" +#include "base/ranges/algorithm.h" +#include "net/base/address_family.h" #include "net/base/net_errors.h" #include "net/quic/address_utils.h" #include "net/third_party/quiche/src/common/platform/api/quiche_command_line_flags.h" @@ -47,6 +49,8 @@ #include "net/third_party/quiche/src/spdy/core/spdy_header_block.h" #include "net/tools/quic/quic_simple_client.h" #include "net/tools/quic/synchronous_host_resolver.h" +#include "url/scheme_host_port.h" +#include "url/url_constants.h" using quic::ProofVerifier; @@ -67,14 +71,35 @@ quic::QuicIpAddress ip_addr; if (!ip_addr.FromString(host_for_lookup)) { net::AddressList addresses; - int rv = - net::SynchronousHostResolver::Resolve(host_for_lookup, &addresses); + // TODO(https://crbug.com/1300660) Let the caller pass in the scheme + // rather than guessing "https" + int rv = net::SynchronousHostResolver::Resolve( + url::SchemeHostPort(url::kHttpsScheme, host_for_lookup, port), + &addresses); if (rv != net::OK) { LOG(ERROR) << "Unable to resolve '" << host_for_lookup << "' : " << net::ErrorToShortString(rv); return nullptr; } - ip_addr = net::ToQuicIpAddress(addresses[0].address()); + const auto endpoint = base::ranges::find_if( + addresses, + [address_family_for_lookup](net::AddressFamily family) { + if (address_family_for_lookup == AF_INET) + return family == net::AddressFamily::ADDRESS_FAMILY_IPV4; + if (address_family_for_lookup == AF_INET6) + return family == net::AddressFamily::ADDRESS_FAMILY_IPV6; + return address_family_for_lookup == AF_UNSPEC; + }, + &net::IPEndPoint::GetFamily); + if (endpoint == addresses.end()) { + LOG(ERROR) << "No results for '" << host_for_lookup + << "' with appropriate address family"; + return nullptr; + } + // Arbitrarily select the first result with a matching address family, + // ignoring any subsequent matches. + ip_addr = net::ToQuicIpAddress(endpoint->address()); + port = endpoint->port(); } quic::QuicServerId server_id(host_for_handshake, port, false);
diff --git a/net/tools/quic/synchronous_host_resolver.cc b/net/tools/quic/synchronous_host_resolver.cc index d28c50f7..a205e3f 100644 --- a/net/tools/quic/synchronous_host_resolver.cc +++ b/net/tools/quic/synchronous_host_resolver.cc
@@ -24,6 +24,7 @@ #include "net/log/net_log.h" #include "net/log/net_log_with_source.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/scheme_host_port.h" namespace net { @@ -40,7 +41,7 @@ ~ResolverThread() override; // Called on the main thread. - int Resolve(const std::string& host, AddressList* addresses); + int Resolve(url::SchemeHostPort scheme_host_port, AddressList* addresses); // SimpleThread methods: void Run() override; @@ -49,12 +50,11 @@ void OnResolutionComplete(base::OnceClosure on_done, int rv); AddressList* addresses_; - std::string host_; - int rv_; + url::SchemeHostPort scheme_host_port_; + int rv_ = ERR_UNEXPECTED; }; -ResolverThread::ResolverThread() - : SimpleThread("resolver_thread"), rv_(ERR_UNEXPECTED) {} +ResolverThread::ResolverThread() : SimpleThread("resolver_thread") {} ResolverThread::~ResolverThread() = default; @@ -67,11 +67,10 @@ std::unique_ptr<net::HostResolver> resolver = net::HostResolver::CreateStandaloneResolver(NetLog::Get(), options); - HostPortPair host_port_pair(host_, 80); // No need to use a NetworkIsolationKey here, since this is an external tool // not used by net/ consumers. std::unique_ptr<net::HostResolver::ResolveHostRequest> request = - resolver->CreateRequest(host_port_pair, NetworkIsolationKey(), + resolver->CreateRequest(scheme_host_port_, NetworkIsolationKey(), NetLogWithSource(), absl::nullopt); base::RunLoop run_loop; @@ -89,8 +88,9 @@ } } -int ResolverThread::Resolve(const std::string& host, AddressList* addresses) { - host_ = host; +int ResolverThread::Resolve(url::SchemeHostPort scheme_host_port, + AddressList* addresses) { + scheme_host_port_ = std::move(scheme_host_port); addresses_ = addresses; this->Start(); this->Join(); @@ -105,10 +105,10 @@ } // namespace // static -int SynchronousHostResolver::Resolve(const std::string& host, +int SynchronousHostResolver::Resolve(url::SchemeHostPort scheme_host_port, AddressList* addresses) { ResolverThread resolver; - return resolver.Resolve(host, addresses); + return resolver.Resolve(std::move(scheme_host_port), addresses); } } // namespace net
diff --git a/net/tools/quic/synchronous_host_resolver.h b/net/tools/quic/synchronous_host_resolver.h index 89b15a2..8bb511d 100644 --- a/net/tools/quic/synchronous_host_resolver.h +++ b/net/tools/quic/synchronous_host_resolver.h
@@ -7,16 +7,16 @@ #ifndef NET_TOOLS_QUIC_SYNCHRONOUS_HOST_RESOLVER_H_ #define NET_TOOLS_QUIC_SYNCHRONOUS_HOST_RESOLVER_H_ -#include <string> - #include "net/base/address_list.h" #include "net/dns/host_resolver.h" +#include "url/scheme_host_port.h" namespace net { class SynchronousHostResolver { public: - static int Resolve(const std::string& host, AddressList* addresses); + static int Resolve(url::SchemeHostPort scheme_host_port, + AddressList* addresses); }; } // namespace net
diff --git a/net/tools/root_store_tool/root_store.proto b/net/tools/root_store_tool/root_store.proto index 030aff95..e4bd09a 100644 --- a/net/tools/root_store_tool/root_store.proto +++ b/net/tools/root_store_tool/root_store.proto
@@ -2,6 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// Proto definitions supporting the Chrome Root Store. +// This file should be manually kept in sync with the corresponding google3 +// file. + syntax = "proto3"; package chrome_root_store; @@ -22,6 +26,12 @@ repeated string ev_policy_oids = 3; } +// Message storing a complete Chrome Root Store. message RootStore { repeated TrustAnchor trust_anchors = 1; + + // Major version # of the Chrome Root Store. It is assumed that if + // root_store_1.version_major > root_store_2.version_major, then root_store_1 + // is newer and should be preferred over root_store_2. + int64 version_major = 2; }
diff --git a/pdf/pdfium/fuzzers/BUILD.gn b/pdf/pdfium/fuzzers/BUILD.gn index 7916e22..bd4e616 100644 --- a/pdf/pdfium/fuzzers/BUILD.gn +++ b/pdf/pdfium/fuzzers/BUILD.gn
@@ -59,9 +59,9 @@ ":pdf_cfx_barcode_fuzzer", ":pdf_codec_jpeg_fuzzer", ":pdf_css_fuzzer", - ":pdf_fm2js_fuzzer", ":pdf_formcalc_context_fuzzer", ":pdf_formcalc_fuzzer", + ":pdf_formcalc_translate_fuzzer", ":pdfium_xfa_fuzzer", ":pdfium_xfa_lpm_fuzzer", ] @@ -195,10 +195,6 @@ dict = "dicts/pdf_css.dict" } - pdfium_fuzzer_test("pdf_fm2js_fuzzer") { - dict = "dicts/pdf_formcalc.dict" - } - pdfium_fuzzer_test("pdf_formcalc_context_fuzzer") { dict = "dicts/pdf_xfa_js.dict" } @@ -207,6 +203,10 @@ dict = "dicts/pdf_formcalc.dict" } + pdfium_fuzzer_test("pdf_formcalc_translate_fuzzer") { + dict = "dicts/pdf_formcalc.dict" + } + if (pdf_enable_xfa_gif) { pdfium_fuzzer_test("pdf_lzw_fuzzer") { }
diff --git a/remoting/host/basic_desktop_environment.cc b/remoting/host/basic_desktop_environment.cc index db502cac..9e7f888 100644 --- a/remoting/host/basic_desktop_environment.cc +++ b/remoting/host/basic_desktop_environment.cc
@@ -101,6 +101,12 @@ return nullptr; } +std::unique_ptr<DesktopDisplayInfoMonitor> +BasicDesktopEnvironment::CreateDisplayInfoMonitor() { + return std::make_unique<DesktopDisplayInfoMonitor>(ui_task_runner_, + client_session_control_); +} + std::unique_ptr<webrtc::MouseCursorMonitor> BasicDesktopEnvironment::CreateMouseCursorMonitor() { return std::make_unique<MouseCursorMonitorProxy>(video_capture_task_runner_, @@ -135,25 +141,25 @@ } std::unique_ptr<DesktopAndCursorConditionalComposer> -BasicDesktopEnvironment::CreateComposingVideoCapturer() { +BasicDesktopEnvironment::CreateComposingVideoCapturer( + std::unique_ptr<DesktopDisplayInfoMonitor> monitor) { #if BUILDFLAG(IS_APPLE) // Mac includes the mouse cursor in the captured image in curtain mode. if (options_.enable_curtaining()) return nullptr; #endif return std::make_unique<DesktopAndCursorConditionalComposer>( - CreateVideoCapturer()); + CreateVideoCapturer(std::move(monitor))); } std::unique_ptr<webrtc::DesktopCapturer> -BasicDesktopEnvironment::CreateVideoCapturer() { +BasicDesktopEnvironment::CreateVideoCapturer( + std::unique_ptr<DesktopDisplayInfoMonitor> monitor) { DCHECK(caller_task_runner_->BelongsToCurrentThread()); auto result = std::make_unique<DesktopCapturerProxy>( video_capture_task_runner_, ui_task_runner_); - result->set_desktop_display_info_monitor( - std::make_unique<DesktopDisplayInfoMonitor>(ui_task_runner_, - client_session_control_)); + result->set_desktop_display_info_monitor(std::move(monitor)); result->CreateCapturer(desktop_capture_options()); return std::move(result); }
diff --git a/remoting/host/basic_desktop_environment.h b/remoting/host/basic_desktop_environment.h index 8f1f249..dd4e439 100644 --- a/remoting/host/basic_desktop_environment.h +++ b/remoting/host/basic_desktop_environment.h
@@ -39,7 +39,10 @@ std::unique_ptr<AudioCapturer> CreateAudioCapturer() override; std::unique_ptr<InputInjector> CreateInputInjector() override; std::unique_ptr<ScreenControls> CreateScreenControls() override; - std::unique_ptr<webrtc::DesktopCapturer> CreateVideoCapturer() override; + std::unique_ptr<webrtc::DesktopCapturer> CreateVideoCapturer( + std::unique_ptr<DesktopDisplayInfoMonitor> monitor) override; + std::unique_ptr<DesktopDisplayInfoMonitor> CreateDisplayInfoMonitor() + override; std::unique_ptr<webrtc::MouseCursorMonitor> CreateMouseCursorMonitor() override; std::unique_ptr<KeyboardLayoutMonitor> CreateKeyboardLayoutMonitor( @@ -52,7 +55,8 @@ void SetCapabilities(const std::string& capabilities) override; uint32_t GetDesktopSessionId() const override; std::unique_ptr<DesktopAndCursorConditionalComposer> - CreateComposingVideoCapturer() override; + CreateComposingVideoCapturer( + std::unique_ptr<DesktopDisplayInfoMonitor> monitor) override; protected: friend class BasicDesktopEnvironmentFactory;
diff --git a/remoting/host/client_session.cc b/remoting/host/client_session.cc index ca12864..b0082ab 100644 --- a/remoting/host/client_session.cc +++ b/remoting/host/client_session.cc
@@ -23,6 +23,7 @@ #include "remoting/host/audio_capturer.h" #include "remoting/host/base/screen_controls.h" #include "remoting/host/base/screen_resolution.h" +#include "remoting/host/desktop_display_info_monitor.h" #include "remoting/host/desktop_environment.h" #include "remoting/host/file_transfer/file_transfer_message_handler.h" #include "remoting/host/file_transfer/rtc_log_file_operations.h" @@ -456,15 +457,23 @@ void ClientSession::CreateMediaStreams() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Create monitor to be used by the capturer. This is used only by + // DesktopCapturerProxy. With multi-process, the IpcDesktopEnvironment + // version of this method returns nullptr, and the monitor is created + // in the Desktop process instead (where DesktopCapturerProxy is used). + auto monitor = desktop_environment_->CreateDisplayInfoMonitor(); + // Create a VideoStream to pump frames from the capturer to the client. - auto composer = desktop_environment_->CreateComposingVideoCapturer(); + auto composer = + desktop_environment_->CreateComposingVideoCapturer(std::move(monitor)); if (composer) { desktop_and_cursor_composer_ = composer->GetWeakPtr(); video_stream_ = connection_->StartVideoStream(kStreamName, std::move(composer)); } else { video_stream_ = connection_->StartVideoStream( - kStreamName, desktop_environment_->CreateVideoCapturer()); + kStreamName, + desktop_environment_->CreateVideoCapturer(std::move(monitor))); } // Create a AudioStream to pump audio from the capturer to the client.
diff --git a/remoting/host/desktop_environment.h b/remoting/host/desktop_environment.h index 439c796..639b9cbe 100644 --- a/remoting/host/desktop_environment.h +++ b/remoting/host/desktop_environment.h
@@ -26,6 +26,7 @@ class AudioCapturer; class ClientSessionControl; class ClientSessionEvents; +class DesktopDisplayInfoMonitor; class FileOperations; class InputInjector; class KeyboardLayoutMonitor; @@ -48,7 +49,22 @@ virtual std::unique_ptr<AudioCapturer> CreateAudioCapturer() = 0; virtual std::unique_ptr<InputInjector> CreateInputInjector() = 0; virtual std::unique_ptr<ScreenControls> CreateScreenControls() = 0; - virtual std::unique_ptr<webrtc::DesktopCapturer> CreateVideoCapturer() = 0; + + // |monitor| is an optional parameter. If provided, it will be notified on + // every captured frame so it can refresh the display-info. Used (by + // DesktopCapturerProxy) only for the single-video-stream case, where there is + // only one capturer which owns the monitor. For multi-stream, the monitor is + // owned and managed independently from DesktopCapturerProxy. + // TODO(lambroslambrou): Remove this parameter when the single-stream + // implementation is removed. Alternatively, if the Win/Mac implementations + // of DesktopDisplayInfoLoader are updated to be event-driven (instead of + // polling per captured frame), this parameter could be removed even in + // the single-video-stream case. + virtual std::unique_ptr<webrtc::DesktopCapturer> CreateVideoCapturer( + std::unique_ptr<DesktopDisplayInfoMonitor> monitor) = 0; + + virtual std::unique_ptr<DesktopDisplayInfoMonitor> + CreateDisplayInfoMonitor() = 0; virtual std::unique_ptr<webrtc::MouseCursorMonitor> CreateMouseCursorMonitor() = 0; virtual std::unique_ptr<KeyboardLayoutMonitor> CreateKeyboardLayoutMonitor( @@ -63,7 +79,8 @@ // If the platform already does this, this method return null, and the caller // should use CreateVideoCapturer() instead. virtual std::unique_ptr<DesktopAndCursorConditionalComposer> - CreateComposingVideoCapturer() = 0; + CreateComposingVideoCapturer( + std::unique_ptr<DesktopDisplayInfoMonitor> monitor) = 0; // Returns the set of all capabilities supported by |this|. virtual std::string GetCapabilities() const = 0;
diff --git a/remoting/host/desktop_process_unittest.cc b/remoting/host/desktop_process_unittest.cc index 2514c7cb..c591801 100644 --- a/remoting/host/desktop_process_unittest.cc +++ b/remoting/host/desktop_process_unittest.cc
@@ -218,7 +218,7 @@ .WillOnce(Invoke(this, &DesktopProcessTest::CreateInputInjector)); EXPECT_CALL(*desktop_environment, CreateActionExecutor()).Times(AtMost(1)); EXPECT_CALL(*desktop_environment, CreateScreenControls()).Times(AtMost(1)); - EXPECT_CALL(*desktop_environment, CreateVideoCapturer()) + EXPECT_CALL(*desktop_environment, CreateVideoCapturer(_)) .Times(AtMost(1)) .WillOnce( Return(ByMove(std::make_unique<protocol::FakeDesktopCapturer>())));
diff --git a/remoting/host/desktop_session_agent.cc b/remoting/host/desktop_session_agent.cc index 2db5138..697fb05 100644 --- a/remoting/host/desktop_session_agent.cc +++ b/remoting/host/desktop_session_agent.cc
@@ -32,6 +32,7 @@ #include "remoting/host/base/screen_resolution.h" #include "remoting/host/chromoting_messages.h" #include "remoting/host/crash_process.h" +#include "remoting/host/desktop_display_info_monitor.h" #include "remoting/host/desktop_environment.h" #include "remoting/host/input_injector.h" #include "remoting/host/keyboard_layout_monitor.h" @@ -431,8 +432,12 @@ } // Start the video capturer and mouse cursor monitor. + // TODO(lambroslambrou): When supporting multiple streams, this class should + // create and own a single DesktopDisplayInfoMonitor and call Start() on it, + // instead of passing it to CreateVideoCapturer() here. video_capturer_ = std::make_unique<DesktopAndCursorConditionalComposer>( - desktop_environment_->CreateVideoCapturer()); + desktop_environment_->CreateVideoCapturer( + desktop_environment_->CreateDisplayInfoMonitor())); video_capturer_->Start(this); video_capturer_->SetSharedMemoryFactory( std::make_unique<SharedMemoryFactoryImpl>(
diff --git a/remoting/host/fake_desktop_environment.cc b/remoting/host/fake_desktop_environment.cc index 8bb75b9..345020d 100644 --- a/remoting/host/fake_desktop_environment.cc +++ b/remoting/host/fake_desktop_environment.cc
@@ -10,6 +10,7 @@ #include "base/memory/weak_ptr.h" #include "remoting/host/audio_capturer.h" #include "remoting/host/desktop_capturer_proxy.h" +#include "remoting/host/desktop_display_info_monitor.h" #include "remoting/host/fake_keyboard_layout_monitor.h" #include "remoting/host/file_transfer/file_operations.h" #include "remoting/host/input_injector.h" @@ -87,7 +88,8 @@ } std::unique_ptr<webrtc::DesktopCapturer> -FakeDesktopEnvironment::CreateVideoCapturer() { +FakeDesktopEnvironment::CreateVideoCapturer( + std::unique_ptr<DesktopDisplayInfoMonitor> monitor) { auto fake_capturer = std::make_unique<protocol::FakeDesktopCapturer>(); if (!frame_generator_.is_null()) fake_capturer->set_frame_generator(frame_generator_); @@ -98,6 +100,11 @@ return std::move(result); } +std::unique_ptr<DesktopDisplayInfoMonitor> +FakeDesktopEnvironment::CreateDisplayInfoMonitor() { + return nullptr; +} + std::unique_ptr<webrtc::MouseCursorMonitor> FakeDesktopEnvironment::CreateMouseCursorMonitor() { return std::make_unique<FakeMouseCursorMonitor>(); @@ -129,7 +136,8 @@ } std::unique_ptr<DesktopAndCursorConditionalComposer> -FakeDesktopEnvironment::CreateComposingVideoCapturer() { +FakeDesktopEnvironment::CreateComposingVideoCapturer( + std::unique_ptr<DesktopDisplayInfoMonitor> monitor) { return nullptr; }
diff --git a/remoting/host/fake_desktop_environment.h b/remoting/host/fake_desktop_environment.h index 6821b08..c8afd5a 100644 --- a/remoting/host/fake_desktop_environment.h +++ b/remoting/host/fake_desktop_environment.h
@@ -106,7 +106,10 @@ std::unique_ptr<AudioCapturer> CreateAudioCapturer() override; std::unique_ptr<InputInjector> CreateInputInjector() override; std::unique_ptr<ScreenControls> CreateScreenControls() override; - std::unique_ptr<webrtc::DesktopCapturer> CreateVideoCapturer() override; + std::unique_ptr<webrtc::DesktopCapturer> CreateVideoCapturer( + std::unique_ptr<DesktopDisplayInfoMonitor> monitor) override; + std::unique_ptr<DesktopDisplayInfoMonitor> CreateDisplayInfoMonitor() + override; std::unique_ptr<webrtc::MouseCursorMonitor> CreateMouseCursorMonitor() override; std::unique_ptr<KeyboardLayoutMonitor> CreateKeyboardLayoutMonitor( @@ -119,7 +122,8 @@ void SetCapabilities(const std::string& capabilities) override; uint32_t GetDesktopSessionId() const override; std::unique_ptr<DesktopAndCursorConditionalComposer> - CreateComposingVideoCapturer() override; + CreateComposingVideoCapturer( + std::unique_ptr<DesktopDisplayInfoMonitor> monitor) override; base::WeakPtr<FakeInputInjector> last_input_injector() { return last_input_injector_;
diff --git a/remoting/host/host_mock_objects.h b/remoting/host/host_mock_objects.h index 63d2dcda..64f20c1c 100644 --- a/remoting/host/host_mock_objects.h +++ b/remoting/host/host_mock_objects.h
@@ -20,6 +20,7 @@ #include "remoting/host/client_session_control.h" #include "remoting/host/client_session_details.h" #include "remoting/host/client_session_events.h" +#include "remoting/host/desktop_display_info_monitor.h" #include "remoting/host/desktop_environment.h" #include "remoting/host/file_transfer/file_operations.h" #include "remoting/host/host_status_observer.h" @@ -64,6 +65,10 @@ (override)); MOCK_METHOD(std::unique_ptr<webrtc::DesktopCapturer>, CreateVideoCapturer, + (std::unique_ptr<DesktopDisplayInfoMonitor>), + (override)); + MOCK_METHOD(std::unique_ptr<DesktopDisplayInfoMonitor>, + CreateDisplayInfoMonitor, (), (override)); MOCK_METHOD(std::unique_ptr<webrtc::MouseCursorMonitor>, @@ -84,7 +89,7 @@ (override)); MOCK_METHOD(std::unique_ptr<DesktopAndCursorConditionalComposer>, CreateComposingVideoCapturer, - (), + (std::unique_ptr<DesktopDisplayInfoMonitor> monitor), (override)); MOCK_METHOD(std::string, GetCapabilities, (), (const, override)); MOCK_METHOD(void, SetCapabilities, (const std::string&), (override));
diff --git a/remoting/host/ipc_desktop_environment.cc b/remoting/host/ipc_desktop_environment.cc index ac1acff1..9c78c232 100644 --- a/remoting/host/ipc_desktop_environment.cc +++ b/remoting/host/ipc_desktop_environment.cc
@@ -17,6 +17,7 @@ #include "remoting/host/audio_capturer.h" #include "remoting/host/base/screen_controls.h" #include "remoting/host/client_session_control.h" +#include "remoting/host/desktop_display_info_monitor.h" #include "remoting/host/desktop_session.h" #include "remoting/host/desktop_session_proxy.h" #include "remoting/host/file_transfer/file_operations.h" @@ -65,6 +66,12 @@ return desktop_session_proxy_->CreateScreenControls(); } +std::unique_ptr<DesktopDisplayInfoMonitor> +IpcDesktopEnvironment::CreateDisplayInfoMonitor() { + // Not used in the Network process. + return nullptr; +} + std::unique_ptr<webrtc::MouseCursorMonitor> IpcDesktopEnvironment::CreateMouseCursorMonitor() { return desktop_session_proxy_->CreateMouseCursorMonitor(); @@ -78,7 +85,8 @@ } std::unique_ptr<webrtc::DesktopCapturer> -IpcDesktopEnvironment::CreateVideoCapturer() { +IpcDesktopEnvironment::CreateVideoCapturer( + std::unique_ptr<DesktopDisplayInfoMonitor> monitor) { return desktop_session_proxy_->CreateVideoCapturer(); } @@ -104,7 +112,8 @@ } std::unique_ptr<DesktopAndCursorConditionalComposer> -IpcDesktopEnvironment::CreateComposingVideoCapturer() { +IpcDesktopEnvironment::CreateComposingVideoCapturer( + std::unique_ptr<DesktopDisplayInfoMonitor> monitor) { // Cursor compositing is done by the desktop process if necessary. return nullptr; }
diff --git a/remoting/host/ipc_desktop_environment.h b/remoting/host/ipc_desktop_environment.h index 8806103f..c95fcf0 100644 --- a/remoting/host/ipc_desktop_environment.h +++ b/remoting/host/ipc_desktop_environment.h
@@ -58,7 +58,10 @@ std::unique_ptr<AudioCapturer> CreateAudioCapturer() override; std::unique_ptr<InputInjector> CreateInputInjector() override; std::unique_ptr<ScreenControls> CreateScreenControls() override; - std::unique_ptr<webrtc::DesktopCapturer> CreateVideoCapturer() override; + std::unique_ptr<webrtc::DesktopCapturer> CreateVideoCapturer( + std::unique_ptr<DesktopDisplayInfoMonitor> monitor) override; + std::unique_ptr<DesktopDisplayInfoMonitor> CreateDisplayInfoMonitor() + override; std::unique_ptr<webrtc::MouseCursorMonitor> CreateMouseCursorMonitor() override; std::unique_ptr<KeyboardLayoutMonitor> CreateKeyboardLayoutMonitor( @@ -71,7 +74,8 @@ void SetCapabilities(const std::string& capabilities) override; uint32_t GetDesktopSessionId() const override; std::unique_ptr<DesktopAndCursorConditionalComposer> - CreateComposingVideoCapturer() override; + CreateComposingVideoCapturer( + std::unique_ptr<DesktopDisplayInfoMonitor> monitor) override; private: scoped_refptr<DesktopSessionProxy> desktop_session_proxy_;
diff --git a/remoting/host/ipc_desktop_environment_unittest.cc b/remoting/host/ipc_desktop_environment_unittest.cc index a99bd826..73b6400 100644 --- a/remoting/host/ipc_desktop_environment_unittest.cc +++ b/remoting/host/ipc_desktop_environment_unittest.cc
@@ -376,8 +376,7 @@ input_injector_ = desktop_environment_->CreateInputInjector(); // Create the screen capturer. - video_capturer_ = - desktop_environment_->CreateVideoCapturer(); + video_capturer_ = desktop_environment_->CreateVideoCapturer(nullptr); desktop_environment_->SetCapabilities(std::string()); @@ -416,7 +415,7 @@ .Times(AtMost(1)) .WillOnce(Invoke(this, &IpcDesktopEnvironmentTest::CreateInputInjector)); EXPECT_CALL(*desktop_environment, CreateScreenControls()).Times(AtMost(1)); - EXPECT_CALL(*desktop_environment, CreateVideoCapturer()) + EXPECT_CALL(*desktop_environment, CreateVideoCapturer(_)) .Times(AtMost(1)) .WillOnce( Return(ByMove(std::make_unique<protocol::FakeDesktopCapturer>())));
diff --git a/remoting/host/linux/linux_me2me_host.py b/remoting/host/linux/linux_me2me_host.py index da1446b..744d779 100755 --- a/remoting/host/linux/linux_me2me_host.py +++ b/remoting/host/linux/linux_me2me_host.py
@@ -853,7 +853,7 @@ socket_num = 1 full_sock_path = os.path.join(self.runtime_dir, "wayland-%s" % socket_num) while ((os.path.exists(full_sock_path)) and - socket_num <= self.MAX_WAYLAND_SOCKET_NUM)): + socket_num <= self.MAX_WAYLAND_SOCKET_NUM): socket_num += 1 full_sock_path = os.path.join(self.runtime_dir, "wayland-%s" % socket_num) if socket_num > self.MAX_WAYLAND_SOCKET_NUM:
diff --git a/services/network/sct_auditing/sct_auditing_cache.cc b/services/network/sct_auditing/sct_auditing_cache.cc index 758ff04..e3b2997 100644 --- a/services/network/sct_auditing/sct_auditing_cache.cc +++ b/services/network/sct_auditing/sct_auditing_cache.cc
@@ -4,6 +4,8 @@ #include "services/network/sct_auditing/sct_auditing_cache.h" +#include <algorithm> + #include "base/callback.h" #include "base/metrics/histogram_functions.h" #include "base/rand_util.h" @@ -163,6 +165,13 @@ return report_entry; } +bool SCTAuditingCache::IsPopularSCT(base::span<const uint8_t> sct_leaf_hash) { + // Copy into a vector to make comparisons easier. + std::vector<uint8_t> leaf_hash(sct_leaf_hash.begin(), sct_leaf_hash.end()); + return std::binary_search(popular_scts_.begin(), popular_scts_.end(), + leaf_hash); +} + void SCTAuditingCache::ClearCache() { // Empty the deduplication cache. dedupe_cache_.Clear();
diff --git a/services/network/sct_auditing/sct_auditing_cache.h b/services/network/sct_auditing/sct_auditing_cache.h index 022f980..50cae28 100644 --- a/services/network/sct_auditing/sct_auditing_cache.h +++ b/services/network/sct_auditing/sct_auditing_cache.h
@@ -82,6 +82,9 @@ const net::SignedCertificateTimestampAndStatusList& signed_certificate_timestamps); + // Returns true if |sct_leaf_hash| corresponds to a known popular SCT. + bool IsPopularSCT(base::span<const uint8_t> sct_leaf_hash); + void ClearCache(); void set_sampling_rate(double rate) { sampling_rate_ = rate; }
diff --git a/services/network/sct_auditing/sct_auditing_handler.cc b/services/network/sct_auditing/sct_auditing_handler.cc index d694d2a..5258f8c 100644 --- a/services/network/sct_auditing/sct_auditing_handler.cc +++ b/services/network/sct_auditing/sct_auditing_handler.cc
@@ -56,6 +56,11 @@ const char kReportKey[] = "report"; const char kSCTHashdanceMetadataKey[] = "sct_metadata"; +void RecordPopularSCTSkippedMetrics(bool popular_sct_skipped) { + base::UmaHistogramBoolean("Security.SCTAuditing.OptOut.PopularSCTSkipped", + popular_sct_skipped); +} + } // namespace SCTAuditingHandler::SCTAuditingHandler(NetworkContext* context, @@ -133,6 +138,16 @@ result = net::ct::HashMerkleTreeLeaf(tree_leaf, &sct_metadata->leaf_hash); DCHECK(result); + // Do not report if this is a known popular SCT. + if (owner_network_context_->network_service() + ->sct_auditing_cache() + ->IsPopularSCT( + base::as_bytes(base::make_span(sct_metadata->leaf_hash)))) { + RecordPopularSCTSkippedMetrics(true); + return; + } + RecordPopularSCTSkippedMetrics(false); + // Find the corresponding log entry metadata. const std::vector<mojom::CTLogInfoPtr>& logs = owner_network_context_->network_service()->log_list();
diff --git a/services/network/sct_auditing/sct_auditing_handler_unittest.cc b/services/network/sct_auditing/sct_auditing_handler_unittest.cc index a144fd07..530806e 100644 --- a/services/network/sct_auditing/sct_auditing_handler_unittest.cc +++ b/services/network/sct_auditing/sct_auditing_handler_unittest.cc
@@ -290,7 +290,8 @@ // If operating on hashdance mode, calculate and store the SCT leaf hash and // append log metadata. -TEST_F(SCTAuditingHandlerTest, PopularSCTMetadataOnHashdanceMode) { +TEST_F(SCTAuditingHandlerTest, PopulateSCTMetadataOnHashdanceMode) { + base::HistogramTester histograms; const net::HostPortPair host_port_pair("example.com", 443); net::SignedCertificateTimestampAndStatusList sct_list; const base::Time issued = base::Time::Now(); @@ -306,7 +307,6 @@ handler_->MaybeEnqueueReport(host_port_pair, chain_.get(), sct_list); auto* pending_reporters = handler_->GetPendingReportersForTesting(); ASSERT_EQ(pending_reporters->size(), 1u); - for (const auto& reporter : *pending_reporters) { if (mode == mojom::SCTAuditingMode::kHashdance) { net::ct::MerkleTreeLeaf merkle_tree_leaf; @@ -327,6 +327,55 @@ EXPECT_FALSE(reporter.second->sct_hashdance_metadata()); } } + histograms.ExpectUniqueSample( + "Security.SCTAuditing.OptOut.PopularSCTSkipped", false, + mode == mojom::SCTAuditingMode::kHashdance ? 1 : 0); + handler_->ClearPendingReports(); + network_service_->sct_auditing_cache()->ClearCache(); + } +} + +// If operating on hashdance mode, do not report popular SCTs. +TEST_F(SCTAuditingHandlerTest, DoNotReportPopularSCT) { + const net::HostPortPair host_port_pair("example.com", 443); + net::SignedCertificateTimestampAndStatusList sct_list; + MakeTestSCTAndStatus( + net::ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, "extensions", + "valid_signature", base::Time::Now(), net::ct::SCT_STATUS_OK, &sct_list); + net::ct::MerkleTreeLeaf merkle_tree_leaf; + std::string leaf_hash_string; + ASSERT_TRUE(net::ct::GetMerkleTreeLeaf(chain_.get(), sct_list.at(0).sct.get(), + &merkle_tree_leaf)); + ASSERT_TRUE(net::ct::HashMerkleTreeLeaf(merkle_tree_leaf, &leaf_hash_string)); + std::vector<uint8_t> leaf_hash(leaf_hash_string.begin(), + leaf_hash_string.end()); + + // Create a list of sorted leaf hashes that will contain the SCT's leaf hash. + std::vector<std::vector<uint8_t>> leaf_hashes; + for (size_t byte = 0; byte < 256; ++byte) { + std::vector<uint8_t> new_leaf_hash = leaf_hash; + new_leaf_hash[0] = byte; + leaf_hashes.emplace_back(std::move(new_leaf_hash)); + } + + network_service_->sct_auditing_cache()->set_popular_scts({leaf_hash}); + + for (mojom::SCTAuditingMode mode : + {mojom::SCTAuditingMode::kEnhancedSafeBrowsingReporting, + mojom::SCTAuditingMode::kHashdance}) { + SCOPED_TRACE(testing::Message() << "Mode: " << static_cast<int>(mode)); + base::HistogramTester histograms; + handler_->SetMode(mode); + handler_->MaybeEnqueueReport(host_port_pair, chain_.get(), sct_list); + auto* pending_reporters = handler_->GetPendingReportersForTesting(); + EXPECT_EQ(pending_reporters->size(), + mode == mojom::SCTAuditingMode::kHashdance ? 0u : 1u); + + // The hashdance request should record a count for PopularSCTSkipped. + histograms.ExpectUniqueSample( + "Security.SCTAuditing.OptOut.PopularSCTSkipped", true, + mode == mojom::SCTAuditingMode::kHashdance ? 1 : 0); + handler_->ClearPendingReports(); network_service_->sct_auditing_cache()->ClearCache(); }
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index bdad468..a974e48 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -200,21 +200,6 @@ ] } ], - "AndroidMessagesPermissionUpdate": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "MessagesForAndroidPermissionUpdate" - ] - } - ] - } - ], "AndroidMessagesSaveCard": [ { "platforms": [ @@ -4878,9 +4863,9 @@ ], "experiments": [ { - "name": "Enabled_20210726", + "name": "Enabled_20220224", "params": { - "compress_bitmaps": "true" + "compress_bitmaps": "false" }, "enable_features": [ "PaintPreviewShowOnStartup"
diff --git a/third_party/android_deps/buildSrc/src/main/groovy/ChromiumDepGraph.groovy b/third_party/android_deps/buildSrc/src/main/groovy/ChromiumDepGraph.groovy index f8f3acf..1d64260e 100644 --- a/third_party/android_deps/buildSrc/src/main/groovy/ChromiumDepGraph.groovy +++ b/third_party/android_deps/buildSrc/src/main/groovy/ChromiumDepGraph.groovy
@@ -181,6 +181,9 @@ org_robolectric_junit: new PropertyOverride( licensePath: 'licenses/Codehaus_License-2009.txt', licenseName: 'MIT'), + org_robolectric_nativeruntime: new PropertyOverride( + licensePath: 'licenses/Codehaus_License-2009.txt', + licenseName: 'MIT'), org_robolectric_pluginapi: new PropertyOverride( licensePath: 'licenses/Codehaus_License-2009.txt', licenseName: 'MIT'),
diff --git a/third_party/android_deps/libs/backport_util_concurrent_backport_util_concurrent/3pp/fetch.py b/third_party/android_deps/libs/backport_util_concurrent_backport_util_concurrent/3pp/fetch.py deleted file mode 100755 index 15d28d8..0000000 --- a/third_party/android_deps/libs/backport_util_concurrent_backport_util_concurrent/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'backport-util-concurrent' -_MODULE_NAME = 'backport-util-concurrent' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/classworlds_classworlds/3pp/3pp.pb b/third_party/android_deps/libs/classworlds_classworlds/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/classworlds_classworlds/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/classworlds_classworlds/3pp/fetch.py b/third_party/android_deps/libs/classworlds_classworlds/3pp/fetch.py deleted file mode 100755 index 7e6e4c0..0000000 --- a/third_party/android_deps/libs/classworlds_classworlds/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'classworlds' -_MODULE_NAME = 'classworlds' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/nekohtml_nekohtml/3pp/3pp.pb b/third_party/android_deps/libs/nekohtml_nekohtml/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/nekohtml_nekohtml/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/nekohtml_nekohtml/3pp/fetch.py b/third_party/android_deps/libs/nekohtml_nekohtml/3pp/fetch.py deleted file mode 100755 index 8023ad3..0000000 --- a/third_party/android_deps/libs/nekohtml_nekohtml/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'nekohtml' -_MODULE_NAME = 'nekohtml' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/nekohtml_xercesminimal/3pp/3pp.pb b/third_party/android_deps/libs/nekohtml_xercesminimal/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/nekohtml_xercesminimal/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/nekohtml_xercesminimal/3pp/fetch.py b/third_party/android_deps/libs/nekohtml_xercesminimal/3pp/fetch.py deleted file mode 100755 index e84243f9..0000000 --- a/third_party/android_deps/libs/nekohtml_xercesminimal/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'nekohtml' -_MODULE_NAME = 'xercesMinimal' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = '1.9.6.2' -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/org_apache_ant_ant/3pp/fetch.py b/third_party/android_deps/libs/org_apache_ant_ant/3pp/fetch.py deleted file mode 100644 index d116427e..0000000 --- a/third_party/android_deps/libs/org_apache_ant_ant/3pp/fetch.py +++ /dev/null
@@ -1,73 +0,0 @@ -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'org/apache/ant' -_MODULE_NAME = 'ant' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode( - 'utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/org_apache_ant_ant_launcher/3pp/3pp.pb b/third_party/android_deps/libs/org_apache_ant_ant_launcher/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/org_apache_ant_ant_launcher/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/org_apache_ant_ant_launcher/3pp/fetch.py b/third_party/android_deps/libs/org_apache_ant_ant_launcher/3pp/fetch.py deleted file mode 100755 index 2aa40bd..0000000 --- a/third_party/android_deps/libs/org_apache_ant_ant_launcher/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'org/apache/ant' -_MODULE_NAME = 'ant-launcher' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/org_apache_maven_maven_ant_tasks/3pp/3pp.pb b/third_party/android_deps/libs/org_apache_maven_maven_ant_tasks/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/org_apache_maven_maven_ant_tasks/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/org_apache_maven_maven_ant_tasks/3pp/fetch.py b/third_party/android_deps/libs/org_apache_maven_maven_ant_tasks/3pp/fetch.py deleted file mode 100755 index e8fbac5e..0000000 --- a/third_party/android_deps/libs/org_apache_maven_maven_ant_tasks/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'org/apache/maven' -_MODULE_NAME = 'maven-ant-tasks' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/org_apache_maven_maven_artifact/3pp/3pp.pb b/third_party/android_deps/libs/org_apache_maven_maven_artifact/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/org_apache_maven_maven_artifact/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/org_apache_maven_maven_artifact/3pp/fetch.py b/third_party/android_deps/libs/org_apache_maven_maven_artifact/3pp/fetch.py deleted file mode 100755 index 0832316..0000000 --- a/third_party/android_deps/libs/org_apache_maven_maven_artifact/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'org/apache/maven' -_MODULE_NAME = 'maven-artifact' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/org_apache_maven_maven_artifact_manager/3pp/3pp.pb b/third_party/android_deps/libs/org_apache_maven_maven_artifact_manager/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/org_apache_maven_maven_artifact_manager/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/org_apache_maven_maven_artifact_manager/3pp/fetch.py b/third_party/android_deps/libs/org_apache_maven_maven_artifact_manager/3pp/fetch.py deleted file mode 100755 index cd1bc74..0000000 --- a/third_party/android_deps/libs/org_apache_maven_maven_artifact_manager/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'org/apache/maven' -_MODULE_NAME = 'maven-artifact-manager' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/org_apache_maven_maven_error_diagnostics/3pp/3pp.pb b/third_party/android_deps/libs/org_apache_maven_maven_error_diagnostics/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/org_apache_maven_maven_error_diagnostics/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/org_apache_maven_maven_error_diagnostics/3pp/fetch.py b/third_party/android_deps/libs/org_apache_maven_maven_error_diagnostics/3pp/fetch.py deleted file mode 100755 index c3abf39..0000000 --- a/third_party/android_deps/libs/org_apache_maven_maven_error_diagnostics/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'org/apache/maven' -_MODULE_NAME = 'maven-error-diagnostics' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/org_apache_maven_maven_model/3pp/3pp.pb b/third_party/android_deps/libs/org_apache_maven_maven_model/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/org_apache_maven_maven_model/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/org_apache_maven_maven_model/3pp/fetch.py b/third_party/android_deps/libs/org_apache_maven_maven_model/3pp/fetch.py deleted file mode 100755 index 81766545..0000000 --- a/third_party/android_deps/libs/org_apache_maven_maven_model/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'org/apache/maven' -_MODULE_NAME = 'maven-model' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/org_apache_maven_maven_plugin_registry/3pp/3pp.pb b/third_party/android_deps/libs/org_apache_maven_maven_plugin_registry/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/org_apache_maven_maven_plugin_registry/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/org_apache_maven_maven_plugin_registry/3pp/fetch.py b/third_party/android_deps/libs/org_apache_maven_maven_plugin_registry/3pp/fetch.py deleted file mode 100755 index 0f920386..0000000 --- a/third_party/android_deps/libs/org_apache_maven_maven_plugin_registry/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'org/apache/maven' -_MODULE_NAME = 'maven-plugin-registry' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/org_apache_maven_maven_profile/3pp/3pp.pb b/third_party/android_deps/libs/org_apache_maven_maven_profile/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/org_apache_maven_maven_profile/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/org_apache_maven_maven_project/3pp/3pp.pb b/third_party/android_deps/libs/org_apache_maven_maven_project/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/org_apache_maven_maven_project/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/org_apache_maven_maven_project/3pp/fetch.py b/third_party/android_deps/libs/org_apache_maven_maven_project/3pp/fetch.py deleted file mode 100755 index 2e40e7e..0000000 --- a/third_party/android_deps/libs/org_apache_maven_maven_project/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'org/apache/maven' -_MODULE_NAME = 'maven-project' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/org_apache_maven_maven_repository_metadata/3pp/3pp.pb b/third_party/android_deps/libs/org_apache_maven_maven_repository_metadata/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/org_apache_maven_maven_repository_metadata/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/org_apache_maven_maven_repository_metadata/3pp/fetch.py b/third_party/android_deps/libs/org_apache_maven_maven_repository_metadata/3pp/fetch.py deleted file mode 100755 index 5e7613c..0000000 --- a/third_party/android_deps/libs/org_apache_maven_maven_repository_metadata/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'org/apache/maven' -_MODULE_NAME = 'maven-repository-metadata' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/org_apache_maven_maven_settings/3pp/3pp.pb b/third_party/android_deps/libs/org_apache_maven_maven_settings/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/org_apache_maven_maven_settings/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/org_apache_maven_maven_settings/3pp/fetch.py b/third_party/android_deps/libs/org_apache_maven_maven_settings/3pp/fetch.py deleted file mode 100755 index 14bfd809..0000000 --- a/third_party/android_deps/libs/org_apache_maven_maven_settings/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'org/apache/maven' -_MODULE_NAME = 'maven-settings' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/org_apache_maven_wagon_wagon_file/3pp/3pp.pb b/third_party/android_deps/libs/org_apache_maven_wagon_wagon_file/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/org_apache_maven_wagon_wagon_file/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/org_apache_maven_wagon_wagon_file/3pp/fetch.py b/third_party/android_deps/libs/org_apache_maven_wagon_wagon_file/3pp/fetch.py deleted file mode 100755 index 5266035..0000000 --- a/third_party/android_deps/libs/org_apache_maven_wagon_wagon_file/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'org/apache/maven/wagon' -_MODULE_NAME = 'wagon-file' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/org_apache_maven_wagon_wagon_http_lightweight/3pp/3pp.pb b/third_party/android_deps/libs/org_apache_maven_wagon_wagon_http_lightweight/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/org_apache_maven_wagon_wagon_http_lightweight/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/org_apache_maven_wagon_wagon_http_lightweight/3pp/fetch.py b/third_party/android_deps/libs/org_apache_maven_wagon_wagon_http_lightweight/3pp/fetch.py deleted file mode 100755 index 2e352b2a..0000000 --- a/third_party/android_deps/libs/org_apache_maven_wagon_wagon_http_lightweight/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'org/apache/maven/wagon' -_MODULE_NAME = 'wagon-http-lightweight' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/org_apache_maven_wagon_wagon_http_shared/3pp/3pp.pb b/third_party/android_deps/libs/org_apache_maven_wagon_wagon_http_shared/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/org_apache_maven_wagon_wagon_http_shared/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/org_apache_maven_wagon_wagon_http_shared/3pp/fetch.py b/third_party/android_deps/libs/org_apache_maven_wagon_wagon_http_shared/3pp/fetch.py deleted file mode 100755 index 1f94c70..0000000 --- a/third_party/android_deps/libs/org_apache_maven_wagon_wagon_http_shared/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'org/apache/maven/wagon' -_MODULE_NAME = 'wagon-http-shared' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/org_apache_maven_wagon_wagon_provider_api/3pp/3pp.pb b/third_party/android_deps/libs/org_apache_maven_wagon_wagon_provider_api/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/org_apache_maven_wagon_wagon_provider_api/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/org_apache_maven_wagon_wagon_provider_api/3pp/fetch.py b/third_party/android_deps/libs/org_apache_maven_wagon_wagon_provider_api/3pp/fetch.py deleted file mode 100755 index 5061abc..0000000 --- a/third_party/android_deps/libs/org_apache_maven_wagon_wagon_provider_api/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'org/apache/maven/wagon' -_MODULE_NAME = 'wagon-provider-api' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/org_codehaus_plexus_plexus_container_default/3pp/3pp.pb b/third_party/android_deps/libs/org_codehaus_plexus_plexus_container_default/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/org_codehaus_plexus_plexus_container_default/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/org_codehaus_plexus_plexus_container_default/3pp/fetch.py b/third_party/android_deps/libs/org_codehaus_plexus_plexus_container_default/3pp/fetch.py deleted file mode 100755 index bb7a442..0000000 --- a/third_party/android_deps/libs/org_codehaus_plexus_plexus_container_default/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'org/codehaus/plexus' -_MODULE_NAME = 'plexus-container-default' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/org_codehaus_plexus_plexus_interpolation/3pp/3pp.pb b/third_party/android_deps/libs/org_codehaus_plexus_plexus_interpolation/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/org_codehaus_plexus_plexus_interpolation/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/org_codehaus_plexus_plexus_interpolation/3pp/fetch.py b/third_party/android_deps/libs/org_codehaus_plexus_plexus_interpolation/3pp/fetch.py deleted file mode 100755 index 92c9eb90..0000000 --- a/third_party/android_deps/libs/org_codehaus_plexus_plexus_interpolation/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'org/codehaus/plexus' -_MODULE_NAME = 'plexus-interpolation' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/org_codehaus_plexus_plexus_utils/3pp/3pp.pb b/third_party/android_deps/libs/org_codehaus_plexus_plexus_utils/3pp/3pp.pb deleted file mode 100644 index d8137c1..0000000 --- a/third_party/android_deps/libs/org_codehaus_plexus_plexus_utils/3pp/3pp.pb +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - -create { - source { - script { name: "fetch.py" } - } -} - -upload { - pkg_prefix: "chromium/third_party/android_deps/libs" - universal: true -}
diff --git a/third_party/android_deps/libs/org_codehaus_plexus_plexus_utils/3pp/fetch.py b/third_party/android_deps/libs/org_codehaus_plexus_plexus_utils/3pp/fetch.py deleted file mode 100755 index 2f611f0..0000000 --- a/third_party/android_deps/libs/org_codehaus_plexus_plexus_utils/3pp/fetch.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is generated, do not edit. Update BuildConfigGenerator.groovy and -# 3ppFetch.template instead. - -from __future__ import print_function - -import argparse -import json -import os -import re - -from six.moves import urllib - -_REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'org/codehaus/plexus' -_MODULE_NAME = 'plexus-utils' -_FILE_EXT = 'jar' -_OVERRIDE_LATEST = None -_PATCH_VERSION = 'cr0' - - -def do_latest(): - if _OVERRIDE_LATEST is not None: - print(_OVERRIDE_LATEST) - return - maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( - _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') - # Do not parse xml with the python included parser since it is susceptible - # to maliciously crafted xmls. Only use regular expression parsing to be - # safe. RE should be enough to handle what we need to extract. - match = re.search('<latest>([^<]+)</latest>', metadata) - if match: - latest = match.group(1) - else: - # if no latest info was found just hope the versions are sorted and the - # last one is the latest (as is commonly the case). - latest = re.findall('<version>([^<]+)</version>', metadata)[-1] - print(latest + f'.{_PATCH_VERSION}') - - -def get_download_url(version): - # Remove the patch version when getting the download url - version_no_patch, patch = version.rsplit('.', 1) - if patch.startswith('cr'): - version = version_no_patch - file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME, - _MODULE_NAME, version, - _FILE_EXT) - file_name = file_url.rsplit('/', 1)[-1] - - partial_manifest = { - 'url': [file_url], - 'name': [file_name], - 'ext': '.' + _FILE_EXT, - } - print(json.dumps(partial_manifest)) - - -def main(): - ap = argparse.ArgumentParser() - sub = ap.add_subparsers() - - latest = sub.add_parser("latest") - latest.set_defaults(func=lambda _opts: do_latest()) - - download = sub.add_parser("get_url") - download.set_defaults( - func=lambda _opts: get_download_url(os.environ['_3PP_VERSION'])) - - opts = ap.parse_args() - opts.func(opts) - - -if __name__ == '__main__': - main()
diff --git a/third_party/android_deps/libs/org_apache_ant_ant/3pp/3pp.pb b/third_party/android_deps/libs/org_robolectric_nativeruntime/3pp/3pp.pb similarity index 100% rename from third_party/android_deps/libs/org_apache_ant_ant/3pp/3pp.pb rename to third_party/android_deps/libs/org_robolectric_nativeruntime/3pp/3pp.pb
diff --git a/third_party/android_deps/libs/org_apache_maven_maven_profile/3pp/fetch.py b/third_party/android_deps/libs/org_robolectric_nativeruntime/3pp/fetch.py similarity index 96% rename from third_party/android_deps/libs/org_apache_maven_maven_profile/3pp/fetch.py rename to third_party/android_deps/libs/org_robolectric_nativeruntime/3pp/fetch.py index 737a5a2a..62d39a2 100755 --- a/third_party/android_deps/libs/org_apache_maven_maven_profile/3pp/fetch.py +++ b/third_party/android_deps/libs/org_robolectric_nativeruntime/3pp/fetch.py
@@ -16,8 +16,8 @@ from six.moves import urllib _REPO_URL = 'https://repo.maven.apache.org/maven2' -_GROUP_NAME = 'org/apache/maven' -_MODULE_NAME = 'maven-profile' +_GROUP_NAME = 'org/robolectric' +_MODULE_NAME = 'nativeruntime' _FILE_EXT = 'jar' _OVERRIDE_LATEST = None _PATCH_VERSION = 'cr0' @@ -29,7 +29,8 @@ return maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format( _REPO_URL, _GROUP_NAME, _MODULE_NAME) - metadata = urllib.request.urlopen(maven_metadata_url).read().decode('utf-8') + metadata = urllib.request.urlopen(maven_metadata_url).read().decode( + 'utf-8') # Do not parse xml with the python included parser since it is susceptible # to maliciously crafted xmls. Only use regular expression parsing to be # safe. RE should be enough to handle what we need to extract.
diff --git a/third_party/android_deps/libs/org_robolectric_nativeruntime/LICENSE b/third_party/android_deps/libs/org_robolectric_nativeruntime/LICENSE new file mode 100644 index 0000000..370fb55 --- /dev/null +++ b/third_party/android_deps/libs/org_robolectric_nativeruntime/LICENSE
@@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2009 codehaus.org. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE.
diff --git a/third_party/android_deps/libs/org_robolectric_nativeruntime/OWNERS b/third_party/android_deps/libs/org_robolectric_nativeruntime/OWNERS new file mode 100644 index 0000000..aea47a05 --- /dev/null +++ b/third_party/android_deps/libs/org_robolectric_nativeruntime/OWNERS
@@ -0,0 +1 @@ +file://third_party/android_deps/OWNERS
diff --git a/third_party/android_deps/libs/org_robolectric_nativeruntime/README.chromium b/third_party/android_deps/libs/org_robolectric_nativeruntime/README.chromium new file mode 100644 index 0000000..6a6e3b16 --- /dev/null +++ b/third_party/android_deps/libs/org_robolectric_nativeruntime/README.chromium
@@ -0,0 +1,13 @@ +Name: nativeruntime +Short Name: nativeruntime +URL: http://robolectric.org +Version: 4.7.3 +License: MIT +License File: NOT_SHIPPED +Security Critical: no + +Description: +An alternative Android testing framework. + +Local Modifications: +No modifications.
diff --git a/third_party/android_deps/libs/org_robolectric_nativeruntime/cipd.yaml b/third_party/android_deps/libs/org_robolectric_nativeruntime/cipd.yaml new file mode 100644 index 0000000..1dabf767 --- /dev/null +++ b/third_party/android_deps/libs/org_robolectric_nativeruntime/cipd.yaml
@@ -0,0 +1,10 @@ +# Copyright 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# To create CIPD package run the following command. +# cipd create --pkg-def cipd.yaml -tag version:2@4.7.3.cr0 +package: chromium/third_party/android_deps/libs/org_robolectric_nativeruntime +description: "nativeruntime" +data: +- file: nativeruntime-4.7.3.jar
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index 9399d9c8..1193390 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -1023,6 +1023,19 @@ return base::FeatureList::IsEnabled(blink::features::kAllowURNsInIframes); } +// https://github.com/jkarlin/topics +// Kill switch for the Topics API. +const base::Feature kBrowsingTopics{"BrowsingTopics", + base::FEATURE_DISABLED_BY_DEFAULT}; +// The max number of entries allowed to be retrieved from the +// `BrowsingTopicsSiteDataStorage` database for each query for the API usage +// contexts. The query will occur once per epoch (week) at topics calculation +// time. The intent is to cap the peak memory usage. +const base::FeatureParam<int> + kBrowsingTopicsMaxNumberOfApiUsageContextEntriesToLoadPerEpoch{ + &kBrowsingTopics, + "max_number_of_api_usage_context_entries_to_load_per_epoch", 100000}; + // Enable the ability to minimize processing in the WebRTC APM when all audio // tracks are disabled. If disabled, the APM in WebRTC will ignore attempts to // set it in a low-processing mode when all audio tracks are disabled.
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index fcbc595..fec732f 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -463,6 +463,10 @@ // Returns true when Prerender2 feature is enabled. BLINK_COMMON_EXPORT bool IsAllowURNsInIframeEnabled(); +BLINK_COMMON_EXPORT extern const base::Feature kBrowsingTopics; +BLINK_COMMON_EXPORT extern const base::FeatureParam<int> + kBrowsingTopicsMaxNumberOfApiUsageContextEntriesToLoadPerEpoch; + // Control switch for minimizing processing in the WebRTC APM when all audio // tracks are disabled. BLINK_COMMON_EXPORT extern const base::Feature
diff --git a/third_party/blink/public/web/web_navigation_control.h b/third_party/blink/public/web/web_navigation_control.h index 7d2ce2b..6bc8ade 100644 --- a/third_party/blink/public/web/web_navigation_control.h +++ b/third_party/blink/public/web/web_navigation_control.h
@@ -54,8 +54,7 @@ bool is_client_redirect, bool has_transient_user_activation, const WebSecurityOrigin& initiator_origin, - bool is_browser_initiated, - std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) = 0; + bool is_browser_initiated) = 0; // Override the normal rules that determine whether the frame is on the // initial empty document or not. Used to propagate state when this frame has
diff --git a/third_party/blink/renderer/core/app_history/app_history_test.cc b/third_party/blink/renderer/core/app_history/app_history_test.cc index 584e9f5..fa9f9ad 100644 --- a/third_party/blink/renderer/core/app_history/app_history_test.cc +++ b/third_party/blink/renderer/core/app_history/app_history_test.cc
@@ -78,7 +78,7 @@ false /* has_transient_user_activation */, nullptr /* initiator_origin */, false /* is_synchronously_committed */, mojom::blink::TriggeringEventInfo::kNotFromEvent, - true /* is_browser_initiated */, nullptr); + true /* is_browser_initiated */); EXPECT_EQ(result, mojom::blink::CommitResult::Ok); }
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 774cb24..2c7a4acd 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -6451,7 +6451,7 @@ return MakeGarbageCollected<Attr>(*this, q_name, g_empty_atom); } -const SVGDocumentExtensions* Document::SvgExtensions() { +const SVGDocumentExtensions* Document::SvgExtensions() const { return svg_extensions_.Get(); }
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index cab07be..b3838e0 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h
@@ -1299,7 +1299,7 @@ void RemoveAllEventListeners() final; - const SVGDocumentExtensions* SvgExtensions(); + const SVGDocumentExtensions* SvgExtensions() const; SVGDocumentExtensions& AccessSVGExtensions(); bool AllowInlineEventHandler(Node*,
diff --git a/third_party/blink/renderer/core/exported/web_view_test.cc b/third_party/blink/renderer/core/exported/web_view_test.cc index 0ec17b9..c0ce1bb 100644 --- a/third_party/blink/renderer/core/exported/web_view_test.cc +++ b/third_party/blink/renderer/core/exported/web_view_test.cc
@@ -2504,21 +2504,21 @@ false /* has_transient_user_activation */, nullptr /* initiator_origin */, false /* is_synchronously_committed */, mojom::blink::TriggeringEventInfo::kNotFromEvent, - true /* is_browser_initiated */, nullptr); + true /* is_browser_initiated */); main_frame_local->Loader().GetDocumentLoader()->CommitSameDocumentNavigation( item2->Url(), WebFrameLoadType::kBackForward, item2.Get(), ClientRedirectPolicy::kNotClientRedirect, false /* has_transient_user_activation */, nullptr /* initiator_origin */, false /* is_synchronously_committed */, mojom::blink::TriggeringEventInfo::kNotFromEvent, - true /* is_browser_initiated */, nullptr); + true /* is_browser_initiated */); main_frame_local->Loader().GetDocumentLoader()->CommitSameDocumentNavigation( item1->Url(), WebFrameLoadType::kBackForward, item1.Get(), ClientRedirectPolicy::kNotClientRedirect, false /* has_transient_user_activation */, nullptr /* initiator_origin */, false /* is_synchronously_committed */, mojom::blink::TriggeringEventInfo::kNotFromEvent, - true /* is_browser_initiated */, nullptr); + true /* is_browser_initiated */); web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases( DocumentUpdateReason::kTest); @@ -2540,7 +2540,7 @@ false /* has_transient_user_activation */, nullptr /* initiator_origin */, false /* is_synchronously_committed */, mojom::blink::TriggeringEventInfo::kNotFromEvent, - true /* is_browser_initiated */, nullptr); + true /* is_browser_initiated */); main_frame_local->Loader().GetDocumentLoader()->CommitSameDocumentNavigation( item3->Url(), WebFrameLoadType::kBackForward, item3.Get(), @@ -2548,7 +2548,7 @@ false /* has_transient_user_activation */, nullptr /* initiator_origin */, false /* is_synchronously_committed */, mojom::blink::TriggeringEventInfo::kNotFromEvent, - true /* is_browser_initiated */, nullptr); + true /* is_browser_initiated */); // The scroll offset is only applied via invoking the anchor via the main // lifecycle, or a forced layout. // TODO(chrishtr): At the moment, WebLocalFrameImpl::GetScrollOffset() does
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h index 32de870..386fb615 100644 --- a/third_party/blink/renderer/core/frame/local_frame_client.h +++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -234,10 +234,6 @@ std::unique_ptr<PolicyContainer> policy_container, std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) = 0; - virtual void UpdateDocumentLoader( - DocumentLoader* document_loader, - std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) = 0; - virtual String UserAgent() = 0; virtual String FullUserAgent() = 0; virtual String ReducedUserAgent() = 0;
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc index e0a867aa..e193f6c 100644 --- a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc +++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
@@ -783,13 +783,6 @@ return document_loader; } -void LocalFrameClientImpl::UpdateDocumentLoader( - DocumentLoader* document_loader, - std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) { - static_cast<WebDocumentLoaderImpl*>(document_loader) - ->SetExtraData(std::move(extra_data)); -} - String LocalFrameClientImpl::UserAgent() { WebString override = web_frame_->Client() ? web_frame_->Client()->UserAgentOverride() : "";
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.h b/third_party/blink/renderer/core/frame/local_frame_client_impl.h index 6eb7606..503b864 100644 --- a/third_party/blink/renderer/core/frame/local_frame_client_impl.h +++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.h
@@ -166,11 +166,6 @@ std::unique_ptr<PolicyContainer> policy_container, std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) override; - // Updates the underlying |WebDocumentLoaderImpl| of |DocumentLoader| with - // extra_data. - void UpdateDocumentLoader( - DocumentLoader* document_loader, - std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) override; WTF::String UserAgent() override; WTF::String FullUserAgent() override; WTF::String ReducedUserAgent() override;
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 94339269..1ae74fb7 100644 --- a/third_party/blink/renderer/core/frame/web_frame_test.cc +++ b/third_party/blink/renderer/core/frame/web_frame_test.cc
@@ -7992,7 +7992,7 @@ false /* has_transient_user_activation */, /*initiator_origin=*/nullptr, /*is_synchronously_committed=*/false, mojom::blink::TriggeringEventInfo::kNotFromEvent, - true /* is_browser_initiated */, nullptr /* extra_data */); + true /* is_browser_initiated */); EXPECT_EQ(kWebBackForwardCommit, client.LastCommitType()); }
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index dd163e2..7bf877e6 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -2416,8 +2416,7 @@ bool is_client_redirect, bool has_transient_user_activation, const WebSecurityOrigin& initiator_origin, - bool is_browser_initiated, - std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) { + bool is_browser_initiated) { DCHECK(GetFrame()); DCHECK(!url.ProtocolIs("javascript")); @@ -2428,8 +2427,7 @@ : ClientRedirectPolicy::kNotClientRedirect, has_transient_user_activation, initiator_origin.Get(), /*is_synchronously_committed=*/false, - mojom::blink::TriggeringEventInfo::kNotFromEvent, is_browser_initiated, - std::move(extra_data)); + mojom::blink::TriggeringEventInfo::kNotFromEvent, is_browser_initiated); } bool WebLocalFrameImpl::IsLoading() const {
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h index 2264b68..ef79b28 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -355,8 +355,7 @@ bool is_client_redirect, bool has_transient_user_activation, const WebSecurityOrigin& initiator_origin, - bool is_browser_initiated, - std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) override; + bool is_browser_initiated) override; void SetIsNotOnInitialEmptyDocument() override; bool IsOnInitialEmptyDocument() override; bool WillStartNavigation(const WebNavigationInfo&) override;
diff --git a/third_party/blink/renderer/core/html/forms/resources/calendar_picker.js b/third_party/blink/renderer/core/html/forms/resources/calendar_picker.js index 1afcf8206..f19563e18 100644 --- a/third_party/blink/renderer/core/html/forms/resources/calendar_picker.js +++ b/third_party/blink/renderer/core/html/forms/resources/calendar_picker.js
@@ -2608,143 +2608,136 @@ }; } -/** - * @constructor - * @extends ListView - * @param {!Month} minimumMonth - * @param {!Month} maximumMonth - */ -function YearListView(minimumMonth, maximumMonth, config) { - ListView.call(this); - this.element.classList.add('year-list-view'); - +class YearListView extends ListView { /** - * @type {?Month} + * @param {!Month} minimumMonth + * @param {!Month} maximumMonth */ - this._selectedMonth = null; - /** - * @type {!Month} - * @const - * @protected - */ - this._minimumMonth = minimumMonth; - /** - * @type {!Month} - * @const - * @protected - */ - this._maximumMonth = maximumMonth; + constructor(minimumMonth, maximumMonth, config) { + super(); + this.element.classList.add('year-list-view'); - this.scrollView.minimumContentOffset = - (this._minimumMonth.year - 1) * YearListCell.GetHeight(); - this.scrollView.maximumContentOffset = - (this._maximumMonth.year - 1) * YearListCell.GetHeight() + - YearListCell.GetSelectedHeight(); + /** + * @type {?Month} + */ + this._selectedMonth = null; + /** + * @type {!Month} + * @const + * @protected + */ + this._minimumMonth = minimumMonth; + /** + * @type {!Month} + * @const + * @protected + */ + this._maximumMonth = maximumMonth; - /** - * @type {!Object} - * @const - * @protected - */ - this._runningAnimators = {}; - /** - * @type {!Array} - * @const - * @protected - */ - this._animatingRows = []; - /** - * @type {!boolean} - * @protected - */ - this._ignoreMouseOutUntillNextMouseOver = false; + this.scrollView.minimumContentOffset = + (this._minimumMonth.year - 1) * YearListCell.GetHeight(); + this.scrollView.maximumContentOffset = + (this._maximumMonth.year - 1) * YearListCell.GetHeight() + + YearListCell.GetSelectedHeight(); - /** - * @type {!ScrubbyScrollBar} - * @const - */ - this.scrubbyScrollBar = new ScrubbyScrollBar(this.scrollView); - this.scrubbyScrollBar.attachTo(this); + /** + * @type {!Object} + * @const + * @protected + */ + this._runningAnimators = {}; + /** + * @type {!Array} + * @const + * @protected + */ + this._animatingRows = []; + /** + * @type {!boolean} + * @protected + */ + this._ignoreMouseOutUntillNextMouseOver = false; - this.element.addEventListener('keydown', this.onKeyDown, false); + /** + * @type {!ScrubbyScrollBar} + * @const + */ + this.scrubbyScrollBar = new ScrubbyScrollBar(this.scrollView); + this.scrubbyScrollBar.attachTo(this); - if (config && config.mode == 'month') { - this.type = 'month'; - this._dateTypeConstructor = Month; + this.element.addEventListener('keydown', this.onKeyDown.bind(this)); - this._setValidDateConfig(config); + if (config && config.mode == 'month') { + this.type = 'month'; + this._dateTypeConstructor = Month; - this._hadValidValueWhenOpened = false; - var initialSelection = parseDateString(config.currentValue); - if (initialSelection) { - this._hadValidValueWhenOpened = this.isValid(initialSelection); - this._selectedMonth = this.getNearestValidRange( - initialSelection, /*lookForwardFirst*/ true); + this._setValidDateConfig(config); + + this._hadValidValueWhenOpened = false; + var initialSelection = parseDateString(config.currentValue); + if (initialSelection) { + this._hadValidValueWhenOpened = this.isValid(initialSelection); + this._selectedMonth = this.getNearestValidRange( + initialSelection, /*lookForwardFirst*/ true); + } else { + // Ensure that the next month closest to today is selected to start with + // so that the user can simply submit the popup to choose it. + this._selectedMonth = this.getValidRangeNearestToDay( + this._dateTypeConstructor.createFromToday(), + /*lookForwardFirst*/ true); + } + + this._initialSelectedMonth = this._selectedMonth; } else { - // Ensure that the next month closest to today is selected to start with so that - // the user can simply submit the popup to choose it. - this._selectedMonth = this.getValidRangeNearestToDay( - this._dateTypeConstructor.createFromToday(), - /*lookForwardFirst*/ true); + // This is a month switcher menu embedded in another calendar control. + // Set up our config so that getNearestValidRangeLookingForward(Backward) + // when called on this YearListView will navigate by month. + this.config = {}; + this.config.minimumValue = minimumMonth; + this.config.maximumValue = maximumMonth; + this.config.step = Month.DefaultStep; + this.config.stepBase = Month.DefaultStepBase; + this._dateTypeConstructor = Month; } - - this._initialSelectedMonth = this._selectedMonth; - } else { - // This is a month switcher menu embedded in another calendar control. - // Set up our config so that getNearestValidRangeLookingForward(Backward) - // when called on this YearListView will navigate by month. - this.config = {}; - this.config.minimumValue = minimumMonth; - this.config.maximumValue = maximumMonth; - this.config.step = Month.DefaultStep; - this.config.stepBase = Month.DefaultStepBase; - this._dateTypeConstructor = Month; } -} -{ - YearListView.prototype = Object.create(ListView.prototype); - Object.assign(YearListView.prototype, DateRangeManager); - - YearListView._VisibleYears = 4; - YearListView._Height = YearListCell._SelectedHeight - 1 + + static _VisibleYears = 4; + static _Height = YearListCell._SelectedHeight - 1 + YearListView._VisibleYears * YearListCell._Height; - YearListView.GetHeight = function() { + static GetHeight() { return YearListView._Height; }; - YearListView.EventTypeYearListViewDidHide = 'yearListViewDidHide'; - YearListView.EventTypeYearListViewDidSelectMonth = - 'yearListViewDidSelectMonth'; + static EventTypeYearListViewDidHide = 'yearListViewDidHide'; + static EventTypeYearListViewDidSelectMonth = 'yearListViewDidSelectMonth'; /** * @param {!number} width Width in pixels. * @override */ - YearListView.prototype.setWidth = function(width) { - ListView.prototype.setWidth.call( - this, width - this.scrubbyScrollBar.element.offsetWidth); + setWidth(width) { + super.setWidth(width - this.scrubbyScrollBar.element.offsetWidth); this.element.style.width = width + 'px'; - }; + } /** * @param {!number} height Height in pixels. * @override */ - YearListView.prototype.setHeight = function(height) { - ListView.prototype.setHeight.call(this, height); + setHeight(height) { + super.setHeight(height); this.scrubbyScrollBar.setHeight(height); - }; + } /** * @enum {number} */ - YearListView.RowAnimationDirection = {Opening: 0, Closing: 1}; + static RowAnimationDirection = {Opening: 0, Closing: 1}; /** * @param {!number} row * @param {!YearListView.RowAnimationDirection} direction */ - YearListView.prototype._animateRow = function(row, direction) { + _animateRow(row, direction) { var fromValue = direction === YearListView.RowAnimationDirection.Closing ? YearListCell.GetSelectedHeight() : YearListCell.GetHeight(); @@ -2755,7 +2748,7 @@ } var cell = this.cellAtRow(row); var animator = new TransitionAnimator(); - animator.step = this.onCellHeightAnimatorStep; + animator.step = this.onCellHeightAnimatorStep.bind(this); animator.setFrom(fromValue); animator.setTo( direction === YearListView.RowAnimationDirection.Opening ? @@ -2765,38 +2758,39 @@ animator.duration = 300; animator.row = row; animator.on( - Animator.EventTypeDidAnimationStop, this.onCellHeightAnimatorDidStop); + Animator.EventTypeDidAnimationStop, + this.onCellHeightAnimatorDidStop.bind(this)); this._runningAnimators[row] = animator; this._animatingRows.push(row); this._animatingRows.sort(); animator.start(); - }; + } /** * @param {?Animator} animator */ - YearListView.prototype.onCellHeightAnimatorDidStop = function(animator) { + onCellHeightAnimatorDidStop(animator) { delete this._runningAnimators[animator.row]; var index = this._animatingRows.indexOf(animator.row); this._animatingRows.splice(index, 1); - }; + } /** * @param {!Animator} animator */ - YearListView.prototype.onCellHeightAnimatorStep = function(animator) { + onCellHeightAnimatorStep(animator) { var cell = this.cellAtRow(animator.row); if (cell) cell.setHeight(animator.currentValue); this.updateCells(); - }; + } /** * @param {?Event} event */ - YearListView.prototype.onClick = function(event) { + onClick(event) { var oldSelectedRow = this.selectedRow; - ListView.prototype.onClick.call(this, event); + super.onClick(event); var year = this.selectedRow + 1; if (this.selectedRow !== oldSelectedRow) { // Always start with first month when changing the year. @@ -2813,14 +2807,14 @@ YearListView.EventTypeYearListViewDidSelectMonth, this, new Month(year, month)); } - }; + } /** * @param {!number} scrollOffset * @return {!number} * @override */ - YearListView.prototype.rowAtScrollOffset = function(scrollOffset) { + rowAtScrollOffset(scrollOffset) { var remainingOffset = scrollOffset; var lastAnimatingRow = 0; var rowsWithIrregularHeight = this._animatingRows.slice(); @@ -2846,14 +2840,14 @@ } return lastAnimatingRow + Math.floor(remainingOffset / YearListCell.GetHeight()); - }; + } /** * @param {!number} row * @return {!number} * @override */ - YearListView.prototype.scrollOffsetForRow = function(row) { + scrollOffsetForRow(row) { var scrollOffset = row * YearListCell.GetHeight(); for (var i = 0; i < this._animatingRows.length; ++i) { var animatingRow = this._animatingRows[i]; @@ -2868,14 +2862,14 @@ YearListCell.GetSelectedHeight() - YearListCell.GetHeight(); } return scrollOffset; - }; + } /** * @param {!number} row * @return {!YearListCell} * @override */ - YearListView.prototype.prepareNewCell = function(row) { + prepareNewCell(row) { var cell = YearListCell._recycleBin.pop() || new YearListCell(global.params.shortMonthLabels); cell.reset(row); @@ -2915,12 +2909,12 @@ else cell.setHeight(YearListCell.GetHeight()); return cell; - }; + } /** * @override */ - YearListView.prototype.updateCells = function() { + updateCells() { var firstVisibleRow = this.firstVisibleRow(); var lastVisibleRow = this.lastVisibleRow(); console.assert(firstVisibleRow <= lastVisibleRow); @@ -2938,12 +2932,12 @@ this.addCellIfNecessary(i); } this.setNeedsUpdateCells(false); - }; + } /** * @override */ - YearListView.prototype.deselect = function() { + deselect() { if (this.selectedRow === ListView.NoSelection) return; var selectedCell = this._cells[this.selectedRow]; @@ -2953,9 +2947,9 @@ this.selectedRow, YearListView.RowAnimationDirection.Closing); this.selectedRow = ListView.NoSelection; this.setNeedsUpdateCells(true); - }; + } - YearListView.prototype.deselectWithoutAnimating = function() { + deselectWithoutAnimating() { if (this.selectedRow === ListView.NoSelection) return; var selectedCell = this._cells[this.selectedRow]; @@ -2965,13 +2959,13 @@ } this.selectedRow = ListView.NoSelection; this.setNeedsUpdateCells(true); - }; + } /** * @param {!number} row * @override */ - YearListView.prototype.select = function(row) { + select(row) { if (this.selectedRow === row) return; this.deselect(); @@ -2986,12 +2980,12 @@ selectedCell.setSelected(true); } this.setNeedsUpdateCells(true); - }; + } /** * @param {!number} row */ - YearListView.prototype.selectWithoutAnimating = function(row) { + selectWithoutAnimating(row) { if (this.selectedRow === row) return; this.deselectWithoutAnimating(); @@ -3006,13 +3000,13 @@ } } this.setNeedsUpdateCells(true); - }; + } /** * @param {!Month} month * @return {?HTMLDivElement} */ - YearListView.prototype.buttonForMonth = function(month) { + buttonForMonth(month) { if (!month) return null; var row = month.year - 1; @@ -3020,9 +3014,9 @@ if (!cell) return null; return cell.monthButtons[month.month]; - }; + } - YearListView.prototype.dehighlightMonth = function() { + dehighlightMonth() { if (!this.highlightedMonth) return; var monthButton = this.buttonForMonth(this.highlightedMonth); @@ -3031,12 +3025,12 @@ } this.highlightedMonth = null; this.element.removeAttribute('aria-activedescendant'); - }; + } /** * @param {!Month} month */ - YearListView.prototype.highlightMonth = function(month) { + highlightMonth(month) { if (this.highlightedMonth && this.highlightedMonth.equals(month)) return; this.dehighlightMonth(); @@ -3048,9 +3042,9 @@ monthButton.classList.add(YearListCell.ClassNameHighlighted); this.element.setAttribute('aria-activedescendant', monthButton.id); } - }; + } - YearListView.prototype.setSelectedMonth = function(month) { + setSelectedMonth(month) { var oldMonthButton = this.buttonForMonth(this._selectedMonth); if (oldMonthButton) { oldMonthButton.classList.remove(YearListCell.ClassNameSelected); @@ -3065,52 +3059,52 @@ this.element.setAttribute('aria-activedescendant', newMonthButton.id); newMonthButton.setAttribute('aria-selected', true); } - }; + } - YearListView.prototype.setSelectedMonthAndUpdateView = function(month) { + setSelectedMonthAndUpdateView(month) { this.setSelectedMonth(month); this.select(this._selectedMonth.year - 1); this.scrollView.scrollTo(this.selectedRow * YearListCell.GetHeight(), true); - }; + } - YearListView.prototype.showSelectedMonth = function() { + showSelectedMonth() { var monthButton = this.buttonForMonth(this._selectedMonth); if (monthButton) { monthButton.classList.add(YearListCell.ClassNameSelected); } - }; + } /** * @param {!Month} month */ - YearListView.prototype.show = function(month) { + show(month) { this._ignoreMouseOutUntillNextMouseOver = true; this.scrollToRow(month.year - 1, false); this.selectWithoutAnimating(month.year - 1); this.showSelectedMonth(); - }; + } - YearListView.prototype.hide = function() { + hide() { this.dispatchEvent(YearListView.EventTypeYearListViewDidHide, this); - }; + } /** * @param {!Month} month */ - YearListView.prototype._moveHighlightTo = function(month) { + _moveHighlightTo(month) { this.highlightMonth(month); this.select(this.highlightedMonth.year - 1); this.scrollView.scrollTo(this.selectedRow * YearListCell.GetHeight(), true); return true; - }; + } /** * @param {?Event} event */ - YearListView.prototype.onKeyDown = function(event) { + onKeyDown(event) { var key = event.key; var eventHandled = false; if (this._selectedMonth) { @@ -3198,9 +3192,11 @@ event.stopPropagation(); event.preventDefault(); } - }; + } } +Object.assign(YearListView.prototype, DateRangeManager); + /** * @constructor * @extends View
diff --git a/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc b/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc index c23fbfd..9815f92 100644 --- a/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc +++ b/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc
@@ -322,8 +322,7 @@ ClientRedirectPolicy::kNotClientRedirect, false /* has_transient_user_activation */, nullptr /* initiator_origin */, false /* is_synchronously_committed */, - mojom::blink::TriggeringEventInfo::kNotFromEvent, is_browser_initiated, - nullptr); + mojom::blink::TriggeringEventInfo::kNotFromEvent, is_browser_initiated); Compositor().BeginFrame(); test::RunPendingTasks();
diff --git a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc index 8086c62e..d84cf8bf 100644 --- a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc
@@ -1346,7 +1346,7 @@ bool row_container_separation = has_processed_first_line_; NGBreakStatus row_break_status = BreakBeforeRowIfNeeded( line_output, (*row_break_between_outputs)[flex_line_idx], - flex_line_idx, flex_item->ng_input_node, *layout_result, + flex_line_idx, flex_item->ng_input_node, row_container_separation); if (row_break_status == NGBreakStatus::kBrokeBefore) { ConsumeRemainingFragmentainerSpace(); @@ -1678,7 +1678,6 @@ EBreakBetween row_break_between, wtf_size_t row_index, NGLayoutInputNode child, - const NGLayoutResult& layout_result, bool has_container_separation) { DCHECK(is_horizontal_flow_); DCHECK(involved_in_block_fragmentation_); @@ -1691,9 +1690,10 @@ NGBreakAppeal appeal_before = kBreakAppealPerfect; if (has_container_separation) { if (IsForcedBreakValue(ConstraintSpace(), row_break_between)) { - BreakBeforeChild(ConstraintSpace(), child, layout_result, + BreakBeforeChild(ConstraintSpace(), child, /* layout_result */ nullptr, fragmentainer_block_offset, kBreakAppealPerfect, - /* is_forced_break */ true, &container_builder_); + /* is_forced_break */ true, &container_builder_, + row.line_cross_size); return NGBreakStatus::kBrokeBefore; } } else { @@ -1716,8 +1716,9 @@ // We're out of space. Figure out where to insert a soft break. It will either // be before this row, or before an earlier sibling, if there's a more // appealing breakpoint there. - if (!AttemptRowSoftBreak(child, layout_result, appeal_before, - fragmentainer_block_offset, row.line_cross_size)) + if (!AttemptSoftBreak(ConstraintSpace(), child, /* layout_result */ nullptr, + fragmentainer_block_offset, appeal_before, + &container_builder_, row.line_cross_size)) return NGBreakStatus::kNeedsEarlierBreak; return NGBreakStatus::kBrokeBefore; @@ -1770,30 +1771,6 @@ return true; } -bool NGFlexLayoutAlgorithm::AttemptRowSoftBreak( - NGLayoutInputNode child, - const NGLayoutResult& layout_result, - NGBreakAppeal appeal_before, - LayoutUnit fragmentainer_block_offset, - LayoutUnit row_block_size) { - if (container_builder_.HasEarlyBreak() && - container_builder_.EarlyBreak().BreakAppeal() > appeal_before) { - PropagateSpaceShortage(ConstraintSpace(), /* layout_result */ nullptr, - fragmentainer_block_offset, &container_builder_, - row_block_size); - return false; - } - - // Break before the row. Note that there may be a better break further up - // with higher appeal (but it's too early to tell), in which case this - // breakpoint will be replaced. - // TODO(almaher): PropagateSpaceShortage() will be different for rows. - BreakBeforeChild(ConstraintSpace(), child, layout_result, - fragmentainer_block_offset, appeal_before, - /* is_forced_break */ false, &container_builder_); - return true; -} - #if DCHECK_IS_ON() void NGFlexLayoutAlgorithm::CheckFlexLines( const Vector<NGFlexLine>& flex_line_outputs) const {
diff --git a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.h index 301c272..4be6fff4 100644 --- a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.h +++ b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.h
@@ -122,7 +122,6 @@ EBreakBetween row_break_between, wtf_size_t row_index, NGLayoutInputNode child, - const NGLayoutResult& layout_result, bool has_container_separation); // Move past the breakpoint before the row, if possible, and return true. Also @@ -135,19 +134,6 @@ LayoutUnit row_block_size, wtf_size_t row_index); - // Attempt to insert a soft break before the row, and return true if we did. - // If false is returned, it means that the desired breakpoint is earlier in - // the container, and that we need to abort and re-layout to that breakpoint. - // |child| and |layout_result| should be those associated with the first child - // in the row. |appeal_before|, |fragmentainer_block_offset| and - // |row_block_size| are specific to the row itself. See - // |::blink::AttemptSoftBreak()| for more documentation. - bool AttemptRowSoftBreak(NGLayoutInputNode child, - const NGLayoutResult& layout_result, - NGBreakAppeal appeal_before, - LayoutUnit fragmentainer_block_offset, - LayoutUnit row_block_size); - #if DCHECK_IS_ON() void CheckFlexLines(const Vector<NGFlexLine>& flex_line_outputs) const; #endif
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc index 876daa40..67edd66 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
@@ -1177,7 +1177,7 @@ LayoutUnit fragmentainer_block_offset = ConstraintSpace().FragmentainerOffsetAtBfc() + positioned_float.bfc_offset.block_offset; - BreakBeforeChild(ConstraintSpace(), child, *positioned_float.layout_result, + BreakBeforeChild(ConstraintSpace(), child, positioned_float.layout_result, fragmentainer_block_offset, /* appeal */ absl::nullopt, /* is_forced_break */ false, &container_builder_); @@ -2394,7 +2394,7 @@ EBreakBetween break_between = CalculateBreakBetweenValue(child, layout_result, container_builder_); if (IsForcedBreakValue(ConstraintSpace(), break_between)) { - BreakBeforeChild(ConstraintSpace(), child, layout_result, + BreakBeforeChild(ConstraintSpace(), child, &layout_result, fragmentainer_block_offset, kBreakAppealPerfect, /* is_forced_break */ true, &container_builder_); ConsumeRemainingFragmentainerSpace(previous_inflow_position); @@ -2501,7 +2501,7 @@ } } - if (!AttemptSoftBreak(ConstraintSpace(), child, layout_result, + if (!AttemptSoftBreak(ConstraintSpace(), child, &layout_result, fragmentainer_block_offset, appeal_before, &container_builder_)) return NGBreakStatus::kNeedsEarlierBreak;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc index fac18fd..fbcf74fc 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc
@@ -596,7 +596,7 @@ EBreakBetween break_between = CalculateBreakBetweenValue(child, layout_result, *builder); if (IsForcedBreakValue(space, break_between)) { - BreakBeforeChild(space, child, layout_result, fragmentainer_block_offset, + BreakBeforeChild(space, child, &layout_result, fragmentainer_block_offset, kBreakAppealPerfect, /* is_forced_break */ true, builder); return NGBreakStatus::kBrokeBefore; @@ -615,8 +615,8 @@ // Breaking inside the child isn't appealing, and we're out of space. Figure // out where to insert a soft break. It will either be before this child, or // before an earlier sibling, if there's a more appealing breakpoint there. - if (!AttemptSoftBreak(space, child, layout_result, fragmentainer_block_offset, - appeal_before, builder)) + if (!AttemptSoftBreak(space, child, &layout_result, + fragmentainer_block_offset, appeal_before, builder)) return NGBreakStatus::kNeedsEarlierBreak; return NGBreakStatus::kBrokeBefore; @@ -624,16 +624,18 @@ void BreakBeforeChild(const NGConstraintSpace& space, NGLayoutInputNode child, - const NGLayoutResult& layout_result, + const NGLayoutResult* layout_result, LayoutUnit fragmentainer_block_offset, absl::optional<NGBreakAppeal> appeal, bool is_forced_break, - NGBoxFragmentBuilder* builder) { + NGBoxFragmentBuilder* builder, + absl::optional<LayoutUnit> block_size_override) { #if DCHECK_IS_ON() - if (layout_result.Status() == NGLayoutResult::kSuccess) { + DCHECK(layout_result || block_size_override); + if (layout_result && layout_result->Status() == NGLayoutResult::kSuccess) { // In order to successfully break before a node, this has to be its first // fragment. - const auto& physical_fragment = layout_result.PhysicalFragment(); + const auto& physical_fragment = layout_result->PhysicalFragment(); DCHECK(!physical_fragment.IsBox() || To<NGPhysicalBoxFragment>(physical_fragment).IsFirstForNode()); } @@ -643,16 +645,17 @@ // (only blocks), because line boxes need handle it in their own way (due to // how we implement widows). if (child.IsBlock() && space.HasKnownFragmentainerBlockSize()) { - PropagateSpaceShortage(space, &layout_result, fragmentainer_block_offset, - builder); + PropagateSpaceShortage(space, layout_result, fragmentainer_block_offset, + builder, block_size_override); } // If the fragmentainer block-size is unknown, we have no reason to insert // soft breaks. DCHECK(is_forced_break || space.HasKnownFragmentainerBlockSize()); - if (space.ShouldPropagateChildBreakValues() && !is_forced_break) - builder->PropagateChildBreakValues(layout_result); + if (layout_result && space.ShouldPropagateChildBreakValues() && + !is_forced_break) + builder->PropagateChildBreakValues(*layout_result); // We'll drop the fragment (if any) on the floor and retry at the start of the // next fragmentainer. @@ -859,18 +862,20 @@ bool AttemptSoftBreak(const NGConstraintSpace& space, NGLayoutInputNode child, - const NGLayoutResult& layout_result, + const NGLayoutResult* layout_result, LayoutUnit fragmentainer_block_offset, NGBreakAppeal appeal_before, - NGBoxFragmentBuilder* builder) { - // if there's a breakpoint with higher appeal among earlier siblings, we need + NGBoxFragmentBuilder* builder, + absl::optional<LayoutUnit> block_size_override) { + DCHECK(layout_result || block_size_override); + // If there's a breakpoint with higher appeal among earlier siblings, we need // to abort and re-layout to that breakpoint. if (builder->HasEarlyBreak() && builder->EarlyBreak().BreakAppeal() > appeal_before) { // Found a better place to break. Before aborting, calculate and report // space shortage from where we'd actually break. - PropagateSpaceShortage(space, &layout_result, fragmentainer_block_offset, - builder); + PropagateSpaceShortage(space, layout_result, fragmentainer_block_offset, + builder, block_size_override); return false; } @@ -878,7 +883,8 @@ // with higher appeal (but it's too early to tell), in which case this // breakpoint will be replaced. BreakBeforeChild(space, child, layout_result, fragmentainer_block_offset, - appeal_before, /* is_forced_break */ false, builder); + appeal_before, /* is_forced_break */ false, builder, + block_size_override); return true; }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h index 0e280ff..0dad67fd 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h +++ b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h
@@ -243,13 +243,17 @@ NGBoxFragmentBuilder*); // Insert a break before the child, and propagate space shortage if needed. -void BreakBeforeChild(const NGConstraintSpace&, - NGLayoutInputNode child, - const NGLayoutResult&, - LayoutUnit fragmentainer_block_offset, - absl::optional<NGBreakAppeal> appeal, - bool is_forced_break, - NGBoxFragmentBuilder*); +// |block_size_override| should only be supplied when you wish to propagate a +// different block-size than that of the provided layout result. +void BreakBeforeChild( + const NGConstraintSpace&, + NGLayoutInputNode child, + const NGLayoutResult*, + LayoutUnit fragmentainer_block_offset, + absl::optional<NGBreakAppeal> appeal, + bool is_forced_break, + NGBoxFragmentBuilder*, + absl::optional<LayoutUnit> block_size_override = absl::nullopt); // Propagate the block-size of unbreakable content. This is used to inflate the // initial minimal column block-size when balancing columns, before we calculate @@ -303,12 +307,16 @@ // Attempt to insert a soft break before the child, and return true if we did. // If false is returned, it means that the desired breakpoint is earlier in the // container, and that we need to abort and re-layout to that breakpoint. -bool AttemptSoftBreak(const NGConstraintSpace&, - NGLayoutInputNode child, - const NGLayoutResult&, - LayoutUnit fragmentainer_block_offset, - NGBreakAppeal appeal_before, - NGBoxFragmentBuilder*); +// |block_size_override| should only be supplied when you wish to propagate a +// different block-size than that of the provided layout result. +bool AttemptSoftBreak( + const NGConstraintSpace&, + NGLayoutInputNode child, + const NGLayoutResult*, + LayoutUnit fragmentainer_block_offset, + NGBreakAppeal appeal_before, + NGBoxFragmentBuilder*, + absl::optional<LayoutUnit> block_size_override = absl::nullopt); // If we have an previously found break point, and we're entering an ancestor of // the node we're going to break before, return the early break inside. This can
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index 940c29b..8f849e5 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -1256,8 +1256,7 @@ const SecurityOrigin* initiator_origin, bool is_synchronously_committed, mojom::blink::TriggeringEventInfo triggering_event_info, - bool is_browser_initiated, - std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) { + bool is_browser_initiated) { DCHECK(!IsReloadLoadType(frame_load_type)); DCHECK(frame_->GetDocument()); DCHECK(!is_browser_initiated || !is_synchronously_committed); @@ -1346,8 +1345,7 @@ same_document_navigation_type, client_redirect_policy, has_transient_user_activation, WTF::RetainedRef(initiator_origin), is_browser_initiated, - is_synchronously_committed, triggering_event_info, - std::move(extra_data))); + is_synchronously_committed, triggering_event_info)); } else { // Treat a navigation to the same url as replacing only if it did not // originate from a cross-origin iframe. If |is_synchronously_committed| is @@ -1359,8 +1357,8 @@ CommitSameDocumentNavigationInternal( url, frame_load_type, history_item, same_document_navigation_type, client_redirect_policy, has_transient_user_activation, initiator_origin, - is_browser_initiated, is_synchronously_committed, triggering_event_info, - std::move(extra_data)); + is_browser_initiated, is_synchronously_committed, + triggering_event_info); } return mojom::CommitResult::Ok; } @@ -1375,8 +1373,7 @@ const SecurityOrigin* initiator_origin, bool is_browser_initiated, bool is_synchronously_committed, - mojom::blink::TriggeringEventInfo triggering_event_info, - std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) { + mojom::blink::TriggeringEventInfo triggering_event_info) { // If this function was scheduled to run asynchronously, this DocumentLoader // might have been detached before the task ran. if (!frame_) @@ -1422,8 +1419,6 @@ history_item_->ItemSequenceNumber() == history_item->ItemSequenceNumber(); if (history_item) history_item_ = history_item; - if (extra_data) - GetLocalFrameClient().UpdateDocumentLoader(this, std::move(extra_data)); UpdateForSameDocumentNavigation( url, same_document_navigation_type, nullptr, mojom::blink::ScrollRestorationType::kAuto, frame_load_type,
diff --git a/third_party/blink/renderer/core/loader/document_loader.h b/third_party/blink/renderer/core/loader/document_loader.h index bbfe47a..30cac0e 100644 --- a/third_party/blink/renderer/core/loader/document_loader.h +++ b/third_party/blink/renderer/core/loader/document_loader.h
@@ -237,8 +237,7 @@ const SecurityOrigin* initiator_origin, bool is_synchronously_committed, mojom::blink::TriggeringEventInfo, - bool is_browser_initiated, - std::unique_ptr<WebDocumentLoader::ExtraData>); + bool is_browser_initiated); void SetDefersLoading(LoaderFreezeMode); @@ -415,8 +414,7 @@ const SecurityOrigin* initiator_origin, bool is_browser_initiated, bool is_synchronously_committed, - mojom::blink::TriggeringEventInfo, - std::unique_ptr<WebDocumentLoader::ExtraData>); + mojom::blink::TriggeringEventInfo); // Use these method only where it's guaranteed that |m_frame| hasn't been // cleared.
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h index 4b639069..d91e67a5 100644 --- a/third_party/blink/renderer/core/loader/empty_clients.h +++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -304,9 +304,6 @@ std::unique_ptr<WebNavigationParams> navigation_params, std::unique_ptr<PolicyContainer> policy_container, std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) override; - void UpdateDocumentLoader( - DocumentLoader* document_loader, - std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) override {} String UserAgent() override { return ""; } String FullUserAgent() override { return ""; }
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index 22ff5a06..8ab32bb9 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -694,7 +694,7 @@ frame_load_type), resource_request.HasUserGesture(), origin_window->GetSecurityOrigin(), /*is_synchronously_committed=*/true, request.GetTriggeringEventInfo(), - false /* is_browser_initiated */, nullptr /* extra_data */); + false /* is_browser_initiated */); return; }
diff --git a/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.cc b/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.cc index f4ff6cc..f954d40a 100644 --- a/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.cc +++ b/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.cc
@@ -28,6 +28,8 @@ compositor_animation_->SetAnimationDelegate(this); } +// TODO(dbaron): This should probably DCHECK(element_detached_), but too +// many unittests would fail such a DCHECK(). ScrollAnimatorCompositorCoordinator::~ScrollAnimatorCompositorCoordinator() = default; @@ -36,6 +38,13 @@ compositor_animation_.reset(); } +void ScrollAnimatorCompositorCoordinator::DetachElement() { + DCHECK(!element_detached_); + element_detached_ = true; + ReattachCompositorAnimationIfNeeded( + GetScrollableArea()->GetCompositorAnimationTimeline()); +} + void ScrollAnimatorCompositorCoordinator::ResetAnimationState() { run_state_ = RunState::kIdle; RemoveAnimation(); @@ -184,7 +193,10 @@ bool ScrollAnimatorCompositorCoordinator::ReattachCompositorAnimationIfNeeded( CompositorAnimationTimeline* timeline) { bool reattached = false; - CompositorElementId element_id = GetScrollElementId(); + CompositorElementId element_id; + if (!element_detached_) { + element_id = GetScrollElementId(); + } if (element_id != element_id_) { if (compositor_animation_ && timeline) { // Detach from old layer (if any).
diff --git a/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.h b/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.h index 03bbc18..5d31fbf 100644 --- a/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.h +++ b/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.h
@@ -92,6 +92,8 @@ void Dispose(); String RunStateAsText() const; + void DetachElement(); + virtual bool HasRunningAnimation() const { return false; } virtual void ResetAnimationState(); @@ -191,6 +193,8 @@ bool impl_only_animation_takeover_; private: + bool element_detached_ = false; + CompositorElementId GetScrollElementId() const; bool HasImplOnlyAnimationUpdate() const; void UpdateImplOnlyCompositorAnimations();
diff --git a/third_party/blink/renderer/core/scroll/scrollable_area.cc b/third_party/blink/renderer/core/scroll/scrollable_area.cc index 82f87d8..df17fe54 100644 --- a/third_party/blink/renderer/core/scroll/scrollable_area.cc +++ b/third_party/blink/renderer/core/scroll/scrollable_area.cc
@@ -127,8 +127,14 @@ void ScrollableArea::ClearScrollableArea() { if (mac_scrollbar_animator_) mac_scrollbar_animator_->Dispose(); - scroll_animator_.Clear(); - programmatic_scroll_animator_.Clear(); + if (scroll_animator_) { + scroll_animator_->DetachElement(); + scroll_animator_.Clear(); + } + if (programmatic_scroll_animator_) { + programmatic_scroll_animator_->DetachElement(); + programmatic_scroll_animator_.Clear(); + } if (fade_overlay_scrollbars_timer_) fade_overlay_scrollbars_timer_->Value().Stop(); }
diff --git a/third_party/blink/renderer/core/svg/graphics/svg_image.cc b/third_party/blink/renderer/core/svg/graphics/svg_image.cc index ffd5e5b..8d5ac4e 100644 --- a/third_party/blink/renderer/core/svg/graphics/svg_image.cc +++ b/third_party/blink/renderer/core/svg/graphics/svg_image.cc
@@ -59,6 +59,7 @@ #include "third_party/blink/renderer/core/svg/animation/smil_time_container.h" #include "third_party/blink/renderer/core/svg/graphics/svg_image_chrome_client.h" #include "third_party/blink/renderer/core/svg/svg_animated_preserve_aspect_ratio.h" +#include "third_party/blink/renderer/core/svg/svg_document_extensions.h" #include "third_party/blink/renderer/core/svg/svg_fe_image_element.h" #include "third_party/blink/renderer/core/svg/svg_image_element.h" #include "third_party/blink/renderer/core/svg/svg_svg_element.h" @@ -151,6 +152,11 @@ } }; +bool HasSmilAnimations(const Document& document) { + const SVGDocumentExtensions* extensions = document.SvgExtensions(); + return extensions && extensions->HasSmilAnimations(); +} + } // namespace // SVGImageLocalFrameClient is used to wait until SVG document's load event @@ -667,8 +673,8 @@ SVGSVGElement* root_element = RootElement(); if (!root_element) return false; - return root_element->TimeContainer()->HasAnimations() || - root_element->GetDocument().Timeline().HasPendingUpdates(); + const Document& document = root_element->GetDocument(); + return HasSmilAnimations(document) || document.Timeline().HasPendingUpdates(); } void SVGImage::ServiceAnimations( @@ -741,7 +747,7 @@ void SVGImage::UpdateUseCounters(const Document& document) const { if (SVGSVGElement* root_element = RootElement()) { - if (root_element->TimeContainer()->HasAnimations()) { + if (HasSmilAnimations(root_element->GetDocument())) { document.CountUse(WebFeature::kSVGSMILAnimationInImageRegardlessOfCache); } }
diff --git a/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc b/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc index a5ba577..5d8573f3 100644 --- a/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc +++ b/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc
@@ -259,6 +259,36 @@ EXPECT_EQ(bitmap.getColor(90, 90), SK_ColorBLUE); } +TEST_F(SVGImageTest, SVGWithSmilAnimationIsAnimated) { + const bool kShouldPause = true; + Load(R"SVG( + <svg xmlns="http://www.w3.org/2000/svg"> + <rect width="10" height="10"/> + <animateTransform attributeName="transform" type="rotate" + from="0 5 5" to="360 5 5" dur="1s" + repeatCount="indefinite"/> + </svg>)SVG", + kShouldPause); + + EXPECT_TRUE(GetImage().MaybeAnimated()); +} + +TEST_F(SVGImageTest, NestedSVGWithSmilAnimationIsAnimated) { + const bool kShouldPause = true; + Load(R"SVG( + <svg xmlns="http://www.w3.org/2000/svg"> + <svg> + <rect width="10" height="10"/> + <animateTransform attributeName="transform" type="rotate" + from="0 5 5" to="360 5 5" dur="1s" + repeatCount="indefinite"/> + </svg> + </svg>)SVG", + kShouldPause); + + EXPECT_TRUE(GetImage().MaybeAnimated()); +} + class SVGImageSimTest : public SimTest, private ScopedMockOverlayScrollbars {}; TEST_F(SVGImageSimTest, PageVisibilityHiddenToVisible) {
diff --git a/third_party/blink/renderer/core/svg/svg_document_extensions.cc b/third_party/blink/renderer/core/svg/svg_document_extensions.cc index f583f91..5359911d 100644 --- a/third_party/blink/renderer/core/svg/svg_document_extensions.cc +++ b/third_party/blink/renderer/core/svg/svg_document_extensions.cc
@@ -105,6 +105,14 @@ element->pauseAnimations(); } +bool SVGDocumentExtensions::HasSmilAnimations() const { + for (SVGSVGElement* element : time_containers_) { + if (element->TimeContainer()->HasAnimations()) + return true; + } + return false; +} + void SVGDocumentExtensions::DispatchSVGLoadEventToOutermostSVGElements() { HeapVector<Member<SVGSVGElement>> time_containers; CopyToVector(time_containers_, time_containers);
diff --git a/third_party/blink/renderer/core/svg/svg_document_extensions.h b/third_party/blink/renderer/core/svg/svg_document_extensions.h index fed22a8..60d1eecb 100644 --- a/third_party/blink/renderer/core/svg/svg_document_extensions.h +++ b/third_party/blink/renderer/core/svg/svg_document_extensions.h
@@ -58,6 +58,7 @@ void StartAnimations(); void PauseAnimations(); + bool HasSmilAnimations() const; // True if a SMIL animation frame is successfully scheduled. bool ServiceSmilAnimations(); void ServiceWebAnimations();
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 74ad3ad..fe0f977 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -4585,9 +4585,26 @@ // now layout is clean. SetNeedsToUpdateChildren(); - SANITIZER_CHECK(LastKnownIsIncludedInTreeValue()) - << "Should only fire children changed on included nodes: " - << ToString(true, true); + // The caller, AXObjectCacheImpl::ChildrenChangedWithCleanLayout(), is only + // Between the time that AXObjectCacheImpl::ChildrenChanged() determines + // which included parent to use and now, it's possible that the parent will + // no longer be ignored. This is rare, but is covered by this test: + // external/wpt/accessibility/crashtests/delayed-ignored-change.html/ + // + // If this object is no longer included in the tree, then our parent needs to + // recompute its included-in-the-tree children vector. (And if our parent + // isn't included in the tree either, it will recursively update its parent + // and so on.) + // + // The first ancestor that's included in the tree will + // be the one that actually fires the ChildrenChanged + // event notification. + if (!LastKnownIsIncludedInTreeValue()) { + if (AXObject* ax_parent = CachedParentObject()) { + ax_parent->ChildrenChangedWithCleanLayout(); + return; + } + } // TODO(accessibility) Move this up. if (!CanHaveChildren())
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_audio_deliverer.h b/third_party/blink/renderer/platform/mediastream/media_stream_audio_deliverer.h index 8a535bbd0..71b64e8 100644 --- a/third_party/blink/renderer/platform/mediastream/media_stream_audio_deliverer.h +++ b/third_party/blink/renderer/platform/mediastream/media_stream_audio_deliverer.h
@@ -11,6 +11,7 @@ #include "base/synchronization/lock.h" #include "base/threading/thread_checker.h" #include "base/trace_event/trace_event.h" +#include "media/base/audio_bus.h" #include "media/base/audio_parameters.h" #include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 4be2387..f8e74a8 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1632,6 +1632,7 @@ virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-034.html [ Pass ] virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-035.html [ Pass ] virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-037.html [ Pass ] +virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-038.html [ Pass ] virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-012.html [ Pass ] virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-014.html [ Pass ] virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-015.html [ Pass ] @@ -4306,6 +4307,7 @@ crbug.com/660611 external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-034.html [ Failure ] crbug.com/660611 external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-035.html [ Failure ] crbug.com/660611 external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-037.html [ Failure ] +crbug.com/660611 external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-038.html [ Failure ] crbug.com/660611 external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-012.html [ Failure ] crbug.com/660611 external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-014.html [ Failure ] crbug.com/660611 external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-015.html [ Failure ] @@ -7367,7 +7369,6 @@ crbug.com/1278570 [ Linux ] virtual/gpu-rasterization/images/directly-composited-image-orientation.html [ Failure Pass ] # Sheriff 2021-12-21 -crbug.com/1281780 [ Mac ] media/video-poster-after-playing.html [ Failure Pass ] crbug.com/1281782 [ Mac ] virtual/no-alloc-direct-call/external/wpt/html/canvas/element/compositing/2d.composite.canvas.source-out.html [ Crash Pass ] crbug.com/1281782 [ Mac ] virtual/no-alloc-direct-call/external/wpt/html/canvas/element/compositing/2d.composite.clip.xor.html [ Crash Pass ] crbug.com/1281782 [ Mac ] virtual/no-alloc-direct-call/external/wpt/html/canvas/element/compositing/2d.composite.operation.darker.html [ Crash Pass ]
diff --git a/third_party/blink/web_tests/external/wpt/accessibility/crashtests/delayed-ignored-change.html b/third_party/blink/web_tests/external/wpt/accessibility/crashtests/delayed-ignored-change.html new file mode 100644 index 0000000..1fc98a1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/accessibility/crashtests/delayed-ignored-change.html
@@ -0,0 +1,17 @@ +<html class="test-wait"> +<style> + body { font-size: x-large; } + .hidden { visibility: hidden; } +</style> +<rb class="hidden"> + <textarea></textarea> +</rb> +<script> +document.addEventListener('load', () => { + window.requestIdleCallback(() => { + document.querySelector('style').remove(); + document.documentElement.className = ''; + }); +}, true); +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-038.html b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-038.html new file mode 100644 index 0000000..e745987 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-038.html
@@ -0,0 +1,28 @@ +<!DOCTYPE html> +<title> + Multi-line row flex fragmentation: break-before:avoid and column balancing. +</title> +<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#pagination"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<style> + #flex { + display: flex; + flex-wrap: wrap; + } + #flex > div { + width: 50px; + } +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="width:100px; height:100px; background:red;"> + <div style="width: 100px; columns: 2; column-gap: 0;position: relative; background: green;"> + <div id="flex"> + <div style="height: 25px;"></div> + <div style="height: 50px; break-before:avoid;"></div> + <div style="height: 5px; width: 25px;"></div> + <div style="height: 25px; width: 25px; break-before: avoid;"></div> + <div style="height: 50px;"></div> + </div> + </div> + </div> +</div>
diff --git a/third_party/blink/web_tests/fast/forms/text/input-readonly-focus.html b/third_party/blink/web_tests/fast/forms/text/input-readonly-focus.html index 1e866c9..7cdd9fd4 100644 --- a/third_party/blink/web_tests/fast/forms/text/input-readonly-focus.html +++ b/third_party/blink/web_tests/fast/forms/text/input-readonly-focus.html
@@ -1,28 +1,19 @@ -<html> -<head> -<script> -function runTest() { - testRunner.waitUntilDone(); - testRunner.dumpAsText(); +<!DOCTYPE html> - var input = document.getElementById('i'); - eventSender.mouseMoveTo(input.offsetLeft + input.offsetWidth / 2, input.offsetTop + input.offsetHeight / 2); - eventSender.mouseDown(); - eventSender.mouseUp(); -} -window.onload = function() { - var input = document.getElementById('i'); - input.onfocus = function(e) { +<input readonly> + +<script> +window.onload = () => { + if (window.testRunner) { + testRunner.waitUntilDone(); + testRunner.dumpAsText(); + } + const input = document.querySelector('input'); + input.onfocus = (e) => { document.body.innerHTML = 'PASS'; if (window.testRunner) window.testRunner.notifyDone(); } - if (window.testRunner) - runTest(); + input.focus(); } </script> -</head> -<body> -<input id="i" readonly> -</body> -</html>
diff --git a/third_party/blink/web_tests/media/video-poster-after-playing.html b/third_party/blink/web_tests/media/video-poster-after-playing.html index ed3d894a..5eaf9c467 100644 --- a/third_party/blink/web_tests/media/video-poster-after-playing.html +++ b/third_party/blink/web_tests/media/video-poster-after-playing.html
@@ -1,5 +1,6 @@ <!DOCTYPE html> <title>Tests setting the poster attribute after a video is playing.</title> +<video></video> <script> if (window.testRunner) testRunner.waitUntilDone(); @@ -9,14 +10,14 @@ video.addEventListener("playing", function () { video.poster = "content/abe.png"; }); - video.addEventListener("timeupdate", function () { - if (video.currentTime > 1 && window.testRunner) + video.requestVideoFrameCallback(function () { + if (window.testRunner) testRunner.notifyDone(); }); + video.src = "resources/test-positive-start-time.webm"; video.play(); } window.addEventListener('load', startTest, false); </script> -<video src="resources/test-positive-start-time.webm"></video>
diff --git a/tools/aggregation_service/aggregation_service_tool_main.cc b/tools/aggregation_service/aggregation_service_tool_main.cc index 96331196..97557a6 100644 --- a/tools/aggregation_service/aggregation_service_tool_main.cc +++ b/tools/aggregation_service/aggregation_service_tool_main.cc
@@ -189,9 +189,8 @@ std::vector<GURL> processing_urls; static constexpr char kDefaultEndpointPath[] = "keys.json"; for (auto& kv : kv_pairs) { - url::Replacements<char> replacements; - replacements.SetPath(kDefaultEndpointPath, - url::Component(0, strlen(kDefaultEndpointPath))); + GURL::Replacements replacements; + replacements.SetPathStr(kDefaultEndpointPath); GURL url = url::Origin::Create(GURL(kv.first)) .GetURL() .ReplaceComponents(replacements); @@ -273,4 +272,4 @@ return 1; return 0; -} \ No newline at end of file +}
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 3f4116b..7a95e0d 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -2850,7 +2850,7 @@ 'official', 'goma', 'minimal_symbols', 'fuchsia', 'fuchsia_include_sd_images', 'arm64', 'ffmpeg_branding_chrome', 'proprietary_codecs', 'test_isolate_no_emulator' ], 'official_goma_fuchsia_x64_perf': [ - 'official', 'goma', 'minimal_symbols', 'fuchsia', 'fuchsia_include_workstation_image', 'x64', 'ffmpeg_branding_chrome', 'proprietary_codecs', 'test_isolate_no_emulator' + 'official', 'goma', 'minimal_symbols', 'fuchsia', 'fuchsia_include_chromebook_image', 'x64', 'ffmpeg_branding_chrome', 'proprietary_codecs', 'test_isolate_no_emulator' ], 'official_goma_linux_pgo': [ @@ -3621,12 +3621,16 @@ 'gn_args': 'fuchsia_code_coverage=true', }, + 'fuchsia_include_chromebook_image': { + 'gn_args': 'fuchsia_additional_boot_images=["//third_party/fuchsia-sdk/images-internal/chromebook-x64-release/"]', + }, + 'fuchsia_include_sd_images': { 'gn_args': 'fuchsia_additional_boot_images=["//third_party/fuchsia-sdk/images-internal/astro-release/","//third_party/fuchsia-sdk/images-internal/sherlock-release/"]', }, 'fuchsia_include_workstation_image': { - 'gn_args': 'fuchsia_additional_boot_images=["//third_party/fuchsia-sdk/images/qemu-x64-release/","//third_party/fuchsia-sdk/images-internal/chromebook-x64-release/"]', + 'gn_args': 'fuchsia_additional_boot_images=["//third_party/fuchsia-sdk/images/qemu-x64-release/"]', }, 'full_symbols': {
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json index a28ffd25..664213e 100644 --- a/tools/mb/mb_config_expectations/chromium.fyi.json +++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -573,8 +573,7 @@ "gn_args": { "dcheck_always_on": false, "fuchsia_additional_boot_images": [ - "//third_party/fuchsia-sdk/images/qemu-x64-release/", - "//third_party/fuchsia-sdk/images-internal/chromebook-x64-release/" + "//third_party/fuchsia-sdk/images/qemu-x64-release/" ], "fuchsia_browser_type": "chrome", "is_component_build": false,
diff --git a/tools/mb/mb_config_expectations/chromium.perf.fyi.json b/tools/mb/mb_config_expectations/chromium.perf.fyi.json index ac1c412..ea89105b 100644 --- a/tools/mb/mb_config_expectations/chromium.perf.fyi.json +++ b/tools/mb/mb_config_expectations/chromium.perf.fyi.json
@@ -61,7 +61,6 @@ "gn_args": { "ffmpeg_branding": "Chrome", "fuchsia_additional_boot_images": [ - "//third_party/fuchsia-sdk/images/qemu-x64-release/", "//third_party/fuchsia-sdk/images-internal/chromebook-x64-release/" ], "is_chrome_branded": true,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.perf.json b/tools/mb/mb_config_expectations/tryserver.chromium.perf.json index 1dc4a83..38edc0b 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.perf.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.perf.json
@@ -96,7 +96,6 @@ "gn_args": { "ffmpeg_branding": "Chrome", "fuchsia_additional_boot_images": [ - "//third_party/fuchsia-sdk/images/qemu-x64-release/", "//third_party/fuchsia-sdk/images-internal/chromebook-x64-release/" ], "is_chrome_branded": true,
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index b7539eb..cc5bd026 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -31095,6 +31095,15 @@ </description> </action> +<action name="TabsSearch.SuggestedActions.RecentTabs"> + <owner>michaeldo@chromium.org</owner> + <owner>mrefaat@chromium.org</owner> + <description> + The user tapped the suggested search action to search recent tabs for the + entered search term. + </description> +</action> + <action name="TabsSearch.SuggestedActions.SearchHistory"> <owner>michaeldo@chromium.org</owner> <owner>mrefaat@chromium.org</owner>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index c403deb0..4b23549 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -2844,6 +2844,9 @@ label="SERVICE_WORKER_SETTINGS_GET_REQUESTED_WITH_HEADER_MODE"> ServiceWorkerWebSettingsCompat#getRequestedWithHeaderMode() </int> + <int value="60" label="GET_VARIATIONS_HEADER"> + WebViewCompat#getVariationsHeader() + </int> </enum> <enum name="ANGLEProgramCacheResult"> @@ -96271,6 +96274,20 @@ <int value="5" label="CycleRightSnapInTablet"/> </enum> +<enum name="WindowSnapActionSource"> + <int value="0" label="Drag window to screen edge to snap"/> + <int value="1" label="Use window caption button to snap"/> + <int value="2" label="Use keyboard shortcut to snap"/> + <int value="3" label="Drag or select overview window to snap"/> + <int value="4" label="Long press overview button to snap"/> + <int value="5" label="Drag up from shelf to snap"/> + <int value="6" label="Drag down from top to snap"/> + <int value="7" label="Drag a tab to snap"/> + <int value="8" label="Auto snapped by splitview"/> + <int value="9" label="Window is snapped from window state restore"/> + <int value="10" label="Other ways to snap a window"/> +</enum> + <enum name="WindowsNotificationActivationStatus"> <int value="0" label="SUCCESS"/> <int value="1" label="GET_PROFILE_ID_INVALID_LAUNCH_ID (deprecated)"/>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index 5d74954fe..7b4e324 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -3966,6 +3966,16 @@ </summary> </histogram> +<histogram name="Ash.Wm.WindowSnapActionSource" enum="WindowSnapActionSource" + expires_after="2023-02-24"> + <owner>xdai@chromium.org</owner> + <owner>nupurjain@chromium.org</owner> + <summary> + Emitted when a window is to be snapped. Records different ways for a user to + snap a window. + </summary> +</histogram> + </histograms> </histogram-configuration>
diff --git a/tools/metrics/histograms/metadata/chromeos/histograms.xml b/tools/metrics/histograms/metadata/chromeos/histograms.xml index 1f59a6d..30012693 100644 --- a/tools/metrics/histograms/metadata/chromeos/histograms.xml +++ b/tools/metrics/histograms/metadata/chromeos/histograms.xml
@@ -1386,7 +1386,7 @@ </histogram> <histogram name="ChromeOS.SecurityAnomaly" enum="SecurityAnomaly" - expires_after="2022-04-03"> + expires_after="2022-10-03"> <owner>jorgelo@chromium.org</owner> <owner>chromeos-security-core@google.com</owner> <summary> @@ -1399,7 +1399,7 @@ </histogram> <histogram name="ChromeOS.SecurityAnomalyUploadSuccess" enum="Boolean" - expires_after="2022-04-03"> + expires_after="2022-10-03"> <owner>jorgelo@chromium.org</owner> <owner>chromeos-security-core@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/input/histograms.xml b/tools/metrics/histograms/metadata/input/histograms.xml index d4cc78c..226a8ee0 100644 --- a/tools/metrics/histograms/metadata/input/histograms.xml +++ b/tools/metrics/histograms/metadata/input/histograms.xml
@@ -529,7 +529,7 @@ </histogram> <histogram name="InputMethod.ID2" enum="InputMethodID2" - expires_after="2022-04-03"> + expires_after="2023-02-22"> <owner>tranbaoduy@chromium.org</owner> <owner>shuchen@chromium.org</owner> <owner>essential-inputs-team@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index a3eea518..b50475c 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -1425,6 +1425,17 @@ <summary>Maximal amount of memory allocated by decoder.</summary> </histogram> +<histogram name="BrowsingTopics.SiteDataStorage.InitStatus" + enum="BooleanSuccess" expires_after="2023-02-10"> + <owner>yaoxia@chromium.org</owner> + <owner>jkarlin@chromium.org</owner> + <summary> + Records initialization status of BrowsingTopics SiteDataStorage database. + Recored when the database is lazily initialised when the first operation is + encountered. + </summary> +</histogram> + <histogram name="Canvas.TextMetrics.SetFont" units="microseconds" expires_after="2021-07-14"> <obsolete>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml index 657d27d..c6869cf 100644 --- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml +++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -1259,17 +1259,25 @@ </histogram> <histogram - name="SafeBrowsing.NavigationObserver.IdentifyReferrerChainByWebContentsTime" + name="SafeBrowsing.NavigationObserver.IdentifyReferrerChainByRenderFrameHostTime" units="ms" expires_after="2022-07-03"> <owner>xinghuilu@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> - Logs the time it takes to identify referrer chain by web contents. Logged - each time the function is called. + Logs the time it takes to identify referrer chain by render frame host. + Logged each time the function is called. </summary> </histogram> <histogram + name="SafeBrowsing.NavigationObserver.MissingInitiatorRenderFrameHostPortal" + units="BooleanExists" expires_after="2022-07-23"> + <owner>vollick@chromium.org</owner> + <owner>chrome-safebrowsing-alerts@google.com</owner> + <summary>Logs the number of times we have a missing initiator RFH.</summary> +</histogram> + +<histogram name="SafeBrowsing.NavigationObserver.NavigationEventsRecordedLength" units="count" expires_after="2022-08-10"> <owner>drubery@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/security/histograms.xml b/tools/metrics/histograms/metadata/security/histograms.xml index 33e4dec..bf2c562 100644 --- a/tools/metrics/histograms/metadata/security/histograms.xml +++ b/tools/metrics/histograms/metadata/security/histograms.xml
@@ -576,6 +576,18 @@ </summary> </histogram> +<histogram name="Security.SCTAuditing.OptOut.PopularSCTSkipped" enum="Boolean" + expires_after="M104"> + <owner>cthomp@chromium.org</owner> + <owner>nsatragno@chromium.org</owner> + <owner>trusty-transport@chromium.org</owner> + <summary> + Records whether an SCT selected for a hashdance lookup query was skipped + because it was found on the Popular SCTs list. Recorded once when creating a + new auditing report, but before the report is sampled or deduplicated. + </summary> +</histogram> + <histogram name="Security.SecurityLevel.DownloadStarted" enum="SecurityLevel" expires_after="2022-09-01"> <owner>cthomp@chromium.org</owner>
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index 00ca4454..b5e04ae 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -41,6 +41,7 @@ # Benchmark: blink_perf.css crbug.com/891878 [ android-nexus-5x android-webview ] blink_perf.css/CustomPropertiesVarAlias.html [ Skip ] +crbug.com/1300672 blink_perf.css/HasSiblingDescendantInvalidation.html [ Skip ] # Benchmark: blink_perf.events crbug.com/963945 [ android-nexus-5x android-webview ] blink_perf.events/EventsDispatchingInDeeplyNestedV1ShadowTrees.html [ Skip ] @@ -62,6 +63,7 @@ crbug.com/859979 [ android-webview ] blink_perf.paint/paint-offset-changes.html [ Skip ] crbug.com/901493 [ android-nexus-6 android-webview ] blink_perf.paint/* [ Skip ] crbug.com/1000460 [ android-pixel-2 ] blink_perf.paint/color-changes.html [ Skip ] +crbug.com/1300693 [ android-pixel-2 android-not-webview ] blink_perf.paint/custom-highlights.html [ Skip ] # Benchmark: blink_perf.parser crbug.com/966913 [ android-nexus-5x android-webview ] blink_perf.parser/query-selector-all-class-deep.html [ Skip ] @@ -96,6 +98,9 @@ crbug.com/1236631 [ mac ] desktop_ui/side_search:* [ Skip ] crbug.com/1236631 [ linux ] desktop_ui/side_search:* [ Skip ] +# Benchmark: blink_perf.webcodecs +crbug.com/1300680 [ android ] blink_perf.webcodecs/software-video-encoding.html [ Skip ] + # Benchmark: dromaeo crbug.com/1050065 [ android-pixel-2 ] dromaeo/http://dromaeo.com?dom-modify [ Skip ]
diff --git a/ui/base/data_transfer_policy/data_transfer_endpoint_serializer_unittest.cc b/ui/base/data_transfer_policy/data_transfer_endpoint_serializer_unittest.cc index 144ecdb..609d15e3 100644 --- a/ui/base/data_transfer_policy/data_transfer_endpoint_serializer_unittest.cc +++ b/ui/base/data_transfer_policy/data_transfer_endpoint_serializer_unittest.cc
@@ -4,7 +4,7 @@ #include "ui/base/data_transfer_policy/data_transfer_endpoint_serializer.h" -#include "build/chromeos_buildflags.h" +#include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/data_transfer_policy/data_transfer_endpoint.h" #include "url/gurl.h" @@ -18,11 +18,9 @@ R"({"endpoint_type":"url","url":"https://www.google.com/","url_origin":"https://www.google.com"})"; constexpr char kExampleJsonUrlTypeNoUrl[] = R"({"endpoint_type":"url"})"; -#if BUILDFLAG(IS_CHROMEOS_ASH) -// TODO(crbug.com/1280545): Enable test when VM DataTransferEndpoint endpoint -// types are built in Lacros. +#if BUILDFLAG(IS_CHROMEOS) constexpr char kExampleJsonNonUrlType[] = R"({"endpoint_type":"crostini"})"; -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) } // namespace @@ -52,9 +50,7 @@ EXPECT_EQ(nullptr, actual); } -#if BUILDFLAG(IS_CHROMEOS_ASH) -// TODO(crbug.com/1280545): Enable test when VM DataTransferEndpoint endpoint -// types are built in Lacros. +#if BUILDFLAG(IS_CHROMEOS) TEST(DataTransferEndpointSerializerTest, DataTransferEndpointToJsonNonUrl) { const DataTransferEndpoint example(EndpointType::kCrostini, /*notify_if_restricted=*/true); @@ -71,6 +67,6 @@ EXPECT_EQ(EndpointType::kCrostini, actual->type()); EXPECT_EQ(nullptr, actual->GetURL()); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) } // namespace ui
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc index 0072f13d..bc544e8 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -421,7 +421,7 @@ // activation change event. This is needed since the activation client may // check whether this widget can receive activation when deciding which window // should receive activation next. - base::AutoReset<bool> resetter(&should_activate_, active); + base::AutoReset<absl::optional<bool>> resetter(&should_activate_, active); if (active) { // TODO(nektar): We need to harmonize the firing of accessibility @@ -1268,7 +1268,8 @@ // DesktopNativeWidgetAura, wm::ActivationDelegate implementation: bool DesktopNativeWidgetAura::ShouldActivate() const { - return should_activate_ && native_widget_delegate_->CanActivate(); + return (!should_activate_.has_value() || should_activate_.value()) && + native_widget_delegate_->CanActivate(); } //////////////////////////////////////////////////////////////////////////////// @@ -1297,17 +1298,23 @@ // content window are active. When the window tree host gains and looses // activation, the window tree host calls into HandleActivationChanged() which // notifies delegates of the activation change. - // However the widget's content window can still be deactivated while the - // window tree host remains active. This is the case if a chid widget is - // spawned (e.g. a bubble) and the child's content window is activated. This - // is a valid state since the window tree host should remain active while - // the child is active. - // In this case this widget would no longer be considered active but since the - // window tree host has not deactivated delegates are not notified in - // HandleActivationChanged(). To ensure activation updates are propagated - // correctly we must notify delegates here. + // However the widget's content window can still be deactivated and activated + // while the window tree host remains active. For e.g. if a child widget is + // spawned (e.g. a bubble) the child's content window is activated and the + // root content window is deactivated. This is a valid state since the window + // tree host should remain active while the child is active. The child bubble + // can then be closed and activation returns to the root content window - all + // without the window tree host's activation state changing. + // As the activation state of the content window changes we must ensure that + // we notify this widget's delegate. Do this here for cases where we are not + // handling an activation change in HandleActivationChanged() since delegates + // will be notified of the change there directly. const bool content_window_activated = content_window_ == gained_active; - if (desktop_window_tree_host_->IsActive() && !content_window_activated) { + const bool tree_host_active = desktop_window_tree_host_->IsActive(); + // TODO(crbug.com/1300567): Update focus rules to avoid focusing the desktop + // widget's content window if its window tree host is not active. + if (!should_activate_.has_value() && + (tree_host_active || !content_window_activated)) { native_widget_delegate_->OnNativeWidgetActivationChanged( content_window_activated); }
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h index 9ea7e63a..362bf7b 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
@@ -322,7 +322,7 @@ // change event in `HandleActivationChanged()`.This is needed as the widget // may not have propagated its new activation state to its delegate before the // activation client decides which window to activate next. - bool should_activate_ = true; + absl::optional<bool> should_activate_; gfx::NativeCursor cursor_; // We must manually reference count the number of users of |cursor_manager_|
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura_interactive_uitest.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura_interactive_uitest.cc index 8833870..da74e658 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura_interactive_uitest.cc +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura_interactive_uitest.cc
@@ -96,4 +96,64 @@ widget2->CloseNow(); } +// Tests to make sure that a widget that shows an active child has activation +// correctly propagate to the child's content window. This also tests to make +// sure that when this child window is closed, and the desktop widget's window +// tree host remains active, the widget's content window has its activation +// state restored. This tests against a regression where the desktop widget +// would not receive activation when it's child bubbles were closed (see +// crbug.com/1294404). +TEST_F(DesktopNativeWidgetAuraTest, + DesktopWidgetsRegainFocusWhenChildWidgetClosed) { + auto widget = std::make_unique<Widget>(); + Widget::InitParams params(Widget::InitParams::TYPE_WINDOW_FRAMELESS); + params.context = GetContext(); + params.native_widget = new DesktopNativeWidgetAura(widget.get()); + params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + widget->Init(std::move(params)); + + auto widget_child = std::make_unique<Widget>(); + Widget::InitParams params_child(Widget::InitParams::TYPE_BUBBLE); + params_child.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + params_child.parent = widget->GetNativeView(); + params_child.native_widget = + CreatePlatformNativeWidgetImpl(widget_child.get(), kDefault, nullptr); + widget_child->Init(std::move(params_child)); + widget_child->widget_delegate()->SetCanActivate(true); + + auto* activation_client = + wm::GetActivationClient(widget->GetNativeView()->GetRootWindow()); + auto* activation_client_child = + wm::GetActivationClient(widget_child->GetNativeView()->GetRootWindow()); + + // All widgets belonging to the same tree host should share an activation + // client. + ASSERT_EQ(activation_client, activation_client_child); + + widget->Show(); + views::test::WidgetActivationWaiter(widget.get(), true).Wait(); + views::test::WidgetActivationWaiter(widget_child.get(), false).Wait(); + EXPECT_TRUE(widget->IsActive()); + EXPECT_FALSE(widget_child->IsActive()); + EXPECT_EQ(activation_client->GetActiveWindow(), widget->GetNativeView()); + + widget_child->Show(); + views::test::WidgetActivationWaiter(widget.get(), false).Wait(); + views::test::WidgetActivationWaiter(widget_child.get(), true).Wait(); + EXPECT_FALSE(widget->IsActive()); + EXPECT_TRUE(widget_child->IsActive()); + EXPECT_EQ(activation_client->GetActiveWindow(), + widget_child->GetNativeView()); + + widget_child->Close(); + views::test::WidgetActivationWaiter(widget.get(), true).Wait(); + views::test::WidgetActivationWaiter(widget_child.get(), false).Wait(); + EXPECT_TRUE(widget->IsActive()); + EXPECT_FALSE(widget_child->IsActive()); + EXPECT_EQ(activation_client->GetActiveWindow(), widget->GetNativeView()); + + widget_child->CloseNow(); + widget->CloseNow(); +} + } // namespace views::test
diff --git a/ui/webui/resources/cr_components/chromeos/network/BUILD.gn b/ui/webui/resources/cr_components/chromeos/network/BUILD.gn index 61ff21c..c731d058 100644 --- a/ui/webui/resources/cr_components/chromeos/network/BUILD.gn +++ b/ui/webui/resources/cr_components/chromeos/network/BUILD.gn
@@ -384,7 +384,7 @@ ":network_listener_behavior.m", ":network_password_input.m", ":network_shared_css.m", - "//chrome/browser/ui/webui/settings/chromeos/search:mojo_bindings_js_library_for_compile", + "//chrome/browser/ui/webui/settings/ash/search:mojo_bindings_js_library_for_compile", "//third_party/polymer/v3_0/components-chromium/iron-flex-layout:iron-flex-layout", "//third_party/polymer/v3_0/components-chromium/iron-icon:iron-icon", "//third_party/polymer/v3_0/components-chromium/paper-spinner:paper-spinner-lite",
diff --git a/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.cc b/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.cc index 1000b4e..abb4b8a 100644 --- a/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.cc +++ b/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.cc
@@ -7,6 +7,7 @@ #include "components/prefs/pref_service.h" #include "components/safe_browsing/android/remote_database_manager.h" #include "components/safe_browsing/content/browser/client_side_detection_service.h" +#include "content/public/browser/global_routing_id.h" #include "weblayer/browser/browser_context_impl.h" #include "weblayer/browser/browser_process.h" #include "weblayer/browser/safe_browsing/client_side_detection_service_factory.h" @@ -55,6 +56,7 @@ void WebLayerClientSideDetectionHostDelegate::AddReferrerChain( safe_browsing::ClientPhishingRequest* verdict, - GURL current_url) {} + GURL current_url, + const content::GlobalRenderFrameHostId& current_outermost_main_frame_id) {} } // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.h b/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.h index da5fa22..9bcb2db0 100644 --- a/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.h +++ b/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.h
@@ -10,6 +10,10 @@ #include "components/safe_browsing/core/common/proto/csd.pb.h" #include "url/gurl.h" +namespace content { +struct GlobalRenderFrameHostId; +} // namespace content + namespace weblayer { class WebLayerClientSideDetectionHostDelegate @@ -35,7 +39,9 @@ safe_browsing::ClientSideDetectionService* GetClientSideDetectionService() override; void AddReferrerChain(safe_browsing::ClientPhishingRequest* verdict, - GURL current_url) override; + GURL current_url, + const content::GlobalRenderFrameHostId& + current_outermost_main_frame_id) override; private: raw_ptr<content::WebContents> web_contents_;