diff --git a/DEPS b/DEPS index 41d7690..58831d9 100644 --- a/DEPS +++ b/DEPS
@@ -253,7 +253,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'ff138c94d60087da0527d86f02565315d86c22ed', + 'skia_revision': 'e1880aed8f81fd9f7cdea2439e7d6d724738647c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -320,7 +320,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'd55bdb952f5c4c0a0abe36df3af65071a3801e0c', + 'catapult_revision': '63a615bbdb57ad0a2e794ed800b826dddcef2713', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # 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': '3b6b4a1051403863b4940d8801bb43a9d84c9070', + 'dawn_revision': '5f881cbca0e92057ad86dc2a93e8b48fafeda17a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -412,7 +412,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. - 'libcxxabi_revision': '289d52ce75d6091a79e90ae6aead38c5c701d786', + 'libcxxabi_revision': 'a897d0f3f8e8c28ac2abf848f3b695b724409298', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -435,7 +435,7 @@ 'libcxx_revision': '79a2e924d96e2fc1e4b937c42efd08898fa472d7', # GN CIPD package version. - 'gn_version': 'git_revision:f27bae882b2178ccc3c24f314c88db9a34118992', + 'gn_version': 'git_revision:bd99dbf98cbdefe18a4128189665c5761263bcfb', } # Only these hosts are allowed for dependencies in this DEPS file. @@ -708,7 +708,7 @@ }, 'src/ios/third_party/earl_grey2/src': { - 'url': Var('chromium_git') + '/external/github.com/google/EarlGrey.git' + '@' + '9753a68d7453aaea0c11320827b21a3bd05512fa', + 'url': Var('chromium_git') + '/external/github.com/google/EarlGrey.git' + '@' + 'd772a0e8eb889fb184e3bd74a1d0cd868d94605c', 'condition': 'checkout_ios', }, @@ -991,7 +991,7 @@ Var('chromium_git') + '/angle/angle.git' + '@' + Var('angle_revision'), 'src/third_party/dav1d/libdav1d': - Var('chromium_git') + '/external/github.com/videolan/dav1d.git' + '@' + '493ffb12f77df791f7dcde991b92d64bf873fefd', + Var('chromium_git') + '/external/github.com/videolan/dav1d.git' + '@' + 'b1a5189c9d37c837099ce50852b6ce9597b89b0c', 'src/third_party/dawn': Var('dawn_git') + '/dawn.git' + '@' + Var('dawn_revision'), @@ -1120,7 +1120,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'c848a4ed332e79a654cb4ee7ef29acd796f7147d', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '34816458276bf9a528f306f0bc26f33dfdb428c8', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1347,7 +1347,7 @@ # Userspace interface to kernel DRM services. 'src/third_party/libdrm/src': { - 'url': Var('chromium_git') + '/chromiumos/third_party/libdrm.git' + '@' + '0190f49a139e7069d7cad6a6890832831da1aa8b', + 'url': Var('chromium_git') + '/chromiumos/third_party/libdrm.git' + '@' + '56f81e6776c1c100c3f627b2c1feb9dcae2aad3c', 'condition': 'checkout_linux', }, @@ -1581,7 +1581,7 @@ 'packages': [ { 'package': 'fuchsia/third_party/android/aemu/release/linux-amd64', - 'version': 'culX6ICjvTS7jMkEu0225UNiGeKAEjTAx20d6zfz58IC' + 'version': 'p_ehnYla4xhPaxDnGkBMOVRzCWuby9Pbm7OknbRYhrwC' }, ], 'condition': 'host_os == "linux" and checkout_fuchsia', @@ -1724,7 +1724,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'd4ab434e91c1a578f6a43c7418eae2b92856ee05', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'fa2c945f73cc68a2a36c31475b2b89421f0aa933', + Var('webrtc_git') + '/src.git' + '@' + '041c08377a0dd4afbd928ef40e3789b08118313c', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1794,7 +1794,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@646427a38792ed15b897a714afd4585659eaee86', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@276ba242765462c7ee95b522886e7ac305caee04', 'condition': 'checkout_src_internal', },
diff --git a/WATCHLISTS b/WATCHLISTS index 08a9a79b..b2b5c0e 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -2712,7 +2712,6 @@ 'vasilii+watchlistpasswordmanager@chromium.org'], 'payments': ['rouslan+payments@chromium.org', 'gogerald+paymentswatch@chromium.org', - 'maxlg+paymentswatch@chromium.org', 'nburris+paymentswatch@chromium.org'], 'pdf': ['pdf-reviews@chromium.org'], 'pepper_api': ['binji+watch@chromium.org',
diff --git a/android_webview/java/src/org/chromium/android_webview/js/browser/AwJsContext.java b/android_webview/java/src/org/chromium/android_webview/js/browser/AwJsContext.java index 0bb958e..07b9664 100644 --- a/android_webview/java/src/org/chromium/android_webview/js/browser/AwJsContext.java +++ b/android_webview/java/src/org/chromium/android_webview/js/browser/AwJsContext.java
@@ -20,6 +20,8 @@ /** Used to report the results of the JS evaluation. */ public interface ExecutionCallback { void reportResult(String result); + + void reportError(String error); } AwJsContext(IJsSandboxContext jsContextStub) { @@ -42,6 +44,11 @@ public void reportResult(String result) { callback.reportResult(result); } + + @Override + public void reportError(String error) { + callback.reportError(error); + } }; try { mJsContextStub.evaluateJavascript(code, callbackStub);
diff --git a/android_webview/java/src/org/chromium/android_webview/js/common/IJsSandboxContextCallback.aidl b/android_webview/java/src/org/chromium/android_webview/js/common/IJsSandboxContextCallback.aidl index 56a4a11..bb3613d 100644 --- a/android_webview/java/src/org/chromium/android_webview/js/common/IJsSandboxContextCallback.aidl +++ b/android_webview/java/src/org/chromium/android_webview/js/common/IJsSandboxContextCallback.aidl
@@ -10,4 +10,5 @@ */ oneway interface IJsSandboxContextCallback { void reportResult(in String result); + void reportError(in String error); }
diff --git a/android_webview/java/src/org/chromium/android_webview/js/renderer/JsSandboxContext.java b/android_webview/java/src/org/chromium/android_webview/js/renderer/JsSandboxContext.java index c14126e..2005aa59 100644 --- a/android_webview/java/src/org/chromium/android_webview/js/renderer/JsSandboxContext.java +++ b/android_webview/java/src/org/chromium/android_webview/js/renderer/JsSandboxContext.java
@@ -21,18 +21,27 @@ private boolean mIsClosed = false; @Override - public void evaluateJavascript(String serialisedJS, IJsSandboxContextCallback callback) { + public void evaluateJavascript(String code, IJsSandboxContextCallback callback) { if (mIsClosed) { throw new IllegalStateException("evaluateJavascript() called after close()"); } // Just posting to the mainLooper for now. Handler handler = new Handler(Looper.getMainLooper()); handler.postDelayed(() -> { - String result = serialisedJS.toUpperCase(); - try { - callback.reportResult(result); - } catch (RemoteException e) { - Log.e(TAG, "reporting result failed", e); + // Currently just hardcoded to return error string when it encounters "ERROR" as input. + if (code.equals("ERROR")) { + try { + callback.reportError("There has been an error."); + } catch (RemoteException e) { + Log.e(TAG, "reporting result failed", e); + } + } else { + String result = code.toUpperCase(); + try { + callback.reportResult(result); + } catch (RemoteException e) { + Log.e(TAG, "reporting result failed", e); + } } }, 100); }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/services/JsSandboxServiceTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/services/JsSandboxServiceTest.java index 24dca42..9478ecc 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/services/JsSandboxServiceTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/services/JsSandboxServiceTest.java
@@ -21,12 +21,19 @@ private class TestExecutionCallback implements AwJsContext.ExecutionCallback { public CallbackHelper helper = new CallbackHelper(); public String result; + public String error; @Override public void reportResult(String result) { this.result = result; helper.notifyCalled(); } + + @Override + public void reportError(String error) { + this.error = error; + helper.notifyCalled(); + } } // Test sending data to the service and retrieving it back. @@ -67,4 +74,20 @@ callback.helper.waitForCallback("Timed out waiting for reportResult() to be called", 0); Assert.assertEquals(expected, callback.result); } + + @Test + @MediumTest + public void testJsEvaluationError() throws Throwable { + final String smallCase = "ERROR"; + final String expected = "There has been an error."; + TestExecutionCallback callback = new TestExecutionCallback(); + + AwJsSandbox.newConnectedInstance(jsSandbox -> { + AwJsContext jsContext = jsSandbox.createContext(); + jsContext.evaluateJavascript(smallCase, callback); + }); + + callback.helper.waitForCallback("Timed out waiting for reportResult() to be called", 0); + Assert.assertEquals(expected, callback.error); + } }
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 11f5c53..0cbf25f4 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -170,6 +170,8 @@ "ambient/model/ambient_slideshow_photo_config.h", "ambient/resources/ambient_animation_resource_constants.h", "ambient/resources/ambient_animation_static_resources.h", + "ambient/ui/ambient_animation_player.cc", + "ambient/ui/ambient_animation_player.h", "ambient/ui/ambient_animation_resizer.cc", "ambient/ui/ambient_animation_resizer.h", "ambient/ui/ambient_animation_shield_controller.cc",
diff --git a/ash/ambient/ui/ambient_animation_player.cc b/ash/ambient/ui/ambient_animation_player.cc new file mode 100644 index 0000000..ce0affa8 --- /dev/null +++ b/ash/ambient/ui/ambient_animation_player.cc
@@ -0,0 +1,100 @@ +// 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 "ash/ambient/ui/ambient_animation_player.h" + +#include <string> + +#include "ash/utility/lottie_util.h" +#include "base/check.h" +#include "base/logging.h" +#include "base/no_destructor.h" +#include "base/strings/strcat.h" +#include "base/strings/string_piece.h" +#include "base/time/time.h" +#include "cc/paint/skottie_marker.h" +#include "cc/paint/skottie_wrapper.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "ui/views/controls/animated_image_view.h" + +namespace ash { + +namespace { + +absl::optional<base::TimeDelta> FindCycleRestartTimestamp( + const cc::SkottieWrapper& skottie) { + static const base::NoDestructor<std::string> kRestartMarkerName( + base::StrCat({kLottieCustomizableIdPrefix, "_Marker_CycleRestart"})); + DCHECK(skottie.is_valid()); + absl::optional<base::TimeDelta> restart_timestamp; + for (const cc::SkottieMarker& marker : skottie.GetAllMarkers()) { + if (marker.name != *kRestartMarkerName) { + continue; + } else if (restart_timestamp.has_value()) { + LOG(DFATAL) << "Multiple markers with name " << *kRestartMarkerName + << " found in animation file. Defaulting to first one."; + } else { + // |marker.begin_time| is a normalized timestamp in range [0, 1), where 1 + // is the animation's cycle duration. + restart_timestamp.emplace(base::Seconds(skottie.duration()) * + marker.begin_time); + DVLOG(1) << "Found restart marker at timestamp " << *restart_timestamp; + } + } + return restart_timestamp; +} + +} // namespace + +AmbientAnimationPlayer::AmbientAnimationPlayer( + views::AnimatedImageView* animated_image_view) + : animated_image_view_(animated_image_view) { + DCHECK(animated_image_view_); + lottie::Animation* animation = animated_image_view_->animated_image(); + DCHECK(animation); + absl::optional<base::TimeDelta> cycle_restart_timestamp_found = + FindCycleRestartTimestamp(*animation->skottie()); + if (cycle_restart_timestamp_found.has_value()) { + cycle_restart_timestamp_ = *cycle_restart_timestamp_found; + if (cycle_restart_timestamp_ >= animation->GetAnimationDuration()) { + LOG(DFATAL) << "Animation has invalid cycle restart timestamp " + << cycle_restart_timestamp_ << ". Total cycle duration " + << animation->GetAnimationDuration(); + } + } else { + DVLOG(1) << "Restart marker not found in animation. Defaulting to cycle " + "restart at timestamp 0"; + DCHECK(cycle_restart_timestamp_.is_zero()); + } + animation_observation_.Observe(animation); + animated_image_view_->Play(lottie::Animation::Style::kLinear); +} + +AmbientAnimationPlayer::~AmbientAnimationPlayer() { + animated_image_view_->Stop(); +} + +void AmbientAnimationPlayer::AnimationCycleEnded( + const lottie::Animation* animation) { + DVLOG(1) << "First animation cycle ended. Restarting at " + << cycle_restart_timestamp_; + // No need to keep observing after the first animation cycle ends because all + // future animation cycles will automatically loop below. + animation_observation_.Reset(); + // Stop()/Play() are actually very light-weight operations. They do not cause + // the animation to be re-loaded and only modify internal book-keeping state. + // The latency between the last frame of the first animation cycle and the + // first frame of the second cycle was compared against the same + // frame-to-frame latency at the end of other animation cycles, and there was + // no observable difference. + animated_image_view_->Stop(); + animated_image_view_->Play( + /*start_offset=*/cycle_restart_timestamp_, + /*duration=*/ + animated_image_view_->animated_image()->GetAnimationDuration() - + cycle_restart_timestamp_, + lottie::Animation::Style::kLoop); +} + +} // namespace ash
diff --git a/ash/ambient/ui/ambient_animation_player.h b/ash/ambient/ui/ambient_animation_player.h new file mode 100644 index 0000000..8f5f29d --- /dev/null +++ b/ash/ambient/ui/ambient_animation_player.h
@@ -0,0 +1,64 @@ +// 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_AMBIENT_UI_AMBIENT_ANIMATION_PLAYER_H_ +#define ASH_AMBIENT_UI_AMBIENT_ANIMATION_PLAYER_H_ + +#include "ash/ash_export.h" +#include "base/memory/raw_ptr.h" +#include "base/scoped_observation.h" +#include "base/time/time.h" +#include "ui/lottie/animation.h" +#include "ui/lottie/animation_observer.h" + +namespace views { +class AnimatedImageView; +} // namespace views + +namespace ash { + +// Plays an AnimatedImageView in a loop until destruction. The "looping" logic +// meets ambient mode's custom requirements: The lottie animation may optionally +// have a "marker" embedded in it. The "marker" is a timestamp set by the motion +// designer, which in this case, indicates where the animation should restart +// after each cycle ends. If the marker timestamp is M and the total animation +// cycle duration is D (where 0 < M < D), then the animation cycles look +// like this: +// [0, D] +// [M, D] +// [M, D] +// ... +// +// Note the very first animation cycle is always played starting at time 0 (the +// very first frame in the animation). +// +// If the animation does not have a marker embedded in it, the default behavior +// is to restart at the beginning of the animation each time (M is effectively +// 0): +// [0, D] +// [0, D] +// [0, D] +// ... +class ASH_EXPORT AmbientAnimationPlayer : public lottie::AnimationObserver { + public: + // Starts playing the |animated_image_view| immediately upon construction. + explicit AmbientAnimationPlayer( + views::AnimatedImageView* animated_image_view); + AmbientAnimationPlayer(const AmbientAnimationPlayer&) = delete; + AmbientAnimationPlayer& operator=(const AmbientAnimationPlayer&) = delete; + ~AmbientAnimationPlayer() override; + + // lottie::AnimationObserver implementation: + void AnimationCycleEnded(const lottie::Animation* animation) override; + + private: + const base::raw_ptr<views::AnimatedImageView> animated_image_view_; + base::ScopedObservation<lottie::Animation, lottie::AnimationObserver> + animation_observation_{this}; + base::TimeDelta cycle_restart_timestamp_; +}; + +} // namespace ash + +#endif // ASH_AMBIENT_UI_AMBIENT_ANIMATION_PLAYER_H_
diff --git a/ash/ambient/ui/ambient_animation_view.cc b/ash/ambient/ui/ambient_animation_view.cc index a2405a8..0a70a34 100644 --- a/ash/ambient/ui/ambient_animation_view.cc +++ b/ash/ambient/ui/ambient_animation_view.cc
@@ -14,6 +14,7 @@ #include "ash/ambient/model/ambient_backend_model.h" #include "ash/ambient/model/ambient_photo_config.h" #include "ash/ambient/resources/ambient_animation_static_resources.h" +#include "ash/ambient/ui/ambient_animation_player.h" #include "ash/ambient/ui/ambient_animation_resizer.h" #include "ash/ambient/ui/ambient_animation_shield_controller.h" #include "ash/ambient/ui/ambient_view_delegate.h" @@ -260,12 +261,6 @@ media_string_view->SetVisible(false); } -void AmbientAnimationView::AnimationWillStartPlaying( - const lottie::Animation* animation) { - event_handler_->OnMarkerHit(AmbientPhotoConfig::Marker::kUiStartRendering); - last_jitter_timestamp_ = base::TimeTicks::Now(); -} - void AmbientAnimationView::AnimationCycleEnded( const lottie::Animation* animation) { event_handler_->OnMarkerHit(AmbientPhotoConfig::Marker::kUiCycleEnded); @@ -302,7 +297,7 @@ << animated_image_view_->animated_image()->GetOriginalSize().ToString() << " from " << previous_animation_bounds.ToString() << " to " << animated_image_view_->GetImageBounds().ToString(); - animated_image_view_->Play(); + StartPlayingAnimation(); if (!throughput_tracker_restart_timer_.IsRunning()) { RestartThroughputTracking(); throughput_tracker_restart_timer_.Start( @@ -311,6 +306,19 @@ } } +void AmbientAnimationView::StartPlayingAnimation() { + // There should only be one active AmbientAnimationPlayer at any given time, + // otherwise multiple active players can lead to confusing simultaneous state + // changes. So destroy the existing player first before creating a new one. + animation_player_.reset(); + // |animated_image_view_| is owned by the base |View| class and outlives the + // |animation_player_|, so it's safe to pass a raw ptr here. + animation_player_ = + std::make_unique<AmbientAnimationPlayer>(animated_image_view_); + event_handler_->OnMarkerHit(AmbientPhotoConfig::Marker::kUiStartRendering); + last_jitter_timestamp_ = base::TimeTicks::Now(); +} + void AmbientAnimationView::RestartThroughputTracking() { // Stop() must be called to trigger throughput reporting. if (throughput_tracker_ && !throughput_tracker_->Stop()) {
diff --git a/ash/ambient/ui/ambient_animation_view.h b/ash/ambient/ui/ambient_animation_view.h index e1c0d67..873ef26 100644 --- a/ash/ambient/ui/ambient_animation_view.h +++ b/ash/ambient/ui/ambient_animation_view.h
@@ -29,6 +29,7 @@ namespace ash { class AmbientAnimationAttributionProvider; +class AmbientAnimationPlayer; class AmbientAnimationStaticResources; class AmbientAnimationShieldController; class AmbientViewDelegate; @@ -50,11 +51,11 @@ private: void Init(AmbientViewDelegate* view_delegate); - void AnimationWillStartPlaying(const lottie::Animation* animation) override; void AnimationCycleEnded(const lottie::Animation* animation) override; void OnViewBoundsChanged(View* observed_view) override; + void StartPlayingAnimation(); void StartThroughputTracking(); void RestartThroughputTracking(); void ApplyJitter(); @@ -71,6 +72,7 @@ views::BoxLayoutView* glanceable_info_container_ = nullptr; views::BoxLayoutView* media_string_container_ = nullptr; std::unique_ptr<AmbientAnimationShieldController> shield_view_controller_; + std::unique_ptr<AmbientAnimationPlayer> animation_player_; base::ScopedObservation<View, ViewObserver> animated_image_view_observer_{ this}; base::ScopedObservation<lottie::Animation, lottie::AnimationObserver>
diff --git a/ash/app_list/app_list_presenter_unittest.cc b/ash/app_list/app_list_presenter_unittest.cc index ece320a7c..d72f9a0 100644 --- a/ash/app_list/app_list_presenter_unittest.cc +++ b/ash/app_list/app_list_presenter_unittest.cc
@@ -4,6 +4,7 @@ #include <algorithm> #include <memory> +#include <string> #include "ash/accessibility/accessibility_controller_impl.h" #include "ash/app_list/app_list_bubble_presenter.h" @@ -354,15 +355,16 @@ INSTANTIATE_TEST_SUITE_P(All, AppListPresenterNonBubbleTest, testing::Bool()); // Tests all tablet/clamshell classic/bubble launcher combinations. -class AppListBubbleAndTabletTest - : public AshTestBase, - public testing::WithParamInterface<std::tuple<bool, bool>> { +class AppListBubbleAndTabletTestBase : public AshTestBase { public: - AppListBubbleAndTabletTest() = default; - AppListBubbleAndTabletTest(const AppListBubbleAndTabletTest&) = delete; - AppListBubbleAndTabletTest& operator=(const AppListBubbleAndTabletTest&) = + AppListBubbleAndTabletTestBase(bool productivity_launcher, bool tablet_mode) + : productivity_launcher_(productivity_launcher), + tablet_mode_(tablet_mode) {} + AppListBubbleAndTabletTestBase(const AppListBubbleAndTabletTestBase&) = delete; - ~AppListBubbleAndTabletTest() override = default; + AppListBubbleAndTabletTestBase& operator=( + const AppListBubbleAndTabletTestBase&) = delete; + ~AppListBubbleAndTabletTestBase() override = default; // testing::Test: void SetUp() override { @@ -412,17 +414,17 @@ /*animate=*/true, /*update_position_closure=*/base::DoNothing()); base::RunLoop run_loop; - GetAppsGridView()->AddReorderCallbackForTest( - base::BindRepeating(&AppListBubbleAndTabletTest::OnReorderAnimationDone, - base::Unretained(this), run_loop.QuitClosure())); + GetAppsGridView()->AddReorderCallbackForTest(base::BindRepeating( + &AppListBubbleAndTabletTestBase::OnReorderAnimationDone, + base::Unretained(this), run_loop.QuitClosure())); run_loop.Run(); } // Whether we should use the ProductivityLauncher flag. - bool productivity_launcher_param() { return std::get<0>(GetParam()); } + bool productivity_launcher_param() { return productivity_launcher_; } // Whether we should run the test in tablet mode. - bool tablet_mode_param() { return std::get<1>(GetParam()); } + bool tablet_mode_param() { return tablet_mode_; } // Bubble launcher is visible in clamshell mode with kProductivityLauncher // enabled. @@ -532,6 +534,21 @@ ->GetFullscreenLauncherAppsSeparatorView(); } + AppListFolderView* GetFolderView() { + return should_show_bubble_launcher() + ? GetAppListTestHelper()->GetBubbleFolderView() + : GetAppListTestHelper()->GetFullscreenFolderView(); + } + + void DeleteFolderItemChildren(AppListFolderItem* item) { + std::vector<std::string> items_to_delete; + for (size_t i = 0; i < item->ChildItemCount(); ++i) { + items_to_delete.push_back(item->GetChildItemAt(i)->id()); + } + for (auto& item_to_delete : items_to_delete) + app_list_test_model_->DeleteItem(item_to_delete); + } + void LongPressAt(const gfx::Point& point) { ui::TouchEvent long_press(ui::ET_GESTURE_LONG_PRESS, point, base::TimeTicks::Now(), @@ -578,6 +595,9 @@ } protected: + const bool productivity_launcher_; + const bool tablet_mode_; + std::unique_ptr<test::AppsGridViewTestApi> grid_test_api_; base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<test::AppListTestModel> app_list_test_model_; @@ -585,6 +605,45 @@ AppsGridView* apps_grid_view_ = nullptr; }; +// Parameterized by productivity launcher flag, and tablet mode. +class AppListBubbleAndTabletTest + : public AppListBubbleAndTabletTestBase, + public testing::WithParamInterface<std::tuple<bool, bool>> { + public: + AppListBubbleAndTabletTest() + : AppListBubbleAndTabletTestBase( + /*productivity_launcher=*/std::get<0>(GetParam()), + /*tablet_mode=*/std::get<1>(GetParam())) {} + AppListBubbleAndTabletTest(const AppListBubbleAndTabletTest&) = delete; + AppListBubbleAndTabletTest& operator=(const AppListBubbleAndTabletTest&) = + delete; + ~AppListBubbleAndTabletTest() override = default; +}; + +// Instantiate the values in the parameterized tests. First boolean is used to +// determine whether to use the kProductivityLauncher feature flag. The second +// boolean is to determine whether to run the test in tablet mode. +INSTANTIATE_TEST_SUITE_P(All, + AppListBubbleAndTabletTest, + testing::Combine(testing::Bool(), testing::Bool())); + +// Parameterized by tablet mode. +class ProductivityLauncherTest : public AppListBubbleAndTabletTestBase, + public testing::WithParamInterface<bool> { + public: + ProductivityLauncherTest() + : AppListBubbleAndTabletTestBase( + /*productivity_launcher=*/true, + /*tablet_mode=*/GetParam()) {} + ProductivityLauncherTest(const ProductivityLauncherTest&) = delete; + ProductivityLauncherTest& operator=(const ProductivityLauncherTest&) = delete; + ~ProductivityLauncherTest() override = default; +}; + +// Instantiate the values in the parameterized tests. The boolean +// determines whether to run the test in tablet mode. +INSTANTIATE_TEST_SUITE_P(TabletMode, ProductivityLauncherTest, testing::Bool()); + // Used to test app_list behavior with a populated apps_grid. class PopulatedAppListTestBase : public AshTestBase { public: @@ -727,18 +786,8 @@ } }; -// Instantiate the values in the parameterized tests. First boolean is used to -// determine whether to use the kProductivityLauncher feature flag. The second -// boolean is to determine whether to run the test in tablet mode. -INSTANTIATE_TEST_SUITE_P(All, - AppListBubbleAndTabletTest, - testing::Combine(testing::Bool(), testing::Bool())); - -// Verify that open folders are closed after sorting apps grid. Only run for -// Productivity launcher. -TEST_P(AppListBubbleAndTabletTest, SortingClosesOpenFolderView) { - if (!productivity_launcher_param()) - return; +// Verify that open folders are closed after sorting apps grid. +TEST_P(ProductivityLauncherTest, SortingClosesOpenFolderView) { ui::ScopedAnimationDurationScaleMode scope_duration( ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); @@ -757,6 +806,536 @@ EXPECT_FALSE(AppListIsInFolderView()); } +// Tests that folder view bounds do not change if an item gets added to app list +// model while the folder view is visible (even if it changes the folder item +// view position in the root apps grid). +TEST_P(ProductivityLauncherTest, + FolderViewRemainsInPlaceWhenAddingItemToModel) { + app_list_test_model_->PopulateApps(2); + AppListFolderItem* const folder_item = + app_list_test_model_->CreateAndPopulateFolderWithApps(3); + const std::string folder_id = folder_item->id(); + app_list_test_model_->PopulateApps(3); + + // Setup tablet/clamshell mode and show launcher. + EnableTabletMode(tablet_mode_param()); + EnsureLauncherShown(); + SetupGridTestApi(); + + ui::ScopedAnimationDurationScaleMode scope_duration( + ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); + + grid_test_api_->PressItemAt(2); + EXPECT_TRUE(AppListIsInFolderView()); + GetAppListTestHelper()->WaitForFolderAnimation(); + AppListFolderView* const folder_view = GetFolderView(); + + // Cache the initial folder bounds. + const gfx::Rect folder_bounds = folder_view->GetBoundsInScreen(); + const gfx::Rect original_folder_item_bounds = + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen(); + const gfx::Rect final_folder_item_bounds = + apps_grid_view_->GetItemViewAt(3)->GetBoundsInScreen(); + + // Add a new item. + test::AppListTestModel::AppListTestItem* new_item = + app_list_test_model_->CreateItem("new_test_item"); + new_item->SetPosition(app_list_test_model_->top_level_item_list() + ->item_at(0) + ->position() + .CreateBefore()); + app_list_test_model_->AddItem(new_item); + apps_grid_view_->GetWidget()->LayoutRootViewIfNecessary(); + grid_test_api_->WaitForItemMoveAnimationDone(); + + // Verify that the folder view location did not change. + EXPECT_EQ(folder_bounds, GetFolderView()->GetBoundsInScreen()); + + AppListItemView* const folder_item_view = apps_grid_view_->GetItemViewAt(3); + ASSERT_TRUE(folder_item_view); + ASSERT_TRUE(folder_item_view->is_folder()); + EXPECT_EQ(original_folder_item_bounds, folder_item_view->GetBoundsInScreen()); + + // The item at slot 2 should be laid out right of the folder while the folder + // is shown. + EXPECT_LT(original_folder_item_bounds.right(), + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen().x()); + + // The item at slot 1 should be laid out left of the folder. + EXPECT_GT(original_folder_item_bounds.x(), + apps_grid_view_->GetItemViewAt(1)->GetBoundsInScreen().right()); + + // Close the folder view. + ui::test::EventGenerator* event_generator = GetEventGenerator(); + event_generator->MoveMouseTo( + GetFolderView()->GetBoundsInScreen().right_center() + + gfx::Vector2d(10, 0)); + event_generator->ClickLeftButton(); + + EXPECT_TRUE(folder_view->IsAnimationRunning()); + EXPECT_EQ(original_folder_item_bounds, folder_item_view->GetBoundsInScreen()); + + // Once folder completes hiding, the folder item view should be moved to + // target location. + GetAppListTestHelper()->WaitForFolderAnimation(); + apps_grid_view_->GetWidget()->LayoutRootViewIfNecessary(); + grid_test_api_->WaitForItemMoveAnimationDone(); + EXPECT_FALSE(AppListIsInFolderView()); + + EXPECT_EQ(final_folder_item_bounds, folder_item_view->GetBoundsInScreen()); + EXPECT_EQ(original_folder_item_bounds, + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen()); +} + +// Tests that folder view bounds do not change if position of the original +// folder item view changes in the model (as long as the folder is open). +TEST_P(ProductivityLauncherTest, + FolderViewRemainsInPlaceWhenItemMovedToEndInModel) { + app_list_test_model_->PopulateApps(2); + AppListFolderItem* const folder_item = + app_list_test_model_->CreateAndPopulateFolderWithApps(3); + const std::string folder_id = folder_item->id(); + app_list_test_model_->PopulateApps(3); + + // Setup tablet/clamshell mode and show launcher. + EnableTabletMode(tablet_mode_param()); + EnsureLauncherShown(); + SetupGridTestApi(); + + ui::ScopedAnimationDurationScaleMode scope_duration( + ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); + + grid_test_api_->PressItemAt(2); + EXPECT_TRUE(AppListIsInFolderView()); + GetAppListTestHelper()->WaitForFolderAnimation(); + AppListFolderView* const folder_view = GetFolderView(); + + // Cache the initial folder bounds. + const gfx::Rect folder_bounds = folder_view->GetBoundsInScreen(); + const gfx::Rect original_folder_item_bounds = + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen(); + const gfx::Rect original_item_1_bounds = + apps_grid_view_->GetItemViewAt(1)->GetBoundsInScreen(); + const gfx::Rect original_item_3_bounds = + apps_grid_view_->GetItemViewAt(3)->GetBoundsInScreen(); + const gfx::Rect final_folder_item_bounds = + apps_grid_view_->GetItemViewAt(5)->GetBoundsInScreen(); + + // Move the folder item to the last position in the model. + app_list_test_model_->RequestPositionUpdate( + folder_id, + app_list_test_model_->top_level_item_list() + ->item_at(5) + ->position() + .CreateAfter(), + RequestPositionUpdateReason::kMoveItem); + + // Verify that the folder view location did not actually change. + EXPECT_EQ(folder_bounds, folder_view->GetBoundsInScreen()); + + AppListItemView* const folder_item_view = apps_grid_view_->GetItemViewAt(5); + ASSERT_TRUE(folder_item_view); + ASSERT_TRUE(folder_item_view->is_folder()); + EXPECT_EQ(original_folder_item_bounds, folder_item_view->GetBoundsInScreen()); + + // The item at slot 2 in the model should remain at slot 3 (where it was + // before folder item moved in the model). + EXPECT_EQ(original_item_3_bounds, + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen()); + + // The item at slot 1 should be remain in place. + EXPECT_EQ(original_item_1_bounds, + apps_grid_view_->GetItemViewAt(1)->GetBoundsInScreen()); + + // Close the folder view. + ui::test::EventGenerator* event_generator = GetEventGenerator(); + event_generator->MoveMouseTo(folder_view->GetBoundsInScreen().right_center() + + gfx::Vector2d(10, 0)); + event_generator->ClickLeftButton(); + + EXPECT_TRUE(folder_view->IsAnimationRunning()); + EXPECT_EQ(original_folder_item_bounds, folder_item_view->GetBoundsInScreen()); + + // Once folder completes hiding, the folder item view should be moved to + // target location. + GetAppListTestHelper()->WaitForFolderAnimation(); + apps_grid_view_->GetWidget()->LayoutRootViewIfNecessary(); + grid_test_api_->WaitForItemMoveAnimationDone(); + EXPECT_FALSE(AppListIsInFolderView()); + + EXPECT_EQ(final_folder_item_bounds, folder_item_view->GetBoundsInScreen()); + + EXPECT_EQ(original_folder_item_bounds, + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen()); + + // The item at slot 1 should be remain in place. + EXPECT_EQ(original_item_1_bounds, + apps_grid_view_->GetItemViewAt(1)->GetBoundsInScreen()); + // The item at slot 2 in the model should move into original folder item slot. + EXPECT_EQ(original_folder_item_bounds, + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen()); +} + +// Tests that folder view bounds do not change if position of the original +// folder item view changes in the model (as long as the folder is open). +TEST_P(ProductivityLauncherTest, + FolderViewRemainsInPlaceWhenItemMovedToStartInModel) { + app_list_test_model_->PopulateApps(2); + AppListFolderItem* const folder_item = + app_list_test_model_->CreateAndPopulateFolderWithApps(3); + const std::string folder_id = folder_item->id(); + app_list_test_model_->PopulateApps(3); + + // Setup tablet/clamshell mode and show launcher. + EnableTabletMode(tablet_mode_param()); + EnsureLauncherShown(); + SetupGridTestApi(); + + ui::ScopedAnimationDurationScaleMode scope_duration( + ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); + + grid_test_api_->PressItemAt(2); + EXPECT_TRUE(AppListIsInFolderView()); + GetAppListTestHelper()->WaitForFolderAnimation(); + AppListFolderView* const folder_view = GetFolderView(); + + // Cache the initial folder bounds. + const gfx::Rect folder_bounds = folder_view->GetBoundsInScreen(); + const gfx::Rect original_folder_item_bounds = + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen(); + const gfx::Rect original_item_1_bounds = + apps_grid_view_->GetItemViewAt(1)->GetBoundsInScreen(); + const gfx::Rect original_item_3_bounds = + apps_grid_view_->GetItemViewAt(3)->GetBoundsInScreen(); + const gfx::Rect final_folder_item_bounds = + apps_grid_view_->GetItemViewAt(0)->GetBoundsInScreen(); + + // Move the folder item to the last position in the model. + app_list_test_model_->RequestPositionUpdate( + folder_id, + app_list_test_model_->top_level_item_list() + ->item_at(0) + ->position() + .CreateBefore(), + RequestPositionUpdateReason::kMoveItem); + + // Verify that the folder view location did not actually change. + EXPECT_EQ(folder_bounds, folder_view->GetBoundsInScreen()); + + AppListItemView* const folder_item_view = apps_grid_view_->GetItemViewAt(0); + ASSERT_TRUE(folder_item_view); + ASSERT_TRUE(folder_item_view->is_folder()); + EXPECT_EQ(original_folder_item_bounds, folder_item_view->GetBoundsInScreen()); + + // The item at slot 3 in the model did not change, so it should remain in + // place. + EXPECT_EQ(original_item_3_bounds, + apps_grid_view_->GetItemViewAt(3)->GetBoundsInScreen()); + + // The item at slot 2 in the model should remain in the old position (slot 1). + EXPECT_EQ(original_item_1_bounds, + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen()); + + // Close the folder view. + ui::test::EventGenerator* event_generator = GetEventGenerator(); + event_generator->MoveMouseTo(folder_view->GetBoundsInScreen().right_center() + + gfx::Vector2d(10, 0)); + event_generator->ClickLeftButton(); + + EXPECT_TRUE(folder_view->IsAnimationRunning()); + EXPECT_EQ(original_folder_item_bounds, folder_item_view->GetBoundsInScreen()); + + // Once folder completes hiding, the folder item view should be moved to + // target location. + GetAppListTestHelper()->WaitForFolderAnimation(); + apps_grid_view_->GetWidget()->LayoutRootViewIfNecessary(); + grid_test_api_->WaitForItemMoveAnimationDone(); + EXPECT_FALSE(AppListIsInFolderView()); + + EXPECT_EQ(final_folder_item_bounds, folder_item_view->GetBoundsInScreen()); + + EXPECT_EQ(original_folder_item_bounds, + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen()); + + // The item at slot 2 in the model should move into original folder item slot. + EXPECT_EQ(original_folder_item_bounds, + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen()); + // The item at slot 3 in the model should move into new position. + EXPECT_EQ(original_item_3_bounds, + apps_grid_view_->GetItemViewAt(3)->GetBoundsInScreen()); +} + +// Tests that folder item deletion during folder view hide animation is handled +// well. +TEST_P(ProductivityLauncherTest, ReorderedFolderItemDeletionDuringFolderClose) { + app_list_test_model_->PopulateApps(2); + AppListFolderItem* const folder_item = + app_list_test_model_->CreateAndPopulateFolderWithApps(3); + const std::string folder_id = folder_item->id(); + app_list_test_model_->PopulateApps(3); + + // Setup tablet/clamshell mode and show launcher. + EnableTabletMode(tablet_mode_param()); + EnsureLauncherShown(); + SetupGridTestApi(); + + ui::ScopedAnimationDurationScaleMode scope_duration( + ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); + + grid_test_api_->PressItemAt(2); + EXPECT_TRUE(AppListIsInFolderView()); + GetAppListTestHelper()->WaitForFolderAnimation(); + AppListFolderView* const folder_view = GetFolderView(); + + // Cache the initial folder bounds. + const gfx::Rect folder_bounds = folder_view->GetBoundsInScreen(); + const gfx::Rect original_folder_item_bounds = + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen(); + const gfx::Rect original_item_1_bounds = + apps_grid_view_->GetItemViewAt(1)->GetBoundsInScreen(); + const gfx::Rect original_item_3_bounds = + apps_grid_view_->GetItemViewAt(3)->GetBoundsInScreen(); + + // Move the folder item to the last position in the model. + app_list_test_model_->RequestPositionUpdate( + folder_id, + app_list_test_model_->top_level_item_list() + ->item_at(0) + ->position() + .CreateBefore(), + RequestPositionUpdateReason::kMoveItem); + + // Verify that the folder view location did not actually change. + EXPECT_EQ(folder_bounds, folder_view->GetBoundsInScreen()); + + AppListItemView* const folder_item_view = apps_grid_view_->GetItemViewAt(0); + ASSERT_TRUE(folder_item_view); + ASSERT_TRUE(folder_item_view->is_folder()); + EXPECT_EQ(original_folder_item_bounds, folder_item_view->GetBoundsInScreen()); + + // The item at slot 3 in the model did not change, so it should remain in + // place. + EXPECT_EQ(original_item_3_bounds, + apps_grid_view_->GetItemViewAt(3)->GetBoundsInScreen()); + // The item at slot 2 in the model should remain in the old position (slot 1). + EXPECT_EQ(original_item_1_bounds, + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen()); + + // Close the folder view. + ui::test::EventGenerator* event_generator = GetEventGenerator(); + event_generator->MoveMouseTo(folder_view->GetBoundsInScreen().right_center() + + gfx::Vector2d(10, 0)); + event_generator->ClickLeftButton(); + + // Delete the folder item while the folder is animating out. + DeleteFolderItemChildren(folder_item); + apps_grid_view_->GetWidget()->LayoutRootViewIfNecessary(); + grid_test_api_->WaitForItemMoveAnimationDone(); + EXPECT_FALSE(AppListIsInFolderView()); + + // Verify remaining items are moved into correct slots. + EXPECT_EQ(original_item_1_bounds, + apps_grid_view_->GetItemViewAt(1)->GetBoundsInScreen()); + EXPECT_EQ(original_folder_item_bounds, + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen()); + EXPECT_EQ(original_item_3_bounds, + apps_grid_view_->GetItemViewAt(3)->GetBoundsInScreen()); +} + +// Tests that folder item deletion just after folder gets hidden (while item +// bounds are still animating to final positions) gets handled well. +TEST_P(ProductivityLauncherTest, ReorderedFolderItemDeletionAfterFolderClose) { + app_list_test_model_->PopulateApps(2); + AppListFolderItem* const folder_item = + app_list_test_model_->CreateAndPopulateFolderWithApps(3); + const std::string folder_id = folder_item->id(); + app_list_test_model_->PopulateApps(3); + + // Setup tablet/clamshell mode and show launcher. + EnableTabletMode(tablet_mode_param()); + EnsureLauncherShown(); + SetupGridTestApi(); + + ui::ScopedAnimationDurationScaleMode scope_duration( + ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); + + grid_test_api_->PressItemAt(2); + EXPECT_TRUE(AppListIsInFolderView()); + GetAppListTestHelper()->WaitForFolderAnimation(); + AppListFolderView* folder_view = GetFolderView(); + + // Cache the initial folder bounds. + const gfx::Rect folder_bounds = folder_view->GetBoundsInScreen(); + const gfx::Rect original_folder_item_bounds = + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen(); + const gfx::Rect original_item_1_bounds = + apps_grid_view_->GetItemViewAt(1)->GetBoundsInScreen(); + const gfx::Rect original_item_3_bounds = + apps_grid_view_->GetItemViewAt(3)->GetBoundsInScreen(); + + // Move the folder item to the last position in the model. + app_list_test_model_->RequestPositionUpdate( + folder_id, + app_list_test_model_->top_level_item_list() + ->item_at(0) + ->position() + .CreateBefore(), + RequestPositionUpdateReason::kMoveItem); + + // Verify that the folder view location did not actually change. + EXPECT_EQ(folder_bounds, folder_view->GetBoundsInScreen()); + + AppListItemView* const folder_item_view = apps_grid_view_->GetItemViewAt(0); + ASSERT_TRUE(folder_item_view); + ASSERT_TRUE(folder_item_view->is_folder()); + EXPECT_EQ(original_folder_item_bounds, folder_item_view->GetBoundsInScreen()); + + // The item at slot 3 in the model did not change, so it should remain in + // place. + EXPECT_EQ(original_item_3_bounds, + apps_grid_view_->GetItemViewAt(3)->GetBoundsInScreen()); + // The item at slot 2 in the model should remain in the old position (slot 1). + EXPECT_EQ(original_item_1_bounds, + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen()); + + // Close the folder view. + ui::test::EventGenerator* event_generator = GetEventGenerator(); + event_generator->MoveMouseTo(folder_view->GetBoundsInScreen().right_center() + + gfx::Vector2d(10, 0)); + event_generator->ClickLeftButton(); + + GetAppListTestHelper()->WaitForFolderAnimation(); + + // Delete the folder item while items are animating into their final + // positions. + DeleteFolderItemChildren(folder_item); + apps_grid_view_->GetWidget()->LayoutRootViewIfNecessary(); + grid_test_api_->WaitForItemMoveAnimationDone(); + EXPECT_FALSE(AppListIsInFolderView()); + + // Verify remaining items are moved into correct slots. + EXPECT_EQ(original_item_1_bounds, + apps_grid_view_->GetItemViewAt(1)->GetBoundsInScreen()); + EXPECT_EQ(original_folder_item_bounds, + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen()); + EXPECT_EQ(original_item_3_bounds, + apps_grid_view_->GetItemViewAt(3)->GetBoundsInScreen()); +} + +// Tests that folder item deletion while the folder is shown gets handled well. +TEST_P(ProductivityLauncherTest, ReorderedFolderItemDeletionWhileFolderShown) { + app_list_test_model_->PopulateApps(2); + AppListFolderItem* const folder_item = + app_list_test_model_->CreateAndPopulateFolderWithApps(3); + const std::string folder_id = folder_item->id(); + app_list_test_model_->PopulateApps(3); + + // Setup tablet/clamshell mode and show launcher. + EnableTabletMode(tablet_mode_param()); + EnsureLauncherShown(); + SetupGridTestApi(); + + ui::ScopedAnimationDurationScaleMode scope_duration( + ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); + + grid_test_api_->PressItemAt(2); + EXPECT_TRUE(AppListIsInFolderView()); + GetAppListTestHelper()->WaitForFolderAnimation(); + AppListFolderView* folder_view = GetFolderView(); + + // Cache the initial folder bounds. + const gfx::Rect folder_bounds = folder_view->GetBoundsInScreen(); + const gfx::Rect original_folder_item_bounds = + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen(); + const gfx::Rect original_item_1_bounds = + apps_grid_view_->GetItemViewAt(1)->GetBoundsInScreen(); + const gfx::Rect original_item_3_bounds = + apps_grid_view_->GetItemViewAt(3)->GetBoundsInScreen(); + + // Move the folder item to the last position in the model. + app_list_test_model_->RequestPositionUpdate( + folder_id, + app_list_test_model_->top_level_item_list() + ->item_at(0) + ->position() + .CreateBefore(), + RequestPositionUpdateReason::kMoveItem); + + // Verify that the folder view location did not actually change. + EXPECT_EQ(folder_bounds, folder_view->GetBoundsInScreen()); + + AppListItemView* const folder_item_view = apps_grid_view_->GetItemViewAt(0); + ASSERT_TRUE(folder_item_view); + ASSERT_TRUE(folder_item_view->is_folder()); + EXPECT_EQ(original_folder_item_bounds, folder_item_view->GetBoundsInScreen()); + + // The item at slot 3 in the model did not change, so it should remain in + // place. + EXPECT_EQ(original_item_3_bounds, + apps_grid_view_->GetItemViewAt(3)->GetBoundsInScreen()); + // The item at slot 2 in the model should remain in the old position (slot 1). + EXPECT_EQ(original_item_1_bounds, + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen()); + + // Delete the folder item while it's still shown. + DeleteFolderItemChildren(folder_item); + + apps_grid_view_->GetWidget()->LayoutRootViewIfNecessary(); + grid_test_api_->WaitForItemMoveAnimationDone(); + EXPECT_FALSE(AppListIsInFolderView()); + + // Verify remaining items are moved into correct slots. + EXPECT_EQ(original_item_1_bounds, + apps_grid_view_->GetItemViewAt(1)->GetBoundsInScreen()); + EXPECT_EQ(original_folder_item_bounds, + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen()); + EXPECT_EQ(original_item_3_bounds, + apps_grid_view_->GetItemViewAt(3)->GetBoundsInScreen()); +} + +// Tests that folder item deletion while the folder view is still animating into +// shown state gets handled well. +TEST_P(ProductivityLauncherTest, ReorderedFolderItemDeletionDuringShow) { + app_list_test_model_->PopulateApps(2); + AppListFolderItem* const folder_item = + app_list_test_model_->CreateAndPopulateFolderWithApps(3); + const std::string folder_id = folder_item->id(); + app_list_test_model_->PopulateApps(3); + + // Setup tablet/clamshell mode and show launcher. + EnableTabletMode(tablet_mode_param()); + EnsureLauncherShown(); + SetupGridTestApi(); + + ui::ScopedAnimationDurationScaleMode scope_duration( + ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); + + grid_test_api_->PressItemAt(2); + EXPECT_TRUE(AppListIsInFolderView()); + + // Cache the initial folder bounds. + const gfx::Rect original_folder_item_bounds = + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen(); + const gfx::Rect original_item_1_bounds = + apps_grid_view_->GetItemViewAt(1)->GetBoundsInScreen(); + const gfx::Rect original_item_3_bounds = + apps_grid_view_->GetItemViewAt(3)->GetBoundsInScreen(); + + // Delete the folder item while the folder is still showing. + DeleteFolderItemChildren(folder_item); + apps_grid_view_->GetWidget()->LayoutRootViewIfNecessary(); + grid_test_api_->WaitForItemMoveAnimationDone(); + EXPECT_FALSE(AppListIsInFolderView()); + + // Verify remaining items are moved into correct slots. + EXPECT_EQ(original_item_1_bounds, + apps_grid_view_->GetItemViewAt(1)->GetBoundsInScreen()); + EXPECT_EQ(original_folder_item_bounds, + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen()); + EXPECT_EQ(original_item_3_bounds, + apps_grid_view_->GetItemViewAt(3)->GetBoundsInScreen()); +} + // Tests that Zero State Search is only shown when needed. TEST_P(AppListBubbleAndTabletTest, LauncherSearchZeroState) { EnableTabletMode(tablet_mode_param()); @@ -1980,11 +2559,14 @@ const int kItemCount = 6; PopulateApps(kItemCount); - // Dragging the item with index 4. - AppListItemView* const dragged_view = apps_grid_view_->GetItemViewAt(4); + // Dragging the item with index 2. + AppListItemView* const dragged_view = apps_grid_view_->GetItemViewAt(2); AppListItem* const dragged_item = dragged_view->item(); AppListItem* const merged_item = apps_grid_view_->GetItemViewAt(3)->item(); + const gfx::Rect expected_folder_item_view_bounds = + apps_grid_view_->GetItemViewAt(2)->GetBoundsInScreen(); + // Drag the item on top of the item with index 3. ui::test::EventGenerator* event_generator = GetEventGenerator(); event_generator->MoveMouseTo(dragged_view->GetBoundsInScreen().CenterPoint()); @@ -1999,9 +2581,11 @@ event_generator->ReleaseLeftButton(); EXPECT_FALSE(apps_grid_view_->IsDragging()); - EXPECT_TRUE(apps_grid_view_->GetItemViewAt(3)->item()->is_folder()); - EXPECT_EQ(dragged_item->folder_id(), - apps_grid_view_->GetItemViewAt(3)->item()->id()); + AppListItemView* const folder_item_view = apps_grid_view_->GetItemViewAt(2); + EXPECT_TRUE(folder_item_view->is_folder()); + EXPECT_EQ(expected_folder_item_view_bounds, + folder_item_view->GetBoundsInScreen()); + EXPECT_EQ(dragged_item->folder_id(), folder_item_view->item()->id()); // Verify that item layers have been destroyed after the drag operation ended. apps_grid_test_api_->WaitForItemMoveAnimationDone(); @@ -2014,10 +2598,12 @@ // Open the newly created folder - when productivity launcher is enabled this // happens automatically. if (!IsProductivityLauncherEnabled()) - LeftClickOn(apps_grid_view_->GetItemViewAt(3)); + LeftClickOn(folder_item_view); // Verify that item views have no layers after the folder has been opened. apps_grid_test_api_->WaitForItemMoveAnimationDone(); + EXPECT_EQ(expected_folder_item_view_bounds, + folder_item_view->GetBoundsInScreen()); EXPECT_TRUE(AppListIsInFolderView()); for (int i = 0; i < apps_grid_view_->view_model()->view_size(); ++i) { views::View* item_view = apps_grid_view_->view_model()->view_at(i); @@ -2038,7 +2624,7 @@ apps_grid_test_api_->WaitForItemMoveAnimationDone(); EXPECT_FALSE(AppListIsInFolderView()); - EXPECT_FALSE(apps_grid_view_->GetItemViewAt(3)->item()->is_folder()); + EXPECT_FALSE(apps_grid_view_->GetItemViewAt(2)->item()->is_folder()); // Verify that a pending layout, if any, does not cause a crash. apps_grid_view_->InvalidateLayout(); @@ -2054,6 +2640,8 @@ AppListItemView* const dragged_view = apps_grid_view_->GetItemViewAt(4); AppListItem* const dragged_item = dragged_view->item(); AppListItem* const merged_item = apps_grid_view_->GetItemViewAt(3)->item(); + const gfx::Rect expected_folder_item_view_bounds = + apps_grid_view_->GetItemViewAt(3)->GetBoundsInScreen(); // Drag the item on top of the item with index 3. ui::test::EventGenerator* event_generator = GetEventGenerator(); @@ -2081,11 +2669,16 @@ EXPECT_FALSE(item_view->layer()) << "at " << i; } + AppListItemView* const folder_item_view = apps_grid_view_->GetItemViewAt(3); + EXPECT_TRUE(folder_item_view->is_folder()); + EXPECT_EQ(expected_folder_item_view_bounds, + folder_item_view->GetBoundsInScreen()); + // Open the newly created folder - with productivity launcher, the folder // should already be open. if (!IsProductivityLauncherEnabled()) { event_generator->MoveMouseTo( - apps_grid_view_->GetItemViewAt(3)->GetBoundsInScreen().CenterPoint()); + folder_item_view->GetBoundsInScreen().CenterPoint()); event_generator->ClickLeftButton(); event_generator->ReleaseLeftButton(); }
diff --git a/ash/app_list/test/app_list_test_helper.cc b/ash/app_list/test/app_list_test_helper.cc index c160cdc..adf6baa 100644 --- a/ash/app_list/test/app_list_test_helper.cc +++ b/ash/app_list/test/app_list_test_helper.cc
@@ -16,6 +16,7 @@ #include "ash/app_list/views/app_list_bubble_apps_page.h" #include "ash/app_list/views/app_list_bubble_search_page.h" #include "ash/app_list/views/app_list_bubble_view.h" +#include "ash/app_list/views/app_list_folder_view.h" #include "ash/app_list/views/app_list_main_view.h" #include "ash/app_list/views/app_list_toast_container_view.h" #include "ash/app_list/views/app_list_view.h" @@ -57,6 +58,22 @@ base::RunLoop().RunUntilIdle(); } +void AppListTestHelper::WaitForFolderAnimation() { + AppListFolderView* folder_view = nullptr; + if (!Shell::Get()->IsInTabletMode() && + features::IsProductivityLauncherEnabled()) { + folder_view = GetBubbleFolderView(); + } else { + folder_view = GetFullscreenFolderView(); + } + if (!folder_view || !folder_view->IsAnimationRunning()) + return; + + base::RunLoop run_loop; + folder_view->SetAnimationDoneTestCallback(run_loop.QuitClosure()); + run_loop.Run(); +} + void AppListTestHelper::ShowAppList() { app_list_controller_->ShowAppList(); }
diff --git a/ash/app_list/test/app_list_test_helper.h b/ash/app_list/test/app_list_test_helper.h index f816936..a3338cf 100644 --- a/ash/app_list/test/app_list_test_helper.h +++ b/ash/app_list/test/app_list_test_helper.h
@@ -96,6 +96,9 @@ // Run all pending in message loop to wait for animation to finish. void WaitUntilIdle(); + // If a folder view is shown, waits until the folder animations complete. + void WaitForFolderAnimation(); + // Adds `num_apps` to the app list model. void AddAppItems(int num_apps);
diff --git a/ash/app_list/views/app_list_bubble_view.cc b/ash/app_list/views/app_list_bubble_view.cc index c978314c..6679775 100644 --- a/ash/app_list/views/app_list_bubble_view.cc +++ b/ash/app_list/views/app_list_bubble_view.cc
@@ -592,7 +592,8 @@ } void AppListBubbleView::ShowFolderForItemView(AppListItemView* folder_item_view, - bool focus_name_input) { + bool focus_name_input, + base::OnceClosure hide_callback) { DVLOG(1) << __FUNCTION__; if (folder_view_->IsAnimationRunning()) return; @@ -601,7 +602,8 @@ // Apps.AppListFolderOpened or introduce a new metric. DCHECK(folder_item_view->is_folder()); - folder_view_->ConfigureForFolderItemView(folder_item_view); + folder_view_->ConfigureForFolderItemView(folder_item_view, + std::move(hide_callback)); showing_folder_ = true; Layout(); folder_background_view_->SetVisible(true);
diff --git a/ash/app_list/views/app_list_bubble_view.h b/ash/app_list/views/app_list_bubble_view.h index 8fce414..f3d2595 100644 --- a/ash/app_list/views/app_list_bubble_view.h +++ b/ash/app_list/views/app_list_bubble_view.h
@@ -106,7 +106,8 @@ // AppListFolderController: void ShowFolderForItemView(AppListItemView* folder_item_view, - bool focus_name_input) override; + bool focus_name_input, + base::OnceClosure hide_callback) override; void ShowApps(AppListItemView* folder_item_view, bool select_folder) override; void ReparentFolderItemTransit(AppListFolderItem* folder_item) override; void ReparentDragEnded() override;
diff --git a/ash/app_list/views/app_list_folder_controller.h b/ash/app_list/views/app_list_folder_controller.h index e0e90d0..4975c05 100644 --- a/ash/app_list/views/app_list_folder_controller.h +++ b/ash/app_list/views/app_list_folder_controller.h
@@ -5,6 +5,8 @@ #ifndef ASH_APP_LIST_VIEWS_APP_LIST_FOLDER_CONTROLLER_H_ #define ASH_APP_LIST_VIEWS_APP_LIST_FOLDER_CONTROLLER_H_ +#include "base/callback_forward.h" + namespace ash { class AppListFolderItem; @@ -25,8 +27,10 @@ // the associated folder item (`folder_item_view->item()`). // `focus_name_input` indicates whether the folder name textfield should // receive focus by default. + // `hide_callback` is a callback run when the folder view gets hidden. virtual void ShowFolderForItemView(AppListItemView* folder_item_view, - bool focus_name_input) = 0; + bool focus_name_input, + base::OnceClosure hide_callback) = 0; // Shows the root level apps list. Called when the UI navigates back from the // folder for `folder_item_view`. If `folder_item_view` is nullptr skips
diff --git a/ash/app_list/views/app_list_folder_view.cc b/ash/app_list/views/app_list_folder_view.cc index a2abfad..bfd7a0e1 100644 --- a/ash/app_list/views/app_list_folder_view.cc +++ b/ash/app_list/views/app_list_folder_view.cc
@@ -742,7 +742,8 @@ } void AppListFolderView::ConfigureForFolderItemView( - AppListItemView* folder_item_view) { + AppListItemView* folder_item_view, + base::OnceClosure hide_callback) { DCHECK(folder_item_view->is_folder()); DCHECK(folder_item_view->item()); DCHECK(items_grid_view_->app_list_config()); @@ -751,6 +752,7 @@ // cancel any pending hide animations. ResetState(/*restore_folder_item_view_state=*/true); + hide_callback_ = std::move(hide_callback); folder_item_view_ = folder_item_view; folder_item_view_observer_.Observe(folder_item_view); @@ -900,6 +902,10 @@ void AppListFolderView::ResetState(bool restore_folder_item_view_state) { DVLOG(1) << __FUNCTION__; + + if (hide_callback_) + std::move(hide_callback_).Run(); + if (folder_item_) { items_grid_view_->ClearSelectedView(); items_grid_view_->SetItemList(nullptr); @@ -947,10 +953,14 @@ // view's liveness (so it can reset animations if the folder item // view gets deleted). // If the view is hidden for reparent, the state will be cleared - // when the reparent drag ends. + // when the reparent drag ends - close callback still needs to be called so + // the root apps grid knows to update its state. if (!hide_for_reparent) { ResetState( /*reset_folder_item_view_state=*/true); + } else { + if (hide_callback_) + std::move(hide_callback_).Run(); } if (animation_done_test_callback_) @@ -1065,6 +1075,10 @@ bool AppListFolderView::IsDragPointOutsideOfFolder( const gfx::Point& drag_point) { + // Wait for the folder bound to stabilize before starting reparent drag. + if (IsAnimationRunning()) + return false; + gfx::Point drag_point_in_folder = drag_point; views::View::ConvertPointToTarget(items_grid_view_, this, &drag_point_in_folder); @@ -1083,6 +1097,7 @@ // drag_view_ in hidden grid view will dispatch the drag and drop event to // the top level grid view, until the drag ends. void AppListFolderView::ReparentItem( + AppsGridView::Pointer pointer, AppListItemView* original_drag_view, const gfx::Point& drag_point_in_folder_grid) { // Convert the drag point relative to the root level AppsGridView. @@ -1093,7 +1108,7 @@ // the drag folder_item_->NotifyOfDraggedItem(original_drag_view->item()); root_apps_grid_view_->InitiateDragFromReparentItemInRootLevelGridView( - original_drag_view, to_root_level_grid, + pointer, original_drag_view, to_root_level_grid, base::BindOnce(&AppListFolderView::CancelReparentDragFromRootGrid, weak_ptr_factory_.GetWeakPtr())); folder_controller_->ReparentFolderItemTransit(folder_item_); @@ -1176,6 +1191,15 @@ void AppListFolderView::HandleKeyboardReparent(AppListItemView* reparented_view, ui::KeyboardCode key_code) { folder_controller_->ReparentFolderItemTransit(folder_item_); + + // Notify the root apps grid that folder is closing before handling keyboard + // reparent, to match general flow during drag reparent (where close callback + // gets called before reparenting the dragged view). This ensures that items + // are in their ideal locations when the item gets reparented (i.e. that the + // folder item's slot is not locked to the folder item's initial location). + if (hide_callback_) + std::move(hide_callback_).Run(); + root_apps_grid_view_->HandleKeyboardReparent(reparented_view, folder_item_view_, key_code); folder_controller_->ReparentDragEnded();
diff --git a/ash/app_list/views/app_list_folder_view.h b/ash/app_list/views/app_list_folder_view.h index e36a4e5..5261de2 100644 --- a/ash/app_list/views/app_list_folder_view.h +++ b/ash/app_list/views/app_list_folder_view.h
@@ -85,8 +85,10 @@ // Configures AppListFolderView to show the contents for the folder item // associated with `folder_item_view`. The folder view will be anchored at - // `folder_item_view`. - void ConfigureForFolderItemView(AppListItemView* folder_item_view); + // `folder_item_view`. `hide_callback` gets called when the folder gets + // hidden (after all hide animations complete). + void ConfigureForFolderItemView(AppListItemView* folder_item_view, + base::OnceClosure hide_callback); // Schedules an animation to show or hide the view. // If |show| is false, the view should be set to invisible after the @@ -177,7 +179,8 @@ void SetItemName(AppListFolderItem* item, const std::string& name) override; // Overridden from AppsGridViewFolderDelegate: - void ReparentItem(AppListItemView* original_drag_view, + void ReparentItem(AppsGridView::Pointer pointer, + AppListItemView* original_drag_view, const gfx::Point& drag_point_in_folder_grid) override; void DispatchDragEventForReparent( AppsGridView::Pointer pointer, @@ -278,6 +281,10 @@ // Whether the folder view is currently shown, or showing. bool shown_ = false; + // If set, the callback that will be called when the folder hides (after hide + // animations complete). + base::OnceClosure hide_callback_; + // The folder item in the root apps grid associated with this folder. AppListItemView* folder_item_view_ = nullptr;
diff --git a/ash/app_list/views/apps_container_view.cc b/ash/app_list/views/apps_container_view.cc index 1414f01..62b6634 100644 --- a/ash/app_list/views/apps_container_view.cc +++ b/ash/app_list/views/apps_container_view.cc
@@ -414,7 +414,8 @@ } void AppsContainerView::ShowFolderForItemView(AppListItemView* folder_item_view, - bool focus_name_input) { + bool focus_name_input, + base::OnceClosure hide_callback) { // Prevent new animations from starting if there are currently animations // pending. This fixes crbug.com/357099. if (app_list_folder_view_->IsAnimationRunning()) @@ -425,7 +426,8 @@ UMA_HISTOGRAM_ENUMERATION("Apps.AppListFolderOpened", kFullscreenAppListFolders, kMaxFolderOpened); - app_list_folder_view_->ConfigureForFolderItemView(folder_item_view); + app_list_folder_view_->ConfigureForFolderItemView(folder_item_view, + std::move(hide_callback)); SetShowState(SHOW_ACTIVE_FOLDER, false); // If there is no selected view in the root grid when a folder is opened,
diff --git a/ash/app_list/views/apps_container_view.h b/ash/app_list/views/apps_container_view.h index d20228ff..3f416cad 100644 --- a/ash/app_list/views/apps_container_view.h +++ b/ash/app_list/views/apps_container_view.h
@@ -146,7 +146,8 @@ // AppListFolderController: void ShowFolderForItemView(AppListItemView* folder_item_view, - bool focus_name_input) override; + bool focus_name_input, + base::OnceClosure hide_callback) override; void ShowApps(AppListItemView* folder_item_view, bool select_folder) override; void ReparentFolderItemTransit(AppListFolderItem* folder_item) override; void ReparentDragEnded() override;
diff --git a/ash/app_list/views/apps_grid_view.cc b/ash/app_list/views/apps_grid_view.cc index 3663bf3..58bc456 100644 --- a/ash/app_list/views/apps_grid_view.cc +++ b/ash/app_list/views/apps_grid_view.cc
@@ -178,6 +178,10 @@ } // namespace +bool GridIndex::IsValid() const { + return page >= 0 && slot >= 0; +} + std::string GridIndex::ToString() const { std::stringstream ss; ss << "Page: " << page << ", Slot: " << slot; @@ -597,6 +601,16 @@ if (!drag_item_) return; // Drag canceled. + // If folder is currently open from the grid, delay drag updates until the + // folder finishes closing. + if (open_folder_info_) { + // Only handle pointers that initiated the drag - e.g. ignore drag events + // that come from touch if a mouse drag is currently in progress. + if (drag_pointer_ == pointer) + last_drag_point_ = point; + return; + } + gfx::Vector2d drag_vector(point - drag_start_grid_view_); if (ExceededDragThreshold(drag_vector)) { @@ -717,11 +731,17 @@ if (MoveItemToFolder(drag_item_, drop_target_, kMoveByDragIntoFolder, &target_folder_id, &is_new_folder)) { MaybeCreateFolderDroppingAccessibilityEvent(); - // If move to folder created a folder, layout the grid to ensure the - // created folder's bounds are correct. - Layout(); - if (is_new_folder && features::IsProductivityLauncherEnabled()) + if (is_new_folder && features::IsProductivityLauncherEnabled()) { folder_to_open_after_drag_icon_animation_ = target_folder_id; + SetOpenFolderInfo(target_folder_id, drop_target_, + reorder_placeholder_); + } + + // If item drag created a folder, layout the grid to ensure the + // created folder's bounds are correct. Note that `open_folder_info_` + // affects ideal item bounds, so `Layout()` needs to be callsed after + // `SetOpenFolderInfo()`. + Layout(); } } else if (IsValidReorderTargetIndex(drop_target_)) { // Ensure reorder event has already been announced by the end of drag. @@ -796,6 +816,7 @@ } void AppsGridView::InitiateDragFromReparentItemInRootLevelGridView( + Pointer pointer, AppListItemView* original_drag_view, const gfx::Point& drag_point, base::OnceClosure cancellation_callback) { @@ -810,13 +831,12 @@ for (const auto& entry : view_model_.entries()) static_cast<AppListItemView*>(entry.view)->EnsureLayer(); + drag_pointer_ = pointer; drag_item_ = original_drag_view->item(); drag_start_grid_view_ = drag_point; // Set the flag in root level grid view. dragging_for_reparent_item_ = true; reparent_drag_cancellation_ = std::move(cancellation_callback); - - MaybeStartCardifiedView(); } void AppsGridView::UpdateDragFromReparentItem(Pointer pointer, @@ -830,6 +850,53 @@ UpdateDrag(pointer, drag_point); } +void AppsGridView::SetOpenFolderInfo(const std::string& folder_id, + const GridIndex& target_folder_position, + const GridIndex& position_to_skip) { + GridIndex expected_folder_position = target_folder_position; + // If the target view is positioned after `position_to_skip`, move the + // target one slot earlier, as `position_to_skip` is assumed about to be + // emptied. + if (position_to_skip.IsValid() && + position_to_skip < expected_folder_position && + expected_folder_position.slot > 0) { + --expected_folder_position.slot; + } + + open_folder_info_ = {.item_id = folder_id, + .grid_index = expected_folder_position}; +} + +void AppsGridView::ShowFolderForView(AppListItemView* folder_view, + bool new_folder) { + DCHECK(open_folder_info_); + + // Guard against invalid folder view. + if (!folder_view || !folder_view->is_folder()) { + open_folder_info_.reset(); + return; + } + + folder_controller_->ShowFolderForItemView( + folder_view, + /*focus_name_input=*/new_folder, + base::BindOnce(&AppsGridView::FolderHidden, weak_factory_.GetWeakPtr(), + folder_view->item()->id())); +} + +void AppsGridView::FolderHidden(const std::string& item_id) { + if (open_folder_info_ && open_folder_info_->item_id == item_id) { + open_folder_info_.reset(); + AnimateToIdealBounds(); + // Drag updates get throttled while folder is closing during reparent drag - + // handle cached drag update if reparent drag is in progress. + if (IsDraggingForReparentInRootLevelGridView()) { + MaybeStartCardifiedView(); + UpdateDrag(drag_pointer_, last_drag_point_); + } + } +} + bool AppsGridView::IsDragging() const { return drag_pointer_ != NONE; } @@ -1110,36 +1177,58 @@ } } +void AppsGridView::SetIdealBoundsForViewToGridIndex( + int view_index_in_model, + const GridIndex& view_grid_index) { + gfx::Rect tile_bounds = GetExpectedTileBounds(view_grid_index); + tile_bounds.Offset(CalculateTransitionOffset(view_grid_index.page)); + if (view_index_in_model < view_model_.view_size()) { + view_model_.set_ideal_bounds(view_index_in_model, tile_bounds); + } else { + pulsing_blocks_model_.set_ideal_bounds( + view_index_in_model - view_model_.view_size(), tile_bounds); + } +} + void AppsGridView::CalculateIdealBounds() { if (view_structure_.mode() == PagedViewStructure::Mode::kPartialPages) { CalculateIdealBoundsForPageStructureWithPartialPages(); return; } + AppListItemView* view_with_locked_position = nullptr; + if (open_folder_info_) + view_with_locked_position = GetItemViewForItem(open_folder_info_->item_id); + + std::set<GridIndex> reserved_slots; + reserved_slots.insert(reorder_placeholder_); + if (open_folder_info_) { + reserved_slots.insert(open_folder_info_->grid_index); + } + const int total_views = view_model_.view_size() + pulsing_blocks_model_.view_size(); int slot_index = 0; for (int i = 0; i < total_views; ++i) { - if (i < view_model_.view_size() && view_model_.view_at(i) == drag_view_) + if (i < view_model_.view_size() && view_model_.view_at(i) == drag_view_) { continue; + } + + if (i < view_model_.view_size() && + view_model_.view_at(i) == view_with_locked_position) { + SetIdealBoundsForViewToGridIndex(i, open_folder_info_->grid_index); + continue; + } GridIndex view_index = view_structure_.GetIndexFromModelIndex(slot_index); // Leaves a blank space in the grid for the current reorder placeholder. - if (reorder_placeholder_ == view_index) { + while (reserved_slots.count(view_index)) { ++slot_index; view_index = view_structure_.GetIndexFromModelIndex(slot_index); } - gfx::Rect tile_slot = GetExpectedTileBounds(view_index); - tile_slot.Offset(CalculateTransitionOffset(view_index.page)); - if (i < view_model_.view_size()) { - view_model_.set_ideal_bounds(i, tile_slot); - } else { - pulsing_blocks_model_.set_ideal_bounds(i - view_model_.view_size(), - tile_slot); - } - + SetIdealBoundsForViewToGridIndex(i, view_index); ++slot_index; } } @@ -1446,10 +1535,7 @@ AppListItemView* folder_view = GetItemViewForItem(folder_to_open_after_drag_icon_animation_); folder_to_open_after_drag_icon_animation_.clear(); - if (folder_view && folder_view->is_folder()) { - folder_controller_->ShowFolderForItemView(folder_view, - /*focus_name_input=*/true); - } + ShowFolderForView(folder_view, /*new_folder=*/true); } } @@ -1539,10 +1625,10 @@ CreateGhostImageView(); } -void AppsGridView::OnFolderItemReparentTimer() { +void AppsGridView::OnFolderItemReparentTimer(Pointer pointer) { DCHECK(folder_delegate_); if (drag_out_of_folder_container_ && drag_view_) { - folder_delegate_->ReparentItem(drag_view_, last_drag_point_); + folder_delegate_->ReparentItem(pointer, drag_view_, last_drag_point_); // Set the flag in the folder's grid view. dragging_for_reparent_item_ = true; @@ -1572,8 +1658,9 @@ if (is_item_dragged_out_of_folder) { if (!drag_out_of_folder_container_) { folder_item_reparent_timer_.Start( - FROM_HERE, base::Milliseconds(kFolderItemReparentDelay), this, - &AppsGridView::OnFolderItemReparentTimer); + FROM_HERE, base::Milliseconds(kFolderItemReparentDelay), + base::BindOnce(&AppsGridView::OnFolderItemReparentTimer, + base::Unretained(this), pointer)); drag_out_of_folder_container_ = true; } } else { @@ -1627,6 +1714,7 @@ } void AppsGridView::HandleKeyboardFoldering(ui::KeyboardCode key_code) { + const GridIndex source_index = GetIndexOfView(selected_view_); const GridIndex target_index = GetTargetGridIndexForKeyboardMove(key_code); if (!CanMoveSelectedToTargetForKeyboardFoldering(target_index)) return; @@ -1643,16 +1731,20 @@ kMoveByKeyboardIntoFolder, &folder_id, &is_new_folder)) { a11y_announcer_->AnnounceKeyboardFoldering( moving_view_title, target_view_title, target_view_is_folder); - Layout(); AppListItemView* folder_view = GetItemViewForItem(folder_id); if (folder_view) { if (is_new_folder && features::IsProductivityLauncherEnabled()) { - folder_controller_->ShowFolderForItemView(folder_view, - /*focus_name_input=*/true); + SetOpenFolderInfo(folder_id, target_index, source_index); + ShowFolderForView(folder_view, /*new_folder=*/true); } else { folder_view->RequestFocus(); } } + + // Layout the grid to ensure the created folder's bounds are correct. + // Note that `open_folder_info_` affects ideal item bounds, so `Layout()` + // needs to be callsed after `SetOpenFolderInfo()`. + Layout(); } } @@ -1800,8 +1892,11 @@ // If move to folder created a folder, layout the grid to ensure the // created folder's bounds are correct. Layout(); - if (is_new_folder && features::IsProductivityLauncherEnabled()) + if (is_new_folder && features::IsProductivityLauncherEnabled()) { folder_to_open_after_drag_icon_animation_ = target_folder_id; + SetOpenFolderInfo(target_folder_id, drop_target_, + reorder_placeholder_); + } } else { cancel_reparent = true; } @@ -2295,6 +2390,10 @@ view_structure_.Remove(item_view); if (item_view == drag_view_) drag_view_ = nullptr; + if (open_folder_info_ && + open_folder_info_->item_id == item_view->item()->id()) { + open_folder_info_.reset(); + } delete item_view; } @@ -2803,7 +2902,7 @@ } void AppsGridView::MaybeCreateDragReorderAccessibilityEvent() { - if (drop_target_region_ == ON_ITEM && !IsFolderItem(drag_view_->item())) + if (drop_target_region_ == ON_ITEM && !IsFolderItem(drag_item_)) return; // If app was dragged out of folder, no need to announce location for the @@ -2904,8 +3003,9 @@ // Note that `folder_controller_` will be null inside a folder apps grid, // but those grid are not expected to contain folder items. DCHECK(folder_controller_); - folder_controller_->ShowFolderForItemView(pressed_item_view, - /*focus_name_input=*/false); + SetOpenFolderInfo(pressed_item_view->item()->id(), + GetIndexOfView(pressed_item_view), GridIndex()); + ShowFolderForView(pressed_item_view, /*new_folder=*/false); return; }
diff --git a/ash/app_list/views/apps_grid_view.h b/ash/app_list/views/apps_grid_view.h index 88988284..96287e5 100644 --- a/ash/app_list/views/apps_grid_view.h +++ b/ash/app_list/views/apps_grid_view.h
@@ -75,6 +75,12 @@ bool operator<(const GridIndex& other) const { return std::tie(page, slot) < std::tie(other.page, other.slot); } + + // Whether the grid index is a valid index, i.e. whether page and slot are + // non-negative. This method does *not* check whether the index exists in an + // apps grid. + bool IsValid() const; + std::string ToString() const; int page = -1; // Which page an item view is on. @@ -222,20 +228,24 @@ // Called to initiate drag for reparenting a folder item in root level grid // view. + // `pointer` - The pointer that's used for dragging (mouse or touch). // `drag_point` is in the coordinates of root level grid view. // `cancellation_callback` - the callback that can be invoked from the root // level grid to cancel drag operation in the originating folder grid. void InitiateDragFromReparentItemInRootLevelGridView( + Pointer pointer, AppListItemView* original_drag_view, const gfx::Point& drag_point, base::OnceClosure cancellation_callback); // Updates drag in the root level grid view when receiving the drag event // dispatched from the hidden grid view for reparenting a folder item. + // `pointer` - The pointer that's used for dragging (mouse or touch). void UpdateDragFromReparentItem(Pointer pointer, const gfx::Point& drag_point); // Dispatches the drag event from hidden grid view to the top level grid view. + // `pointer` - The pointer that's used for dragging (mouse or touch). void DispatchDragEventForReparent(Pointer pointer, const gfx::Point& drag_point); @@ -468,6 +478,12 @@ // the grid, so number of actual columns may be smaller than `max_columns`. void SetMaxColumnsInternal(int max_columns); + // Sets the ideal bounds for view at index `view_inde_in_model` in + // `view_model_`. The bounds are set to match the expected tile bounds at + // `view_grid_index` in the apps grid. + void SetIdealBoundsForViewToGridIndex(int view_index_in_model, + const GridIndex& view_grid_index); + // Calculates the item views' bounds for both folder and non-folder. void CalculateIdealBounds(); void CalculateIdealBoundsForPageStructureWithPartialPages(); @@ -650,6 +666,7 @@ // Called when the user is dragging an app. |point| is in grid view // coordinates. + // `pointer` - The pointer that's used for dragging (mouse or touch). void UpdateDrag(Pointer pointer, const gfx::Point& point); // Returns true if the current drag is occurring within a certain range of the @@ -762,9 +779,10 @@ void OnReorderTimer(); // Invoked when |folder_item_reparent_timer_| fires. - void OnFolderItemReparentTimer(); + void OnFolderItemReparentTimer(Pointer pointer); // Updates drag state for dragging inside a folder's grid view. + // `pointer` - The pointer that's used for dragging (mouse or touch). void UpdateDragStateInsideFolder(Pointer pointer, const gfx::Point& drag_point); @@ -866,6 +884,28 @@ bool aborted, AppListReorderAnimationStatus animation_source); + // Sets `open_folder_info_` for a folder that is about to be shown. + // `folder_id` is the folder's item ID, `target_folder_position` is the grid + // index at which the folder is located (or being created). + // `position_to_skip`, if valid, is the grid index of an app list item that is + // expected to be removed (for example, the reorder placeholder gets removed + // after an app list item drag ends, and should thus be ignored when + // calculating the final folder position during drag end). The target folder + // position should be adjusted as if the item at this position is gone. + void SetOpenFolderInfo(const std::string& folder_id, + const GridIndex& target_folder_position, + const GridIndex& position_to_skip); + + // Requsets a folder view for the provided app list folder item to be shown. + // `new_folder` indicates whether the folder is a newly created folder. + void ShowFolderForView(AppListItemView* folder_view, bool new_folder); + + // Called when a folder view that was opened from this apps grid hides (and + // completes hide animation), either when user closes the folder, or when the + // folder gets hidden during reparent drag. + // `item_id` is the folder items app list model ID. + void FolderHidden(const std::string& item_id); + class ScopedModelUpdate; AppListModel* model_ = nullptr; // Owned by AppListView. @@ -999,6 +1039,18 @@ // The location when |current_ghost_view_| was shown. GridIndex current_ghost_location_; + struct OpenFolderInfo { + std::string item_id; + GridIndex grid_index; + }; + // Set when a folder view was opened from the apps grid - it contains the + // opened folder ID and original location in the grid. While the folder + // remains open, the folder item view position will be forced to the original + // grid slot, to prevent folder UI from jumping, or empty slots from appearing + // behind a folder when the gird item list changes (e.g. if another item gets + // added by sync, or the folder item moves as a result of folder rename). + absl::optional<OpenFolderInfo> open_folder_info_; + std::unique_ptr<AppsGridContextMenu> context_menu_; // Indicates the current reorder animation.
diff --git a/ash/app_list/views/apps_grid_view_folder_delegate.h b/ash/app_list/views/apps_grid_view_folder_delegate.h index 1fc2251..1c8e686a 100644 --- a/ash/app_list/views/apps_grid_view_folder_delegate.h +++ b/ash/app_list/views/apps_grid_view_folder_delegate.h
@@ -23,10 +23,12 @@ class ASH_EXPORT AppsGridViewFolderDelegate { public: // Called when a folder item is dragged out of the folder to be re-parented. - // |original_drag_view| is the |drag_view_| inside the folder's grid view. - // |drag_point_in_folder_grid| is the last drag point in coordinate of the - // AppsGridView inside the folder. - virtual void ReparentItem(AppListItemView* original_drag_view, + // `original_drag_view` is the `drag_view_` inside the folder's grid view. + // `drag_point_in_folder_grid` is the last drag point in coordinate of the + // AppsGridView inside the folder. `pointer` describes the type of pointer + // used for the drag action (mouse or touch). + virtual void ReparentItem(AppsGridView::Pointer pointer, + AppListItemView* original_drag_view, const gfx::Point& drag_point_in_folder_grid) = 0; // Dispatches drag event from the hidden grid view to the root level grid view
diff --git a/ash/app_list/views/apps_grid_view_unittest.cc b/ash/app_list/views/apps_grid_view_unittest.cc index 6e83664..e9caf56 100644 --- a/ash/app_list/views/apps_grid_view_unittest.cc +++ b/ash/app_list/views/apps_grid_view_unittest.cc
@@ -2827,6 +2827,7 @@ AppListItemView* first_item = GetItemViewInTopLevelGrid(0); const std::string first_item_id = first_item->item()->id(); const std::string second_item_id = GetItemViewInTopLevelGrid(1)->item()->id(); + const gfx::Rect expected_folder_view_bounds = first_item->GetBoundsInScreen(); ui::test::EventGenerator* const event_generator = GetEventGenerator(); // Press an arrow key to engage keyboard traversal in fullscreen launcher. @@ -2840,6 +2841,7 @@ // Test that the first item in the grid is now a folder with the first and // second items. AppListItemView* new_folder = GetItemViewInTopLevelGrid(0); + EXPECT_EQ(expected_folder_view_bounds, new_folder->GetBoundsInScreen()); AppListFolderItem* folder_item = static_cast<AppListFolderItem*>(new_folder->item()); EXPECT_TRUE(folder_item->is_folder()); @@ -2865,6 +2867,7 @@ event_generator->PressAndReleaseKey(ui::VKEY_UP); event_generator->PressAndReleaseKey(ui::VKEY_ESCAPE); EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView()); + EXPECT_EQ(expected_folder_view_bounds, new_folder->GetBoundsInScreen()); } ASSERT_TRUE(new_folder->HasFocus()); ASSERT_TRUE(apps_grid_view_->IsSelectedView(new_folder)); @@ -2920,6 +2923,64 @@ kMoveByKeyboardIntoFolder, 4); } +// Tests that control + shift + left arrow puts |selected_item_| creates a +// folder if one does not exist. +TEST_P(AppsGridViewClamshellAndTabletTest, + ControlShiftLeftArrowFoldersItemBasic) { + base::HistogramTester histogram_tester; + model_->PopulateApps(3 * apps_grid_view_->cols()); + UpdateLayout(); + // Select the first item in the grid, folder it with the item to the right. + AppListItemView* first_item = GetItemViewInTopLevelGrid(0); + const std::string first_item_id = first_item->item()->id(); + AppListItemView* second_item = GetItemViewInTopLevelGrid(1); + const std::string second_item_id = second_item->item()->id(); + gfx::Rect expected_folder_view_bounds = first_item->GetBoundsInScreen(); + + ui::test::EventGenerator* const event_generator = GetEventGenerator(); + // Press an arrow key to engage keyboard traversal in fullscreen launcher. + event_generator->PressAndReleaseKey(ui::VKEY_DOWN); + + // Focus second item, and folder it. + apps_grid_view_->GetFocusManager()->SetFocusedView(second_item); + event_generator->PressAndReleaseKey(ui::VKEY_LEFT, + ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN); + + // Test that the first item in the grid is now a folder with the first and + // second items. + AppListItemView* new_folder = GetItemViewInTopLevelGrid(0); + EXPECT_EQ(expected_folder_view_bounds, new_folder->GetBoundsInScreen()); + AppListFolderItem* folder_item = + static_cast<AppListFolderItem*>(new_folder->item()); + EXPECT_TRUE(folder_item->is_folder()); + EXPECT_EQ(2u, folder_item->ChildItemCount()); + EXPECT_TRUE(folder_item->FindChildItem(first_item_id)); + EXPECT_TRUE(folder_item->FindChildItem(second_item_id)); + histogram_tester.ExpectBucketCount(GetItemMoveTypeHistogramName(), + kMoveByKeyboardIntoFolder, 1); + + // With productivity launcher enabled, the folder is expected to get opened + // after creation. + EXPECT_EQ(!is_productivity_launcher_enabled_, + apps_grid_view_->IsSelectedView(new_folder)); + EXPECT_EQ(is_productivity_launcher_enabled_, + GetAppListTestHelper()->IsInFolderView()); + if (is_productivity_launcher_enabled_) { + EXPECT_EQ(folder_item, app_list_folder_view_->folder_item()); + EXPECT_TRUE(app_list_folder_view_->folder_header_view() + ->GetFolderNameViewForTest() + ->HasFocus()); + + // Close the folder. + event_generator->PressAndReleaseKey(ui::VKEY_UP); + event_generator->PressAndReleaseKey(ui::VKEY_ESCAPE); + EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView()); + EXPECT_EQ(expected_folder_view_bounds, new_folder->GetBoundsInScreen()); + } + ASSERT_TRUE(new_folder->HasFocus()); + ASSERT_TRUE(apps_grid_view_->IsSelectedView(new_folder)); +} + // Tests that foldering an item that is on a different page fails. TEST_P(AppsGridViewTabletTest, ControlShiftArrowFailsToFolderAcrossPages) { model_->PopulateApps(GetTilesPerPage(0) + GetTilesPerPage(1)); @@ -3004,11 +3065,14 @@ folder_view->RequestFocus(); EXPECT_TRUE(apps_grid_view_->GetWidget()->GetWindowBoundsInScreen().Contains( folder_view->GetBoundsInScreen())); + const gfx::Rect original_folder_view_bounds = + folder_view->GetBoundsInScreen(); // Open the folder. ui::test::EventGenerator* const event_generator = GetEventGenerator(); event_generator->PressAndReleaseKey(ui::VKEY_RETURN); ASSERT_TRUE(GetAppListTestHelper()->IsInFolderView()); + EXPECT_EQ(original_folder_view_bounds, folder_view->GetBoundsInScreen()); const AppListItemView* reparented_item_view = folder_apps_grid_view()->view_model()->view_at(0); @@ -3069,11 +3133,14 @@ folder_view->RequestFocus(); EXPECT_TRUE(apps_grid_view_->GetWidget()->GetWindowBoundsInScreen().Contains( folder_view->GetBoundsInScreen())); + const gfx::Rect original_folder_view_bounds = + folder_view->GetBoundsInScreen(); // Open the folder. ui::test::EventGenerator* const event_generator = GetEventGenerator(); event_generator->PressAndReleaseKey(ui::VKEY_RETURN); ASSERT_TRUE(GetAppListTestHelper()->IsInFolderView()); + EXPECT_EQ(original_folder_view_bounds, folder_view->GetBoundsInScreen()); const AppListItemView* reparented_item_view = folder_apps_grid_view()->view_model()->view_at(0); @@ -3123,11 +3190,14 @@ test_api_->GetViewAtIndex(GridIndex(0, GetTilesPerPage(0) - 2)); ASSERT_TRUE(folder_view->is_folder()); folder_view->RequestFocus(); + const gfx::Rect original_folder_view_bounds = + folder_view->GetBoundsInScreen(); // Open the folder. ui::test::EventGenerator* const event_generator = GetEventGenerator(); event_generator->PressAndReleaseKey(ui::VKEY_RETURN); ASSERT_TRUE(GetAppListTestHelper()->IsInFolderView()); + EXPECT_EQ(original_folder_view_bounds, folder_view->GetBoundsInScreen()); const AppListItemView* reparented_item_view = folder_apps_grid_view()->view_model()->view_at(0); @@ -3171,6 +3241,8 @@ const std::string first_item_id = moving_item->item()->id(); const std::string second_item_id = GetItemViewInTopLevelGrid(kNumberOfApps - 1)->item()->id(); + const gfx::Rect expected_folder_view_bounds = + moving_item->GetBoundsInScreen(); ui::test::EventGenerator* const event_generator = GetEventGenerator(); // Press an arrow key to engage keyboard traversal in fullscreen launcher. @@ -3183,6 +3255,7 @@ // Test that the first item in the grid is now a folder with the first and // second items, and that the folder is the selected view. AppListItemView* new_folder = GetItemViewInTopLevelGrid(kNumberOfApps - 2); + EXPECT_EQ(expected_folder_view_bounds, new_folder->GetBoundsInScreen()); AppListFolderItem* folder_item = static_cast<AppListFolderItem*>(new_folder->item()); EXPECT_TRUE(folder_item->is_folder());
diff --git a/ash/components/arc/test/fake_file_system_instance.cc b/ash/components/arc/test/fake_file_system_instance.cc index c840342f..7ea647ca 100644 --- a/ash/components/arc/test/fake_file_system_instance.cc +++ b/ash/components/arc/test/fake_file_system_instance.cc
@@ -50,7 +50,7 @@ return root; } -// Generates unique document ID on each calls. +// Generates unique document ID on each call. std::string GenerateDocumentId() { static int count = 0; std::ostringstream ss; @@ -58,12 +58,17 @@ return ss.str(); } +// Generates unique URL ID on each call. +std::string GenerateUrlId() { + static int count = 0; + std::ostringstream ss; + ss << "url_" << count++; + return ss.str(); +} + // Maximum size in bytes to read FD from PIPE. constexpr size_t kMaxBytesToReadFromPipe = 8 * 1024; // 8KB; -// URL ID used by OpenFileSessionToWrite() and OpenFileSessionToRead(). -constexpr char kUrlId[] = "url_id"; - } // namespace constexpr base::FilePath::CharType FakeFileSystemInstance::kFakeAndroidPath[]; @@ -444,12 +449,13 @@ base::File::Flags::FLAG_WRITE) : CreateStreamFileDescriptorToWrite(file.url); DCHECK(fd.is_valid()); - AddOpenSession(kUrlId, fd.get()); + std::string url_id = GenerateUrlId(); + AddOpenSession(url_id, fd.get()); mojo::ScopedHandle wrapped_handle = mojo::WrapPlatformHandle(mojo::PlatformHandle(std::move(fd))); DCHECK(wrapped_handle.is_valid()); mojom::FileSessionPtr file_session = mojom::FileSession::New(); - file_session->url_id = kUrlId; + file_session->url_id = std::move(url_id); file_session->fd = std::move(wrapped_handle); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), std::move(file_session))); @@ -473,12 +479,13 @@ base::File::Flags::FLAG_READ) : CreateStreamFileDescriptorToRead(file.content); DCHECK(fd.is_valid()); - AddOpenSession(kUrlId, fd.get()); + std::string url_id = GenerateUrlId(); + AddOpenSession(url_id, fd.get()); mojo::ScopedHandle wrapped_handle = mojo::WrapPlatformHandle(mojo::PlatformHandle(std::move(fd))); DCHECK(wrapped_handle.is_valid()); mojom::FileSessionPtr file_session = mojom::FileSession::New(); - file_session->url_id = kUrlId; + file_session->url_id = std::move(url_id); file_session->fd = std::move(wrapped_handle); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), std::move(file_session)));
diff --git a/ash/components/device_activity/BUILD.gn b/ash/components/device_activity/BUILD.gn index d1a3502a..389c253 100644 --- a/ash/components/device_activity/BUILD.gn +++ b/ash/components/device_activity/BUILD.gn
@@ -60,6 +60,7 @@ deps = [ ":device_activity", ":fresnel_service_proto", + "//ash/constants:constants", "//base", "//base/test:test_support", "//chromeos/network",
diff --git a/ash/components/device_activity/device_activity_client.cc b/ash/components/device_activity/device_activity_client.cc index 8fbdf86d..831c539 100644 --- a/ash/components/device_activity/device_activity_client.cc +++ b/ash/components/device_activity/device_activity_client.cc
@@ -328,15 +328,20 @@ } case psm_rlwe::RlweUseCase::CROS_FRESNEL_MONTHLY: if (base::FeatureList::IsEnabled( - features::kDeviceActiveClientMonthlyCheckMembership)) { - TransitionToCheckMembershipOprf(current_use_case); - return; - } else { + features::kDeviceActiveClientMonthlyCheckIn)) { // During rollout, we perform CheckIn without CheckMembership for // powerwash, recovery, or RMA devices. TransitionToCheckIn(current_use_case); return; } + + if (base::FeatureList::IsEnabled( + features::kDeviceActiveClientMonthlyCheckMembership)) { + TransitionToCheckMembershipOprf(current_use_case); + return; + } + + break; default: VLOG(1) << "Use case is not supported yet. " << psm_rlwe::RlweUseCase_Name(
diff --git a/ash/components/device_activity/device_activity_client_unittest.cc b/ash/components/device_activity/device_activity_client_unittest.cc index 5f6c1674..9914e5f 100644 --- a/ash/components/device_activity/device_activity_client_unittest.cc +++ b/ash/components/device_activity/device_activity_client_unittest.cc
@@ -9,11 +9,13 @@ #include "ash/components/device_activity/fresnel_pref_names.h" #include "ash/components/device_activity/fresnel_service.pb.h" #include "ash/components/device_activity/monthly_use_case_impl.h" +#include "ash/constants/ash_features.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/no_destructor.h" #include "base/path_service.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "base/timer/mock_timer.h" #include "chromeos/network/network_state_handler_observer.h" @@ -236,6 +238,12 @@ // testing::Test: void SetUp() override { + scoped_feature_list_.InitWithFeatures( + /*enabled_features=*/{features::kDeviceActiveClientMonthlyCheckIn}, + /*disabled_features*/ { + features::kDeviceActiveClientDailyCheckMembership, + features::kDeviceActiveClientMonthlyCheckMembership}); + // Initialize pointer to our fake |PsmTestData| object. psm_test_data_ = GetPsmTestData(); @@ -320,6 +328,7 @@ // The underlying |psm_test_data_| object will outlive this testing class. PsmTestData* psm_test_data_ = nullptr; + base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<NetworkStateTestHelper> network_state_test_helper_; TestingPrefServiceSimple local_state_; scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index bc2b563c..43f3753 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -574,8 +574,7 @@ // Enables or disables enterprise policy control for eSIM cellular networks. // See https://crbug.com/1231305. -const base::Feature kESimPolicy{"ESimPolicy", - base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kESimPolicy{"ESimPolicy", base::FEATURE_ENABLED_BY_DEFAULT}; // Enable or disable support for touchpad with haptic feedback. const base::Feature kExoHapticFeedbackSupport("ExoHapticFeedbackSupport", @@ -1429,6 +1428,11 @@ "DeviceActiveClientDailyCheckMembership", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enables or disables PSM CheckIn for the monthly device active pings +// on Chrome OS. +const base::Feature kDeviceActiveClientMonthlyCheckIn{ + "DeviceActiveClientMonthlyCheckIn", base::FEATURE_DISABLED_BY_DEFAULT}; + // Enables or disables PSM CheckMembership for monthly device active pings // on Chrome OS. const base::Feature kDeviceActiveClientMonthlyCheckMembership{
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index 8c27d9e..0790e1b4 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -163,6 +163,8 @@ COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kDeviceActiveClientDailyCheckMembership; COMPONENT_EXPORT(ASH_CONSTANTS) +extern const base::Feature kDeviceActiveClientMonthlyCheckIn; +COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kDeviceActiveClientMonthlyCheckMembership; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kDeviceForceScheduledReboot;
diff --git a/ash/webui/eche_app_ui/eche_app_manager.cc b/ash/webui/eche_app_ui/eche_app_manager.cc index d4307d7..b183c67 100644 --- a/ash/webui/eche_app_ui/eche_app_manager.cc +++ b/ash/webui/eche_app_ui/eche_app_manager.cc
@@ -40,7 +40,8 @@ presence_monitor_client, LaunchAppHelper::LaunchEcheAppFunction launch_eche_app_function, LaunchAppHelper::CloseEcheAppFunction close_eche_app_function, - LaunchAppHelper::LaunchNotificationFunction launch_notification_function) + LaunchAppHelper::LaunchNotificationFunction launch_notification_function, + StreamStatusChangedFunction stream_status_changed_function) : connection_manager_( std::make_unique<secure_channel::ConnectionManagerImpl>( multidevice_setup_client, @@ -65,8 +66,7 @@ std::make_unique<EcheNotificationClickHandler>( phone_hub_manager, feature_status_provider_.get(), - launch_app_helper_.get(), - display_stream_handler_.get())), + launch_app_helper_.get())), eche_connector_( std::make_unique<EcheConnectorImpl>(feature_status_provider_.get(), connection_manager_.get())), @@ -86,8 +86,7 @@ std::make_unique<EcheRecentAppClickHandler>( phone_hub_manager, feature_status_provider_.get(), - launch_app_helper_.get(), - display_stream_handler_.get())), + launch_app_helper_.get())), notification_generator_(std::make_unique<EcheNotificationGenerator>( launch_app_helper_.get())), apps_access_manager_(std::make_unique<AppsAccessManagerImpl>( @@ -95,11 +94,14 @@ message_receiver_.get(), feature_status_provider_.get(), pref_service, - multidevice_setup_client)) { + multidevice_setup_client)), + stream_status_changed_function_( + std::move(stream_status_changed_function)) { ash::GetNetworkConfigService( remote_cros_network_config_.BindNewPipeAndPassReceiver()); system_info_provider_ = std::make_unique<SystemInfoProvider>( std::move(system_info), remote_cros_network_config_.get()); + display_stream_handler_->AddObserver(this); } EcheAppManager::~EcheAppManager() = default; @@ -129,6 +131,15 @@ display_stream_handler_->Bind(std::move(receiver)); } +void EcheAppManager::OnStartStreaming() { + stream_status_changed_function_.Run( + mojom::StreamStatus::kStreamStatusStarted); +} + +void EcheAppManager::OnStreamStatusChanged(mojom::StreamStatus status) { + stream_status_changed_function_.Run(status); +} + AppsAccessManager* EcheAppManager::GetAppsAccessManager() { return apps_access_manager_.get(); } @@ -146,6 +157,7 @@ signaler_.reset(); eche_connector_.reset(); eche_notification_click_handler_.reset(); + display_stream_handler_->RemoveObserver(this); display_stream_handler_.reset(); launch_app_helper_.reset(); feature_status_provider_.reset();
diff --git a/ash/webui/eche_app_ui/eche_app_manager.h b/ash/webui/eche_app_ui/eche_app_manager.h index b84d0da..b767a99 100644 --- a/ash/webui/eche_app_ui/eche_app_manager.h +++ b/ash/webui/eche_app_ui/eche_app_manager.h
@@ -16,6 +16,7 @@ #include "ash/services/secure_channel/public/cpp/client/presence_monitor_client_impl.h" // TODO(https://crbug.com/1164001): move to forward declaration. #include "ash/services/secure_channel/public/cpp/client/secure_channel_client.h" +#include "ash/webui/eche_app_ui/eche_display_stream_handler.h" #include "ash/webui/eche_app_ui/eche_feature_status_provider.h" #include "ash/webui/eche_app_ui/eche_notification_click_handler.h" #include "ash/webui/eche_app_ui/eche_recent_app_click_handler.h" @@ -49,8 +50,14 @@ // Implements the core logic of the EcheApp and exposes interfaces via its // public API. Implemented as a KeyedService since it depends on other // KeyedService instances. -class EcheAppManager : public KeyedService { +class EcheAppManager : public KeyedService, + public EcheDisplayStreamHandler::Observer { public: + using StreamStatusChangedFunction = + base::RepeatingCallback<void(const mojom::StreamStatus status)>; + + // TODO(b/223321926): clean up callback functions from constructor to a + // specific class EcheAppManager(PrefService* pref_service, std::unique_ptr<SystemInfo> system_info, phonehub::PhoneHubManager*, @@ -61,7 +68,8 @@ presence_monitor_client, LaunchAppHelper::LaunchEcheAppFunction, LaunchAppHelper::CloseEcheAppFunction, - LaunchAppHelper::LaunchNotificationFunction); + LaunchAppHelper::LaunchNotificationFunction, + StreamStatusChangedFunction); ~EcheAppManager() override; EcheAppManager(const EcheAppManager&) = delete; @@ -87,6 +95,10 @@ // KeyedService: void Shutdown() override; + // EcheDisplayStreamHandler::Observer: + void OnStartStreaming() override; + void OnStreamStatusChanged(mojom::StreamStatus status) override; + private: std::unique_ptr<secure_channel::ConnectionManager> connection_manager_; std::unique_ptr<EcheFeatureStatusProvider> feature_status_provider_; @@ -105,6 +117,7 @@ remote_cros_network_config_; std::unique_ptr<SystemInfoProvider> system_info_provider_; std::unique_ptr<AppsAccessManager> apps_access_manager_; + StreamStatusChangedFunction stream_status_changed_function_; }; } // namespace eche_app
diff --git a/ash/webui/eche_app_ui/eche_app_manager_unittest.cc b/ash/webui/eche_app_ui/eche_app_manager_unittest.cc index 90944bff..7525f8c 100644 --- a/ash/webui/eche_app_ui/eche_app_manager_unittest.cc +++ b/ash/webui/eche_app_ui/eche_app_manager_unittest.cc
@@ -46,6 +46,8 @@ const absl::optional<std::u16string>& message, std::unique_ptr<LaunchAppHelper::NotificationInfo> info) {} +void StreamStatusChangedFunction(const mojom::StreamStatus status) {} + class FakePresenceMonitorClient : public secure_channel::PresenceMonitorClient { public: FakePresenceMonitorClient() = default; @@ -117,7 +119,8 @@ std::move(fake_presence_monitor_client), base::BindRepeating(&LaunchEcheAppFunction), base::BindRepeating(&CloseEcheAppFunction), - base::BindRepeating(&LaunchNotificationFunction)); + base::BindRepeating(&LaunchNotificationFunction), + base::BindRepeating(&StreamStatusChangedFunction)); } mojo::Remote<mojom::SignalingMessageExchanger>&
diff --git a/ash/webui/eche_app_ui/eche_display_stream_handler.cc b/ash/webui/eche_app_ui/eche_display_stream_handler.cc index d1b9f86a9..7d2f1ee 100644 --- a/ash/webui/eche_app_ui/eche_display_stream_handler.cc +++ b/ash/webui/eche_app_ui/eche_display_stream_handler.cc
@@ -19,6 +19,13 @@ NotifyStartStreaming(); } +void EcheDisplayStreamHandler::OnStreamStatusChanged( + mojom::StreamStatus status) { + PA_LOG(INFO) << "echeapi EcheDisplayStreamHandler OnStreamStatusChanged " + << status; + NotifyStreamStatusChanged(status); +} + void EcheDisplayStreamHandler::Bind( mojo::PendingReceiver<mojom::DisplayStreamHandler> receiver) { display_stream_receiver_.reset(); @@ -38,5 +45,11 @@ observer.OnStartStreaming(); } +void EcheDisplayStreamHandler::NotifyStreamStatusChanged( + mojom::StreamStatus status) { + for (auto& observer : observer_list_) + observer.OnStreamStatusChanged(status); +} + } // namespace eche_app } // namespace ash
diff --git a/ash/webui/eche_app_ui/eche_display_stream_handler.h b/ash/webui/eche_app_ui/eche_display_stream_handler.h index 339b1b2..0696119 100644 --- a/ash/webui/eche_app_ui/eche_display_stream_handler.h +++ b/ash/webui/eche_app_ui/eche_display_stream_handler.h
@@ -25,11 +25,8 @@ public: ~Observer() override = default; - // Called when the streaming is ready. About another status: - // OnStopStreaming, we prefer to listen to the stop signal when the bubble - // is really closed. - // TODO(paulzchen): Using generic method `OnStreamStatusChanged`. virtual void OnStartStreaming() = 0; + virtual void OnStreamStatusChanged(mojom::StreamStatus status) = 0; }; EcheDisplayStreamHandler(); @@ -40,6 +37,7 @@ // mojom::DisplayStreamHandler: void StartStreaming() override; + void OnStreamStatusChanged(mojom::StreamStatus status) override; void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); @@ -48,6 +46,7 @@ protected: void NotifyStartStreaming(); + void NotifyStreamStatusChanged(mojom::StreamStatus status); private: mojo::Receiver<mojom::DisplayStreamHandler> display_stream_receiver_{this};
diff --git a/ash/webui/eche_app_ui/eche_display_stream_handler_unittest.cc b/ash/webui/eche_app_ui/eche_display_stream_handler_unittest.cc index fec38a0..4db83d6 100644 --- a/ash/webui/eche_app_ui/eche_display_stream_handler_unittest.cc +++ b/ash/webui/eche_app_ui/eche_display_stream_handler_unittest.cc
@@ -15,13 +15,23 @@ FakeObserver() = default; ~FakeObserver() override = default; - size_t num_calls() const { return num_calls_; } + size_t num_start_streaming_calls() const { + return num_start_streaming_calls_; + } + mojom::StreamStatus last_notified_stream_status() const { + return last_notified_stream_status_; + } // EcheDisplayStreamHandler::Observer: - void OnStartStreaming() override { ++num_calls_; } + void OnStartStreaming() override { ++num_start_streaming_calls_; } + void OnStreamStatusChanged(mojom::StreamStatus status) override { + last_notified_stream_status_ = status; + } private: - size_t num_calls_ = 0; + size_t num_start_streaming_calls_ = 0; + mojom::StreamStatus last_notified_stream_status_ = + mojom::StreamStatus::kStreamStatusUnknown; }; } // namespace @@ -46,8 +56,16 @@ } void StartStreaming() { handler_->StartStreaming(); } + void NotifyStreamStatus(mojom::StreamStatus status) { + handler_->OnStreamStatusChanged(status); + } - size_t GetNumObserverCalls() const { return fake_observer_.num_calls(); } + size_t GetNumObserverStartStreamingCalls() const { + return fake_observer_.num_start_streaming_calls(); + } + mojom::StreamStatus GetObservedStreamStatus() const { + return fake_observer_.last_notified_stream_status(); + } private: FakeObserver fake_observer_; @@ -56,8 +74,22 @@ TEST_F(EcheDisplayStreamHandlerTest, StartStreaming) { StartStreaming(); - EXPECT_EQ(1u, GetNumObserverCalls()); + EXPECT_EQ(1u, GetNumObserverStartStreamingCalls()); +} + +TEST_F(EcheDisplayStreamHandlerTest, OnStreamStatusChanged) { + NotifyStreamStatus(mojom::StreamStatus::kStreamStatusInitializing); + EXPECT_EQ(mojom::StreamStatus::kStreamStatusInitializing, + GetObservedStreamStatus()); + + NotifyStreamStatus(mojom::StreamStatus::kStreamStatusStarted); + EXPECT_EQ(mojom::StreamStatus::kStreamStatusStarted, + GetObservedStreamStatus()); + + NotifyStreamStatus(mojom::StreamStatus::kStreamStatusStopped); + EXPECT_EQ(mojom::StreamStatus::kStreamStatusStopped, + GetObservedStreamStatus()); } } // namespace eche_app -} // namespace ash \ No newline at end of file +} // namespace ash
diff --git a/ash/webui/eche_app_ui/eche_notification_click_handler.cc b/ash/webui/eche_app_ui/eche_notification_click_handler.cc index 3f6324e..6b58bbe8 100644 --- a/ash/webui/eche_app_ui/eche_notification_click_handler.cc +++ b/ash/webui/eche_app_ui/eche_notification_click_handler.cc
@@ -18,11 +18,9 @@ EcheNotificationClickHandler::EcheNotificationClickHandler( phonehub::PhoneHubManager* phone_hub_manager, FeatureStatusProvider* feature_status_provider, - LaunchAppHelper* launch_app_helper, - EcheDisplayStreamHandler* display_stream_handler) + LaunchAppHelper* launch_app_helper) : feature_status_provider_(feature_status_provider), - launch_app_helper_(launch_app_helper), - display_stream_handler_(display_stream_handler) { + launch_app_helper_(launch_app_helper) { handler_ = phone_hub_manager->GetNotificationInteractionHandler(); feature_status_provider_->AddObserver(this); if (handler_ && IsClickable(feature_status_provider_->GetStatus())) { @@ -32,18 +30,12 @@ PA_LOG(INFO) << "No Phone Hub interaction handler to set Eche click handler"; } - - if (features::IsEcheSWAInBackgroundEnabled()) - display_stream_handler_->AddObserver(this); } EcheNotificationClickHandler::~EcheNotificationClickHandler() { feature_status_provider_->RemoveObserver(this); if (is_click_handler_set_ && handler_) handler_->RemoveNotificationClickHandler(this); - - if (features::IsEcheSWAInBackgroundEnabled()) - display_stream_handler_->RemoveObserver(this); } void EcheNotificationClickHandler::HandleNotificationClick( @@ -58,7 +50,6 @@ notification_id, app_metadata.package_name, app_metadata.visible_app_name, app_metadata.user_id, app_metadata.icon); - is_waiting_for_streaming_to_show_ = true; break; case LaunchAppHelper::AppLaunchProhibitedReason::kDisabledByScreenLock: launch_app_helper_->ShowNotification( @@ -93,30 +84,15 @@ } else if (is_click_handler_set_ && !clickable) { handler_->RemoveNotificationClickHandler(this); is_click_handler_set_ = false; - is_waiting_for_streaming_to_show_ = false; } if (NeedClose(feature_status_provider_->GetStatus()) && !base::FeatureList::IsEnabled(features::kEcheSWADebugMode)) { PA_LOG(INFO) << "Close Eche app window"; - is_waiting_for_streaming_to_show_ = false; launch_app_helper_->CloseEcheApp(); } } -void EcheNotificationClickHandler::OnStartStreaming() { - if (features::IsEcheCustomWidgetEnabled()) { - // TODO(paulzchen): Move the eche tray control to factory. - auto* eche_tray = Shell::GetPrimaryRootWindowController() - ->GetStatusAreaWidget() - ->eche_tray(); - if (eche_tray && is_waiting_for_streaming_to_show_) { - eche_tray->ShowBubble(); - is_waiting_for_streaming_to_show_ = false; - } - } -} - bool EcheNotificationClickHandler::IsClickable(FeatureStatus status) { return status == FeatureStatus::kDisconnected || status == FeatureStatus::kConnecting ||
diff --git a/ash/webui/eche_app_ui/eche_notification_click_handler.h b/ash/webui/eche_app_ui/eche_notification_click_handler.h index c46cc41..5fe0c234 100644 --- a/ash/webui/eche_app_ui/eche_notification_click_handler.h +++ b/ash/webui/eche_app_ui/eche_notification_click_handler.h
@@ -10,7 +10,6 @@ #include "ash/components/phonehub/notification_interaction_handler.h" // TODO(https://crbug.com/1164001): move to forward declaration. #include "ash/components/phonehub/phone_hub_manager.h" -#include "ash/webui/eche_app_ui/eche_display_stream_handler.h" #include "ash/webui/eche_app_ui/feature_status_provider.h" #include "base/callback.h" @@ -21,14 +20,11 @@ // Handles notification clicks originating from Phone Hub notifications. class EcheNotificationClickHandler : public phonehub::NotificationClickHandler, - public FeatureStatusProvider::Observer, - public EcheDisplayStreamHandler::Observer { + public FeatureStatusProvider::Observer { public: - EcheNotificationClickHandler( - phonehub::PhoneHubManager* phone_hub_manager, - FeatureStatusProvider* feature_status_provider, - LaunchAppHelper* launch_app_helper, - EcheDisplayStreamHandler* display_stream_handler); + EcheNotificationClickHandler(phonehub::PhoneHubManager* phone_hub_manager, + FeatureStatusProvider* feature_status_provider, + LaunchAppHelper* launch_app_helper); ~EcheNotificationClickHandler() override; EcheNotificationClickHandler(const EcheNotificationClickHandler&) = delete; @@ -43,14 +39,6 @@ // FeatureStatusProvider::Observer: void OnFeatureStatusChanged() override; - // EcheDisplayStreamHandler::Observer: - void OnStartStreaming() override; - - // Test helpers, we need this to confirm the streaming will work as expected. - bool waiting_for_streaming_to_show() { - return is_waiting_for_streaming_to_show_; - } - private: bool IsClickable(FeatureStatus status); @@ -59,9 +47,7 @@ phonehub::NotificationInteractionHandler* handler_; FeatureStatusProvider* feature_status_provider_; LaunchAppHelper* launch_app_helper_; - EcheDisplayStreamHandler* display_stream_handler_; bool is_click_handler_set_ = false; - bool is_waiting_for_streaming_to_show_ = false; }; } // namespace eche_app
diff --git a/ash/webui/eche_app_ui/eche_notification_click_handler_unittest.cc b/ash/webui/eche_app_ui/eche_notification_click_handler_unittest.cc index 64fb496..04df5a3 100644 --- a/ash/webui/eche_app_ui/eche_notification_click_handler_unittest.cc +++ b/ash/webui/eche_app_ui/eche_notification_click_handler_unittest.cc
@@ -8,12 +8,6 @@ #include "ash/components/phonehub/fake_phone_hub_manager.h" #include "ash/constants/ash_features.h" -#include "ash/system/eche/eche_tray.h" -#include "ash/system/status_area_widget_test_helper.h" -#include "ash/system/tray/tray_bubble_wrapper.h" -#include "ash/test/ash_test_base.h" -#include "ash/test/ash_test_suite.h" -#include "ash/test/test_ash_web_view_factory.h" #include "ash/webui/eche_app_ui/fake_feature_status_provider.h" #include "ash/webui/eche_app_ui/fake_launch_app_helper.h" #include "ash/webui/eche_app_ui/launch_app_helper.h" @@ -27,7 +21,7 @@ namespace ash { namespace eche_app { -class EcheNotificationClickHandlerTest : public AshTestBase { +class EcheNotificationClickHandlerTest : public testing::Test { protected: EcheNotificationClickHandlerTest() = default; EcheNotificationClickHandlerTest(const EcheNotificationClickHandlerTest&) = @@ -36,23 +30,14 @@ const EcheNotificationClickHandlerTest&) = delete; ~EcheNotificationClickHandlerTest() override = default; - // AshTestBase::Test: + // testing::Test: void SetUp() override { - scoped_feature_list_.InitWithFeatures( - /*enabled_features=*/{features::kEcheSWA, features::kEcheCustomWidget}, - /*disabled_features=*/{}); - - DCHECK(test_web_view_factory_.get()); - - ui::ResourceBundle::CleanupSharedInstance(); - AshTestSuite::LoadTestResources(); - AshTestBase::SetUp(); - eche_tray_ = - ash::StatusAreaWidgetTestHelper::GetStatusAreaWidget()->eche_tray(); - fake_phone_hub_manager_.fake_feature_status_provider()->SetStatus( phonehub::FeatureStatus::kEnabledAndConnected); fake_feature_status_provider_.SetStatus(FeatureStatus::kIneligible); + scoped_feature_list_.InitWithFeatures( + /*enabled_features=*/{features::kEcheSWA}, + /*disabled_features=*/{}); launch_app_helper_ = std::make_unique<FakeLaunchAppHelper>( &fake_phone_hub_manager_, base::BindRepeating( @@ -64,16 +49,13 @@ base::BindRepeating( &EcheNotificationClickHandlerTest::FakeLaunchNotificationFunction, base::Unretained(this))); - display_stream_handler_ = std::make_unique<EcheDisplayStreamHandler>(); handler_ = std::make_unique<EcheNotificationClickHandler>( &fake_phone_hub_manager_, &fake_feature_status_provider_, - launch_app_helper_.get(), display_stream_handler_.get()); + launch_app_helper_.get()); } void TearDown() override { - AshTestBase::TearDown(); launch_app_helper_.reset(); - display_stream_handler_.reset(); handler_.reset(); } @@ -114,20 +96,12 @@ ->notification_click_handler_count(); } - void StartStreaming() { handler_->OnStartStreaming(); } - bool close_eche_is_called() { return close_eche_is_called_; } size_t num_notifications_shown() { return num_notifications_shown_; } size_t num_app_launch() { return num_app_launch_; } - bool waiting_for_streaming_to_show() { - return handler_->waiting_for_streaming_to_show(); - } - - EcheTray* eche_tray() { return eche_tray_; } - void reset() { close_eche_is_called_ = false; num_notifications_shown_ = 0; @@ -141,15 +115,9 @@ base::test::ScopedFeatureList scoped_feature_list_; FakeFeatureStatusProvider fake_feature_status_provider_; std::unique_ptr<FakeLaunchAppHelper> launch_app_helper_; - std::unique_ptr<EcheDisplayStreamHandler> display_stream_handler_; bool close_eche_is_called_; size_t num_notifications_shown_ = 0; size_t num_app_launch_ = 0; - EcheTray* eche_tray_ = nullptr; // Not owned - - // Calling the factory constructor is enough to set it up. - std::unique_ptr<TestAshWebViewFactory> test_web_view_factory_ = - std::make_unique<TestAshWebViewFactory>(); }; TEST_F(EcheNotificationClickHandlerTest, StatusChangeTransitions) { @@ -236,28 +204,5 @@ EXPECT_EQ(num_notifications_shown(), 1u); } -TEST_F(EcheNotificationClickHandlerTest, StartStreaming) { - EXPECT_FALSE(waiting_for_streaming_to_show()); - - const int64_t notification_id = 0; - const char16_t app_name[] = u"Test App"; - const char package_name[] = "com.google.testapp"; - const int64_t user_id = 0; - phonehub::Notification::AppMetadata app_meta_data = - phonehub::Notification::AppMetadata(app_name, package_name, - /*icon=*/gfx::Image(), - /*icon_color=*/absl::nullopt, - /*icon_is_monochrome=*/true, user_id); - HandleNotificationClick(notification_id, app_meta_data); - - EXPECT_TRUE(waiting_for_streaming_to_show()); - - StartStreaming(); - - EXPECT_TRUE( - eche_tray()->get_bubble_wrapper_for_test()->bubble_view()->GetVisible()); - EXPECT_FALSE(waiting_for_streaming_to_show()); -} - } // namespace eche_app } // namespace ash
diff --git a/ash/webui/eche_app_ui/eche_recent_app_click_handler.cc b/ash/webui/eche_app_ui/eche_recent_app_click_handler.cc index 6c770649..ae5fe2c 100644 --- a/ash/webui/eche_app_ui/eche_recent_app_click_handler.cc +++ b/ash/webui/eche_app_ui/eche_recent_app_click_handler.cc
@@ -17,11 +17,9 @@ EcheRecentAppClickHandler::EcheRecentAppClickHandler( phonehub::PhoneHubManager* phone_hub_manager, FeatureStatusProvider* feature_status_provider, - LaunchAppHelper* launch_app_helper, - EcheDisplayStreamHandler* display_stream_handler) + LaunchAppHelper* launch_app_helper) : feature_status_provider_(feature_status_provider), - launch_app_helper_(launch_app_helper), - display_stream_handler_(display_stream_handler) { + launch_app_helper_(launch_app_helper) { notification_handler_ = phone_hub_manager->GetNotificationInteractionHandler(); recent_apps_handler_ = phone_hub_manager->GetRecentAppsInteractionHandler(); @@ -33,9 +31,6 @@ recent_apps_handler_->AddRecentAppClickObserver(this); is_click_handler_set_ = true; } - - if (features::IsEcheSWAInBackgroundEnabled()) - display_stream_handler_->AddObserver(this); } EcheRecentAppClickHandler::~EcheRecentAppClickHandler() { @@ -44,9 +39,6 @@ notification_handler_->RemoveNotificationClickHandler(this); if (recent_apps_handler_) recent_apps_handler_->RemoveRecentAppClickObserver(this); - - if (features::IsEcheSWAInBackgroundEnabled()) - display_stream_handler_->RemoveObserver(this); } void EcheRecentAppClickHandler::HandleNotificationClick( @@ -74,7 +66,6 @@ /*notification_id=*/absl::nullopt, app_metadata.package_name, app_metadata.visible_app_name, app_metadata.user_id, app_metadata.icon); - is_waiting_for_streaming_to_show_ = true; break; case LaunchAppHelper::AppLaunchProhibitedReason::kDisabledByScreenLock: launch_app_helper_->ShowNotification( @@ -110,20 +101,6 @@ notification_handler_->RemoveNotificationClickHandler(this); recent_apps_handler_->RemoveRecentAppClickObserver(this); is_click_handler_set_ = false; - is_waiting_for_streaming_to_show_ = false; - } -} - -void EcheRecentAppClickHandler::OnStartStreaming() { - if (features::IsEcheCustomWidgetEnabled()) { - // TODO(paulzchen): Move the eche tray control to factory. - auto* eche_tray = Shell::GetPrimaryRootWindowController() - ->GetStatusAreaWidget() - ->eche_tray(); - if (eche_tray && is_waiting_for_streaming_to_show_) { - eche_tray->ShowBubble(); - is_waiting_for_streaming_to_show_ = false; - } } }
diff --git a/ash/webui/eche_app_ui/eche_recent_app_click_handler.h b/ash/webui/eche_app_ui/eche_recent_app_click_handler.h index efdb6aae..f5297a1 100644 --- a/ash/webui/eche_app_ui/eche_recent_app_click_handler.h +++ b/ash/webui/eche_app_ui/eche_recent_app_click_handler.h
@@ -12,7 +12,6 @@ #include "ash/components/phonehub/phone_hub_manager.h" #include "ash/components/phonehub/recent_app_click_observer.h" #include "ash/components/phonehub/recent_apps_interaction_handler.h" -#include "ash/webui/eche_app_ui/eche_display_stream_handler.h" #include "ash/webui/eche_app_ui/feature_status_provider.h" #include "base/callback.h" @@ -24,13 +23,11 @@ // Handles recent app clicks originating from Phone Hub recent apps. class EcheRecentAppClickHandler : public phonehub::NotificationClickHandler, public FeatureStatusProvider::Observer, - public phonehub::RecentAppClickObserver, - public EcheDisplayStreamHandler::Observer { + public phonehub::RecentAppClickObserver { public: EcheRecentAppClickHandler(phonehub::PhoneHubManager* phone_hub_manager, FeatureStatusProvider* feature_status_provider, - LaunchAppHelper* launch_app_helper, - EcheDisplayStreamHandler* display_stream_handler); + LaunchAppHelper* launch_app_helper); ~EcheRecentAppClickHandler() override; EcheRecentAppClickHandler(const EcheRecentAppClickHandler&) = delete; @@ -49,14 +46,6 @@ // FeatureStatusProvider::Observer: void OnFeatureStatusChanged() override; - // EcheDisplayStreamHandler::Observer: - void OnStartStreaming() override; - - // Test helpers - bool waiting_for_streaming_to_show() { - return is_waiting_for_streaming_to_show_; - } - private: bool IsClickable(FeatureStatus status); @@ -64,9 +53,7 @@ phonehub::RecentAppsInteractionHandler* recent_apps_handler_; FeatureStatusProvider* feature_status_provider_; LaunchAppHelper* launch_app_helper_; - EcheDisplayStreamHandler* display_stream_handler_; bool is_click_handler_set_ = false; - bool is_waiting_for_streaming_to_show_ = false; }; } // namespace eche_app
diff --git a/ash/webui/eche_app_ui/eche_recent_app_click_handler_unittest.cc b/ash/webui/eche_app_ui/eche_recent_app_click_handler_unittest.cc index e13cb35..6da1e7d5 100644 --- a/ash/webui/eche_app_ui/eche_recent_app_click_handler_unittest.cc +++ b/ash/webui/eche_app_ui/eche_recent_app_click_handler_unittest.cc
@@ -8,12 +8,6 @@ #include "ash/components/phonehub/fake_phone_hub_manager.h" #include "ash/constants/ash_features.h" -#include "ash/system/eche/eche_tray.h" -#include "ash/system/status_area_widget_test_helper.h" -#include "ash/system/tray/tray_bubble_wrapper.h" -#include "ash/test/ash_test_base.h" -#include "ash/test/ash_test_suite.h" -#include "ash/test/test_ash_web_view_factory.h" #include "ash/webui/eche_app_ui/fake_feature_status_provider.h" #include "ash/webui/eche_app_ui/fake_launch_app_helper.h" #include "ash/webui/eche_app_ui/launch_app_helper.h" @@ -27,7 +21,7 @@ namespace ash { namespace eche_app { -class EcheRecentAppClickHandlerTest : public AshTestBase { +class EcheRecentAppClickHandlerTest : public testing::Test { protected: EcheRecentAppClickHandlerTest() = default; EcheRecentAppClickHandlerTest(const EcheRecentAppClickHandlerTest&) = delete; @@ -35,24 +29,14 @@ const EcheRecentAppClickHandlerTest&) = delete; ~EcheRecentAppClickHandlerTest() override = default; - // AshTestBase::Test: + // testing::Test: void SetUp() override { - scoped_feature_list_.InitWithFeatures( - /*enabled_features=*/{features::kEcheSWA, features::kEcheCustomWidget}, - /*disabled_features=*/{}); - - DCHECK(test_web_view_factory_.get()); - - ui::ResourceBundle::CleanupSharedInstance(); - AshTestSuite::LoadTestResources(); - AshTestBase::SetUp(); - eche_tray_ = - ash::StatusAreaWidgetTestHelper::GetStatusAreaWidget()->eche_tray(); - fake_phone_hub_manager_.fake_feature_status_provider()->SetStatus( phonehub::FeatureStatus::kEnabledAndConnected); fake_feature_status_provider_.SetStatus(FeatureStatus::kIneligible); - + scoped_feature_list_.InitWithFeatures( + /*enabled_features=*/{features::kEcheSWA}, + /*disabled_features=*/{}); launch_app_helper_ = std::make_unique<FakeLaunchAppHelper>( &fake_phone_hub_manager_, base::BindRepeating( @@ -64,16 +48,13 @@ base::BindRepeating( &EcheRecentAppClickHandlerTest::FakeLaunchNotificationFunction, base::Unretained(this))); - display_stream_handler_ = std::make_unique<EcheDisplayStreamHandler>(); handler_ = std::make_unique<EcheRecentAppClickHandler>( &fake_phone_hub_manager_, &fake_feature_status_provider_, - launch_app_helper_.get(), display_stream_handler_.get()); + launch_app_helper_.get()); } void TearDown() override { - AshTestBase::TearDown(); launch_app_helper_.reset(); - display_stream_handler_.reset(); handler_.reset(); } @@ -124,35 +105,21 @@ ->FetchRecentAppMetadataList(); } - void StartStreaming() { handler_->OnStartStreaming(); } - const std::string& get_package_name() { return package_name_; } const std::u16string& get_visible_name() { return visible_name_; } int64_t get_user_id() { return user_id_; } - bool waiting_for_streaming_to_show() { - return handler_->waiting_for_streaming_to_show(); - } - - EcheTray* eche_tray() { return eche_tray_; } - private: phonehub::FakePhoneHubManager fake_phone_hub_manager_; base::test::ScopedFeatureList scoped_feature_list_; FakeFeatureStatusProvider fake_feature_status_provider_; std::unique_ptr<LaunchAppHelper> launch_app_helper_; std::unique_ptr<EcheRecentAppClickHandler> handler_; - std::unique_ptr<EcheDisplayStreamHandler> display_stream_handler_; std::string package_name_; std::u16string visible_name_; int64_t user_id_; - EcheTray* eche_tray_ = nullptr; // Not owned - - // Calling the factory constructor is enough to set it up. - std::unique_ptr<TestAshWebViewFactory> test_web_view_factory_ = - std::make_unique<TestAshWebViewFactory>(); }; TEST_F(EcheRecentAppClickHandlerTest, StatusChangeTransitions) { @@ -217,25 +184,5 @@ EXPECT_EQ(fake_app_metadata.user_id, app_metadata[0].user_id); } -TEST_F(EcheRecentAppClickHandlerTest, StartStreaming) { - EXPECT_FALSE(waiting_for_streaming_to_show()); - - const int64_t user_id = 1; - const char16_t app_visible_name[] = u"Fake App"; - const char package_name[] = "com.fakeapp"; - auto fake_app_metadata = phonehub::Notification::AppMetadata( - app_visible_name, package_name, gfx::Image(), - /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id); - RecentAppClicked(fake_app_metadata); - - EXPECT_TRUE(waiting_for_streaming_to_show()); - - StartStreaming(); - - EXPECT_TRUE( - eche_tray()->get_bubble_wrapper_for_test()->bubble_view()->GetVisible()); - EXPECT_FALSE(waiting_for_streaming_to_show()); -} - } // namespace eche_app } // namespace ash
diff --git a/ash/webui/eche_app_ui/mojom/eche_app.mojom b/ash/webui/eche_app_ui/mojom/eche_app.mojom index 3bfbaa1..312b34b 100644 --- a/ash/webui/eche_app_ui/mojom/eche_app.mojom +++ b/ash/webui/eche_app_ui/mojom/eche_app.mojom
@@ -89,9 +89,21 @@ mojo_base.mojom.String16 message, WebNotificationType type); }; -// Interface for streaming a display video with which the connection is -// established. TODO(paulzchen): Using generic method `OnStreamStatusChanged`. +// Enum representing the video streaming status from browser. Numerical +// values should not be changed because they must stay in sync with value on +// Eche web app code. +enum StreamStatus { + kStreamStatusUnknown, // Initial state, not trigger anything yet + kStreamStatusInitializing, // Eche browser is setting up video streaming + kStreamStatusStarted, // Video streaming is set up and started + kStreamStatusStopped, // Video streaming is stopped +}; + +// Interface to notify the video streaming status from Eche browser to Eche +// SWA native code. interface DisplayStreamHandler { // Stream a display video for Eche. StartStreaming(); + // Notifies the stream status change for Eche. + OnStreamStatusChanged(StreamStatus status); };
diff --git a/ash/webui/eche_app_ui/resources/browser_proxy.js b/ash/webui/eche_app_ui/resources/browser_proxy.js index f1ede4e..e0e3c4a 100644 --- a/ash/webui/eche_app_ui/resources/browser_proxy.js +++ b/ash/webui/eche_app_ui/resources/browser_proxy.js
@@ -86,7 +86,8 @@ console.log('echeapi debug on, browser_proxy.js window.close block'); } else { console.log('echeapi browser_proxy.js window.close'); - window.close(); + displayStreamHandler.onStreamStatusChanged( + ash.echeApp.mojom.StreamStatus.kStreamStatusStopped); } }); @@ -153,7 +154,8 @@ // Register START_STREAMING pipes. guestMessagePipe.registerHandler(Message.START_STREAMING, async () => { console.log('echeapi browser_proxy.js startStreaming'); - displayStreamHandler.startStreaming(); + displayStreamHandler.onStreamStatusChanged( + ash.echeApp.mojom.StreamStatus.kStreamStatusStarted); }); // We can't access hash change event inside iframe so parse the notification
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/albums_subpage_element.ts b/ash/webui/personalization_app/resources/trusted/ambient/albums_subpage_element.ts index 81222234..8df577a2 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/albums_subpage_element.ts +++ b/ash/webui/personalization_app/resources/trusted/ambient/albums_subpage_element.ts
@@ -102,7 +102,7 @@ return; } } - setAlbumSelected(albumChanged, getAmbientProvider()); + setAlbumSelected(albumChanged, getAmbientProvider(), this.getStore()); } private onArtAlbumDialogClose_() {
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/ambient_actions.ts b/ash/webui/personalization_app/resources/trusted/ambient/ambient_actions.ts index 9299805..d8bd9ef 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/ambient_actions.ts +++ b/ash/webui/personalization_app/resources/trusted/ambient/ambient_actions.ts
@@ -12,19 +12,24 @@ export enum AmbientActionName { SET_ALBUMS = 'set_albums', + SET_ALBUM_SELECTED = 'set_album_selected', SET_AMBIENT_MODE_ENABLED = 'set_ambient_mode_enabled', SET_TEMPERATURE_UNIT = 'set_temperature_unit', SET_TOPIC_SOURCE = 'set_topic_source', } -export type AmbientActions = SetAlbumsAction|SetAmbientModeEnabledAction| - SetTopicSourceAction|SetTemperatureUnitAction; +export type AmbientActions = SetAlbumsAction|SetAlbumSelectedAction| + SetAmbientModeEnabledAction|SetTopicSourceAction|SetTemperatureUnitAction; export type SetAlbumsAction = Action&{ name: AmbientActionName.SET_ALBUMS; albums: AmbientModeAlbum[]; }; +export type SetAlbumSelectedAction = Action&{ + name: AmbientActionName.SET_ALBUM_SELECTED; +}; + export type SetAmbientModeEnabledAction = Action&{ name: AmbientActionName.SET_AMBIENT_MODE_ENABLED; enabled: boolean; @@ -47,6 +52,10 @@ return {name: AmbientActionName.SET_ALBUMS, albums}; } +export function setAlbumSelectedAction(): SetAlbumSelectedAction { + return {name: AmbientActionName.SET_ALBUM_SELECTED}; +} + /** * Sets the current value of the ambient mode pref. */
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/ambient_controller.ts b/ash/webui/personalization_app/resources/trusted/ambient/ambient_controller.ts index 8d45b4e..82134d7 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/ambient_controller.ts +++ b/ash/webui/personalization_app/resources/trusted/ambient/ambient_controller.ts
@@ -5,7 +5,7 @@ import {AmbientModeAlbum, AmbientProviderInterface, TemperatureUnit, TopicSource} from '../personalization_app.mojom-webui.js'; import {PersonalizationStore} from '../personalization_store.js'; -import {setAmbientModeEnabledAction, setTemperatureUnitAction, setTopicSourceAction} from './ambient_actions.js'; +import {setAlbumSelectedAction, setAmbientModeEnabledAction, setTemperatureUnitAction, setTopicSourceAction} from './ambient_actions.js'; /** * @fileoverview contains all of the functions to interact with ambient mode @@ -46,6 +46,10 @@ // Set one album as selected or not. export function setAlbumSelected( - album: AmbientModeAlbum, provider: AmbientProviderInterface): void { + album: AmbientModeAlbum, provider: AmbientProviderInterface, + store: PersonalizationStore): void { + // Dispatch action to update albums info with the changed album. + store.dispatch(setAlbumSelectedAction()); + provider.setAlbumSelected(album.id, album.topicSource, album.checked); }
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/ambient_reducers.ts b/ash/webui/personalization_app/resources/trusted/ambient/ambient_reducers.ts index 8798c336..4e22619 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/ambient_reducers.ts +++ b/ash/webui/personalization_app/resources/trusted/ambient/ambient_reducers.ts
@@ -15,6 +15,14 @@ switch (action.name) { case AmbientActionName.SET_ALBUMS: return action.albums; + case AmbientActionName.SET_ALBUM_SELECTED: + if (!state) { + return state; + } + // An albums in AmbientState.albums is mutated by setting checked + // to True/False, have to return a copy of albums state so that + // Polymer knows there is an update. + return [...state]; default: return state; }
diff --git a/ash/wm/desks/templates/desks_templates_unittest.cc b/ash/wm/desks/templates/desks_templates_unittest.cc index f6204f6..c3406fd 100644 --- a/ash/wm/desks/templates/desks_templates_unittest.cc +++ b/ash/wm/desks/templates/desks_templates_unittest.cc
@@ -43,6 +43,7 @@ #include "ash/wm/overview/overview_session.h" #include "ash/wm/overview/overview_test_base.h" #include "ash/wm/overview/overview_test_util.h" +#include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" #include "base/callback_helpers.h" @@ -471,6 +472,48 @@ EXPECT_FALSE(grid_list[1]->no_windows_widget()); } +// Tests that the "App does not support split-screen" label is hidden when the +// desk templates grid is shown. +TEST_F(DesksTemplatesTest, NoAppSplitScreenLabelOnTemplateGridShow) { + std::unique_ptr<aura::Window> unsnappable_window = CreateUnsnappableWindow(); + auto test_window = CreateAppWindow(); + + // At least one entry is required for the templates grid to be shown. + AddEntry(base::GUID::GenerateRandomV4(), "template", base::Time::Now()); + + // Start overview mode. + ToggleOverview(); + WaitForDesksTemplatesUI(); + ASSERT_TRUE(GetOverviewSession()); + + ASSERT_TRUE(GetOverviewController()->InOverviewSession()); + + OverviewItem* snappable_overview_item = + GetOverviewItemForWindow(test_window.get()); + OverviewItem* unsnappable_overview_item = + GetOverviewItemForWindow(unsnappable_window.get()); + + // Note: `cannot_snap_widget_` will be created on demand. + EXPECT_FALSE(snappable_overview_item->cannot_snap_widget_for_testing()); + ASSERT_FALSE(unsnappable_overview_item->cannot_snap_widget_for_testing()); + + // Snap the extra snappable window to enter split view mode. + SplitViewController* split_view_controller = + SplitViewController::Get(Shell::GetPrimaryRootWindow()); + + split_view_controller->SnapWindow(test_window.get(), + SplitViewController::LEFT); + ASSERT_TRUE(split_view_controller->InSplitViewMode()); + ASSERT_TRUE(unsnappable_overview_item->cannot_snap_widget_for_testing()); + ui::Layer* unsnappable_layer = + unsnappable_overview_item->cannot_snap_widget_for_testing()->GetLayer(); + EXPECT_EQ(1.f, unsnappable_layer->opacity()); + + // Entering the templates grid will hide the unsnappable label. + ShowDesksTemplatesGrids(); + EXPECT_EQ(0.f, unsnappable_layer->opacity()); +} + // Tests when user enter desk templates, a11y alert being sent. TEST_F(DesksTemplatesTest, InvokeAccessibilityAlertOnEnterDeskTemplates) { TestAccessibilityControllerClient client;
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc index 71627a4..8bffaff 100644 --- a/ash/wm/overview/overview_grid.cc +++ b/ash/wm/overview/overview_grid.cc
@@ -1054,7 +1054,7 @@ if (split_view_drag_indicators_) split_view_drag_indicators_->OnDisplayBoundsChanged(); - UpdateCannotSnapWarningVisibility(); + UpdateCannotSnapWarningVisibility(/*animate=*/true); // In case of split view mode, the grid bounds and item positions will be // updated in |OnSplitViewDividerPositionChanged|. @@ -2002,7 +2002,7 @@ } // Update the cannot snap warnings and adjust the grid bounds. - UpdateCannotSnapWarningVisibility(); + UpdateCannotSnapWarningVisibility(/*animate=*/true); SetBoundsAndUpdatePositions(GetGridBoundsInScreen(root_window_), /*ignored_items=*/{}, /*animate=*/false); @@ -2399,9 +2399,9 @@ root_window_); } -void OverviewGrid::UpdateCannotSnapWarningVisibility() { +void OverviewGrid::UpdateCannotSnapWarningVisibility(bool animate) { for (auto& overview_mode_item : window_list_) - overview_mode_item->UpdateCannotSnapWarningVisibility(); + overview_mode_item->UpdateCannotSnapWarningVisibility(animate); } void OverviewGrid::OnSaveDeskAsTemplateButtonPressed() {
diff --git a/ash/wm/overview/overview_grid.h b/ash/wm/overview/overview_grid.h index 5c86e2e..c161a0187 100644 --- a/ash/wm/overview/overview_grid.h +++ b/ash/wm/overview/overview_grid.h
@@ -510,7 +510,7 @@ // Returns the the bounds of the desks widget in screen coordinates. gfx::Rect GetDesksWidgetBounds() const; - void UpdateCannotSnapWarningVisibility(); + void UpdateCannotSnapWarningVisibility(bool animate); // Called back when the button to save a desk template is pressed. void OnSaveDeskAsTemplateButtonPressed();
diff --git a/ash/wm/overview/overview_item.cc b/ash/wm/overview/overview_item.cc index e1123b4..8a8cc5e 100644 --- a/ash/wm/overview/overview_item.cc +++ b/ash/wm/overview/overview_item.cc
@@ -231,6 +231,8 @@ item_widget_event_blocker_ = std::make_unique<aura::ScopedWindowEventTargetingBlocker>( item_widget_->GetNativeWindow()); + + HideCannotSnapWarning(animate); } void OverviewItem::RevertHideForDesksTemplatesGrid(bool animate) { @@ -244,6 +246,8 @@ } item_widget_event_blocker_.reset(); + + UpdateCannotSnapWarningVisibility(animate); } void OverviewItem::OnMovingWindowToAnotherDesk() { @@ -509,7 +513,7 @@ transform_window_.Close(); } -void OverviewItem::UpdateCannotSnapWarningVisibility() { +void OverviewItem::UpdateCannotSnapWarningVisibility(bool animate) { // Windows which can snap will never show this warning. Or if the window is // the drop target window, also do not show this warning. bool visible = true; @@ -546,21 +550,28 @@ GetWindow()->parent()->StackChildAbove( cannot_snap_widget_->GetNativeWindow(), GetWindow()); } - - DoSplitviewOpacityAnimation(cannot_snap_widget_->GetNativeWindow()->layer(), - visible - ? SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_IN - : SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_OUT); + if (animate) { + DoSplitviewOpacityAnimation( + cannot_snap_widget_->GetLayer(), + visible ? SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_IN + : SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_OUT); + } else { + cannot_snap_widget_->GetLayer()->SetOpacity(visible ? 1.f : 0.f); + } const gfx::Rect bounds = ToStableSizeRoundedRect(GetWindowTargetBoundsWithInsets()); cannot_snap_widget_->SetBoundsCenteredIn(bounds, /*animate=*/false); } -void OverviewItem::HideCannotSnapWarning() { +void OverviewItem::HideCannotSnapWarning(bool animate) { if (!cannot_snap_widget_) return; - DoSplitviewOpacityAnimation(cannot_snap_widget_->GetNativeWindow()->layer(), - SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_OUT); + if (animate) { + DoSplitviewOpacityAnimation(cannot_snap_widget_->GetLayer(), + SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_OUT); + } else { + cannot_snap_widget_->GetLayer()->SetOpacity(0.f); + } } void OverviewItem::OnSelectorItemDragStarted(OverviewItem* item) { @@ -787,7 +798,7 @@ const bool show_backdrop = GetWindowDimensionsType() != OverviewGridWindowFillMode::kNormal; overview_item_view_->SetBackdropVisibility(show_backdrop); - UpdateCannotSnapWarningVisibility(); + UpdateCannotSnapWarningVisibility(/*animate=*/true); } void OverviewItem::StopWidgetAnimation() {
diff --git a/ash/wm/overview/overview_item.h b/ash/wm/overview/overview_item.h index ec1e2b6..7e7eec2 100644 --- a/ash/wm/overview/overview_item.h +++ b/ash/wm/overview/overview_item.h
@@ -123,11 +123,11 @@ // Shows the cannot snap warning if currently in splitview, and the associated // window cannot be snapped. - void UpdateCannotSnapWarningVisibility(); + void UpdateCannotSnapWarningVisibility(bool animate); // Hides the cannot snap warning (if it was showing) until the next call to // |UpdateCannotSnapWarningVisibility|. - void HideCannotSnapWarning(); + void HideCannotSnapWarning(bool animate); // Called when a OverviewItem on any grid is dragged. Hides the close button // when a drag is started, and reshows it when a drag is finished.
diff --git a/ash/wm/overview/overview_window_drag_controller.cc b/ash/wm/overview/overview_window_drag_controller.cc index c2b3bec4..ed31c5c 100644 --- a/ash/wm/overview/overview_window_drag_controller.cc +++ b/ash/wm/overview/overview_window_drag_controller.cc
@@ -320,7 +320,7 @@ /*is_dragging=*/true, SplitViewDragIndicators::WindowDraggingState::kFromOverview, SplitViewController::NONE)); - item_->HideCannotSnapWarning(); + item_->HideCannotSnapWarning(/*animate=*/true); // Update the split view divider bar status if necessary. If splitview is // active when dragging the overview window, the split divider bar should be @@ -428,7 +428,7 @@ SplitViewController::Get(Shell::GetPrimaryRootWindow()) ->OnWindowDragCanceled(); overview_session_->ResetSplitViewDragIndicatorsWindowDraggingStates(); - item_->UpdateCannotSnapWarningVisibility(); + item_->UpdateCannotSnapWarningVisibility(/*animate=*/true); } } overview_session_->PositionWindows(/*animate=*/true); @@ -649,7 +649,7 @@ // orientation was changed. UpdateDragIndicatorsAndOverviewGrid(location_in_screen); overview_session_->ResetSplitViewDragIndicatorsWindowDraggingStates(); - item_->UpdateCannotSnapWarningVisibility(); + item_->UpdateCannotSnapWarningVisibility(/*animate=*/true); } // This function has multiple exit positions, at each we must update the desks
diff --git a/base/files/file_util.h b/base/files/file_util.h index 19c9f1d..2d6122ae 100644 --- a/base/files/file_util.h +++ b/base/files/file_util.h
@@ -578,7 +578,9 @@ // Returns true if it was able to set it in the close-on-exec mode, otherwise // false. BASE_EXPORT bool SetCloseOnExec(int fd); +#endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) +#if BUILDFLAG(IS_MAC) // Test that |path| can only be changed by a given user and members of // a given set of groups. // Specifically, test that all parts of |path| under (and including) |base|: @@ -594,9 +596,7 @@ const base::FilePath& path, uid_t owner_uid, const std::set<gid_t>& group_gids); -#endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) -#if BUILDFLAG(IS_MAC) // Is |path| writable only by a user with administrator privileges? // This function uses Mac OS conventions. The super user is assumed to have // uid 0, and the administrator group is assumed to be named "admin".
diff --git a/base/files/file_util_posix.cc b/base/files/file_util_posix.cc index ee25c71..7577b45 100644 --- a/base/files/file_util_posix.cc +++ b/base/files/file_util_posix.cc
@@ -76,6 +76,7 @@ namespace { +#if BUILDFLAG(IS_MAC) // Helper for VerifyPathControlledByUser. bool VerifySpecificPathControlledByUser(const FilePath& path, uid_t owner_uid, @@ -111,6 +112,7 @@ return true; } +#endif base::FilePath GetTempTemplate() { return FormatTemporaryFileName("XXXXXX"); @@ -1012,6 +1014,7 @@ return chdir(path.value().c_str()) == 0; } +#if BUILDFLAG(IS_MAC) bool VerifyPathControlledByUser(const FilePath& base, const FilePath& path, uid_t owner_uid, @@ -1047,7 +1050,6 @@ return true; } -#if BUILDFLAG(IS_MAC) bool VerifyPathControlledByAdmin(const FilePath& path) { const unsigned kRootUid = 0; const FilePath kFileSystemRoot("/");
diff --git a/base/files/file_util_unittest.cc b/base/files/file_util_unittest.cc index a57f38d..c66e348e 100644 --- a/base/files/file_util_unittest.cc +++ b/base/files/file_util_unittest.cc
@@ -214,9 +214,7 @@ #endif -// Fuchsia doesn't support file permissions. -#if !BUILDFLAG(IS_FUCHSIA) -#if BUILDFLAG(IS_POSIX) +#if BUILDFLAG(IS_MAC) // Provide a simple way to change the permissions bits on |path| in tests. // ASSERT failures will return, but not stop the test. Caller should wrap // calls to this function in ASSERT_NO_FATAL_FAILURE(). @@ -232,8 +230,10 @@ mode &= ~mode_bits_to_clear; ASSERT_TRUE(SetPosixFilePermissions(path, mode)); } -#endif // BUILDFLAG(IS_POSIX) +#endif // BUILDFLAG(IS_MAC) +// Fuchsia doesn't support file permissions. +#if !BUILDFLAG(IS_FUCHSIA) // Sets the source file to read-only. void SetReadOnly(const FilePath& path, bool read_only) { #if BUILDFLAG(IS_WIN) @@ -3760,7 +3760,7 @@ #endif -#if BUILDFLAG(IS_POSIX) +#if BUILDFLAG(IS_MAC) // Testing VerifyPathControlledByAdmin() is hard, because there is no // way a test can make a file owned by root, or change file paths @@ -4044,7 +4044,7 @@ EXPECT_TRUE(VerifyPathControlledByUser(sub_dir_, text_file_, uid_, ok_gids_)); } -#endif // BUILDFLAG(IS_POSIX) +#endif // BUILDFLAG(IS_MAC) // Flaky test: crbug/1054637 #if BUILDFLAG(IS_ANDROID)
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1 index ca9ed58..10e41d6 100644 --- a/build/fuchsia/linux_internal.sdk.sha1 +++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@ -7.20220314.2.1 +7.20220314.3.3
diff --git a/build/toolchain/apple/toolchain.gni b/build/toolchain/apple/toolchain.gni index e837b981..7221c80 100644 --- a/build/toolchain/apple/toolchain.gni +++ b/build/toolchain/apple/toolchain.gni
@@ -230,7 +230,7 @@ # However, it seems -fuse-ld=lld causes difficulties. tool("rust_staticlib") { - rust_outfile = "{{target_out_dir}}/{{crate_name}}.a" + rust_outfile = "{{output_dir}}/{{target_output_name}}.a" depfile = "{{output}}.d" rspfile = "$rust_outfile.rsp" rspfile_content = "{{rustdeps}} {{externs}}" @@ -241,7 +241,7 @@ } tool("rust_rlib") { - rust_outfile = "{{target_out_dir}}/lib{{crate_name}}.rlib" + rust_outfile = "{{output_dir}}/lib{{target_output_name}}.rlib" depfile = "{{output}}.d" # Do not use rsp files in this (common) case because they occupy the @@ -255,7 +255,7 @@ if (toolchain_args.rustc_can_link) { tool("rust_bin") { - rust_outfile = "{{root_out_dir}}/{{crate_name}}" + rust_outfile = "{{root_out_dir}}/{{target_output_name}}" depfile = "{{output}}.d" rspfile = "$rust_outfile.rsp" rspfile_content = "{{rustdeps}} {{externs}}" @@ -266,7 +266,7 @@ } tool("rust_cdylib") { - rust_outfile = "{{target_out_dir}}/lib{{crate_name}}.dylib" + rust_outfile = "{{output_dir}}/lib{{target_output_name}}.dylib" depfile = "{{output}}.d" rspfile = "$rust_outfile.rsp" rspfile_content = "{{rustdeps}} {{externs}}" @@ -277,7 +277,7 @@ } tool("rust_macro") { - rust_outfile = "{{target_out_dir}}/lib{{crate_name}}.dylib" + rust_outfile = "{{output_dir}}/lib{{target_output_name}}.dylib" depfile = "{{output}}.d" rspfile = "$rust_outfile.rsp" rspfile_content = "{{rustdeps}} {{externs}}"
diff --git a/build/toolchain/win/BUILD.gn b/build/toolchain/win/BUILD.gn index 96a914bb..254855d 100644 --- a/build/toolchain/win/BUILD.gn +++ b/build/toolchain/win/BUILD.gn
@@ -307,7 +307,7 @@ rustc = rebase_path("${rust_sysroot}/bin/rustc", root_build_dir) rust_sysroot_relative_to_out = rebase_path(rust_sysroot, root_out_dir) tool("rust_staticlib") { - rust_outfile = "{{target_out_dir}}/{{crate_name}}.lib" + rust_outfile = "{{output_dir}}/{{target_output_name}}.lib" depfile = "{{output}}.d" rspfile = "$rust_outfile.rsp" rspfile_content = "{{rustdeps}} {{externs}}" @@ -318,8 +318,9 @@ } tool("rust_rlib") { - rust_outfile = "{{target_out_dir}}/lib{{crate_name}}.rlib" + rust_outfile = "{{output_dir}}/lib{{target_output_name}}.rlib" depfile = "{{output}}.d" + # Do not use rsp files in this (common) case because they occupy the # ninja main thread, and {{rlibs}} have shorter command lines than # fully linked targets. @@ -331,7 +332,7 @@ if (toolchain_args.rustc_can_link) { tool("rust_bin") { - rust_outfile = "{{root_out_dir}}/{{crate_name}}.exe" + rust_outfile = "{{root_out_dir}}/{{target_output_name}}.exe" depfile = "{{output}}.d" rspfile = "$rust_outfile.rsp" rspfile_content = "{{rustdeps}} {{externs}}" @@ -342,7 +343,7 @@ } tool("rust_cdylib") { - rust_outfile = "{{target_out_dir}}/lib{{crate_name}}.dll" + rust_outfile = "{{output_dir}}/lib{{target_output_name}}.dll" depfile = "{{output}}.d" rspfile = "$rust_outfile.rsp" rspfile_content = "{{rustdeps}} {{externs}}" @@ -353,7 +354,7 @@ } tool("rust_macro") { - rust_outfile = "{{target_out_dir}}/{{crate_name}}.dll" + rust_outfile = "{{output_dir}}/{{target_output_name}}.dll" depfile = "{{output}}.d" rspfile = "$rust_outfile.rsp" rspfile_content = "{{rustdeps}} {{externs}}"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java index d2e065e..2eb809f0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
@@ -103,7 +103,6 @@ add(ChromeFeatureList.PAINT_PREVIEW_DEMO); add(ChromeFeatureList.PAINT_PREVIEW_SHOW_ON_STARTUP); add(ChromeFeatureList.READ_LATER); - add(ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP); add(ChromeFeatureList.START_SURFACE_ANDROID); add(ChromeFeatureList.STORE_HOURS); add(ChromeFeatureList.SWAP_PIXEL_FORMAT_TO_FIX_CONVERT_FROM_TRANSLUCENT);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java index 460057954..f3635215 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java
@@ -248,7 +248,7 @@ } mNoSearchLogoSpacer = findViewById(R.id.no_search_logo_spacer); - if (ChromeFeatureList.isEnabled(ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP)) { + if (ChromeFeatureList.isEnabled(ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID)) { // If SHOW_SCROLLABLE_MV_ON_NTP is true, TileGroup and other logic will be handled by // MostVisitedListCoordinator. initializeMostVisitedListCoordinator( @@ -392,7 +392,7 @@ private void initializeMostVisitedListCoordinator( ActivityLifecycleDispatcher activityLifecycleDispatcher, TileGroup.Delegate tileGroupDelegate, TouchEnabledDelegate touchEnabledDelegate) { - assert ChromeFeatureList.isEnabled(ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP); + assert ChromeFeatureList.isEnabled(ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID); assert mMvTilesLayout != null; mMostVisitedListCoordinator = new MostVisitedListCoordinator(mActivity, activityLifecycleDispatcher, mMvTilesLayout.findViewById(R.id.mv_tiles_layout), @@ -470,7 +470,7 @@ private void insertSiteSectionView() { int insertionPoint = indexOfChild(mMiddleSpacer) + 1; - if (ChromeFeatureList.isEnabled(ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP)) { + if (ChromeFeatureList.isEnabled(ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID)) { setClipToPadding(false); mMvTilesLayout = (ViewGroup) LayoutInflater.from(this.getContext()) .inflate(R.layout.mv_tiles_layout, this, false);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java index a6b1a8e..4c8a51ef 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java
@@ -365,7 +365,7 @@ @Test @SmallTest @Feature({"NewTabPage", "FeedNewTabPage"}) - @Features.EnableFeatures({ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP}) + @Features.EnableFeatures({ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID}) public void testClickMostVisitedItemOnMVTCarousel() { Assert.assertNotNull(mMVTCarouselLayout); ChromeTabUtils.waitForTabPageLoaded( @@ -385,7 +385,7 @@ @Test @SmallTest @Feature({"NewTabPage", "FeedNewTabPage"}) - @Features.EnableFeatures({ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP}) + @Features.EnableFeatures({ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID}) public void testOpenMostVisitedItemInNewTabOnMVTCarousel() throws ExecutionException { Assert.assertNotNull(mMVTCarouselLayout); ChromeTabUtils.invokeContextMenuAndOpenInANewTab(mActivityTestRule, @@ -400,7 +400,7 @@ @Test @SmallTest @Feature({"NewTabPage", "FeedNewTabPage"}) - @Features.EnableFeatures({ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP}) + @Features.EnableFeatures({ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID}) public void testOpenMostVisitedItemInIncognitoTabOnMVTCarousel() throws ExecutionException { Assert.assertNotNull(mMVTCarouselLayout); ChromeTabUtils.invokeContextMenuAndOpenInANewTab(mActivityTestRule, @@ -416,7 +416,7 @@ @SmallTest @Feature({"NewTabPage", "FeedNewTabPage"}) @FlakyTest(message = "crbug.com/1075804") - @Features.EnableFeatures({ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP}) + @Features.EnableFeatures({ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID}) public void testRemoveMostVisitedItemOnMVTCarousel() throws ExecutionException { Assert.assertNotNull(mMVTCarouselLayout); SiteSuggestion testSite = mSiteSuggestions.get(0);
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index b9e070d..f28e0102 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -5556,6 +5556,11 @@ flag_descriptions::kPrintWithReducedRasterizationDescription, kOsWin, FEATURE_VALUE_TYPE(printing::features::kPrintWithReducedRasterization)}, + {"read-printer-capabilities-with-xps", + flag_descriptions::kReadPrinterCapabilitiesWithXpsName, + flag_descriptions::kReadPrinterCapabilitiesWithXpsDescription, kOsWin, + FEATURE_VALUE_TYPE(printing::features::kReadPrinterCapabilitiesWithXps)}, + {"use-xps-for-printing", flag_descriptions::kUseXpsForPrintingName, flag_descriptions::kUseXpsForPrintingDescription, kOsWin, FEATURE_VALUE_TYPE(printing::features::kUseXpsForPrinting)}, @@ -5585,6 +5590,11 @@ flag_descriptions::kInstantStartDescription, kOsAndroid, FEATURE_VALUE_TYPE(chrome::android::kInstantStart)}, + {"enable-show-scrollable-mvt-on-ntp", + flag_descriptions::kShowScrollableMVTOnNTPAndroidName, + flag_descriptions::kShowScrollableMVTOnNTPAndroidDescription, kOsAndroid, + FEATURE_VALUE_TYPE(chrome::android::kShowScrollableMVTOnNTPAndroid)}, + {"enable-close-tab-suggestions", flag_descriptions::kCloseTabSuggestionsName, flag_descriptions::kCloseTabSuggestionsDescription, kOsAndroid, @@ -8462,11 +8472,12 @@ return !ash::features::IsWallpaperWebUIEnabled(); // Only show Google Photos wallpaper integration flag if: - // * channel is one of Dev/Canary/Unknown, and + // * channel is one of Beta/Dev/Canary/Unknown, and // * wallpaper Web UI flag is enabled. if (!strcmp(kWallpaperGooglePhotosIntegrationInternalName, entry.internal_name)) { - return (channel != version_info::Channel::DEV && + return (channel != version_info::Channel::BETA && + channel != version_info::Channel::DEV && channel != version_info::Channel::CANARY && channel != version_info::Channel::UNKNOWN) || !ash::features::IsWallpaperWebUIEnabled();
diff --git a/chrome/browser/android/omnibox/autocomplete_controller_android.cc b/chrome/browser/android/omnibox/autocomplete_controller_android.cc index 3e8df92..1691ac6c 100644 --- a/chrome/browser/android/omnibox/autocomplete_controller_android.cc +++ b/chrome/browser/android/omnibox/autocomplete_controller_android.cc
@@ -204,6 +204,20 @@ autocomplete_controller_->Start(input_); } +void AutocompleteControllerAndroid::StartPrefetch(JNIEnv* env) { + AutocompleteInput autocomplete_input( + u"", metrics::OmniboxEventProto::NTP_ZPS_PREFETCH, + ChromeAutocompleteSchemeClassifier(profile_)); + autocomplete_input.set_focus_type(OmniboxFocusType::ON_FOCUS); + + if (base::FeatureList::IsEnabled(omnibox::kZeroSuggestPrefetching)) { + autocomplete_controller_->StartPrefetch(autocomplete_input); + } else { + // ZeroSuggestPrefetcher deletes itself after it's done prefetching. + new ZeroSuggestPrefetcher(profile_); + } +} + ScopedJavaLocalRef<jobject> AutocompleteControllerAndroid::Classify( JNIEnv* env, const JavaParamRef<jstring>& j_text, @@ -535,12 +549,3 @@ return {}; return native_bridge->GetJavaObject(); } - -static void JNI_AutocompleteController_PrefetchZeroSuggestResults(JNIEnv* env) { - Profile* profile = ProfileManager::GetActiveUserProfile(); - if (!profile) - return; - - // ZeroSuggestPrefetcher deletes itself after it's done prefetching. - new ZeroSuggestPrefetcher(profile); -}
diff --git a/chrome/browser/android/omnibox/autocomplete_controller_android.h b/chrome/browser/android/omnibox/autocomplete_controller_android.h index e150fb3..2e8f6b2 100644 --- a/chrome/browser/android/omnibox/autocomplete_controller_android.h +++ b/chrome/browser/android/omnibox/autocomplete_controller_android.h
@@ -48,6 +48,7 @@ bool prefer_keyword, bool allow_exact_keyword_match, bool want_asynchronous_matches); + void StartPrefetch(JNIEnv* env); base::android::ScopedJavaLocalRef<jobject> Classify( JNIEnv* env, const base::android::JavaParamRef<jstring>& j_text,
diff --git a/chrome/browser/apps/intent_helper/chromeos_intent_picker_helpers.cc b/chrome/browser/apps/intent_helper/chromeos_intent_picker_helpers.cc index bfdf4725..785a8d6 100644 --- a/chrome/browser/apps/intent_helper/chromeos_intent_picker_helpers.cc +++ b/chrome/browser/apps/intent_helper/chromeos_intent_picker_helpers.cc
@@ -182,7 +182,7 @@ if (entry_type == PickerEntryType::kUnknown && close_reason == IntentPickerCloseReason::DIALOG_DEACTIVATED && ui_auto_display_service) { - ui_auto_display_service->IncrementCounter(url); + ui_auto_display_service->IncrementPickerUICounter(url); } if (should_persist) { @@ -207,6 +207,10 @@ Profile* profile = Profile::FromBrowserContext(web_contents->GetBrowserContext()); + if (base::FeatureList::IsEnabled(features::kLinkCapturingUiUpdate)) { + IntentPickerAutoDisplayService::Get(profile)->ResetIntentChipCounter(url); + } + auto* proxy = AppServiceProxyFactory::GetForProfile(profile); if (app_type == PickerEntryType::kWeb) {
diff --git a/chrome/browser/apps/intent_helper/intent_picker_auto_display_service.cc b/chrome/browser/apps/intent_helper/intent_picker_auto_display_service.cc index da89a47..4a6111c 100644 --- a/chrome/browser/apps/intent_helper/intent_picker_auto_display_service.cc +++ b/chrome/browser/apps/intent_helper/intent_picker_auto_display_service.cc
@@ -59,7 +59,7 @@ return pref_dict.FindIntKey(kAutoDisplayKey).value_or(0) < kDismissThreshold; } -void IntentPickerAutoDisplayService::IncrementCounter(const GURL& url) { +void IntentPickerAutoDisplayService::IncrementPickerUICounter(const GURL& url) { auto* settings_map = HostContentSettingsMapFactory::GetForProfile(profile_); base::Value pref_dict = GetAutoDisplayDictForSettings(settings_map, url); @@ -91,6 +91,17 @@ return ChipState::kExpanded; } +void IntentPickerAutoDisplayService::ResetIntentChipCounter(const GURL& url) { + auto* settings_map = HostContentSettingsMapFactory::GetForProfile(profile_); + base::Value pref_dict = GetAutoDisplayDictForSettings(settings_map, url); + + pref_dict.SetIntKey(kIntentChipCountKey, 0); + + settings_map->SetWebsiteSettingDefaultScope( + url, url, ContentSettingsType::INTENT_PICKER_DISPLAY, + std::move(pref_dict)); +} + IntentPickerAutoDisplayService::Platform IntentPickerAutoDisplayService::GetLastUsedPlatformForTablets(const GURL& url) { base::Value pref_dict = GetAutoDisplayDictForSettings(
diff --git a/chrome/browser/apps/intent_helper/intent_picker_auto_display_service.h b/chrome/browser/apps/intent_helper/intent_picker_auto_display_service.h index 9f5bcbf..59f227bd 100644 --- a/chrome/browser/apps/intent_helper/intent_picker_auto_display_service.h +++ b/chrome/browser/apps/intent_helper/intent_picker_auto_display_service.h
@@ -36,13 +36,18 @@ bool ShouldAutoDisplayUi(const GURL& url); // Keep track of the |url| repetitions. - void IncrementCounter(const GURL& url); + void IncrementPickerUICounter(const GURL& url); // Returns a ChipState indicating whether the Intent Chip should be shown as // expanded or collapsed for a given URL. Increments an internal counter to // track the number of times the chip has been shown for that URL. ChipState GetChipStateAndIncrementCounter(const GURL& url); + // Reset the intent chip counter to 0. When this is called, it allows the + // GetChipStateAndIncrementCounter function will return an Expanded ChipState + // another 3 times for that |url|. + void ResetIntentChipCounter(const GURL& url); + // Returns the last platform selected by the user to handle |url|. // If it has not been checked then it will return |Platform::kNone| // for devices of tablet form factor.
diff --git a/chrome/browser/apps/intent_helper/intent_picker_auto_display_service_unittest.cc b/chrome/browser/apps/intent_helper/intent_picker_auto_display_service_unittest.cc index c04f3e0..16f7b5d 100644 --- a/chrome/browser/apps/intent_helper/intent_picker_auto_display_service_unittest.cc +++ b/chrome/browser/apps/intent_helper/intent_picker_auto_display_service_unittest.cc
@@ -98,9 +98,9 @@ IntentPickerAutoDisplayService::Get(&profile); EXPECT_TRUE(service->ShouldAutoDisplayUi(url1)); - service->IncrementCounter(url1); + service->IncrementPickerUICounter(url1); EXPECT_TRUE(service->ShouldAutoDisplayUi(url1)); - service->IncrementCounter(url1); + service->IncrementPickerUICounter(url1); EXPECT_FALSE(service->ShouldAutoDisplayUi(url1)); // Should return false for a different URL on the same host. @@ -109,6 +109,34 @@ EXPECT_TRUE(service->ShouldAutoDisplayUi(url3)); } +TEST_F(IntentPickerAutoDisplayServiceTest, ResetIntentChipCounter) { + GURL url("https://www.google.com/abcde"); + + TestingProfile profile; + IntentPickerAutoDisplayService* service = + IntentPickerAutoDisplayService::Get(&profile); + + // Increment counter a few times. + EXPECT_EQ(service->GetChipStateAndIncrementCounter(url), + IntentPickerAutoDisplayService::ChipState::kExpanded); + EXPECT_EQ(service->GetChipStateAndIncrementCounter(url), + IntentPickerAutoDisplayService::ChipState::kExpanded); + + // Reset the count back to 0. + service->ResetIntentChipCounter(url); + + // Since the counter is reset, the chip is expanded another 3 times + // before collapsing. + EXPECT_EQ(service->GetChipStateAndIncrementCounter(url), + IntentPickerAutoDisplayService::ChipState::kExpanded); + EXPECT_EQ(service->GetChipStateAndIncrementCounter(url), + IntentPickerAutoDisplayService::ChipState::kExpanded); + EXPECT_EQ(service->GetChipStateAndIncrementCounter(url), + IntentPickerAutoDisplayService::ChipState::kExpanded); + EXPECT_EQ(service->GetChipStateAndIncrementCounter(url), + IntentPickerAutoDisplayService::ChipState::kCollapsed); +} + // Checks that calling GetChipStateAndIncrementCounter tracks views per-URL // and collapses the chip after a fixed number of views. TEST_F(IntentPickerAutoDisplayServiceTest, GetChipStateAndIncrementCounter) {
diff --git a/chrome/browser/apps/intent_helper/intent_picker_helpers.cc b/chrome/browser/apps/intent_helper/intent_picker_helpers.cc index 155bfbbb..e1f8af2 100644 --- a/chrome/browser/apps/intent_helper/intent_picker_helpers.cc +++ b/chrome/browser/apps/intent_helper/intent_picker_helpers.cc
@@ -67,6 +67,12 @@ #if BUILDFLAG(IS_CHROMEOS) LaunchAppFromIntentPickerChromeOs(web_contents, url, launch_name, app_type); #else + if (base::FeatureList::IsEnabled(features::kLinkCapturingUiUpdate)) { + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + IntentPickerAutoDisplayService::Get(profile)->ResetIntentChipCounter(url); + } + switch (app_type) { case PickerEntryType::kWeb: web_app::ReparentWebContentsIntoAppBrowser(web_contents, launch_name); @@ -109,7 +115,7 @@ // We reach here if the picker was closed without an app being chosen, e.g. // due to the tab being closed. Keep count of this scenario so we can stop // the UI from showing after 2+ dismissals. - ui_auto_display_service->IncrementCounter(url); + ui_auto_display_service->IncrementPickerUICounter(url); } #endif // BUILDFLAG(IS_CHROMEOS) }
diff --git a/chrome/browser/ash/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc b/chrome/browser/ash/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc index d0f87c4..3649ac1 100644 --- a/chrome/browser/ash/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc +++ b/chrome/browser/ash/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc
@@ -51,6 +51,11 @@ constexpr char kMimeType[] = "application/octet-stream"; +// Non-zero read offsets used in unit tests. +constexpr size_t kOffset5 = 5; +constexpr size_t kOffset10 = 10; +constexpr size_t kOffset15 = 15; + // Reads data from the reader to fill the buffer. bool ReadData(ArcContentFileSystemFileStreamReader* reader, net::IOBufferWithSize* buffer) { @@ -139,18 +144,59 @@ } TEST_F(ArcContentFileSystemFileStreamReaderTest, ReadRegularFileWithOffset) { - constexpr size_t kOffset = 10; auto buffer = - base::MakeRefCounted<net::IOBufferWithSize>(strlen(kData) - kOffset); + base::MakeRefCounted<net::IOBufferWithSize>(strlen(kData) - kOffset10); { - ArcContentFileSystemFileStreamReader reader(GURL(kArcUrlFile), kOffset); + ArcContentFileSystemFileStreamReader reader(GURL(kArcUrlFile), kOffset10); EXPECT_TRUE(ReadData(&reader, buffer.get())); } base::RunLoop().RunUntilIdle(); - EXPECT_EQ(base::StringPiece(kData + kOffset, strlen(kData) - kOffset), + EXPECT_EQ(base::StringPiece(kData + kOffset10, strlen(kData) - kOffset10), base::StringPiece(buffer->data(), buffer->size())); } +TEST_F(ArcContentFileSystemFileStreamReaderTest, ReadRegularFileWithOffsets) { + auto buffer1 = + base::MakeRefCounted<net::IOBufferWithSize>(kOffset15 - kOffset5); + auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>( + strlen(kData) - kOffset5 - kOffset15); + { + ArcContentFileSystemFileStreamReader reader1(GURL(kArcUrlFile), kOffset5); + EXPECT_TRUE(ReadData(&reader1, buffer1.get())); + ArcContentFileSystemFileStreamReader reader2(GURL(kArcUrlFile), kOffset15); + EXPECT_TRUE(ReadData(&reader2, buffer2.get())); + } + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(base::StringPiece(kData + kOffset5, kOffset15 - kOffset5), + base::StringPiece(buffer1->data(), buffer1->size())); + EXPECT_EQ(base::StringPiece(kData + kOffset15, + strlen(kData) - kOffset5 - kOffset15), + base::StringPiece(buffer2->data(), buffer2->size())); +} + +TEST_F(ArcContentFileSystemFileStreamReaderTest, + ReadRegularFileWithOffsets_CloseWithWait) { + auto buffer1 = + base::MakeRefCounted<net::IOBufferWithSize>(kOffset15 - kOffset5); + auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>( + strlen(kData) - kOffset5 - kOffset15); + { + ArcContentFileSystemFileStreamReader reader1(GURL(kArcUrlFile), kOffset5); + EXPECT_TRUE(ReadData(&reader1, buffer1.get())); + } + base::RunLoop().RunUntilIdle(); + { + ArcContentFileSystemFileStreamReader reader2(GURL(kArcUrlFile), kOffset15); + EXPECT_TRUE(ReadData(&reader2, buffer2.get())); + } + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(base::StringPiece(kData + kOffset5, kOffset15 - kOffset5), + base::StringPiece(buffer1->data(), buffer1->size())); + EXPECT_EQ(base::StringPiece(kData + kOffset15, + strlen(kData) - kOffset5 - kOffset15), + base::StringPiece(buffer2->data(), buffer2->size())); +} + TEST_F(ArcContentFileSystemFileStreamReaderTest, ReadPipe) { auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(strlen(kData)); { @@ -164,18 +210,58 @@ } TEST_F(ArcContentFileSystemFileStreamReaderTest, ReadPipeWithOffset) { - constexpr size_t kOffset = 10; auto buffer = - base::MakeRefCounted<net::IOBufferWithSize>(strlen(kData) - kOffset); + base::MakeRefCounted<net::IOBufferWithSize>(strlen(kData) - kOffset10); { - ArcContentFileSystemFileStreamReader reader(GURL(kArcUrlPipe), kOffset); + ArcContentFileSystemFileStreamReader reader(GURL(kArcUrlPipe), kOffset10); EXPECT_TRUE(ReadData(&reader, buffer.get())); } base::RunLoop().RunUntilIdle(); - EXPECT_EQ(base::StringPiece(kData + kOffset, strlen(kData) - kOffset), + EXPECT_EQ(base::StringPiece(kData + kOffset10, strlen(kData) - kOffset10), base::StringPiece(buffer->data(), buffer->size())); } +TEST_F(ArcContentFileSystemFileStreamReaderTest, ReadPipeWithOffsets) { + auto buffer1 = + base::MakeRefCounted<net::IOBufferWithSize>(kOffset15 - kOffset5); + auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>( + strlen(kData) - kOffset5 - kOffset15); + { + ArcContentFileSystemFileStreamReader reader1(GURL(kArcUrlPipe), kOffset5); + EXPECT_TRUE(ReadData(&reader1, buffer1.get())); + ArcContentFileSystemFileStreamReader reader2(GURL(kArcUrlPipe), kOffset15); + EXPECT_TRUE(ReadData(&reader2, buffer2.get())); + } + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(base::StringPiece(kData + kOffset5, kOffset15 - kOffset5), + base::StringPiece(buffer1->data(), buffer1->size())); + EXPECT_EQ(base::StringPiece(kData + kOffset15, + strlen(kData) - kOffset5 - kOffset15), + base::StringPiece(buffer2->data(), buffer2->size())); +} + +TEST_F(ArcContentFileSystemFileStreamReaderTest, + ReadPipeWithOffsets_CloseWithoutWait) { + auto buffer1 = + base::MakeRefCounted<net::IOBufferWithSize>(kOffset15 - kOffset5); + auto buffer2 = base::MakeRefCounted<net::IOBufferWithSize>( + strlen(kData) - kOffset5 - kOffset15); + { + ArcContentFileSystemFileStreamReader reader1(GURL(kArcUrlPipe), kOffset5); + EXPECT_TRUE(ReadData(&reader1, buffer1.get())); + } + { + ArcContentFileSystemFileStreamReader reader2(GURL(kArcUrlPipe), kOffset15); + EXPECT_TRUE(ReadData(&reader2, buffer2.get())); + } + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(base::StringPiece(kData + kOffset5, kOffset15 - kOffset5), + base::StringPiece(buffer1->data(), buffer1->size())); + EXPECT_EQ(base::StringPiece(kData + kOffset15, + strlen(kData) - kOffset5 - kOffset15), + base::StringPiece(buffer2->data(), buffer2->size())); +} + TEST_F(ArcContentFileSystemFileStreamReaderTest, GetLength) { { ArcContentFileSystemFileStreamReader reader(GURL(kArcUrlFile),
diff --git a/chrome/browser/ash/arc/fileapi/arc_content_file_system_file_stream_writer.h b/chrome/browser/ash/arc/fileapi/arc_content_file_system_file_stream_writer.h index 18b85e3..e79aa585 100644 --- a/chrome/browser/ash/arc/fileapi/arc_content_file_system_file_stream_writer.h +++ b/chrome/browser/ash/arc/fileapi/arc_content_file_system_file_stream_writer.h
@@ -44,7 +44,7 @@ // storage::FileStreamWriter override: int Write(net::IOBuffer* buffer, - int bufffer_length, + int buffer_length, net::CompletionOnceCallback callback) override; int Cancel(net::CompletionOnceCallback callback) override; int Flush(net::CompletionOnceCallback callback) override;
diff --git a/chrome/browser/ash/arc/fileapi/arc_content_file_system_file_stream_writer_unittest.cc b/chrome/browser/ash/arc/fileapi/arc_content_file_system_file_stream_writer_unittest.cc index 805d2e4..ab71a78 100644 --- a/chrome/browser/ash/arc/fileapi/arc_content_file_system_file_stream_writer_unittest.cc +++ b/chrome/browser/ash/arc/fileapi/arc_content_file_system_file_stream_writer_unittest.cc
@@ -126,9 +126,9 @@ TEST_F(ArcContentFileSystemFileStreamWriterTest, Write) { std::string url = - CreateFileWithContent("file_a", std::string(), true /* seekable */); + CreateFileWithContent("file_a", std::string(), /* seekable */ true); { - ArcContentFileSystemFileStreamWriter writer(GURL(url), 0); + ArcContentFileSystemFileStreamWriter writer(GURL(url), /* offset */ 0); EXPECT_EQ(net::OK, WriteStringToWriter(&writer, "foo")); EXPECT_EQ(net::OK, WriteStringToWriter(&writer, "bar")); } @@ -138,9 +138,9 @@ TEST_F(ArcContentFileSystemFileStreamWriterTest, WriteMiddle) { std::string url = - CreateFileWithContent("file_a", "foobar", true /* seekable */); + CreateFileWithContent("file_a", "foobar", /* seekable */ true); { - ArcContentFileSystemFileStreamWriter writer(GURL(url), 2); + ArcContentFileSystemFileStreamWriter writer(GURL(url), /* offset */ 2); EXPECT_EQ(net::OK, WriteStringToWriter(&writer, "xxx")); } base::RunLoop().RunUntilIdle(); @@ -149,19 +149,95 @@ TEST_F(ArcContentFileSystemFileStreamWriterTest, WriteEnd) { std::string url = - CreateFileWithContent("file_a", "foobar", true /* seekable */); + CreateFileWithContent("file_a", "foobar", /* seekable */ true); { - ArcContentFileSystemFileStreamWriter writer(GURL(url), 6); + ArcContentFileSystemFileStreamWriter writer(GURL(url), /* offset */ 6); EXPECT_EQ(net::OK, WriteStringToWriter(&writer, "xxx")); } base::RunLoop().RunUntilIdle(); EXPECT_EQ("foobarxxx", GetFileContent(url)); } +TEST_F(ArcContentFileSystemFileStreamWriterTest, WriteBeginningAndMiddle) { + std::string url = + CreateFileWithContent("file_ab", "foobar123456789", /* seekable */ true); + { + ArcContentFileSystemFileStreamWriter writer1(GURL(url), /* offset */ 0); + EXPECT_EQ(net::OK, WriteStringToWriter(&writer1, "xx ")); + ArcContentFileSystemFileStreamWriter writer2(GURL(url), /* offset */ 6); + EXPECT_EQ(net::OK, WriteStringToWriter(&writer2, " xx ")); + } + base::RunLoop().RunUntilIdle(); + EXPECT_EQ("xx bar xx 56789", GetFileContent(url)); +} + +TEST_F(ArcContentFileSystemFileStreamWriterTest, WriteMiddleAndEnd) { + std::string url = + CreateFileWithContent("file_bc", "foobar123456789", /* seekable */ true); + { + ArcContentFileSystemFileStreamWriter writer1(GURL(url), /* offset */ 6); + EXPECT_EQ(net::OK, WriteStringToWriter(&writer1, " x ")); + ArcContentFileSystemFileStreamWriter writer2(GURL(url), /* offset */ 12); + EXPECT_EQ(net::OK, WriteStringToWriter(&writer2, " xxx")); + } + base::RunLoop().RunUntilIdle(); + EXPECT_EQ("foobar x 456 xxx", GetFileContent(url)); +} + +TEST_F(ArcContentFileSystemFileStreamWriterTest, WriteBeginningAndPastEnd) { + std::string url = + CreateFileWithContent("file_ac", "foobar123456789", /* seekable */ true); + { + ArcContentFileSystemFileStreamWriter writer1(GURL(url), /* offset */ 0); + EXPECT_EQ(net::OK, WriteStringToWriter(&writer1, " xx")); + ArcContentFileSystemFileStreamWriter writer2(GURL(url), /* offset */ 12); + EXPECT_EQ(net::OK, WriteStringToWriter(&writer2, "xxx ")); + } + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(" xxbar123456xxx ", GetFileContent(url)); +} + +TEST_F(ArcContentFileSystemFileStreamWriterTest, + WriteBeginningAndEnd_CloseWithWait) { + std::string url = + CreateFileWithContent("file_ac", "foobar123456789", /* seekable */ true); + { + ArcContentFileSystemFileStreamWriter writer1(GURL(url), /* offset */ 0); + EXPECT_EQ(net::OK, WriteStringToWriter(&writer1, "xxx")); + } + base::RunLoop().RunUntilIdle(); + { + ArcContentFileSystemFileStreamWriter writer2(GURL(url), /* offset */ 12); + EXPECT_EQ(net::OK, WriteStringToWriter(&writer2, "xxx")); + } + base::RunLoop().RunUntilIdle(); + EXPECT_EQ("xxxbar123456xxx", GetFileContent(url)); +} + +TEST_F(ArcContentFileSystemFileStreamWriterTest, + WriteBeginningMiddleAndEnd_CloseWithoutWait) { + std::string url = + CreateFileWithContent("file_abc", "foobar123456789", /* seekable */ true); + { + ArcContentFileSystemFileStreamWriter writer1(GURL(url), /* offset */ 0); + EXPECT_EQ(net::OK, WriteStringToWriter(&writer1, "xx")); + } + { + ArcContentFileSystemFileStreamWriter writer2(GURL(url), /* offset */ 7); + EXPECT_EQ(net::OK, WriteStringToWriter(&writer2, " obar")); + } + { + ArcContentFileSystemFileStreamWriter writer3(GURL(url), /* offset */ 13); + EXPECT_EQ(net::OK, WriteStringToWriter(&writer3, "xx")); + } + base::RunLoop().RunUntilIdle(); + EXPECT_EQ("xxobar1 obar7xx", GetFileContent(url)); +} + TEST_F(ArcContentFileSystemFileStreamWriterTest, WriteFailForNonexistingFile) { std::string url = ArcUrl("file_a"); { - ArcContentFileSystemFileStreamWriter writer(GURL(url), 0); + ArcContentFileSystemFileStreamWriter writer(GURL(url), /* offset */ 0); EXPECT_EQ(net::ERR_INVALID_ARGUMENT, WriteStringToWriter(&writer, "foo")); } base::RunLoop().RunUntilIdle(); @@ -169,21 +245,21 @@ TEST_F(ArcContentFileSystemFileStreamWriterTest, WriteNonSeekable) { std::string url = - CreateFileWithContent("file_a", std::string(), false /* not seekable */); + CreateFileWithContent("file_a", std::string(), /* seekable */ false); { - ArcContentFileSystemFileStreamWriter writer(GURL(url), 0); + ArcContentFileSystemFileStreamWriter writer(GURL(url), /* offset */ 0); EXPECT_EQ(net::OK, WriteStringToWriter(&writer, "foo")); EXPECT_EQ(net::OK, WriteStringToWriter(&writer, "bar")); } base::RunLoop().RunUntilIdle(); - EXPECT_EQ("foobar", GetFileContent(url, 6)); + EXPECT_EQ("foobar", GetFileContent(url, /* bytes */ 6)); } TEST_F(ArcContentFileSystemFileStreamWriterTest, WriteNonSeekableFailForSeek) { std::string url = - CreateFileWithContent("file_a", "foobar", false /* not seekable */); + CreateFileWithContent("file_a", "foobar", /* seekable */ false); { - ArcContentFileSystemFileStreamWriter writer(GURL(url), 2); + ArcContentFileSystemFileStreamWriter writer(GURL(url), /* offset */ 2); EXPECT_EQ(net::ERR_FAILED, WriteStringToWriter(&writer, "xxx")); } base::RunLoop().RunUntilIdle(); @@ -191,9 +267,9 @@ TEST_F(ArcContentFileSystemFileStreamWriterTest, CancelBeforeOperation) { std::string url = - CreateFileWithContent("file_a", std::string(), true /* seekable */); + CreateFileWithContent("file_a", std::string(), /* seekable */ true); { - ArcContentFileSystemFileStreamWriter writer(GURL(url), 0); + ArcContentFileSystemFileStreamWriter writer(GURL(url), /* offset */ 0); // Cancel immediately fails when there's no in-flight operation. int cancel_result = writer.Cancel(base::BindOnce(&NeverCalled)); EXPECT_EQ(net::ERR_UNEXPECTED, cancel_result); @@ -203,9 +279,9 @@ TEST_F(ArcContentFileSystemFileStreamWriterTest, CancelAfterFinishedOperation) { std::string url = - CreateFileWithContent("file_a", std::string(), true /* seekable */); + CreateFileWithContent("file_a", std::string(), /* seekable */ true); { - ArcContentFileSystemFileStreamWriter writer(GURL(url), 0); + ArcContentFileSystemFileStreamWriter writer(GURL(url), /* offset */ 0); EXPECT_EQ(net::OK, WriteStringToWriter(&writer, "foo")); // Cancel immediately fails when there's no in-flight operation. @@ -213,14 +289,14 @@ EXPECT_EQ(net::ERR_UNEXPECTED, cancel_result); } base::RunLoop().RunUntilIdle(); - EXPECT_EQ("foo", GetFileContent(url, 6)); + EXPECT_EQ("foo", GetFileContent(url, /* bytes */ 6)); } TEST_F(ArcContentFileSystemFileStreamWriterTest, CancelWrite) { std::string url = - CreateFileWithContent("file_a", "foobar", true /* seekable */); + CreateFileWithContent("file_a", "foobar", /* seekable */ true); { - ArcContentFileSystemFileStreamWriter writer(GURL(url), 0); + ArcContentFileSystemFileStreamWriter writer(GURL(url), /* offset */ 0); scoped_refptr<net::StringIOBuffer> buffer( base::MakeRefCounted<net::StringIOBuffer>("xxx"));
diff --git a/chrome/browser/ash/borealis/borealis_context_manager_impl.cc b/chrome/browser/ash/borealis/borealis_context_manager_impl.cc index e95e82e..a059fb0 100644 --- a/chrome/browser/ash/borealis/borealis_context_manager_impl.cc +++ b/chrome/browser/ash/borealis/borealis_context_manager_impl.cc
@@ -85,19 +85,19 @@ BorealisContextManagerImpl::BorealisContextManagerImpl(Profile* profile) : profile_(profile), weak_factory_(this) { - // DBusThreadManager may not be initialized in tests. - if (chromeos::DBusThreadManager::IsInitialized()) { + // ConciergeClient may not be initialized in tests. + if (chromeos::ConciergeClient::Get()) { ShutDownBorealisIfRunning(); chromeos::ConciergeClient::Get()->AddVmObserver(this); } } BorealisContextManagerImpl::~BorealisContextManagerImpl() { - // Even if initialized, DBusThreadManager may be destroyed prior to - // BorealisService/BorealisContextManagerImpl in tests. Therefore we must not - // keep a pointer to the observed ConciergeClient, either directly or via - // ScopedObservation or similar. - if (chromeos::DBusThreadManager::IsInitialized()) { + // Even if initialized, DBusThreadManager or ConciergeClient may be destroyed + // prior to BorealisService/BorealisContextManagerImpl in tests. Therefore we + // must not keep a pointer to the observed ConciergeClient, either directly or + // via ScopedObservation or similar. + if (chromeos::ConciergeClient::Get()) { chromeos::ConciergeClient::Get()->RemoveVmObserver(this); } }
diff --git a/chrome/browser/ash/eche_app/eche_app_manager_factory.cc b/chrome/browser/ash/eche_app/eche_app_manager_factory.cc index 54c064c..e4dd75e 100644 --- a/chrome/browser/ash/eche_app/eche_app_manager_factory.cc +++ b/chrome/browser/ash/eche_app/eche_app_manager_factory.cc
@@ -62,27 +62,6 @@ ->eche_tray(); } -void CloseEche(Profile* profile) { - if (features::IsEcheCustomWidgetEnabled()) { - auto* eche_tray = GetEcheTray(); - if (eche_tray) { - eche_tray->PurgeAndClose(); - } - return; - } - for (auto* browser : *(BrowserList::GetInstance())) { - if (browser->profile() != profile) - continue; - if (!browser->app_controller() || - !browser->app_controller()->system_app() || - browser->app_controller()->system_app()->GetType() != - web_app::SystemAppType::ECHE) { - continue; - } - browser->window()->Close(); - return; - } -} // Enumeration of possible interactions with a PhoneHub notification. Keep in // sync with corresponding enum in tools/metrics/histograms/enums.xml. These // values are persisted to logs. Entries should not be renumbered and numeric @@ -102,7 +81,6 @@ eche_tray->SetVisiblePreferred(true); if (!features::IsEcheSWAInBackgroundEnabled()) { eche_tray->ShowBubble(); - } else { eche_tray->InitBubble(); @@ -160,27 +138,13 @@ params); } -void LaunchEcheApp(Profile* profile, - const absl::optional<int64_t>& notification_id, - const std::string& package_name, - const std::u16string& visible_name, - const absl::optional<int64_t>& user_id, - const gfx::Image& icon) { - LaunchWebApp(package_name, notification_id, visible_name, user_id, icon, - profile); - base::UmaHistogramEnumeration("Eche.NotificationClicked", - NotificationInteraction::kOpenAppStreaming); - EcheAppManagerFactory::GetInstance() - ->CloseConnectionOrLaunchErrorNotifications(); -} - void RelaunchLast(Profile* profile) { std::unique_ptr<LaunchedAppInfo> last_launched_app_info = EcheAppManagerFactory::GetInstance()->GetLastLaunchedAppInfo(); - LaunchEcheApp(profile, absl::nullopt, last_launched_app_info->package_name(), - last_launched_app_info->visible_name(), - last_launched_app_info->user_id(), - last_launched_app_info->icon()); + EcheAppManagerFactory::LaunchEcheApp( + profile, absl::nullopt, last_launched_app_info->package_name(), + last_launched_app_info->visible_name(), last_launched_app_info->user_id(), + last_launched_app_info->icon()); } } // namespace @@ -244,6 +208,55 @@ } } +// static +void EcheAppManagerFactory::CloseEche(Profile* profile) { + if (features::IsEcheCustomWidgetEnabled()) { + GetEcheTray()->PurgeAndClose(); + return; + } + for (auto* browser : *(BrowserList::GetInstance())) { + if (browser->profile() != profile) + continue; + if (!browser->app_controller() || + !browser->app_controller()->system_app() || + browser->app_controller()->system_app()->GetType() != + web_app::SystemAppType::ECHE) { + continue; + } + browser->window()->Close(); + return; + } +} + +// static +void EcheAppManagerFactory::LaunchEcheApp( + Profile* profile, + const absl::optional<int64_t>& notification_id, + const std::string& package_name, + const std::u16string& visible_name, + const absl::optional<int64_t>& user_id, + const gfx::Image& icon) { + LaunchWebApp(package_name, notification_id, visible_name, user_id, icon, + profile); + base::UmaHistogramEnumeration("Eche.NotificationClicked", + NotificationInteraction::kOpenAppStreaming); + EcheAppManagerFactory::GetInstance() + ->CloseConnectionOrLaunchErrorNotifications(); +} + +// static +void EcheAppManagerFactory::OnStreamStateChanged( + Profile* profile, + const mojom::StreamStatus status) { + if (status == mojom::StreamStatus::kStreamStatusStarted && + features::IsEcheCustomWidgetEnabled() && + features::IsEcheSWAInBackgroundEnabled()) { + GetEcheTray()->ShowBubble(); + } else if (status == mojom::StreamStatus::kStreamStatusStopped) { + CloseEche(profile); + } +} + EcheAppManagerFactory::EcheAppManagerFactory() : BrowserContextKeyedServiceFactory( "EcheAppManager", @@ -299,10 +312,12 @@ profile->GetPrefs(), GetSystemInfo(profile), phone_hub_manager, device_sync_client, multidevice_setup_client, secure_channel_client, std::move(presence_monitor_client), - base::BindRepeating(&LaunchEcheApp, profile), - base::BindRepeating(&CloseEche, profile), + base::BindRepeating(&EcheAppManagerFactory::LaunchEcheApp, profile), + base::BindRepeating(&EcheAppManagerFactory::CloseEche, profile), base::BindRepeating(&EcheAppManagerFactory::ShowNotification, - weak_ptr_factory_.GetWeakPtr(), profile)); + weak_ptr_factory_.GetWeakPtr(), profile), + base::BindRepeating(&EcheAppManagerFactory::OnStreamStateChanged, + profile)); } std::unique_ptr<SystemInfo> EcheAppManagerFactory::GetSystemInfo(
diff --git a/chrome/browser/ash/eche_app/eche_app_manager_factory.h b/chrome/browser/ash/eche_app/eche_app_manager_factory.h index f505952..8005689 100644 --- a/chrome/browser/ash/eche_app/eche_app_manager_factory.h +++ b/chrome/browser/ash/eche_app/eche_app_manager_factory.h
@@ -93,6 +93,15 @@ const absl::optional<std::u16string>& title, const absl::optional<std::u16string>& message, std::unique_ptr<LaunchAppHelper::NotificationInfo> info); + static void CloseEche(Profile* profile); + static void LaunchEcheApp(Profile* profile, + const absl::optional<int64_t>& notification_id, + const std::string& package_name, + const std::u16string& visible_name, + const absl::optional<int64_t>& user_id, + const gfx::Image& icon); + static void OnStreamStateChanged(Profile* profile, + const mojom::StreamStatus status); void SetLastLaunchedAppInfo( std::unique_ptr<LaunchedAppInfo> last_launched_app_info);
diff --git a/chrome/browser/ash/eche_app/eche_app_manager_factory_unittest.cc b/chrome/browser/ash/eche_app/eche_app_manager_factory_unittest.cc new file mode 100644 index 0000000..d1a2031c --- /dev/null +++ b/chrome/browser/ash/eche_app/eche_app_manager_factory_unittest.cc
@@ -0,0 +1,184 @@ +// 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/ash/eche_app/eche_app_manager_factory.h" + +#include "ash/constants/ash_features.h" +#include "ash/system/eche/eche_tray.h" +#include "ash/system/status_area_widget_test_helper.h" +#include "ash/system/tray/tray_bubble_wrapper.h" +#include "ash/test/test_ash_web_view_factory.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/test/base/chrome_ash_test_base.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile.h" +#include "chrome/test/base/testing_profile_manager.h" + +namespace ash { +namespace eche_app { + +class EcheAppManagerFactoryTest : public ChromeAshTestBase { + protected: + EcheAppManagerFactoryTest() { + scoped_feature_list_.InitWithFeatures( + /*enabled_features=*/{features::kEcheSWA, features::kEcheCustomWidget}, + /*disabled_features=*/{features::kEcheSWAInBackground}); + profile_manager_ = std::make_unique<TestingProfileManager>( + TestingBrowserProcess::GetGlobal()); + if (profile_manager_->SetUp()) { + profile_ = profile_manager_->CreateTestingProfile("testing_profile"); + } + } + ~EcheAppManagerFactoryTest() override = default; + EcheAppManagerFactoryTest(const EcheAppManagerFactoryTest&) = delete; + EcheAppManagerFactoryTest& operator=(const EcheAppManagerFactoryTest&) = + delete; + + // AshTestBase::Test: + void SetUp() override { + DCHECK(profile_); + DCHECK(test_web_view_factory_.get()); + ChromeAshTestBase::SetUp(); + eche_tray_ = + ash::StatusAreaWidgetTestHelper::GetStatusAreaWidget()->eche_tray(); + } + + TestingProfile* GetProfile() { return profile_; } + + EcheTray* eche_tray() { return eche_tray_; } + + private: + base::test::ScopedFeatureList scoped_feature_list_; + std::unique_ptr<TestingProfileManager> profile_manager_; + TestingProfile* profile_; + EcheTray* eche_tray_ = nullptr; + // Calling the factory constructor is enough to set it up. + std::unique_ptr<TestAshWebViewFactory> test_web_view_factory_ = + std::make_unique<TestAshWebViewFactory>(); +}; + +class EcheAppManagerFactoryWithBackgroundTest : public ChromeAshTestBase { + protected: + EcheAppManagerFactoryWithBackgroundTest() { + scoped_feature_list_.InitWithFeatures( + /*enabled_features=*/{features::kEcheSWA, features::kEcheCustomWidget, + features::kEcheSWAInBackground}, + /*disabled_features=*/{}); + profile_manager_ = std::make_unique<TestingProfileManager>( + TestingBrowserProcess::GetGlobal()); + if (profile_manager_->SetUp()) { + profile_ = profile_manager_->CreateTestingProfile("testing_profile"); + } + } + ~EcheAppManagerFactoryWithBackgroundTest() override = default; + EcheAppManagerFactoryWithBackgroundTest( + const EcheAppManagerFactoryWithBackgroundTest&) = delete; + EcheAppManagerFactoryWithBackgroundTest& operator=( + const EcheAppManagerFactoryWithBackgroundTest&) = delete; + + // AshTestBase::Test: + void SetUp() override { + DCHECK(profile_); + DCHECK(test_web_view_factory_.get()); + ChromeAshTestBase::SetUp(); + eche_tray_ = + ash::StatusAreaWidgetTestHelper::GetStatusAreaWidget()->eche_tray(); + } + + TestingProfile* GetProfile() { return profile_; } + + EcheTray* eche_tray() { return eche_tray_; } + + private: + base::test::ScopedFeatureList scoped_feature_list_; + std::unique_ptr<TestingProfileManager> profile_manager_; + TestingProfile* profile_; + EcheTray* eche_tray_ = nullptr; + // Calling the factory constructor is enough to set it up. + std::unique_ptr<TestAshWebViewFactory> test_web_view_factory_ = + std::make_unique<TestAshWebViewFactory>(); +}; + +TEST_F(EcheAppManagerFactoryTest, LaunchEcheApp) { + const int64_t user_id = 1; + const char16_t visible_name[] = u"Fake App"; + const char package_name[] = "com.fakeapp"; + EcheAppManagerFactory::LaunchEcheApp( + GetProfile(), /*notification_id=*/absl::nullopt, package_name, + visible_name, user_id, gfx::Image()); + base::RunLoop().RunUntilIdle(); + // Eche tray should be visible after launch. + EXPECT_TRUE(eche_tray()->is_active()); +} + +TEST_F(EcheAppManagerFactoryTest, CloseEche) { + const int64_t user_id = 1; + const char16_t visible_name[] = u"Fake App"; + const char package_name[] = "com.fakeapp"; + EcheAppManagerFactory::LaunchEcheApp( + GetProfile(), /*notification_id=*/absl::nullopt, package_name, + visible_name, user_id, gfx::Image()); + EcheAppManagerFactory::CloseEche(GetProfile()); + base::RunLoop().RunUntilIdle(); + // Eche tray should be visible after close. + EXPECT_FALSE(eche_tray()->is_active()); +} + +TEST_F(EcheAppManagerFactoryTest, OnStreamStateChanged) { + const int64_t user_id = 1; + const char16_t visible_name[] = u"Fake App"; + const char package_name[] = "com.fakeapp"; + EcheAppManagerFactory::LaunchEcheApp( + GetProfile(), /*notification_id=*/absl::nullopt, package_name, + visible_name, user_id, gfx::Image()); + + // Eche tray should be visible when streaming is active + EcheAppManagerFactory::OnStreamStateChanged( + GetProfile(), mojom::StreamStatus::kStreamStatusStarted); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(eche_tray()->is_active()); + + // Eche tray should not be visible when streaming is finished + EcheAppManagerFactory::OnStreamStateChanged( + GetProfile(), mojom::StreamStatus::kStreamStatusStopped); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(eche_tray()->is_active()); +} + +TEST_F(EcheAppManagerFactoryWithBackgroundTest, LaunchEcheApp) { + const int64_t user_id = 1; + const char16_t visible_name[] = u"Fake App"; + const char package_name[] = "com.fakeapp"; + EcheAppManagerFactory::LaunchEcheApp( + GetProfile(), /*notification_id=*/absl::nullopt, package_name, + visible_name, user_id, gfx::Image()); + base::RunLoop().RunUntilIdle(); + // Eche tray should be visible when streaming is active, not ative when + // launch. + EXPECT_FALSE(eche_tray()->is_active()); +} + +TEST_F(EcheAppManagerFactoryWithBackgroundTest, OnStreamStateChanged) { + const int64_t user_id = 1; + const char16_t visible_name[] = u"Fake App"; + const char package_name[] = "com.fakeapp"; + EcheAppManagerFactory::LaunchEcheApp( + GetProfile(), /*notification_id=*/absl::nullopt, package_name, + visible_name, user_id, gfx::Image()); + + // Eche tray should be visible when streaming is active + EcheAppManagerFactory::OnStreamStateChanged( + GetProfile(), mojom::StreamStatus::kStreamStatusStarted); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(eche_tray()->is_active()); + + // Eche tray should not be visible when streaming is finished + EcheAppManagerFactory::OnStreamStateChanged( + GetProfile(), mojom::StreamStatus::kStreamStatusStopped); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(eche_tray()->is_active()); +} + +} // namespace eche_app +} // namespace ash
diff --git a/chrome/browser/ash/file_manager/file_manager_string_util.cc b/chrome/browser/ash/file_manager/file_manager_string_util.cc index ab2acf6d..2cca21a3 100644 --- a/chrome/browser/ash/file_manager/file_manager_string_util.cc +++ b/chrome/browser/ash/file_manager/file_manager_string_util.cc
@@ -97,6 +97,9 @@ IDS_FILE_BROWSER_POWERPOINT_PRESENTATION_FILE_TYPE); SET_STRING("RAR_ARCHIVE_FILE_TYPE", IDS_FILE_BROWSER_RAR_ARCHIVE_FILE_TYPE); SET_STRING("TAR_ARCHIVE_FILE_TYPE", IDS_FILE_BROWSER_TAR_ARCHIVE_FILE_TYPE); + SET_STRING("ISO_ARCHIVE_FILE_TYPE", IDS_FILE_BROWSER_ISO_ARCHIVE_FILE_TYPE); + SET_STRING("7Z_ARCHIVE_FILE_TYPE", IDS_FILE_BROWSER_7Z_ARCHIVE_FILE_TYPE); + SET_STRING("CRX_ARCHIVE_FILE_TYPE", IDS_FILE_BROWSER_CRX_ARCHIVE_FILE_TYPE); SET_STRING("TAR_BZIP2_ARCHIVE_FILE_TYPE", IDS_FILE_BROWSER_TAR_BZIP2_ARCHIVE_FILE_TYPE); SET_STRING("BZIP2_ARCHIVE_FILE_TYPE",
diff --git a/chrome/browser/ash/file_manager/file_tasks.cc b/chrome/browser/ash/file_manager/file_tasks.cc index b4d6a203..3ed93c27 100644 --- a/chrome/browser/ash/file_manager/file_tasks.cc +++ b/chrome/browser/ash/file_manager/file_tasks.cc
@@ -264,11 +264,20 @@ web_drive_office_action_id_ = parseFilesAppActionId(web_drive_office_task->task_descriptor.action_id); - // Remove Web Drive Office action if Web Drive Office is disabled or if - // Drive is Offline. - if (!base::FeatureList::IsEnabled(ash::features::kFilesWebDriveOffice) || - drive::util::GetDriveConnectionStatus(profile) != - drive::util::DRIVE_CONNECTED) { + // Remove Web Drive Office action if Web Drive Office is disabled. + if (!base::FeatureList::IsEnabled(ash::features::kFilesWebDriveOffice)) { + UMA_HISTOGRAM_ENUMERATION(kWebDriveOfficeMetricName, + WebDriveOfficeTaskResult::FLAG_DISABLED); + disabled_actions_.emplace(web_drive_office_action_id_); + EndAdjustTasks(); + return; + } + + // Remove Web Drive Office action if Drive is Offline. + if (drive::util::GetDriveConnectionStatus(profile) != + drive::util::DRIVE_CONNECTED) { + UMA_HISTOGRAM_ENUMERATION(kWebDriveOfficeMetricName, + WebDriveOfficeTaskResult::OFFLINE); disabled_actions_.emplace(web_drive_office_action_id_); EndAdjustTasks(); return; @@ -282,12 +291,17 @@ void ProcessNextEntryForWebDriveOffice(size_t entry_index) { // Web Drive Office is available for all the selected entries. if (entry_index == entries.size()) { + UMA_HISTOGRAM_ENUMERATION(kWebDriveOfficeMetricName, + WebDriveOfficeTaskResult::AVAILABLE); EndAdjustTasks(); return; } + // Check whether the entry is on Drive. if (!::file_manager::util::IsDriveLocalPath(profile, entries[entry_index].path)) { + UMA_HISTOGRAM_ENUMERATION(kWebDriveOfficeMetricName, + WebDriveOfficeTaskResult::NOT_ON_DRIVE); disabled_actions_.emplace(web_drive_office_action_id_); EndAdjustTasks(); return; @@ -301,6 +315,8 @@ integration_service->GetDriveFsInterface() && integration_service->GetRelativeDrivePath(entries[entry_index].path, &relative_drive_path))) { + UMA_HISTOGRAM_ENUMERATION(kWebDriveOfficeMetricName, + WebDriveOfficeTaskResult::DRIVE_ERROR); disabled_actions_.emplace(web_drive_office_action_id_); EndAdjustTasks(); return; @@ -321,6 +337,8 @@ drive::FileError error, drivefs::mojom::FileMetadataPtr metadata) { if (error != drive::FILE_ERROR_OK) { + UMA_HISTOGRAM_ENUMERATION(kWebDriveOfficeMetricName, + WebDriveOfficeTaskResult::DRIVE_METADATA_ERROR); disabled_actions_.emplace(web_drive_office_action_id_); EndAdjustTasks(); return; @@ -328,8 +346,24 @@ GURL hosted_url(metadata->alternate_url); // URLs for editing Office files in Web Drive all have a "docs.google.com" - // host. - if (!hosted_url.is_valid() || hosted_url.host() != "docs.google.com") { + // host: Disable the task if the entry doesn't have such alternate URL. + if (!hosted_url.is_valid()) { + UMA_HISTOGRAM_ENUMERATION( + kWebDriveOfficeMetricName, + WebDriveOfficeTaskResult::INVALID_ALTERNATE_URL); + disabled_actions_.emplace(web_drive_office_action_id_); + EndAdjustTasks(); + return; + } else if (hosted_url.host() == "drive.google.com") { + UMA_HISTOGRAM_ENUMERATION(kWebDriveOfficeMetricName, + WebDriveOfficeTaskResult::DRIVE_ALTERNATE_URL); + disabled_actions_.emplace(web_drive_office_action_id_); + EndAdjustTasks(); + return; + } else if (hosted_url.host() != "docs.google.com") { + UMA_HISTOGRAM_ENUMERATION( + kWebDriveOfficeMetricName, + WebDriveOfficeTaskResult::UNEXPECTED_ALTERNATE_URL); disabled_actions_.emplace(web_drive_office_action_id_); EndAdjustTasks(); return;
diff --git a/chrome/browser/ash/file_manager/file_tasks.h b/chrome/browser/ash/file_manager/file_tasks.h index 2e437a0d..d0aa969 100644 --- a/chrome/browser/ash/file_manager/file_tasks.h +++ b/chrome/browser/ash/file_manager/file_tasks.h
@@ -144,6 +144,27 @@ TaskType StringToTaskType(const std::string& str); std::string TaskTypeToString(TaskType task_type); +// UMA metric name that tracks the result of trying to enable the Web Drive +// Office task. +constexpr char kWebDriveOfficeMetricName[] = + "FileBrowser.OfficeFiles.WebDriveOffice"; + +// List of UMA enum value for Web Drive Office task results. The enum values +// must be kept in sync with WebDriveOfficeTaskResult in +// tools/metrics/histograms/enums.xml. +enum class WebDriveOfficeTaskResult { + AVAILABLE = 0, + FLAG_DISABLED = 1, + OFFLINE = 2, + NOT_ON_DRIVE = 3, + DRIVE_ERROR = 4, + DRIVE_METADATA_ERROR = 5, + INVALID_ALTERNATE_URL = 6, + DRIVE_ALTERNATE_URL = 7, + UNEXPECTED_ALTERNATE_URL = 8, + kMaxValue = UNEXPECTED_ALTERNATE_URL, +}; + // Describes a task. // See the comment above for <app-id>, <task-type>, and <action-id>. struct TaskDescriptor {
diff --git a/chrome/browser/ash/input_method/assistive_suggester.cc b/chrome/browser/ash/input_method/assistive_suggester.cc index cb31d7d9..e2a324f4 100644 --- a/chrome/browser/ash/input_method/assistive_suggester.cc +++ b/chrome/browser/ash/input_method/assistive_suggester.cc
@@ -453,11 +453,11 @@ (cursor_pos == len || base::IsAsciiWhitespace(text[cursor_pos])) && (base::IsAsciiWhitespace(text[cursor_pos - 1]) || IsSuggestionShown())) { if (IsSuggestionShown()) { - return current_suggester_->Suggest(text, cursor_pos, anchor_pos); + return current_suggester_->Suggest(text, cursor_pos); } if (IsAssistPersonalInfoEnabled() && suggester_switch_->IsPersonalInfoSuggestionAllowed() && - personal_info_suggester_.Suggest(text, cursor_pos, anchor_pos)) { + personal_info_suggester_.Suggest(text, cursor_pos)) { current_suggester_ = &personal_info_suggester_; if (personal_info_suggester_.IsFirstShown()) { RecordAssistiveCoverage(current_suggester_->GetProposeActionType()); @@ -466,7 +466,7 @@ } else if (IsEmojiSuggestAdditionEnabled() && !IsEnhancedEmojiSuggestEnabled() && suggester_switch_->IsEmojiSuggestionAllowed() && - emoji_suggester_.Suggest(text, cursor_pos, anchor_pos)) { + emoji_suggester_.Suggest(text, cursor_pos)) { current_suggester_ = &emoji_suggester_; RecordAssistiveCoverage(current_suggester_->GetProposeActionType()); return true;
diff --git a/chrome/browser/ash/input_method/emoji_suggester.cc b/chrome/browser/ash/input_method/emoji_suggester.cc index 0d5e4af..3b80cc1 100644 --- a/chrome/browser/ash/input_method/emoji_suggester.cc +++ b/chrome/browser/ash/input_method/emoji_suggester.cc
@@ -221,9 +221,7 @@ return false; } -bool EmojiSuggester::Suggest(const std::u16string& text, - size_t cursor_pos, - size_t anchor_pos) { +bool EmojiSuggester::Suggest(const std::u16string& text, size_t cursor_pos) { if (emoji_map_.empty() || text[text.length() - 1] != kSpaceChar) return false; std::string last_word =
diff --git a/chrome/browser/ash/input_method/emoji_suggester.h b/chrome/browser/ash/input_method/emoji_suggester.h index ad504a0..238ba7a4 100644 --- a/chrome/browser/ash/input_method/emoji_suggester.h +++ b/chrome/browser/ash/input_method/emoji_suggester.h
@@ -35,9 +35,7 @@ void OnExternalSuggestionsUpdated( const std::vector<ime::TextSuggestion>& suggestions) override; SuggestionStatus HandleKeyEvent(const ui::KeyEvent& event) override; - bool Suggest(const std::u16string& text, - size_t cursor_pos, - size_t anchor_pos) override; + bool Suggest(const std::u16string& text, size_t cursor_pos) override; bool AcceptSuggestion(size_t index) override; void DismissSuggestion() override; AssistiveType GetProposeActionType() override;
diff --git a/chrome/browser/ash/input_method/emoji_suggester_unittest.cc b/chrome/browser/ash/input_method/emoji_suggester_unittest.cc index 54d91602..0cd381e9 100644 --- a/chrome/browser/ash/input_method/emoji_suggester_unittest.cc +++ b/chrome/browser/ash/input_method/emoji_suggester_unittest.cc
@@ -145,58 +145,58 @@ }; TEST_F(EmojiSuggesterTest, SuggestWhenStringEndsWithSpace) { - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); } TEST_F(EmojiSuggesterTest, SuggestWhenStringStartsWithOpenBracket) { - EXPECT_TRUE(emoji_suggester_->Suggest(u"(happy ", 7, 7)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"(happy ", 7)); } TEST_F(EmojiSuggesterTest, SuggestWhenStringEndsWithSpaceAndIsUppercase) { - EXPECT_TRUE(emoji_suggester_->Suggest(u"HAPPY ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"HAPPY ", 6)); } TEST_F(EmojiSuggesterTest, DoNotSuggestWhenStringEndsWithNewLine) { - EXPECT_FALSE(emoji_suggester_->Suggest(u"happy\n", 6, 6)); + EXPECT_FALSE(emoji_suggester_->Suggest(u"happy\n", 6)); } TEST_F(EmojiSuggesterTest, DoNotSuggestWhenStringDoesNotEndWithSpace) { - EXPECT_FALSE(emoji_suggester_->Suggest(u"happy", 5, 5)); + EXPECT_FALSE(emoji_suggester_->Suggest(u"happy", 5)); } TEST_F(EmojiSuggesterTest, DoNotSuggestWhenWordNotInMap) { - EXPECT_FALSE(emoji_suggester_->Suggest(u"hapy ", 5, 5)); + EXPECT_FALSE(emoji_suggester_->Suggest(u"hapy ", 5)); } TEST_F(EmojiSuggesterTest, DoNotShowSuggestionWhenVirtualKeyboardEnabled) { chrome_keyboard_controller_client_->set_keyboard_visible_for_test(true); - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); EXPECT_FALSE(emoji_suggester_->HasSuggestions()); } TEST_F(EmojiSuggesterTest, ReturnkBrowsingWhenPressingDown) { - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); ui::KeyEvent event = CreateKeyEventFromCode(ui::DomCode::ARROW_DOWN); EXPECT_EQ(SuggestionStatus::kBrowsing, emoji_suggester_->HandleKeyEvent(event)); } TEST_F(EmojiSuggesterTest, ReturnkBrowsingWhenPressingUp) { - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); ui::KeyEvent event = CreateKeyEventFromCode(ui::DomCode::ARROW_UP); EXPECT_EQ(SuggestionStatus::kBrowsing, emoji_suggester_->HandleKeyEvent(event)); } TEST_F(EmojiSuggesterTest, ReturnkDismissWhenPressingEsc) { - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); ui::KeyEvent event = CreateKeyEventFromCode(ui::DomCode::ESCAPE); EXPECT_EQ(SuggestionStatus::kDismiss, emoji_suggester_->HandleKeyEvent(event)); } TEST_F(EmojiSuggesterTest, ReturnkNotHandledWhenPressDownThenValidNumber) { - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); ui::KeyEvent event1 = CreateKeyEventFromCode(ui::DomCode::ARROW_DOWN); emoji_suggester_->HandleKeyEvent(event1); ui::KeyEvent event2 = CreateKeyEventFromCode(ui::DomCode::DIGIT1); @@ -205,7 +205,7 @@ } TEST_F(EmojiSuggesterTest, ReturnkNotHandledWhenPressDownThenNotANumber) { - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); ui::KeyEvent event1 = CreateKeyEventFromCode(ui::DomCode::ARROW_DOWN); emoji_suggester_->HandleKeyEvent(event1); ui::KeyEvent event2 = CreateKeyEventFromCode(ui::DomCode::US_A); @@ -215,7 +215,7 @@ TEST_F(EmojiSuggesterTest, ReturnkNotHandledWhenPressingEnterAndACandidateHasNotBeenChosen) { - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); ui::KeyEvent event = CreateKeyEventFromCode(ui::DomCode::ENTER); EXPECT_EQ(SuggestionStatus::kNotHandled, emoji_suggester_->HandleKeyEvent(event)); @@ -223,7 +223,7 @@ TEST_F(EmojiSuggesterTest, ReturnkAcceptWhenPressingEnterAndACandidateHasBeenChosenByPressingDown) { - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); // Press ui::DomCode::ARROW_DOWN to choose a candidate. ui::KeyEvent event1 = CreateKeyEventFromCode(ui::DomCode::ARROW_DOWN); emoji_suggester_->HandleKeyEvent(event1); @@ -233,13 +233,13 @@ } TEST_F(EmojiSuggesterTest, HighlightFirstCandidateWhenPressingDown) { - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); Press(ui::DomCode::ARROW_DOWN); engine_->VerifyCandidateHighlighted(0, true); } TEST_F(EmojiSuggesterTest, HighlightButtonCorrectlyWhenPressingUp) { - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); // Go into the window. Press(ui::DomCode::ARROW_DOWN); @@ -265,7 +265,7 @@ } TEST_F(EmojiSuggesterTest, HighlightButtonCorrectlyWhenPressingDown) { - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); // Press ui::DomCode::ARROW_DOWN to go through candidates. for (size_t i = 0; i < emoji_suggester_->GetCandidatesSizeForTesting(); i++) { @@ -291,7 +291,7 @@ TEST_F(EmojiSuggesterTest, OpenSettingWhenPressingEnterAndLearnMoreButtonIsChosen) { - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); // Go into the window. Press(ui::DomCode::ARROW_DOWN); @@ -303,57 +303,57 @@ } TEST_F(EmojiSuggesterTest, DoesNotShowIndicesWhenFirstSuggesting) { - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); engine_->VerifyShowIndices(false); } TEST_F(EmojiSuggesterTest, DoesNotShowIndexAfterPressingDown) { - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); Press(ui::DomCode::ARROW_DOWN); engine_->VerifyShowIndices(false); } TEST_F(EmojiSuggesterTest, DoesNotShowIndicesAfterGettingSuggestionsTwice) { - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); engine_->VerifyShowIndices(false); } TEST_F(EmojiSuggesterTest, DoesNotShowIndicesAfterPressingDownThenGetNewSuggestions) { - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); Press(ui::DomCode::ARROW_DOWN); - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); engine_->VerifyShowIndices(false); } TEST_F(EmojiSuggesterTest, ShowSettingLinkCorrectly) { for (int i = 0; i < kEmojiSuggesterShowSettingMaxCount; i++) { - emoji_suggester_->Suggest(u"happy ", 6, 6); + emoji_suggester_->Suggest(u"happy ", 6); // Dismiss suggestion. Press(ui::DomCode::ESCAPE); engine_->VerifyShowSettingLink(true); } - emoji_suggester_->Suggest(u"happy ", 6, 6); + emoji_suggester_->Suggest(u"happy ", 6); engine_->VerifyShowSettingLink(false); } TEST_F(EmojiSuggesterTest, IsShowingSuggestionTrueWhenCandidatesAvailable) { - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); EXPECT_TRUE(emoji_suggester_->HasSuggestions()); } TEST_F(EmojiSuggesterTest, IsShowingSuggestionFalseWhenCandidatesUnavailable) { - EXPECT_FALSE(emoji_suggester_->Suggest(u"hapy", 4, 4)); + EXPECT_FALSE(emoji_suggester_->Suggest(u"hapy", 4)); EXPECT_FALSE(emoji_suggester_->HasSuggestions()); } TEST_F(EmojiSuggesterTest, GetSuggestionReturnsCandidatesWhenAvailable) { - EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6, 6)); + EXPECT_TRUE(emoji_suggester_->Suggest(u"happy ", 6)); EXPECT_EQ(emoji_suggester_->GetSuggestions(), (std::vector<TextSuggestion>{ TextSuggestion{.mode = TextSuggestionMode::kPrediction, @@ -370,7 +370,7 @@ TEST_F(EmojiSuggesterTest, GetSuggestionDoesNotReturnCandidatesWhenUnavailable) { - EXPECT_FALSE(emoji_suggester_->Suggest(u"hapy", 4, 4)); + EXPECT_FALSE(emoji_suggester_->Suggest(u"hapy", 4)); EXPECT_TRUE(emoji_suggester_->GetSuggestions().empty()); }
diff --git a/chrome/browser/ash/input_method/multi_word_suggester.cc b/chrome/browser/ash/input_method/multi_word_suggester.cc index 282ca6094..9593dab1 100644 --- a/chrome/browser/ash/input_method/multi_word_suggester.cc +++ b/chrome/browser/ash/input_method/multi_word_suggester.cc
@@ -26,6 +26,8 @@ using ime::TextSuggestionMode; using ime::TextSuggestionType; +// Used for UmaHistogramExactLinear, should remain <= 101. +constexpr size_t kMaxSuggestionLength = 101; constexpr char kMultiWordFirstAcceptTimeDays[] = "multi_word_first_accept"; constexpr char16_t kSuggestionShownMessage[] = u"predictive writing candidate shown, press down to select or " @@ -74,6 +76,12 @@ delta); } +void RecordSuggestionLength(size_t suggestion_length) { + base::UmaHistogramExactLinear( + "InputMethod.Assistive.MultiWord.SuggestionLength", suggestion_length, + kMaxSuggestionLength); +} + absl::optional<int> GetTimeFirstAcceptedSuggestion(Profile* profile) { DictionaryPrefUpdate update(profile->GetPrefs(), prefs::kAssistiveInputFeatureSettings); @@ -153,6 +161,11 @@ return; } + if (auto suggestion_length = multi_word_suggestion->text.size(); + suggestion_length < kMaxSuggestionLength) { + RecordSuggestionLength(suggestion_length); + } + auto suggestion = SuggestionState::Suggestion{ .mode = multi_word_suggestion->mode, .text = base::UTF8ToUTF16(multi_word_suggestion->text), @@ -192,8 +205,7 @@ } bool MultiWordSuggester::Suggest(const std::u16string& text, - size_t cursor_pos, - size_t anchor_pos) { + size_t cursor_pos) { return state_.IsSuggestionShowing(); }
diff --git a/chrome/browser/ash/input_method/multi_word_suggester.h b/chrome/browser/ash/input_method/multi_word_suggester.h index 6701b0f..dfd3912 100644 --- a/chrome/browser/ash/input_method/multi_word_suggester.h +++ b/chrome/browser/ash/input_method/multi_word_suggester.h
@@ -32,9 +32,7 @@ void OnExternalSuggestionsUpdated( const std::vector<ime::TextSuggestion>& suggestions) override; SuggestionStatus HandleKeyEvent(const ui::KeyEvent& event) override; - bool Suggest(const std::u16string& text, - size_t cursor_pos, - size_t anchor_pos) override; + bool Suggest(const std::u16string& text, size_t cursor_pos) override; bool AcceptSuggestion(size_t index = 0) override; void DismissSuggestion() override; AssistiveType GetProposeActionType() override;
diff --git a/chrome/browser/ash/input_method/multi_word_suggester_unittest.cc b/chrome/browser/ash/input_method/multi_word_suggester_unittest.cc index c9a48f3..9245c7e 100644 --- a/chrome/browser/ash/input_method/multi_word_suggester_unittest.cc +++ b/chrome/browser/ash/input_method/multi_word_suggester_unittest.cc
@@ -450,12 +450,12 @@ suggester_->OnFocus(kFocusedContextId); suggester_->OnSurroundingTextChanged(u"h", /*cursor_pos=*/1, /*anchor_pos=*/1); - suggester_->Suggest(u"h", /*cursor_pos=*/1, /*anchor_pos=*/1); + suggester_->Suggest(u"h", /*cursor_pos=*/1); suggester_->OnExternalSuggestionsUpdated(suggestions); suggester_->OnSurroundingTextChanged(u"hh", /*cursor_pos=*/2, /*anchor_pos=*/2); - EXPECT_FALSE(suggester_->Suggest(u"hh", /*cursor_pos=*/2, /*anchor_pos=*/2)); + EXPECT_FALSE(suggester_->Suggest(u"hh", /*cursor_pos=*/2)); } TEST_F(MultiWordSuggesterTest, DoesNotDismissOnMultipleCursorMoveToEndOfText) { @@ -468,16 +468,15 @@ suggester_->OnFocus(kFocusedContextId); suggester_->OnSurroundingTextChanged(u"hello h", /*cursor_pos=*/7, /*anchor_pos=*/7); - suggester_->Suggest(u"hello h", /*cursor_pos=*/7, /*anchor_pos=*/7); + suggester_->Suggest(u"hello h", /*cursor_pos=*/7); suggester_->OnExternalSuggestionsUpdated(suggestions); suggester_->OnSurroundingTextChanged(u"hello h", /*cursor_pos=*/7, /*anchor_pos=*/7); - suggester_->Suggest(u"hello h", /*cursor_pos=*/7, /*anchor_pos=*/7); + suggester_->Suggest(u"hello h", /*cursor_pos=*/7); suggester_->OnSurroundingTextChanged(u"hello h", /*cursor_pos=*/7, /*anchor_pos=*/7); - EXPECT_TRUE(suggester_->Suggest(u"hello h", /*cursor_pos=*/7, - /*anchor_pos=*/7)); + EXPECT_TRUE(suggester_->Suggest(u"hello h", /*cursor_pos=*/7)); } TEST_F(MultiWordSuggesterTest, TracksLastSuggestionOnSurroundingTextChange) { @@ -491,17 +490,17 @@ suggester_->OnSurroundingTextChanged(u"hey there sam whe", 17, 17); suggester_->OnExternalSuggestionsUpdated(suggestions); suggester_->OnSurroundingTextChanged(u"hey there sam wher", 18, 18); - suggester_->Suggest(u"hey there sam wher", 18, 18); + suggester_->Suggest(u"hey there sam wher", 18); suggester_->OnSurroundingTextChanged(u"hey there sam where", 19, 19); - suggester_->Suggest(u"hey there sam where", 19, 19); + suggester_->Suggest(u"hey there sam where", 19); suggester_->OnSurroundingTextChanged(u"hey there sam where ", 20, 20); - suggester_->Suggest(u"hey there sam where ", 20, 20); + suggester_->Suggest(u"hey there sam where ", 20); suggester_->OnSurroundingTextChanged(u"hey there sam where a", 21, 21); - suggester_->Suggest(u"hey there sam where a", 21, 21); + suggester_->Suggest(u"hey there sam where a", 21); suggester_->OnSurroundingTextChanged(u"hey there sam where ar", 22, 22); - suggester_->Suggest(u"hey there sam where ar", 22, 22); + suggester_->Suggest(u"hey there sam where ar", 22); suggester_->OnSurroundingTextChanged(u"hey there sam where are", 23, 23); - suggester_->Suggest(u"hey there sam where are", 23, 23); + suggester_->Suggest(u"hey there sam where are", 23); EXPECT_TRUE(suggestion_handler_.GetShowingSuggestion()); EXPECT_EQ(suggestion_handler_.GetSuggestionText(), u"where are you going"); @@ -520,9 +519,9 @@ suggester_->OnSurroundingTextChanged(u"h", 1, 1); suggester_->OnExternalSuggestionsUpdated(suggestions); suggester_->OnSurroundingTextChanged(u"ho", 2, 2); - suggester_->Suggest(u"ho", 2, 2); + suggester_->Suggest(u"ho", 2); suggester_->OnSurroundingTextChanged(u"how", 3, 3); - suggester_->Suggest(u"how", 3, 3); + suggester_->Suggest(u"how", 3); EXPECT_TRUE(suggestion_handler_.GetShowingSuggestion()); EXPECT_EQ(suggestion_handler_.GetSuggestionText(), u"how are you"); @@ -541,9 +540,9 @@ suggester_->OnSurroundingTextChanged(u"h", 1, 1); suggester_->OnExternalSuggestionsUpdated(suggestions); suggester_->OnSurroundingTextChanged(u"how ar", 6, 6); - suggester_->Suggest(u"how ar", 6, 6); + suggester_->Suggest(u"how ar", 6); suggester_->OnSurroundingTextChanged(u"how are yo", 10, 10); - suggester_->Suggest(u"how are yo", 10, 10); + suggester_->Suggest(u"how are yo", 10); EXPECT_TRUE(suggestion_handler_.GetShowingSuggestion()); EXPECT_EQ(suggestion_handler_.GetSuggestionText(), u"how are you"); @@ -562,11 +561,11 @@ suggester_->OnSurroundingTextChanged(u"h", 1, 1); suggester_->OnExternalSuggestionsUpdated(suggestions); suggester_->OnSurroundingTextChanged(u"how ar", 6, 6); - suggester_->Suggest(u"how ar", 6, 6); + suggester_->Suggest(u"how ar", 6); suggester_->OnSurroundingTextChanged(u"how yo", 6, 6); // The consumer will handle dismissing the suggestion - EXPECT_FALSE(suggester_->Suggest(u"how yo", 6, 6)); + EXPECT_FALSE(suggester_->Suggest(u"how yo", 6)); } TEST_F(MultiWordSuggesterTest, @@ -581,18 +580,18 @@ suggester_->OnSurroundingTextChanged(u"this is some text", 17, 17); suggester_->OnExternalSuggestionsUpdated(suggestions); suggester_->OnSurroundingTextChanged(u"this is some text ", 18, 18); - suggester_->Suggest(u"this is some text ", 18, 18); + suggester_->Suggest(u"this is some text ", 18); suggester_->OnSurroundingTextChanged(u"this is some text f", 19, 19); - suggester_->Suggest(u"this is some text f", 19, 19); + suggester_->Suggest(u"this is some text f", 19); suggester_->OnSurroundingTextChanged(u"this is some text fo", 20, 20); - suggester_->Suggest(u"this is some text fo", 20, 20); + suggester_->Suggest(u"this is some text fo", 20); suggester_->OnSurroundingTextChanged(u"this is some text f", 19, 19); - suggester_->Suggest(u"this is some text f", 19, 19); + suggester_->Suggest(u"this is some text f", 19); suggester_->OnSurroundingTextChanged(u"this is some text ", 18, 18); - suggester_->Suggest(u"this is some text ", 18, 18); + suggester_->Suggest(u"this is some text ", 18); suggester_->OnSurroundingTextChanged(u"this is some text", 17, 17); - EXPECT_FALSE(suggester_->Suggest(u"this is some text", 17, 17)); + EXPECT_FALSE(suggester_->Suggest(u"this is some text", 17)); } TEST_F(MultiWordSuggesterTest, DoesNotTrackSuggestionPastSuggestionPoint) { @@ -606,13 +605,13 @@ suggester_->OnSurroundingTextChanged(u"this is some text fo", 20, 20); suggester_->OnExternalSuggestionsUpdated(suggestions); suggester_->OnSurroundingTextChanged(u"this is some text for", 21, 21); - suggester_->Suggest(u"this is some text for", 21, 21); + suggester_->Suggest(u"this is some text for", 21); suggester_->OnSurroundingTextChanged(u"this is some text fo", 20, 20); bool at_suggestion_point = - suggester_->Suggest(u"this is some text fo", 20, 20); + suggester_->Suggest(u"this is some text fo", 20); suggester_->OnSurroundingTextChanged(u"this is some text f", 19, 19); bool before_suggestion_point = - suggester_->Suggest(u"this is some text f", 19, 19); + suggester_->Suggest(u"this is some text f", 19); EXPECT_TRUE(at_suggestion_point); EXPECT_FALSE(before_suggestion_point); @@ -630,10 +629,10 @@ suggester_->OnSurroundingTextChanged(u"this is some text fo", 20, 20); suggester_->OnExternalSuggestionsUpdated(suggestions); suggester_->OnSurroundingTextChanged(u"this is some text for", 21, 21); - suggester_->Suggest(u"this is some text for", 21, 21); + suggester_->Suggest(u"this is some text for", 21); suggester_->OnSurroundingTextChanged(u"this is some text for", 15, 15); - EXPECT_FALSE(suggester_->Suggest(u"this is some text for", 15, 15)); + EXPECT_FALSE(suggester_->Suggest(u"this is some text for", 15)); } TEST_F(MultiWordSuggesterTest, DismissesSuggestionOnUserTypingFullSuggestion) { @@ -647,14 +646,14 @@ suggester_->OnSurroundingTextChanged(u"how", 3, 3); suggester_->OnExternalSuggestionsUpdated(suggestions); suggester_->OnSurroundingTextChanged(u"how ", 4, 4); - suggester_->Suggest(u"how ", 4, 4); + suggester_->Suggest(u"how ", 4); suggester_->OnSurroundingTextChanged(u"how a", 5, 5); - suggester_->Suggest(u"how a", 5, 5); + suggester_->Suggest(u"how a", 5); suggester_->OnSurroundingTextChanged(u"how ar", 6, 6); - suggester_->Suggest(u"how ar", 6, 6); + suggester_->Suggest(u"how ar", 6); suggester_->OnSurroundingTextChanged(u"how are", 7, 7); - EXPECT_FALSE(suggester_->Suggest(u"how are", 7, 7)); + EXPECT_FALSE(suggester_->Suggest(u"how are", 7)); } TEST_F(MultiWordSuggesterTest, ReturnsGenericActionIfNoSuggestionHasBeenShown) { @@ -706,7 +705,7 @@ suggester_->OnFocus(kFocusedContextId); suggester_->OnSurroundingTextChanged(u"why ar", 6, 6); - suggester_->Suggest(u"why", 6, 6); + suggester_->Suggest(u"why", 6); suggester_->OnExternalSuggestionsUpdated(suggestions); SendKeyEvent(suggester_.get(), ui::DomCode::TAB); @@ -724,7 +723,7 @@ suggester_->OnFocus(kFocusedContextId); suggester_->OnSurroundingTextChanged(u"why", 3, 3); - suggester_->Suggest(u"why", 3, 3); + suggester_->Suggest(u"why", 3); suggester_->OnExternalSuggestionsUpdated(suggestions); SendKeyEvent(suggester_.get(), ui::DomCode::TAB); @@ -773,17 +772,59 @@ "InputMethod.Assistive.TimeToDismiss.MultiWord", 1); } +TEST_F(MultiWordSuggesterTest, RecordsSuggestionLengthMetric) { + std::vector<TextSuggestion> suggestions = { + TextSuggestion{.mode = TextSuggestionMode::kPrediction, + .type = TextSuggestionType::kMultiWord, + .text = "how are you"}, + }; + + base::HistogramTester histogram_tester; + histogram_tester.ExpectTotalCount( + "InputMethod.Assistive.MultiWord.SuggestionLength", 0); + + suggester_->OnFocus(kFocusedContextId); + suggester_->OnSurroundingTextChanged(u"how", 3, 3); + suggester_->OnExternalSuggestionsUpdated(suggestions); + + histogram_tester.ExpectTotalCount( + "InputMethod.Assistive.MultiWord.SuggestionLength", 1); + // "how are you" = 11 chars + histogram_tester.ExpectUniqueSample( + "InputMethod.Assistive.MultiWord.SuggestionLength", /*sample=*/11, + /*expected_bucket_count=*/1); +} + +TEST_F(MultiWordSuggesterTest, DoesntRecordIfSuggestionLengthIsBig) { + std::vector<TextSuggestion> suggestions = { + TextSuggestion{.mode = TextSuggestionMode::kPrediction, + .type = TextSuggestionType::kMultiWord, + .text = std::string(101, 'h')}, + }; + + base::HistogramTester histogram_tester; + histogram_tester.ExpectTotalCount( + "InputMethod.Assistive.MultiWord.SuggestionLength", 0); + + suggester_->OnFocus(kFocusedContextId); + suggester_->OnSurroundingTextChanged(u"how", 3, 3); + suggester_->OnExternalSuggestionsUpdated(suggestions); + + histogram_tester.ExpectTotalCount( + "InputMethod.Assistive.MultiWord.SuggestionLength", 0); +} + TEST_F(MultiWordSuggesterTest, SurroundingTextChangesDoNotTriggerAnnouncements) { suggester_->OnFocus(kFocusedContextId); suggester_->OnSurroundingTextChanged(u"why are", 7, 7); - suggester_->Suggest(u"why are", 7, 7); + suggester_->Suggest(u"why are", 7); suggester_->OnSurroundingTextChanged(u"why aren", 8, 8); - suggester_->Suggest(u"why aren", 8, 8); + suggester_->Suggest(u"why aren", 8); suggester_->OnSurroundingTextChanged(u"why aren'", 9, 9); - suggester_->Suggest(u"why aren'", 9, 9); + suggester_->Suggest(u"why aren'", 9); suggester_->OnSurroundingTextChanged(u"why aren't", 10, 10); - suggester_->Suggest(u"why aren't", 10, 10); + suggester_->Suggest(u"why aren't", 10); ASSERT_EQ(suggestion_handler_.GetAnnouncements().size(), 0u); } @@ -797,7 +838,7 @@ suggester_->OnFocus(kFocusedContextId); suggester_->OnSurroundingTextChanged(u"why are", 7, 7); - suggester_->Suggest(u"why are", 7, 7); + suggester_->Suggest(u"why are", 7); suggester_->OnExternalSuggestionsUpdated(suggestions); ASSERT_EQ(suggestion_handler_.GetAnnouncements().size(), 1u); @@ -816,14 +857,14 @@ suggester_->OnFocus(kFocusedContextId); suggester_->OnSurroundingTextChanged(u"why are", 7, 7); - suggester_->Suggest(u"why are", 7, 7); + suggester_->Suggest(u"why are", 7); suggester_->OnExternalSuggestionsUpdated(suggestions); suggester_->OnSurroundingTextChanged(u"why aren", 8, 8); - suggester_->Suggest(u"why aren", 8, 8); + suggester_->Suggest(u"why aren", 8); suggester_->OnSurroundingTextChanged(u"why aren'", 9, 9); - suggester_->Suggest(u"why aren'", 9, 9); + suggester_->Suggest(u"why aren'", 9); suggester_->OnSurroundingTextChanged(u"why aren't", 10, 10); - suggester_->Suggest(u"why aren't", 10, 10); + suggester_->Suggest(u"why aren't", 10); ASSERT_EQ(suggestion_handler_.GetAnnouncements().size(), 1u); EXPECT_EQ(suggestion_handler_.GetAnnouncements().back(), @@ -840,7 +881,7 @@ suggester_->OnFocus(kFocusedContextId); suggester_->OnSurroundingTextChanged(u"why are", 7, 7); - suggester_->Suggest(u"why are", 7, 7); + suggester_->Suggest(u"why are", 7); suggester_->OnExternalSuggestionsUpdated(suggestions); SendKeyEvent(suggester_.get(), ui::DomCode::TAB); @@ -859,11 +900,11 @@ suggester_->OnFocus(kFocusedContextId); suggester_->OnSurroundingTextChanged(u"why are", 7, 7); - suggester_->Suggest(u"why are", 7, 7); + suggester_->Suggest(u"why are", 7); suggester_->OnExternalSuggestionsUpdated(suggestions); SendKeyEvent(suggester_.get(), ui::DomCode::TAB); suggester_->OnSurroundingTextChanged(u"why aren", 8, 8); - suggester_->Suggest(u"why aren", 8, 8); + suggester_->Suggest(u"why aren", 8); ASSERT_EQ(suggestion_handler_.GetAnnouncements().size(), 2u); } @@ -877,7 +918,7 @@ suggester_->OnFocus(kFocusedContextId); suggester_->OnSurroundingTextChanged(u"why are", 7, 7); - suggester_->Suggest(u"why are", 7, 7); + suggester_->Suggest(u"why are", 7); suggester_->OnExternalSuggestionsUpdated(suggestions); suggester_->DismissSuggestion(); @@ -896,11 +937,11 @@ suggester_->OnFocus(kFocusedContextId); suggester_->OnSurroundingTextChanged(u"why are", 7, 7); - suggester_->Suggest(u"why are", 7, 7); + suggester_->Suggest(u"why are", 7); suggester_->OnExternalSuggestionsUpdated(suggestions); suggester_->DismissSuggestion(); suggester_->OnSurroundingTextChanged(u"why aren", 8, 8); - suggester_->Suggest(u"why aren", 8, 8); + suggester_->Suggest(u"why aren", 8); ASSERT_EQ(suggestion_handler_.GetAnnouncements().size(), 2u); }
diff --git a/chrome/browser/ash/input_method/personal_info_suggester.cc b/chrome/browser/ash/input_method/personal_info_suggester.cc index 4e6eb49..01bbd0b 100644 --- a/chrome/browser/ash/input_method/personal_info_suggester.cc +++ b/chrome/browser/ash/input_method/personal_info_suggester.cc
@@ -239,8 +239,7 @@ } bool PersonalInfoSuggester::Suggest(const std::u16string& text, - size_t cursor_pos, - size_t anchor_pos) { + size_t cursor_pos) { // |text| could be very long, we get at most |kMaxTextBeforeCursorLength| // characters before cursor. int start_pos = cursor_pos >= kMaxTextBeforeCursorLength
diff --git a/chrome/browser/ash/input_method/personal_info_suggester.h b/chrome/browser/ash/input_method/personal_info_suggester.h index 095f6be0..b9c79c5 100644 --- a/chrome/browser/ash/input_method/personal_info_suggester.h +++ b/chrome/browser/ash/input_method/personal_info_suggester.h
@@ -53,9 +53,7 @@ void OnExternalSuggestionsUpdated( const std::vector<ime::TextSuggestion>& suggestions) override; SuggestionStatus HandleKeyEvent(const ui::KeyEvent& event) override; - bool Suggest(const std::u16string& text, - size_t cursor_pos, - size_t anchor_pos) override; + bool Suggest(const std::u16string& text, size_t cursor_pos) override; // index defaults to 0 as not required for this suggester. bool AcceptSuggestion(size_t index = 0) override; void DismissSuggestion() override;
diff --git a/chrome/browser/ash/input_method/personal_info_suggester_unittest.cc b/chrome/browser/ash/input_method/personal_info_suggester_unittest.cc index ba8c46d..9fa8f32 100644 --- a/chrome/browser/ash/input_method/personal_info_suggester_unittest.cc +++ b/chrome/browser/ash/input_method/personal_info_suggester_unittest.cc
@@ -191,15 +191,15 @@ profile_->set_profile_name(base::UTF16ToUTF8(email_)); - suggester_->Suggest(u"my email is ", 12, 12); + suggester_->Suggest(u"my email is ", 12); suggestion_handler_->VerifySuggestion(email_, 0); SendKeyboardEvent(ui::DomCode::ESCAPE); - suggester_->Suggest(u"My email is: ", 13, 13); + suggester_->Suggest(u"My email is: ", 13); suggestion_handler_->VerifySuggestion(email_, 0); SendKeyboardEvent(ui::DomCode::ESCAPE); - suggester_->Suggest(u"hi, my email: ", 14, 14); + suggester_->Suggest(u"hi, my email: ", 14); suggestion_handler_->VerifySuggestion(email_, 0); } @@ -211,11 +211,11 @@ profile_->set_profile_name(base::UTF16ToUTF8(email_)); - suggester_->Suggest(u"\nmy email is ", 13, 13); + suggester_->Suggest(u"\nmy email is ", 13); suggestion_handler_->VerifySuggestion(email_, 0); SendKeyboardEvent(ui::DomCode::ESCAPE); - suggester_->Suggest(u"Hey\nMan\nmy email is ", 20, 20); + suggester_->Suggest(u"Hey\nMan\nmy email is ", 20); suggestion_handler_->VerifySuggestion(email_, 0); SendKeyboardEvent(ui::DomCode::ESCAPE); } @@ -228,13 +228,13 @@ profile_->set_profile_name(base::UTF16ToUTF8(email_)); - suggester_->Suggest(u"\nmy email is \n", 14, 14); + suggester_->Suggest(u"\nmy email is \n", 14); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); - suggester_->Suggest(u"\nmy email is \n ", 15, 15); + suggester_->Suggest(u"\nmy email is \n ", 15); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); - suggester_->Suggest(u"Hey\nMan\nmy email is \nhey ", 25, 25); + suggester_->Suggest(u"Hey\nMan\nmy email is \nhey ", 25); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); } @@ -246,7 +246,7 @@ profile_->set_profile_name(base::UTF16ToUTF8(email_)); - suggester_->Suggest(u"my email is ", 12, 12); + suggester_->Suggest(u"my email is ", 12); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); } @@ -258,10 +258,10 @@ profile_->set_profile_name(base::UTF16ToUTF8(email_)); - suggester_->Suggest(u"my email is John", 16, 16); + suggester_->Suggest(u"my email is John", 16); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); - suggester_->Suggest(u"our email is: ", 14, 14); + suggester_->Suggest(u"our email is: ", 14); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); } @@ -274,7 +274,7 @@ chrome_keyboard_controller_client_->set_keyboard_visible_for_test(true); profile_->set_profile_name(base::UTF16ToUTF8(email_)); - suggester_->Suggest(u"my email is ", 12, 12); + suggester_->Suggest(u"my email is ", 12); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); } @@ -288,7 +288,7 @@ chrome_keyboard_controller_client_->set_keyboard_visible_for_test(true); profile_->set_profile_name(base::UTF16ToUTF8(email_)); - suggester_->Suggest(u"my email is ", 12, 12); + suggester_->Suggest(u"my email is ", 12); suggestion_handler_->VerifySuggestionDispatchedToExtension( std::vector<std::string>{base::UTF16ToUTF8(email_)}); } @@ -307,19 +307,19 @@ autofill_profile.SetRawInfo(autofill::ServerFieldType::NAME_FULL, full_name_); personal_data_->AddProfile(autofill_profile); - suggester_->Suggest(u"my first name is ", 17, 17); + suggester_->Suggest(u"my first name is ", 17); suggestion_handler_->VerifySuggestion(first_name_, 0); SendKeyboardEvent(ui::DomCode::ESCAPE); - suggester_->Suggest(u"my last name is: ", 17, 17); + suggester_->Suggest(u"my last name is: ", 17); suggestion_handler_->VerifySuggestion(last_name_, 0); SendKeyboardEvent(ui::DomCode::ESCAPE); - suggester_->Suggest(u"my name is ", 12, 12); + suggester_->Suggest(u"my name is ", 12); suggestion_handler_->VerifySuggestion(full_name_, 0); SendKeyboardEvent(ui::DomCode::ESCAPE); - suggester_->Suggest(u"Hmm... my FULL name: ", 21, 21); + suggester_->Suggest(u"Hmm... my FULL name: ", 21); suggestion_handler_->VerifySuggestion(full_name_, 0); } @@ -336,7 +336,7 @@ histogram_tester.ExpectUniqueSample("InputMethod.Assistive.InsufficientData", AssistiveType::kPersonalName, 0); - suggester_->Suggest(u"my name is ", 12, 12); + suggester_->Suggest(u"my name is ", 12); histogram_tester.ExpectUniqueSample("InputMethod.Assistive.InsufficientData", AssistiveType::kPersonalName, 1); } @@ -355,13 +355,13 @@ autofill_profile.SetRawInfo(autofill::ServerFieldType::NAME_FULL, full_name_); personal_data_->AddProfile(autofill_profile); - suggester_->Suggest(u"my first name is ", 17, 17); + suggester_->Suggest(u"my first name is ", 17); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); - suggester_->Suggest(u"my last name is: ", 17, 17); + suggester_->Suggest(u"my last name is: ", 17); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); - suggester_->Suggest(u"my name is ", 12, 12); + suggester_->Suggest(u"my name is ", 12); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); } @@ -379,16 +379,16 @@ autofill_profile.SetRawInfo(autofill::ServerFieldType::NAME_FULL, full_name_); personal_data_->AddProfile(autofill_profile); - suggester_->Suggest(u"our first name is ", 18, 18); + suggester_->Suggest(u"our first name is ", 18); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); - suggester_->Suggest(u"our last name is: ", 18, 18); + suggester_->Suggest(u"our last name is: ", 18); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); - suggester_->Suggest(u"our name is ", 12, 12); + suggester_->Suggest(u"our name is ", 12); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); - suggester_->Suggest(u"our full name: ", 15, 15); + suggester_->Suggest(u"our full name: ", 15); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); } @@ -413,23 +413,23 @@ u"US"); personal_data_->AddProfile(autofill_profile); - suggester_->Suggest(u"my address is ", 14, 14); + suggester_->Suggest(u"my address is ", 14); suggestion_handler_->VerifySuggestion(address_, 0); SendKeyboardEvent(ui::DomCode::ESCAPE); - suggester_->Suggest(u"our address is: ", 16, 16); + suggester_->Suggest(u"our address is: ", 16); suggestion_handler_->VerifySuggestion(address_, 0); SendKeyboardEvent(ui::DomCode::ESCAPE); - suggester_->Suggest(u"my shipping address: ", 21, 21); + suggester_->Suggest(u"my shipping address: ", 21); suggestion_handler_->VerifySuggestion(address_, 0); SendKeyboardEvent(ui::DomCode::ESCAPE); - suggester_->Suggest(u"our billing address is ", 23, 23); + suggester_->Suggest(u"our billing address is ", 23); suggestion_handler_->VerifySuggestion(address_, 0); SendKeyboardEvent(ui::DomCode::ESCAPE); - suggester_->Suggest(u"my current address: ", 20, 20); + suggester_->Suggest(u"my current address: ", 20); suggestion_handler_->VerifySuggestion(address_, 0); } @@ -454,7 +454,7 @@ u"US"); personal_data_->AddProfile(autofill_profile); - suggester_->Suggest(u"my address is ", 14, 14); + suggester_->Suggest(u"my address is ", 14); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); } @@ -479,13 +479,13 @@ u"US"); personal_data_->AddProfile(autofill_profile); - suggester_->Suggest(u"my address ", 11, 11); + suggester_->Suggest(u"my address ", 11); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); - suggester_->Suggest(u"my last address is: ", 20, 20); + suggester_->Suggest(u"my last address is: ", 20); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); - suggester_->Suggest(u"our address number is ", 22, 22); + suggester_->Suggest(u"our address number is ", 22); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); } @@ -501,23 +501,23 @@ autofill::ServerFieldType::PHONE_HOME_WHOLE_NUMBER, phone_number_); personal_data_->AddProfile(autofill_profile); - suggester_->Suggest(u"my phone number is ", 19, 19); + suggester_->Suggest(u"my phone number is ", 19); suggestion_handler_->VerifySuggestion(phone_number_, 0); SendKeyboardEvent(ui::DomCode::ESCAPE); - suggester_->Suggest(u"my number is ", 13, 13); + suggester_->Suggest(u"my number is ", 13); suggestion_handler_->VerifySuggestion(phone_number_, 0); SendKeyboardEvent(ui::DomCode::ESCAPE); - suggester_->Suggest(u"my mobile number is: ", 21, 21); + suggester_->Suggest(u"my mobile number is: ", 21); suggestion_handler_->VerifySuggestion(phone_number_, 0); SendKeyboardEvent(ui::DomCode::ESCAPE); - suggester_->Suggest(u"my number: ", 11, 11); + suggester_->Suggest(u"my number: ", 11); suggestion_handler_->VerifySuggestion(phone_number_, 0); SendKeyboardEvent(ui::DomCode::ESCAPE); - suggester_->Suggest(u"my telephone number is ", 23, 23); + suggester_->Suggest(u"my telephone number is ", 23); suggestion_handler_->VerifySuggestion(phone_number_, 0); } @@ -533,7 +533,7 @@ autofill::ServerFieldType::PHONE_HOME_WHOLE_NUMBER, phone_number_); personal_data_->AddProfile(autofill_profile); - suggester_->Suggest(u"my phone number is ", 20, 20); + suggester_->Suggest(u"my phone number is ", 20); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); } @@ -550,16 +550,16 @@ autofill::ServerFieldType::PHONE_HOME_WHOLE_NUMBER, phone_number_); personal_data_->AddProfile(autofill_profile); - suggester_->Suggest(u"our phone number is ", 20, 20); + suggester_->Suggest(u"our phone number is ", 20); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); - suggester_->Suggest(u"my number ", 10, 10); + suggester_->Suggest(u"my number ", 10); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); - suggester_->Suggest(u"my number phone is: ", 20, 20); + suggester_->Suggest(u"my number phone is: ", 20); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); - suggester_->Suggest(u"my phone phone: ", 16, 16); + suggester_->Suggest(u"my phone phone: ", 16); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); } @@ -571,7 +571,7 @@ profile_->set_profile_name(base::UTF16ToUTF8(email_)); - suggester_->Suggest(u"my email is ", 12, 12); + suggester_->Suggest(u"my email is ", 12); SendKeyboardEvent(ui::DomCode::ARROW_DOWN); SendKeyboardEvent(ui::DomCode::ENTER); @@ -590,7 +590,7 @@ update->SetIntKey(kPersonalInfoSuggesterAcceptanceCount, 1); profile_->set_profile_name(base::UTF16ToUTF8(email_)); - suggester_->Suggest(u"my email is ", 12, 12); + suggester_->Suggest(u"my email is ", 12); SendKeyboardEvent(ui::DomCode::ARROW_UP); SendKeyboardEvent(ui::DomCode::ENTER); @@ -609,7 +609,7 @@ autofill_profile.SetRawInfo(autofill::ServerFieldType::NAME_FULL, full_name_); personal_data_->AddProfile(autofill_profile); - suggester_->Suggest(u"my name is ", 11, 11); + suggester_->Suggest(u"my name is ", 11); SendKeyboardEvent(ui::DomCode::ESCAPE); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); EXPECT_FALSE(suggestion_handler_->IsSuggestionAccepted()); @@ -627,8 +627,8 @@ autofill::ServerFieldType::PHONE_HOME_WHOLE_NUMBER, phone_number_); personal_data_->AddProfile(autofill_profile); - suggester_->Suggest(u"my phone number is ", 19, 19); - suggester_->Suggest(u"my phone number is 16", 21, 21); + suggester_->Suggest(u"my phone number is ", 19); + suggester_->Suggest(u"my phone number is 16", 21); suggestion_handler_->VerifySuggestion(phone_number_, 2); } @@ -642,7 +642,7 @@ profile_->GetPrefs()->SetBoolean( ash::prefs::kAccessibilitySpokenFeedbackEnabled, true); - suggester_->Suggest(u"my email is ", 12, 12); + suggester_->Suggest(u"my email is ", 12); task_environment_.FastForwardBy(base::Milliseconds(200)); suggestion_handler_->VerifyAnnouncement( u"Personal info suggested. Press down arrow to access; escape to " @@ -653,7 +653,7 @@ task_environment_.FastForwardBy(base::Milliseconds(200)); suggestion_handler_->VerifyAnnouncement(u"Suggestion inserted."); - suggester_->Suggest(u"my email is ", 12, 12); + suggester_->Suggest(u"my email is ", 12); task_environment_.FastForwardBy(base::Milliseconds(1500)); suggestion_handler_->VerifyAnnouncement( u"Personal info suggested. Press down arrow to access; escape to " @@ -670,12 +670,12 @@ /*disabled_features=*/{}); for (int i = 0; i < kMaxAcceptanceCount; i++) { - suggester_->Suggest(u"my email is ", 12, 12); + suggester_->Suggest(u"my email is ", 12); SendKeyboardEvent(ui::DomCode::ARROW_DOWN); SendKeyboardEvent(ui::DomCode::ENTER); suggestion_handler_->VerifyShowAnnotation(true); } - suggester_->Suggest(u"my email is ", 12, 12); + suggester_->Suggest(u"my email is ", 12); suggestion_handler_->VerifyShowAnnotation(false); } @@ -690,12 +690,12 @@ update->RemoveKey(kPersonalInfoSuggesterShowSettingCount); update->RemoveKey(kPersonalInfoSuggesterAcceptanceCount); for (int i = 0; i < kMaxShowSettingCount; i++) { - suggester_->Suggest(u"my email is ", 12, 12); + suggester_->Suggest(u"my email is ", 12); // Dismiss suggestion. SendKeyboardEvent(ui::DomCode::ESCAPE); suggestion_handler_->VerifyShowSettingLink(true); } - suggester_->Suggest(u"my email is ", 12, 12); + suggester_->Suggest(u"my email is ", 12); suggestion_handler_->VerifyShowSettingLink(false); } @@ -708,12 +708,12 @@ DictionaryPrefUpdate update(profile_->GetPrefs(), prefs::kAssistiveInputFeatureSettings); update->SetIntKey(kPersonalInfoSuggesterShowSettingCount, 0); - suggester_->Suggest(u"my email is ", 12, 12); + suggester_->Suggest(u"my email is ", 12); suggestion_handler_->VerifyShowSettingLink(true); // Accept suggestion. SendKeyboardEvent(ui::DomCode::ARROW_DOWN); SendKeyboardEvent(ui::DomCode::ENTER); - suggester_->Suggest(u"my email is ", 12, 12); + suggester_->Suggest(u"my email is ", 12); suggestion_handler_->VerifyShowSettingLink(false); } @@ -729,7 +729,7 @@ update->RemoveKey(kPersonalInfoSuggesterAcceptanceCount); profile_->set_profile_name(base::UTF16ToUTF8(email_)); - suggester_->Suggest(u"my email is ", 12, 12); + suggester_->Suggest(u"my email is ", 12); SendKeyboardEvent(ui::DomCode::ARROW_DOWN); SendKeyboardEvent(ui::DomCode::ARROW_DOWN); SendKeyboardEvent(ui::DomCode::ENTER); @@ -750,7 +750,7 @@ update->RemoveKey(kPersonalInfoSuggesterAcceptanceCount); profile_->set_profile_name(base::UTF16ToUTF8(email_)); - suggester_->Suggest(u"my email is ", 12, 12); + suggester_->Suggest(u"my email is ", 12); SendKeyboardEvent(ui::DomCode::ARROW_UP); SendKeyboardEvent(ui::DomCode::ENTER); @@ -767,7 +767,7 @@ profile_->set_profile_name(base::UTF16ToUTF8(email_)); - suggester_->Suggest(u"my email is ", 12, 12); + suggester_->Suggest(u"my email is ", 12); suggestion_handler_->VerifySuggestion(email_, 0); EXPECT_TRUE(suggester_->HasSuggestions()); } @@ -781,7 +781,7 @@ profile_->set_profile_name(base::UTF16ToUTF8(email_)); - suggester_->Suggest(u"", 0, 0); + suggester_->Suggest(u"", 0); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); EXPECT_FALSE(suggester_->HasSuggestions()); } @@ -795,7 +795,7 @@ profile_->set_profile_name(base::UTF16ToUTF8(email_)); - suggester_->Suggest(u"my email is ", 12, 12); + suggester_->Suggest(u"my email is ", 12); suggestion_handler_->VerifySuggestion(email_, 0); EXPECT_EQ(suggester_->GetSuggestions(), (std::vector<TextSuggestion>{TextSuggestion{ @@ -813,7 +813,7 @@ profile_->set_profile_name(base::UTF16ToUTF8(email_)); - suggester_->Suggest(u"", 0, 0); + suggester_->Suggest(u"", 0); suggestion_handler_->VerifySuggestion(base::EmptyString16(), 0); EXPECT_TRUE(suggester_->GetSuggestions().empty()); }
diff --git a/chrome/browser/ash/input_method/suggester.h b/chrome/browser/ash/input_method/suggester.h index 35aa2a2..d202bf0 100644 --- a/chrome/browser/ash/input_method/suggester.h +++ b/chrome/browser/ash/input_method/suggester.h
@@ -34,9 +34,7 @@ // Check if suggestion should be displayed according to the surrounding text // information. - virtual bool Suggest(const std::u16string& text, - size_t cursor_pos, - size_t anchor_pos) = 0; + virtual bool Suggest(const std::u16string& text, size_t cursor_pos) = 0; // Accepts the suggestion at a given index, index can be made default if // unnecessary. Returns true if suggestion is accepted successfully.
diff --git a/chrome/browser/ash/policy/networking/euicc_status_uploader.cc b/chrome/browser/ash/policy/networking/euicc_status_uploader.cc index 85197fa..bd5f73b 100644 --- a/chrome/browser/ash/policy/networking/euicc_status_uploader.cc +++ b/chrome/browser/ash/policy/networking/euicc_status_uploader.cc
@@ -8,9 +8,9 @@ #include "base/metrics/histogram_functions.h" #include "base/timer/timer.h" #include "chrome/browser/ash/profiles/profile_helper.h" +#include "chrome/browser/ash/settings/device_settings_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" -#include "chromeos/dbus/hermes/hermes_manager_client.h" #include "chromeos/network/managed_network_configuration_handler.h" #include "chromeos/network/network_event_log.h" #include "chromeos/network/network_handler.h" @@ -52,6 +52,15 @@ // Starts with initial delay. true, }; + +// Returns whether the device's policy data is active and provisioned. +bool IsDeviceManaged() { + return ::ash::DeviceSettingsService::IsInitialized() && + ::ash::DeviceSettingsService::Get()->policy_data() && + ::ash::DeviceSettingsService::Get()->policy_data()->state() == + enterprise_management::PolicyData::ACTIVE; +} + } // namespace // static @@ -62,25 +71,33 @@ EuiccStatusUploader::EuiccStatusUploader(CloudPolicyClient* client, PrefService* local_state) + : EuiccStatusUploader(client, + local_state, + base::BindRepeating(&IsDeviceManaged)) {} + +EuiccStatusUploader::EuiccStatusUploader( + CloudPolicyClient* client, + PrefService* local_state, + IsDeviceActiveCallback is_device_active_callback) : client_(client), local_state_(local_state), + is_device_managed_callback_(std::move(is_device_active_callback)), retry_entry_(&kBackOffPolicy) { if (!chromeos::NetworkHandler::IsInitialized()) { LOG(WARNING) << "NetworkHandler is not initialized."; return; } + + hermes_manager_observation_.Observe(chromeos::HermesManagerClient::Get()); + hermes_euicc_observation_.Observe(chromeos::HermesEuiccClient::Get()); + cloud_policy_client_observation_.Observe(client_); + network_handler_ = chromeos::NetworkHandler::Get(); network_handler_->managed_network_configuration_handler()->AddObserver(this); - chromeos::HermesEuiccClient::Get()->AddObserver(this); network_handler_->network_state_handler()->AddObserver(this, FROM_HERE); - - MaybeUploadStatus(); } EuiccStatusUploader::~EuiccStatusUploader() { - if (chromeos::HermesEuiccClient::Get()) - chromeos::HermesEuiccClient::Get()->RemoveObserver(this); - if (network_handler_) OnShuttingDown(); } @@ -125,6 +142,19 @@ network_handler_ = nullptr; } +void EuiccStatusUploader::OnRegistrationStateChanged( + CloudPolicyClient* client) { + MaybeUploadStatus(); +} + +void EuiccStatusUploader::OnPolicyFetched(CloudPolicyClient* client) { + if (is_policy_fetched_) { + return; + } + is_policy_fetched_ = true; + MaybeUploadStatus(); +} + void EuiccStatusUploader::PoliciesApplied(const std::string& userhash) { MaybeUploadStatus(); } @@ -133,6 +163,10 @@ MaybeUploadStatus(); } +void EuiccStatusUploader::OnAvailableEuiccListChanged() { + MaybeUploadStatus(); +} + void EuiccStatusUploader::OnEuiccReset(const dbus::ObjectPath& euicc_path) { // Remember that we should clear the profile list in the next upload. This // ensures that profile list will be eventually cleared even if the immediate @@ -141,7 +175,7 @@ MaybeUploadStatus(); } -base::Value EuiccStatusUploader::GetCurrentEuiccStatus() { +base::Value EuiccStatusUploader::GetCurrentEuiccStatus() const { base::Value status(base::Value::Type::DICTIONARY); status.SetIntKey( @@ -153,7 +187,7 @@ chromeos::NetworkStateHandler::NetworkStateList networks; network_handler_->network_state_handler()->GetNetworkListByType( ash::NetworkTypePattern::Cellular(), - /*configure_only=*/false, /*visible_only=*/false, + /*configured_only=*/false, /*visible_only=*/false, /*limit=*/0, &networks); onc::ONCSource onc_source = onc::ONC_SOURCE_NONE; @@ -205,10 +239,31 @@ } void EuiccStatusUploader::MaybeUploadStatus() { + if (!client_->is_registered()) { + VLOG(1) << "Policy client is not registered."; + return; + } + + if (!is_policy_fetched_) { + VLOG(1) << "Policy not fetched yet."; + return; + } + + if (!is_device_managed_callback_.Run()) { + VLOG(1) << "Device is unmanaged or deprovisioned."; + return; + } + if (!network_handler_) { LOG(WARNING) << "NetworkHandler is not initialized."; return; } + + if (chromeos::HermesManagerClient::Get()->GetAvailableEuiccs().empty()) { + VLOG(1) << "No EUICC available on the device."; + return; + } + const base::Value* last_uploaded_pref = local_state_->Get(kLastUploadedEuiccStatusPref); auto current_state = GetCurrentEuiccStatus();
diff --git a/chrome/browser/ash/policy/networking/euicc_status_uploader.h b/chrome/browser/ash/policy/networking/euicc_status_uploader.h index c537fea..a76e4c19 100644 --- a/chrome/browser/ash/policy/networking/euicc_status_uploader.h +++ b/chrome/browser/ash/policy/networking/euicc_status_uploader.h
@@ -8,9 +8,11 @@ #include "base/memory/weak_ptr.h" #include "base/scoped_observation.h" #include "chromeos/dbus/hermes/hermes_euicc_client.h" +#include "chromeos/dbus/hermes/hermes_manager_client.h" #include "chromeos/network/network_policy_observer.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_state_handler_observer.h" +#include "components/policy/core/common/cloud/cloud_policy_client.h" #include "net/base/backoff_entry.h" class PrefService; @@ -26,13 +28,13 @@ namespace policy { -class CloudPolicyClient; - // Class responsible for uploading the information about the current ESim // profiles to DMServer. class EuiccStatusUploader : public chromeos::NetworkPolicyObserver, public chromeos::NetworkStateHandlerObserver, - public chromeos::HermesEuiccClient::Observer { + public chromeos::HermesManagerClient::Observer, + public chromeos::HermesEuiccClient::Observer, + public CloudPolicyClient::Observer { public: EuiccStatusUploader(CloudPolicyClient* client, PrefService* local_state); ~EuiccStatusUploader() override; @@ -42,6 +44,13 @@ private: friend class EuiccStatusUploaderTest; + // Callback used in tests to mock out check for device provisioning state. + using IsDeviceActiveCallback = base::RepeatingCallback<bool()>; + + EuiccStatusUploader(CloudPolicyClient* client, + PrefService* local_state, + IsDeviceActiveCallback is_device_managed_callback); + // A local state preference that stores the last uploaded Euicc status in such // format: // { @@ -70,10 +79,20 @@ void NetworkListChanged() override; void OnShuttingDown() override; + // CloudPolicyClient::Observer: + void OnRegistrationStateChanged(CloudPolicyClient* client) override; + void OnPolicyFetched(CloudPolicyClient* client) override; + void OnClientError(CloudPolicyClient* client) override {} + void OnServiceAccountSet(CloudPolicyClient* client, + const std::string& account_email) override {} + + // chromeos::HermesManagerClient: + void OnAvailableEuiccListChanged() override; + // chromeos::HermesEuiccClient: void OnEuiccReset(const dbus::ObjectPath& euicc_path) override; - base::Value GetCurrentEuiccStatus(); + base::Value GetCurrentEuiccStatus() const; void MaybeUploadStatus(); void MaybeUploadStatusWithDelay(); void UploadStatus(base::Value status); @@ -89,11 +108,22 @@ bool currently_uploading_ = false; // The status that is being uploaded right now. base::Value attempted_upload_status_{base::Value::Type::DICTIONARY}; + bool is_policy_fetched_ = false; + IsDeviceActiveCallback is_device_managed_callback_; // Timer which will try to reupload the status after a while. std::unique_ptr<base::OneShotTimer> retry_timer_; net::BackoffEntry retry_entry_; + base::ScopedObservation<chromeos::HermesManagerClient, + chromeos::HermesManagerClient::Observer> + hermes_manager_observation_{this}; + base::ScopedObservation<chromeos::HermesEuiccClient, + chromeos::HermesEuiccClient::Observer> + hermes_euicc_observation_{this}; + base::ScopedObservation<CloudPolicyClient, CloudPolicyClient::Observer> + cloud_policy_client_observation_{this}; + chromeos::NetworkHandler* network_handler_ = nullptr; base::WeakPtrFactory<EuiccStatusUploader> weak_ptr_factory_{this};
diff --git a/chrome/browser/ash/policy/networking/euicc_status_uploader_unittest.cc b/chrome/browser/ash/policy/networking/euicc_status_uploader_unittest.cc index 2eb385b2..8a042159 100644 --- a/chrome/browser/ash/policy/networking/euicc_status_uploader_unittest.cc +++ b/chrome/browser/ash/policy/networking/euicc_status_uploader_unittest.cc
@@ -6,6 +6,7 @@ #include "ash/constants/ash_pref_names.h" #include "base/json/json_string_value_serializer.h" +#include "base/strings/stringprintf.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/values_test_util.h" #include "chrome/test/base/testing_browser_process.h" @@ -64,6 +65,7 @@ lhs.clear_profile_list() == rhs.clear_profile_list(); } +const char kDmToken[] = "token"; const char kFakeObjectPath[] = "object-path"; const char kFakeEid[] = "12"; const char kEuiccStatusUploadResultHistogram[] = @@ -138,11 +140,27 @@ EuiccStatusUploader::RegisterLocalStatePrefs(local_state_.registry()); helper_->RegisterPrefs(nullptr, local_state_.registry()); helper_->InitializePrefs(nullptr, &local_state_); + SetPolicyClientIsRegistered(/*is_registered=*/true); } - std::unique_ptr<EuiccStatusUploader> CreateStatusUploader() { - return std::make_unique<EuiccStatusUploader>(&cloud_policy_client_, - &local_state_); + std::unique_ptr<EuiccStatusUploader> CreateStatusUploader( + bool is_policy_fetched = true) { + auto status_uploader = base::WrapUnique(new EuiccStatusUploader( + &cloud_policy_client_, &local_state_, + base::BindRepeating(&EuiccStatusUploaderTest::is_device_active, + base::Unretained(this)))); + if (is_policy_fetched) { + SetPolicyFetched(status_uploader.get()); + } + return status_uploader; + } + + void SetPolicyClientIsRegistered(bool is_registered) { + cloud_policy_client_.dm_token_ = is_registered ? kDmToken : std::string(); + } + + void SetPolicyFetched(EuiccStatusUploader* status_uploader) { + status_uploader->OnPolicyFetched(&cloud_policy_client_); } void SetServerSuccessStatus(bool success) { @@ -167,13 +185,18 @@ status_uploader->FireRetryTimerIfExistsForTesting(); } + void SetupEuicc(int euicc_id = 0) { + chromeos::HermesManagerClient::Get()->GetTestInterface()->AddEuicc( + dbus::ObjectPath(base::StringPrintf("%s%d", kFakeObjectPath, euicc_id)), + base::StringPrintf("%s%d", kFakeEid, euicc_id), /*is_active=*/true, + euicc_id); + } + void SetUpDeviceProfiles(const EuiccTestData& data, bool add_to_onc = true) { // Create |data.euicc_count| fake EUICCs. chromeos::HermesManagerClient::Get()->GetTestInterface()->ClearEuiccs(); for (int euicc_id = 0; euicc_id < data.euicc_count; euicc_id++) { - chromeos::HermesManagerClient::Get()->GetTestInterface()->AddEuicc( - dbus::ObjectPath(kFakeObjectPath), kFakeEid, /*is_active=*/true, - euicc_id); + SetupEuicc(euicc_id); } ash::ShillServiceClient::TestInterface* shill_service_client = @@ -261,7 +284,12 @@ /*expected_count=*/failed_count); } + void SetIsDeviceActive(bool value) { is_device_active_ = value; } + private: + bool is_device_active() { return is_device_active_; } + + bool is_device_active_ = true; content::BrowserTaskEnvironment task_environment_; FakeCloudPolicyClient cloud_policy_client_; TestingPrefServiceSimple local_state_; @@ -271,29 +299,54 @@ TEST_F(EuiccStatusUploaderTest, EmptySetup) { auto status_uploader = CreateStatusUploader(); - // Initial upload request. - EXPECT_EQ(GetRequestCount(), 1); + EXPECT_EQ(GetRequestCount(), 0); // No value is uploaded yet. EXPECT_EQ("{}", GetStoredPrefString()); - CheckHistogram(/*total_count=*/1, /*success_count=*/0, /*failed_count=*/1); // Make server accept requests. SetServerSuccessStatus(true); UpdateUploader(status_uploader.get()); - EXPECT_EQ(GetRequestCount(), 2); - // Verify that last uploaded configuration is stored. - ValidateUploadedStatus(kEmptyEuiccStatus, /*clear_profile_list=*/false); - CheckHistogram(/*total_count=*/2, /*success_count=*/1, /*failed_count=*/1); + // Verify that no status is uploaded if there is no EUICC. + EXPECT_EQ(GetRequestCount(), 0); + CheckHistogram(/*total_count=*/0, /*success_count=*/0, /*failed_count=*/0); +} + +TEST_F(EuiccStatusUploaderTest, InactiveDevice) { + SetIsDeviceActive(false); + auto status_uploader = CreateStatusUploader(); + EXPECT_EQ(GetRequestCount(), 0); + // No value is uploaded yet. + EXPECT_EQ("{}", GetStoredPrefString()); + + // Make server accept requests. + SetServerSuccessStatus(true); + UpdateUploader(status_uploader.get()); + // Verify that no status is uploaded if the device is inactive. + EXPECT_EQ(GetRequestCount(), 0); + CheckHistogram(/*total_count=*/0, /*success_count=*/0, /*failed_count=*/0); +} + +TEST_F(EuiccStatusUploaderTest, ClientNotRegistered) { + SetupEuicc(); + base::RunLoop().RunUntilIdle(); + SetPolicyClientIsRegistered(/*is_registered=*/false); + + auto status_uploader = CreateStatusUploader(); + EXPECT_EQ(GetRequestCount(), 0); + // No value is uploaded yet. + EXPECT_EQ("{}", GetStoredPrefString()); + + UpdateUploader(status_uploader.get()); + // Verify that no requests are made if client is not registered. + EXPECT_EQ(GetRequestCount(), 0); + EXPECT_EQ("{}", GetStoredPrefString()); + CheckHistogram(/*total_count=*/0, /*success_count=*/0, /*failed_count=*/0); } TEST_F(EuiccStatusUploaderTest, ServerError) { + SetupEuicc(); + base::RunLoop().RunUntilIdle(); auto status_uploader = CreateStatusUploader(); - // Initial upload request. - EXPECT_EQ(GetRequestCount(), 1); - // No value is uploaded yet. - EXPECT_EQ("{}", GetStoredPrefString()); - CheckHistogram(/*total_count=*/1, /*success_count=*/0, /*failed_count=*/1); - UpdateUploader(status_uploader.get()); EXPECT_EQ(GetRequestCount(), 2); // Nothing is stored when requests fail. @@ -301,6 +354,26 @@ CheckHistogram(/*total_count=*/2, /*success_count=*/0, /*failed_count=*/2); } +TEST_F(EuiccStatusUploaderTest, WaitForPolicyFetch) { + SetUpDeviceProfiles(kSetupOneEsimProfile); + + auto status_uploader = CreateStatusUploader(/*is_policy_fetched=*/false); + EXPECT_EQ(GetRequestCount(), 0); + // No value is uploaded yet. + EXPECT_EQ("{}", GetStoredPrefString()); + + // Verify that no requests are made when policy has not been fetched. + SetServerSuccessStatus(true); + UpdateUploader(status_uploader.get()); + EXPECT_EQ(GetRequestCount(), 0); + + // Verify that status is uploaded correctly when policy is fetched. + SetPolicyFetched(status_uploader.get()); + ValidateUploadedStatus(kEuiccStatusWithOneProfile, + /*clear_profile_list=*/false); + CheckHistogram(/*total_count=*/1, /*success_count=*/1, /*failed_count=*/0); +} + TEST_F(EuiccStatusUploaderTest, Basic) { SetUpDeviceProfiles(kSetupOneEsimProfile);
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index c334140..1b9dc4e 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -4230,6 +4230,7 @@ "../ash/drive/drive_integration_service_unittest.cc", "../ash/drive/drivefs_native_message_host_unittest.cc", "../ash/drive/file_system_util_unittest.cc", + "../ash/eche_app/eche_app_manager_factory_unittest.cc", "../ash/eche_app/eche_app_notification_controller_unittest.cc", "../ash/enhanced_network_tts/enhanced_network_tts_impl_unittest.cc", "../ash/enhanced_network_tts/enhanced_network_tts_test_utils.cc",
diff --git a/chrome/browser/chromeos/extensions/device_local_account_management_policy_provider_unittest.cc b/chrome/browser/chromeos/extensions/device_local_account_management_policy_provider_unittest.cc index ce5f88d..32cdbfa7 100644 --- a/chrome/browser/chromeos/extensions/device_local_account_management_policy_provider_unittest.cc +++ b/chrome/browser/chromeos/extensions/device_local_account_management_policy_provider_unittest.cc
@@ -456,15 +456,15 @@ // Verify that a platform app with socket dictionary permission can be // installed. { - auto socket = std::make_unique<base::DictionaryValue>(); - base::ListValue tcp_list; + base::Value::Dict socket; + base::Value::List tcp_list; tcp_list.Append("tcp-connect"); - socket->SetKey("socket", std::move(tcp_list)); - base::ListValue permissions; + socket.Set("socket", std::move(tcp_list)); + base::Value::List permissions; permissions.Append(std::move(socket)); base::DictionaryValue values; values.SetKey(extensions::manifest_keys::kPermissions, - std::move(permissions)); + base::Value(std::move(permissions))); extension = CreatePlatformAppWithExtraValues( &values, ManifestLocation::kExternalPolicy, @@ -479,15 +479,15 @@ // Verify that a platform app with unknown dictionary permission cannot be // installed. { - auto socket = std::make_unique<base::DictionaryValue>(); - base::ListValue tcp_list; + base::Value::Dict socket; + base::Value::List tcp_list; tcp_list.Append("unknown_value"); - socket->SetKey("unknown_key", std::move(tcp_list)); - base::ListValue permissions; + socket.Set("unknown_key", std::move(tcp_list)); + base::Value::List permissions; permissions.Append(std::move(socket)); base::DictionaryValue values; values.SetKey(extensions::manifest_keys::kPermissions, - std::move(permissions)); + base::Value(std::move(permissions))); extension = CreatePlatformAppWithExtraValues( &values, ManifestLocation::kExternalPolicy,
diff --git a/chrome/browser/chromeos/extensions/dictionary_event_router.cc b/chrome/browser/chromeos/extensions/dictionary_event_router.cc index ff39579c..28289cde 100644 --- a/chrome/browser/chromeos/extensions/dictionary_event_router.cc +++ b/chrome/browser/chromeos/extensions/dictionary_event_router.cc
@@ -71,23 +71,25 @@ return; } - std::unique_ptr<base::ListValue> added_words(new base::ListValue()); + base::Value::List added_words; + added_words.reserve(dictionary_change.to_add().size()); for (const std::string& word : dictionary_change.to_add()) - added_words->Append(word); + added_words.Append(word); - std::unique_ptr<base::ListValue> removed_words(new base::ListValue()); + base::Value::List removed_words; + removed_words.reserve(dictionary_change.to_remove().size()); for (const std::string& word : dictionary_change.to_remove()) - removed_words->Append(word); + removed_words.Append(word); - std::unique_ptr<base::ListValue> args(new base::ListValue()); - args->Append(std::move(added_words)); - args->Append(std::move(removed_words)); + base::Value::List args; + args.Append(std::move(added_words)); + args.Append(std::move(removed_words)); // The router will only send the event to extensions that are listening. auto event = std::make_unique<extensions::Event>( extensions::events::INPUT_METHOD_PRIVATE_ON_DICTIONARY_CHANGED, - OnDictionaryChanged::kEventName, std::move(*args).TakeListDeprecated(), - context_); + OnDictionaryChanged::kEventName, + base::Value(std::move(args)).TakeListDeprecated(), context_); router->BroadcastEvent(std::move(event)); }
diff --git a/chrome/browser/chromeos/extensions/input_method_api.cc b/chrome/browser/chromeos/extensions/input_method_api.cc index b4bf6a9..08f37b1 100644 --- a/chrome/browser/chromeos/extensions/input_method_api.cc +++ b/chrome/browser/chromeos/extensions/input_method_api.cc
@@ -180,7 +180,7 @@ ExtensionFunction::ResponseAction InputMethodPrivateGetInputMethodsFunction::Run() { - std::unique_ptr<base::ListValue> output(new base::ListValue()); + base::Value::List output; auto* manager = ash::input_method::InputMethodManager::Get(); ash::input_method::InputMethodUtil* util = manager->GetInputMethodUtil(); scoped_refptr<ash::input_method::InputMethodManager::State> ime_state = @@ -190,14 +190,13 @@ for (size_t i = 0; i < input_methods->size(); ++i) { const ash::input_method::InputMethodDescriptor& input_method = (*input_methods)[i]; - auto val = std::make_unique<base::DictionaryValue>(); - val->SetStringKey("id", input_method.id()); - val->SetStringKey("name", util->GetInputMethodLongName(input_method)); - val->SetStringKey("indicator", input_method.GetIndicator()); - output->Append(std::move(val)); + base::Value::Dict val; + val.Set("id", input_method.id()); + val.Set("name", util->GetInputMethodLongName(input_method)); + val.Set("indicator", input_method.GetIndicator()); + output.Append(std::move(val)); } - return RespondNow( - OneArgument(base::Value::FromUniquePtrValue(std::move(output)))); + return RespondNow(OneArgument(base::Value(std::move(output)))); } ExtensionFunction::ResponseAction @@ -590,8 +589,6 @@ if (!engine->InputMethodEngine::SetAutocorrectRange( params.context_id, gfx::Range(params.selection_start, params.selection_end), &error)) { - auto results = std::make_unique<base::ListValue>(); - results->Append(std::make_unique<base::Value>(false)); return RespondNow(Error(InformativeError(error, static_function_name()))); } return RespondNow(NoArguments()); @@ -614,7 +611,7 @@ params.context_id, *params.selection_start, *params.selection_end, &error)) { auto results = std::make_unique<base::ListValue>(); - results->Append(std::make_unique<base::Value>(false)); + results->Append(false); return RespondNow(ErrorWithArguments( std::move(results), InformativeError(error, static_function_name()))); }
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_warn_dialog.h b/chrome/browser/chromeos/policy/dlp/dlp_warn_dialog.h index 0d40e4b..ef3cf96 100644 --- a/chrome/browser/chromeos/policy/dlp/dlp_warn_dialog.h +++ b/chrome/browser/chromeos/policy/dlp/dlp_warn_dialog.h
@@ -57,24 +57,11 @@ }; DlpWarnDialog() = delete; + DlpWarnDialog(OnDlpRestrictionCheckedCallback callback, + DlpWarnDialogOptions options); DlpWarnDialog(const DlpWarnDialog& other) = delete; DlpWarnDialog& operator=(const DlpWarnDialog& other) = delete; ~DlpWarnDialog() override = default; - - private: - // DlpWarnNotifier is used to create and show DlpWarnDialogs and should be the - // only way to do that. Therefore it needs access to some private members of - // the DlpWarnDialog class, such as the options and restriction types, as well - // as the constructor. - friend class DlpWarnNotifier; - - // Helper method to create and show a warning dialog for a given - // |restriction|. - static void ShowDlpWarningDialog(OnDlpRestrictionCheckedCallback callback, - DlpWarnDialogOptions options); - - DlpWarnDialog(OnDlpRestrictionCheckedCallback callback, - DlpWarnDialogOptions options); }; } // namespace policy
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_warn_notifier.cc b/chrome/browser/chromeos/policy/dlp/dlp_warn_notifier.cc index 1b5bc68..6097cf14 100644 --- a/chrome/browser/chromeos/policy/dlp/dlp_warn_notifier.cc +++ b/chrome/browser/chromeos/policy/dlp/dlp_warn_notifier.cc
@@ -74,7 +74,7 @@ OnDlpRestrictionCheckedCallback callback, DlpWarnDialog::DlpWarnDialogOptions options) { views::Widget* widget = views::DialogDelegate::CreateDialogWidget( - new DlpWarnDialog(std::move(callback), options), + std::make_unique<DlpWarnDialog>(std::move(callback), options), /*context=*/nullptr, /*parent=*/nullptr); widget->Show(); // We disable the dialog's hide animations after showing it so that it doesn't
diff --git a/chrome/browser/devtools/devtools_file_system_indexer.cc b/chrome/browser/devtools/devtools_file_system_indexer.cc index 82e5822..cd876e0e 100644 --- a/chrome/browser/devtools/devtools_file_system_indexer.cc +++ b/chrome/browser/devtools/devtools_file_system_indexer.cc
@@ -8,6 +8,7 @@ #include <iterator> #include <memory> +#include <set> #include "base/bind.h" #include "base/callback.h"
diff --git a/chrome/browser/extensions/external_pref_loader.cc b/chrome/browser/extensions/external_pref_loader.cc index 0c2204ff..0267a80 100644 --- a/chrome/browser/extensions/external_pref_loader.cc +++ b/chrome/browser/extensions/external_pref_loader.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/extensions/external_pref_loader.h" +#include <set> #include <utility> #include "base/bind.h"
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index fb2833c..e89fffc 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -1878,7 +1878,7 @@ }, { "name": "enable-debug-for-store-billing", - "owners": [ "maxlg", "web-payments-team@google.com" ], + "owners": [ "web-payments-team@google.com" ], // This flag is to allow developers to develop their app-billing capable // TWA apps locally, without having to upload the apps to the Play Store. "expiry_milestone": -1 @@ -2586,7 +2586,7 @@ }, { "name": "enable-payment-request-basic-card", - "owners": [ "maxlg", "web-payments-team@google.com" ], + "owners": [ "web-payments-team@google.com" ], // This flag is used by developers to disable the "basic-card" method, to // make sure their web pages do not break after Chrome deprecates // "basic-card" in M100. @@ -2760,7 +2760,7 @@ }, { "name": "enable-secure-payment-confirmation-android", - "owners": [ "maxlg", "web-payments-team@google.com" ], + "owners": [ "web-payments-team@google.com" ], "expiry_milestone": 102 }, { @@ -2785,6 +2785,11 @@ "expiry_milestone": -1 }, { + "name": "enable-show-scrollable-mvt-on-ntp", + "owners": ["clank-start","hanxi","spdonghao"], + "expiry_milestone": 110 + }, + { "name": "enable-site-isolation-for-password-sites", "owners": [ "site-isolation-dev", "alexmos", "lukasza" ], // Note: while password-triggered site isolation launched in M77, it only @@ -5117,6 +5122,11 @@ "expiry_milestone": 102 }, { + "name": "read-printer-capabilities-with-xps", + "owners": [ "awscreen", "//printing/OWNERS" ], + "expiry_milestone": 106 + }, + { "name": "reader-mode-heuristics", "owners": [ "mdjones", "wychen" ], // This flag is a utility for testing Reader Mode heuristics or force @@ -5410,12 +5420,12 @@ { "name": "sharing-desktop-screenshots", "owners": ["skare", "kmilka", "chrome-sharing-eng@google.com" ], - "expiry_milestone": 99 + "expiry_milestone": 102 }, { "name": "sharing-desktop-screenshots-edit", "owners": ["skare", "jeffreycohen", "chrome-sharing-eng@google.com" ], - "expiry_milestone": 100 + "expiry_milestone": 102 }, { "name": "sharing-hub-desktop-app-menu",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index f47a94a..6b59512 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3549,6 +3549,10 @@ " On tablets with small screens a mobile site will be requested by " "default."; +const char kShowScrollableMVTOnNTPAndroidName[] = "Show scrollable MVT on NTP"; +const char kShowScrollableMVTOnNTPAndroidDescription[] = + "Enable showing the scrollable most visited tiles on NTP."; + const char kSecurePaymentConfirmationAndroidName[] = "Secure Payment Confirmation on Android"; const char kSecurePaymentConfirmationAndroidDescription[] = @@ -4009,6 +4013,11 @@ const char kPrintWithReducedRasterizationDescription[] = "When using GDI printing, avoid rasterization if possible."; +const char kReadPrinterCapabilitiesWithXpsName[] = + "Read printer capabilities with XPS"; +extern const char kReadPrinterCapabilitiesWithXpsDescription[] = + "When enabled, utilize XPS interface to read printer capabilities."; + const char kUseXpsForPrintingName[] = "Use XPS for printing"; const char kUseXpsForPrintingDescription[] = "When enabled, use XPS printing API instead of the GDI print API.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index cbddde18..3511e76c 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -2030,6 +2030,9 @@ extern const char kSecurePaymentConfirmationAndroidName[]; extern const char kSecurePaymentConfirmationAndroidDescription[]; +extern const char kShowScrollableMVTOnNTPAndroidName[]; +extern const char kShowScrollableMVTOnNTPAndroidDescription[]; + extern const char kSendTabToSelfV2Name[]; extern const char kSendTabToSelfV2Description[]; @@ -2291,6 +2294,9 @@ extern const char kPrintWithReducedRasterizationName[]; extern const char kPrintWithReducedRasterizationDescription[]; +extern const char kReadPrinterCapabilitiesWithXpsName[]; +extern const char kReadPrinterCapabilitiesWithXpsDescription[]; + extern const char kUseXpsForPrintingName[]; extern const char kUseXpsForPrintingDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 8f2bcae3c..53fc7b7 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -271,7 +271,7 @@ &kServiceManagerForDownload, &kShareButtonInTopToolbar, &kSharedClipboardUI, - &kShowScrollableMVTOnNTP, + &kShowScrollableMVTOnNTPAndroid, &kSpannableInlineAutocomplete, &kSpecialLocaleWrapper, &kSpecialUserDecision, @@ -749,8 +749,8 @@ const base::Feature kShareButtonInTopToolbar{"ShareButtonInTopToolbar", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kShowScrollableMVTOnNTP{"ShowScrollableMVTOnNTP", - base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kShowScrollableMVTOnNTPAndroid{ + "ShowScrollableMVTOnNTPAndroid", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kSpannableInlineAutocomplete{ "SpannableInlineAutocomplete", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h index 4e28592..b00c9de 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -135,7 +135,7 @@ extern const base::Feature kServiceManagerForDownload; extern const base::Feature kShareButtonInTopToolbar; extern const base::Feature kSharingHubLinkToggle; -extern const base::Feature kShowScrollableMVTOnNTP; +extern const base::Feature kShowScrollableMVTOnNTPAndroid; extern const base::Feature kSpannableInlineAutocomplete; extern const base::Feature kSpecialLocaleWrapper; extern const base::Feature kSpecialUserDecision;
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java index f46e836..f0f9c65e 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
@@ -105,7 +105,6 @@ .put(ChromeFeatureList.GRID_TAB_SWITCHER_FOR_TABLETS, false) .put(ChromeFeatureList.TAB_GROUPS_FOR_TABLETS, false) .put(ChromeFeatureList.TAB_STRIP_IMPROVEMENTS, false) - .put(ChromeFeatureList.SHOW_SCROLLABLE_MVT_ON_NTP, false) .build(); /**
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index 529e853..145a4e4b 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -483,7 +483,7 @@ public static final String SHARED_HIGHLIGHTING_AMP = "SharedHighlightingAmp"; public static final String SHOPPING_LIST = "ShoppingList"; public static final String SHOW_EXTENDED_PRELOADING_SETTING = "ShowExtendedPreloadingSetting"; - public static final String SHOW_SCROLLABLE_MVT_ON_NTP = "ShowScrollableMVTOnNTP"; + public static final String SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID = "ShowScrollableMVTOnNTPAndroid"; public static final String SHOW_TRUSTED_PUBLISHER_URL = "ShowTrustedPublisherURL"; public static final String SMART_SUGGESTION_FOR_LARGE_DOWNLOADS = "SmartSuggestionForLargeDownloads";
diff --git a/chrome/browser/permissions/notification_blocked_message_delegate_android.cc b/chrome/browser/permissions/notification_blocked_message_delegate_android.cc index 84c34e8..c7040e9 100644 --- a/chrome/browser/permissions/notification_blocked_message_delegate_android.cc +++ b/chrome/browser/permissions/notification_blocked_message_delegate_android.cc
@@ -177,7 +177,6 @@ if (!permission_prompt_) return; permission_prompt_->Closing(); - permission_prompt_.reset(); } void NotificationBlockedMessageDelegate::Delegate::SetManageClicked() {
diff --git a/chrome/browser/policy/messaging_layer/public/report_client_unittest.cc b/chrome/browser/policy/messaging_layer/public/report_client_unittest.cc index 37b68c0..d685071 100644 --- a/chrome/browser/policy/messaging_layer/public/report_client_unittest.cc +++ b/chrome/browser/policy/messaging_layer/public/report_client_unittest.cc
@@ -22,6 +22,7 @@ #include "build/chromeos_buildflags.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/policy/messaging_layer/util/dm_token_retriever_provider.h" +#include "chrome/browser/policy/messaging_layer/util/test.h" #include "components/policy/core/common/cloud/mock_cloud_policy_client.h" #include "components/reporting/client/dm_token_retriever.h" #include "components/reporting/client/mock_dm_token_retriever.h" @@ -406,7 +407,8 @@ if (StorageSelector::is_uploader_required() && !StorageSelector::is_use_missive()) { - EXPECT_CALL(*client_, UploadEncryptedReport(_, _, _)) + EXPECT_CALL(*client_, + UploadEncryptedReport(IsDataUploadRequestValid(), _, _)) .WillOnce(WithArgs<0, 2>(Invoke(GetVerifyDataInvocation()))); } @@ -439,13 +441,16 @@ if (StorageSelector::is_uploader_required() && !StorageSelector::is_use_missive()) { // Note: there does not seem to be another way to define the expectations - // A+B for encrypted case and just B for non-encrypted.g + // A+B for encrypted case and just B for non-encrypted. if (is_encryption_enabled()) { EXPECT_CALL(*client_, UploadEncryptedReport(_, _, _)) - .WillOnce(WithArgs<0, 2>(Invoke(GetEncryptionKeyInvocation()))) + .WillOnce(WithArgs<0, 2>(Invoke(GetEncryptionKeyInvocation()))); + EXPECT_CALL(*client_, + UploadEncryptedReport(IsDataUploadRequestValid(), _, _)) .WillOnce(WithArgs<0, 2>(Invoke(GetVerifyDataInvocation()))); } else { - EXPECT_CALL(*client_, UploadEncryptedReport(_, _, _)) + EXPECT_CALL(*client_, + UploadEncryptedReport(IsDataUploadRequestValid(), _, _)) .WillOnce(WithArgs<0, 2>(Invoke(GetVerifyDataInvocation()))); } }
diff --git a/chrome/browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc b/chrome/browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc index 6491d32..16c4f76 100644 --- a/chrome/browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc +++ b/chrome/browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc
@@ -18,6 +18,7 @@ #include "base/values.h" #include "chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.h" #include "chrome/browser/policy/messaging_layer/upload/record_upload_request_builder.h" +#include "chrome/browser/policy/messaging_layer/util/test.h" #include "components/policy/core/common/cloud/cloud_policy_client.h" #include "components/policy/core/common/cloud/dm_token.h" #include "components/policy/core/common/cloud/mock_cloud_policy_client.h" @@ -258,7 +259,7 @@ .sequence_information = test_records->back().sequence_information(), .force_confirm = force_confirm()}; - EXPECT_CALL(*client_, UploadEncryptedReport(_, _, _)) + EXPECT_CALL(*client_, UploadEncryptedReport(IsDataUploadRequestValid(), _, _)) .WillOnce(WithArgs<0, 2>( Invoke([&force_confirm_by_server]( base::Value::Dict request, @@ -294,7 +295,7 @@ auto test_records = BuildTestRecordsVector(kNumTestRecords, kGenerationId); const auto force_confirm_by_server = force_confirm(); - EXPECT_CALL(*client_, UploadEncryptedReport(_, _, _)) + EXPECT_CALL(*client_, UploadEncryptedReport(IsDataUploadRequestValid(), _, _)) .WillOnce(WithArgs<0, 2>( Invoke([&force_confirm_by_server]( base::Value::Dict request, @@ -323,7 +324,7 @@ auto test_records = BuildTestRecordsVector(kNumTestRecords, kGenerationId); const auto force_confirm_by_server = force_confirm(); - EXPECT_CALL(*client_, UploadEncryptedReport(_, _, _)) + EXPECT_CALL(*client_, UploadEncryptedReport(IsDataUploadRequestValid(), _, _)) .WillOnce(WithArgs<0, 2>( Invoke([&force_confirm_by_server]( base::Value::Dict request, @@ -351,7 +352,7 @@ static constexpr int64_t kGenerationId = 1234; auto test_records = BuildTestRecordsVector(kNumTestRecords, kGenerationId); - EXPECT_CALL(*client_, UploadEncryptedReport(_, _, _)) + EXPECT_CALL(*client_, UploadEncryptedReport(IsDataUploadRequestValid(), _, _)) .WillOnce(WithArgs<2>(Invoke( [](base::OnceCallback<void(absl::optional<base::Value::Dict>)> callback) { std::move(callback).Run(absl::nullopt); }))); @@ -389,7 +390,8 @@ // Once for failure, and once for gap. { ::testing::InSequence seq; - EXPECT_CALL(*client_, UploadEncryptedReport(_, _, _)) + EXPECT_CALL(*client_, + UploadEncryptedReport(IsDataUploadRequestValid(), _, _)) .WillOnce(WithArgs<0, 2>( Invoke([](base::Value::Dict request, policy::CloudPolicyClient::ResponseCallback callback) { @@ -397,7 +399,8 @@ FailedResponseFromRequest(request, response); std::move(callback).Run(std::move(response)); }))); - EXPECT_CALL(*client_, UploadEncryptedReport(_, _, _)) + EXPECT_CALL(*client_, + UploadEncryptedReport(IsDataUploadRequestValid(), _, _)) .WillOnce(WithArgs<0, 2>( Invoke([&force_confirm_by_server]( base::Value::Dict request, @@ -439,7 +442,7 @@ static constexpr int64_t kGenerationId = 1234; auto test_records = BuildTestRecordsVector(kNumTestRecords, kGenerationId); - EXPECT_CALL(*client_, UploadEncryptedReport(_, _, _)) + EXPECT_CALL(*client_, UploadEncryptedReport(IsDataUploadRequestValid(), _, _)) .WillOnce(WithArgs<2>( Invoke([](policy::CloudPolicyClient::ResponseCallback callback) { std::move(callback).Run(base::Value::Dict()); @@ -474,7 +477,7 @@ .sequence_information = test_records->back().sequence_information(), .force_confirm = force_confirm()}; - EXPECT_CALL(*client_, UploadEncryptedReport(_, _, _)) + EXPECT_CALL(*client_, UploadEncryptedReport(IsDataUploadRequestValid(), _, _)) .WillOnce(WithArgs<0, 2>( Invoke([&force_confirm_by_server]( base::Value::Dict request,
diff --git a/chrome/browser/policy/messaging_layer/upload/test_util.cc b/chrome/browser/policy/messaging_layer/upload/test_util.cc deleted file mode 100644 index b380b7f..0000000 --- a/chrome/browser/policy/messaging_layer/upload/test_util.cc +++ /dev/null
@@ -1,75 +0,0 @@ -// Copyright 2022 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/policy/messaging_layer/upload/test_util.h" - -#include "base/json/json_reader.h" - -namespace reporting { - -bool RequestContainingRecordMatcher::IsSubDict(const base::Value::Dict& sub, - const base::Value::Dict& super) { - for (auto&& [key, sub_value] : sub) { - const auto* super_value = super.Find(key); - if (super_value == nullptr || *super_value != sub_value) { - return false; - } - } - return true; -} - -RequestContainingRecordMatcher::RequestContainingRecordMatcher( - base::StringPiece matched_record_json) - : matched_record_json_(matched_record_json) {} - -bool RequestContainingRecordMatcher::MatchAndExplain( - const base::Value::Dict& arg, - std::ostream* os) const { - const auto* record_list = arg.FindList("encryptedRecord"); - if (record_list == nullptr) { - *os << "No key named \"encryptedRecord\" in the argument."; - return false; - } - - const auto matched_record = base::JSONReader::Read(matched_record_json_); - if (!matched_record.has_value()) { - *os << "The specified record cannot be parsed as a JSON object."; - return false; - } - const auto* matched_record_dict = matched_record->GetIfDict(); - if (matched_record_dict == nullptr) { - *os << "The specified record must be a Dict itself because each record " - "is a Dict."; - return false; - } - - for (const auto& record : *record_list) { - const auto* record_dict = record.GetIfDict(); - if (!record_dict) { - continue; - } - - // Match each key and value of matched_record with those of the iterated - // record_dict. In this way, users can specify part of a record instead of - // the full record. - if (IsSubDict(*matched_record_dict, *record_dict)) { - return true; - } - } - - *os << "The specified record is not found in the argument."; - return false; -} - -void RequestContainingRecordMatcher::DescribeTo(std::ostream* os) const { - *os << "contains the specified record."; -} - -void RequestContainingRecordMatcher::DescribeNegationTo( - std::ostream* os) const { - *os << "does not contain the specified record or there are other failed " - "conditions."; -} - -} // namespace reporting
diff --git a/chrome/browser/policy/messaging_layer/upload/test_util.h b/chrome/browser/policy/messaging_layer/upload/test_util.h deleted file mode 100644 index a1ef104..0000000 --- a/chrome/browser/policy/messaging_layer/upload/test_util.h +++ /dev/null
@@ -1,58 +0,0 @@ -// Copyright 2022 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_POLICY_MESSAGING_LAYER_UPLOAD_TEST_UTIL_H_ -#define CHROME_BROWSER_POLICY_MESSAGING_LAYER_UPLOAD_TEST_UTIL_H_ - -#include <ostream> -#include <string> - -#include "base/strings/string_piece.h" -#include "base/values.h" - -#include "testing/gmock/include/gmock/gmock.h" - -namespace reporting { - -using ::testing::Matcher; - -class RequestContainingRecordMatcher { - public: - using is_gtest_matcher = void; - - explicit RequestContainingRecordMatcher( - base::StringPiece matched_record_json); - bool MatchAndExplain(const base::Value::Dict& arg, std::ostream* os) const; - void DescribeTo(std::ostream* os) const; - void DescribeNegationTo(std::ostream* os) const; - - private: - const std::string matched_record_json_; - - // Determine if |sub| is a sub-dictionary of |super|. That means, whether - // |super| contains all keys of |sub| and the values corresponding to each of - // |sub|'s keys equal. This method does not call itself recursively on values - // that are dictionaries. - static bool IsSubDict(const base::Value::Dict& sub, - const base::Value::Dict& super); -}; - -// Match a request Dict object that contains the given record -// |matched_record_json|. The match will be successful as long as any record in -// the request contains |matched_record_json| as a sub-dictionary -- they are -// not required to equal. In this way, you can specify only part of the record -// of interest (e.g., omit "encryptedWrappedRecord"). -// -// This is templated because we expect the tested request comes in different -// forms, including their referenceness (gtest need the matcher type to also -// match references to some extent). As long as the type can be cast to a -// |base::Value::Dict| object, this matcher should work. -template <class T = base::Value::Dict> -Matcher<T> DoesRequestContainRecord(base::StringPiece matched_record_json) { - return RequestContainingRecordMatcher(matched_record_json); -} - -} // namespace reporting - -#endif // CHROME_BROWSER_POLICY_MESSAGING_LAYER_UPLOAD_TEST_UTIL_H_
diff --git a/chrome/browser/policy/messaging_layer/upload/upload_client_unittest.cc b/chrome/browser/policy/messaging_layer/upload/upload_client_unittest.cc index 53fd697c..9f8885b7 100644 --- a/chrome/browser/policy/messaging_layer/upload/upload_client_unittest.cc +++ b/chrome/browser/policy/messaging_layer/upload/upload_client_unittest.cc
@@ -3,7 +3,7 @@ // found in the LICENSE file. #include "chrome/browser/policy/messaging_layer/upload/upload_client.h" -#include "chrome/browser/policy/messaging_layer/upload/test_util.h" +#include "chrome/browser/policy/messaging_layer/util/test.h" #include <tuple> @@ -210,7 +210,8 @@ } )JSON"; EXPECT_CALL(*client, UploadEncryptedReport( - AllOf(DoesRequestContainRecord(base::StringPrintf( + AllOf(IsDataUploadRequestValid(), + DoesRequestContainRecord(base::StringPrintf( matched_record_template, 0)), DoesRequestContainRecord(base::StringPrintf( matched_record_template, 1)),
diff --git a/chrome/browser/policy/messaging_layer/util/test.cc b/chrome/browser/policy/messaging_layer/util/test.cc new file mode 100644 index 0000000..76d6d2ec --- /dev/null +++ b/chrome/browser/policy/messaging_layer/util/test.cc
@@ -0,0 +1,129 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/policy/messaging_layer/util/test.h" + +#include <string> +#include "base/json/json_reader.h" + +namespace reporting { + +DataUploadRequestValidityMatcher::Settings& +DataUploadRequestValidityMatcher::Settings::SetCheckEncryptedRecord(bool flag) { + check_encrypted_record_ = flag; + return *this; +} + +DataUploadRequestValidityMatcher::DataUploadRequestValidityMatcher( + const Settings& settings) + : settings_(settings) {} + +bool DataUploadRequestValidityMatcher::MatchAndExplain( + const base::Value::Dict& arg, + MatchResultListener* listener) const { + if (settings_.check_encrypted_record_ && + arg.FindList("encryptedRecord") == nullptr) { + *listener + << "No key named \"encryptedRecord\" in the argument or the value is " + "not a list."; + return false; + } + // TODO: Check the validity of each record based on whether they have required + // fields and types. + + const auto* request_id = arg.FindString("requestId"); + if (request_id == nullptr) { + *listener + << "No key named \"requestId\" in the argument or the value is not a " + "string."; + return false; + } + if (request_id->empty()) { + *listener << "Request ID is empty."; + return false; + } + if (request_id->find_first_not_of("0123456789abcdefABCDEF") != + std::string::npos) { + *listener << "Request ID is not a hexadecimal number."; + return false; + } + + return true; +} + +void DataUploadRequestValidityMatcher::DescribeTo(std::ostream* os) const { + *os << "is valid."; +} + +void DataUploadRequestValidityMatcher::DescribeNegationTo( + std::ostream* os) const { + *os << "is invalid."; +} + +bool RequestContainingRecordMatcher::IsSubDict(const base::Value::Dict& sub, + const base::Value::Dict& super) { + for (auto&& [key, sub_value] : sub) { + const auto* super_value = super.Find(key); + if (super_value == nullptr || *super_value != sub_value) { + return false; + } + } + return true; +} + +RequestContainingRecordMatcher::RequestContainingRecordMatcher( + base::StringPiece matched_record_json) + : matched_record_json_(matched_record_json) {} + +bool RequestContainingRecordMatcher::MatchAndExplain( + const base::Value::Dict& arg, + std::ostream* os) const { + const auto* record_list = arg.FindList("encryptedRecord"); + if (record_list == nullptr) { + *os << "No key named \"encryptedRecord\" in the argument or the value is " + "not a list."; + return false; + } + + const auto matched_record = base::JSONReader::Read(matched_record_json_); + if (!matched_record.has_value()) { + *os << "The specified record cannot be parsed as a JSON object."; + return false; + } + const auto* matched_record_dict = matched_record->GetIfDict(); + if (matched_record_dict == nullptr) { + *os << "The specified record must be a Dict itself because each record " + "is a Dict."; + return false; + } + + for (const auto& record : *record_list) { + const auto* record_dict = record.GetIfDict(); + if (!record_dict) { + continue; + } + + // Match each key and value of matched_record with those of the iterated + // record_dict. In this way, users can specify part of a record instead of + // the full record. + if (IsSubDict(*matched_record_dict, *record_dict)) { + return true; + } + } + + *os << "The specified record is not found in the argument."; + return false; +} + +void RequestContainingRecordMatcher::DescribeTo(std::ostream* os) const { + *os << "contains the specified record."; +} + +void RequestContainingRecordMatcher::DescribeNegationTo( + std::ostream* os) const { + *os << "does not contain the specified record or there are other failed " + "conditions."; +} + +} // namespace reporting
diff --git a/chrome/browser/policy/messaging_layer/util/test.h b/chrome/browser/policy/messaging_layer/util/test.h new file mode 100644 index 0000000..347727d --- /dev/null +++ b/chrome/browser/policy/messaging_layer/util/test.h
@@ -0,0 +1,104 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_POLICY_MESSAGING_LAYER_UTIL_TEST_H_ +#define CHROME_BROWSER_POLICY_MESSAGING_LAYER_UTIL_TEST_H_ + +#include <ostream> +#include <string> + +#include "base/strings/string_piece.h" +#include "base/values.h" + +#include "testing/gmock/include/gmock/gmock.h" + +namespace reporting { + +using ::testing::Matcher; +using ::testing::MatchResultListener; + +class DataUploadRequestValidityMatcher { + public: + using is_gtest_matcher = void; + + class Settings { + public: + Settings() = default; + Settings(const Settings& other) = default; + Settings(Settings&& other) = default; + // Enable or disable checking the existence of key "encryptedRecord" and + // that the value is a list. + Settings& SetCheckEncryptedRecord(bool flag); + + private: + friend DataUploadRequestValidityMatcher; + bool check_encrypted_record_ = true; + }; + + DataUploadRequestValidityMatcher() = default; + explicit DataUploadRequestValidityMatcher(const Settings& settings); + bool MatchAndExplain(const base::Value::Dict& arg, + MatchResultListener* listener) const; + void DescribeTo(std::ostream* os) const; + void DescribeNegationTo(std::ostream* os) const; + + private: + const Settings settings_{}; +}; + +class RequestContainingRecordMatcher { + public: + using is_gtest_matcher = void; + + explicit RequestContainingRecordMatcher( + base::StringPiece matched_record_json); + bool MatchAndExplain(const base::Value::Dict& arg, std::ostream* os) const; + void DescribeTo(std::ostream* os) const; + void DescribeNegationTo(std::ostream* os) const; + + private: + const std::string matched_record_json_; + + // Determine if |sub| is a sub-dictionary of |super|. That means, whether + // |super| contains all keys of |sub| and the values corresponding to each of + // |sub|'s keys equal. This method does not call itself recursively on values + // that are dictionaries. + static bool IsSubDict(const base::Value::Dict& sub, + const base::Value::Dict& super); +}; + +// The following matcher functions templated because we expect the tested +// request comes in different forms, including their referenceness (gtest need +// the matcher type to also match references to some extent). As long as the +// type can be cast to a |base::Value::Dict| object, this matcher should work. + +// Match a data upload request that is valid. This matcher is intended to be +// called for most tested data upload requests to verify whether the request is +// valid on some basic fronts, such as containing an "encryptedRecord" key, etc. +// +// You can use settings to enable or skip some part of the validity checks if +// your test case intentionally creates a malformed request. +template <class T = base::Value::Dict> +Matcher<T> IsDataUploadRequestValid( + const DataUploadRequestValidityMatcher::Settings& settings) { + return DataUploadRequestValidityMatcher(settings); +} +template <class T = base::Value::Dict> +Matcher<T> IsDataUploadRequestValid() { + return DataUploadRequestValidityMatcher(); +} + +// Match a request that contains the given record |matched_record_json|. The +// match will be successful as long as any record in the request contains +// |matched_record_json| as a sub-dictionary -- they are not required to equal. +// In this way, you can specify only part of the record of interest (e.g., omit +// "encryptedWrappedRecord"). +template <class T = base::Value::Dict> +Matcher<T> DoesRequestContainRecord(base::StringPiece matched_record_json) { + return RequestContainingRecordMatcher(matched_record_json); +} + +} // namespace reporting + +#endif // CHROME_BROWSER_POLICY_MESSAGING_LAYER_UTIL_TEST_H_
diff --git a/chrome/browser/prefetch/search_prefetch/base_search_prefetch_request.cc b/chrome/browser/prefetch/search_prefetch/base_search_prefetch_request.cc index 02118ca..067a17c0 100644 --- a/chrome/browser/prefetch/search_prefetch/base_search_prefetch_request.cc +++ b/chrome/browser/prefetch/search_prefetch/base_search_prefetch_request.cc
@@ -109,7 +109,7 @@ BaseSearchPrefetchRequest::BaseSearchPrefetchRequest( const GURL& prefetch_url, - base::OnceClosure report_error_callback) + base::OnceCallback<void(bool)> report_error_callback) : prefetch_url_(prefetch_url), report_error_callback_(std::move(report_error_callback)) {}
diff --git a/chrome/browser/prefetch/search_prefetch/base_search_prefetch_request.h b/chrome/browser/prefetch/search_prefetch/base_search_prefetch_request.h index 104a28ef3..82eb67d 100644 --- a/chrome/browser/prefetch/search_prefetch/base_search_prefetch_request.h +++ b/chrome/browser/prefetch/search_prefetch/base_search_prefetch_request.h
@@ -48,8 +48,9 @@ // updating |current_status_|. class BaseSearchPrefetchRequest { public: - BaseSearchPrefetchRequest(const GURL& prefetch_url, - base::OnceClosure report_error_callback); + BaseSearchPrefetchRequest( + const GURL& prefetch_url, + base::OnceCallback<void(bool)> report_error_callback); virtual ~BaseSearchPrefetchRequest(); BaseSearchPrefetchRequest(const BaseSearchPrefetchRequest&) = delete; @@ -91,7 +92,7 @@ Profile* profile, std::unique_ptr<network::ResourceRequest> resource_request, const net::NetworkTrafficAnnotationTag& traffic_annotation, - base::OnceClosure report_error_callback) = 0; + base::OnceCallback<void(bool)> report_error_callback) = 0; // Stops the on-going prefetch and should mark |current_status_| // appropriately. @@ -112,7 +113,7 @@ GURL prefetch_url_; // Called when there is a network/server error on the prefetch request. - base::OnceClosure report_error_callback_; + base::OnceCallback<void(bool)> report_error_callback_; }; #endif // CHROME_BROWSER_PREFETCH_SEARCH_PREFETCH_BASE_SEARCH_PREFETCH_REQUEST_H_
diff --git a/chrome/browser/prefetch/search_prefetch/search_prefetch_service.cc b/chrome/browser/prefetch/search_prefetch/search_prefetch_service.cc index 02a20f3e..c79bb542 100644 --- a/chrome/browser/prefetch/search_prefetch/search_prefetch_service.cc +++ b/chrome/browser/prefetch/search_prefetch/search_prefetch_service.cc
@@ -183,7 +183,7 @@ std::unique_ptr<BaseSearchPrefetchRequest> prefetch_request = std::make_unique<StreamingSearchPrefetchRequest>( - url, base::BindOnce(&SearchPrefetchService::ReportError, + url, base::BindOnce(&SearchPrefetchService::ReportFetchResult, base::Unretained(this))); DCHECK(prefetch_request); @@ -381,7 +381,10 @@ prefetch_expiry_timers_.erase(search_terms); } -void SearchPrefetchService::ReportError() { +void SearchPrefetchService::ReportFetchResult(bool error) { + UMA_HISTOGRAM_BOOLEAN("Omnibox.SearchPrefetch.FetchResult", !error); + if (!error) + return; last_error_time_ticks_ = base::TimeTicks::Now(); }
diff --git a/chrome/browser/prefetch/search_prefetch/search_prefetch_service.h b/chrome/browser/prefetch/search_prefetch/search_prefetch_service.h index a440fb5..9456dc6 100644 --- a/chrome/browser/prefetch/search_prefetch/search_prefetch_service.h +++ b/chrome/browser/prefetch/search_prefetch/search_prefetch_service.h
@@ -137,8 +137,9 @@ // Removes the prefetch and prefetch timers associated with |search_terms|. void DeletePrefetch(std::u16string search_terms); - // Records the current time to prevent prefetches for a set duration. - void ReportError(); + // Records metrics around the error rate of prefetches. When |error| is true, + // records the current time to prevent prefetches for a set duration. + void ReportFetchResult(bool error); // If the navigation URL matches with a prefetch that can be served, this // function marks that prefetch as clicked to prevent deletion when omnibox
diff --git a/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc b/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc index 4abf0fd..8cfc7c2 100644 --- a/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc +++ b/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc
@@ -729,6 +729,8 @@ WaitUntilStatusChangesTo(base::ASCIIToUTF16(search_terms), SearchPrefetchStatus::kComplete); + histogram_tester.ExpectUniqueSample("Omnibox.SearchPrefetch.FetchResult", + true, 1); EXPECT_EQ(1u, search_server_requests().size()); EXPECT_NE(std::string::npos, @@ -1048,6 +1050,7 @@ IN_PROC_BROWSER_TEST_P(SearchPrefetchServiceEnabledBrowserTest, 502PrefetchFunctionality) { + base::HistogramTester histogram_tester; auto* search_prefetch_service = SearchPrefetchServiceFactory::GetForProfile(browser()->profile()); EXPECT_NE(nullptr, search_prefetch_service); @@ -1068,6 +1071,9 @@ WaitUntilStatusChangesTo(base::ASCIIToUTF16(search_terms), SearchPrefetchStatus::kRequestFailed); + histogram_tester.ExpectUniqueSample("Omnibox.SearchPrefetch.FetchResult", + false, 1); + EXPECT_EQ(1u, search_server_requests().size()); EXPECT_NE(std::string::npos, search_server_requests()[0].GetURL().spec().find(search_terms));
diff --git a/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_request.cc b/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_request.cc index 22b7166bb..a076c204 100644 --- a/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_request.cc +++ b/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_request.cc
@@ -9,7 +9,7 @@ StreamingSearchPrefetchRequest::StreamingSearchPrefetchRequest( const GURL& prefetch_url, - base::OnceClosure report_error_callback) + base::OnceCallback<void(bool)> report_error_callback) : BaseSearchPrefetchRequest(prefetch_url, std::move(report_error_callback)) {} @@ -19,7 +19,7 @@ Profile* profile, std::unique_ptr<network::ResourceRequest> resource_request, const net::NetworkTrafficAnnotationTag& network_traffic_annotation, - base::OnceClosure report_error_callback) { + base::OnceCallback<void(bool)> report_error_callback) { streaming_url_loader_ = std::make_unique<StreamingSearchPrefetchURLLoader>( this, profile, std::move(resource_request), network_traffic_annotation, std::move(report_error_callback));
diff --git a/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_request.h b/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_request.h index 3b291a0..8e29761 100644 --- a/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_request.h +++ b/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_request.h
@@ -25,8 +25,9 @@ // more easily. class StreamingSearchPrefetchRequest : public BaseSearchPrefetchRequest { public: - StreamingSearchPrefetchRequest(const GURL& prefetch_url, - base::OnceClosure report_error_callback); + StreamingSearchPrefetchRequest( + const GURL& prefetch_url, + base::OnceCallback<void(bool)> report_error_callback); ~StreamingSearchPrefetchRequest() override; StreamingSearchPrefetchRequest(const StreamingSearchPrefetchRequest&) = @@ -39,7 +40,7 @@ Profile* profile, std::unique_ptr<network::ResourceRequest> resource_request, const net::NetworkTrafficAnnotationTag& network_traffic_annotation, - base::OnceClosure report_error_callback) override; + base::OnceCallback<void(bool)> report_error_callback) override; void StopPrefetch() override; std::unique_ptr<SearchPrefetchURLLoader> TakeSearchPrefetchURLLoader() override;
diff --git a/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.cc b/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.cc index b23d489..5262adc 100644 --- a/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.cc +++ b/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.cc
@@ -54,7 +54,7 @@ Profile* profile, std::unique_ptr<network::ResourceRequest> resource_request, const net::NetworkTrafficAnnotationTag& network_traffic_annotation, - base::OnceClosure report_error_callback) + base::OnceCallback<void(bool)> report_error_callback) : streaming_prefetch_request_(streaming_prefetch_request), report_error_callback_(std::move(report_error_callback)), profile_(profile), @@ -181,10 +181,12 @@ return; } + bool can_serve_response = CanServePrefetchRequest(head->headers); + std::move(report_error_callback_).Run(!can_serve_response); + // If there is an error, either cancel the request or fallback depending on // whether we still have a parent pointer. - if (!CanServePrefetchRequest(head->headers)) { - std::move(report_error_callback_).Run(); + if (!can_serve_response) { if (SearchPrefetchBlockBeforeHeadersIsEnabled() && !streaming_prefetch_request_) { Fallback();
diff --git a/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.h b/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.h index e57152e..aa64916 100644 --- a/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.h +++ b/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.h
@@ -41,7 +41,7 @@ Profile* profile, std::unique_ptr<network::ResourceRequest> resource_request, const net::NetworkTrafficAnnotationTag& network_traffic_annotation, - base::OnceClosure report_error_callback); + base::OnceCallback<void(bool)> report_error_callback); ~StreamingSearchPrefetchURLLoader() override; @@ -198,7 +198,7 @@ // Whenever an error is reported, it needs to be reported to the service via // this callback. - base::OnceClosure report_error_callback_; + base::OnceCallback<void(bool)> report_error_callback_; // Track if the request has already been marked as servable, and if so, don't // report it again.
diff --git a/chrome/browser/resources/history/history_clusters/cluster.html b/chrome/browser/resources/history/history_clusters/cluster.html index 00224173..dba56ca4 100644 --- a/chrome/browser/resources/history/history_clusters/cluster.html +++ b/chrome/browser/resources/history/history_clusters/cluster.html
@@ -101,7 +101,8 @@ } </style> <div id="container" on-visit-clicked="onVisitClicked_" - on-open-all-visits="onOpenAllVisits_"> + on-open-all-visits="onOpenAllVisits_" + on-remove-visits="onRemoveVisits_"> <div id="label-row" hidden="[[!cluster.label]]"> <div id="label">[[cluster.label]]</div> <div class="timestamp-and-menu"> @@ -110,22 +111,17 @@ </menu-container> </div> </div> - <url-visit visit="[[cluster.visit]]" index="0" - is-top-visit$="[[!cluster.label]]"> + <url-visit visit="[[cluster.visit]]" is-top-visit$="[[!cluster.label]]"> </url-visit> <template is="dom-repeat" items="[[visibleRelatedVisits_]]"> - <url-visit visit="[[item]]" - index="[[getVisitIndex_(item, cluster.visit.relatedVisits.*)]]" - indented$="[[!cluster.label]]"> + <url-visit visit="[[item]]" indented$="[[!cluster.label]]"> </url-visit> </template> <!-- Disable animation on iron-collapse, as the parent iron-list can't easily handle it. --> <iron-collapse opened="[[expanded_]]" no-animation> <template is="dom-repeat" items="[[hiddenRelatedVisits_]]"> - <url-visit visit="[[item]]" - index="[[getVisitIndex_(item, cluster.visit.relatedVisits.*)]]" - indented$="[[!cluster.label]]"> + <url-visit visit="[[item]]" indented$="[[!cluster.label]]"> </url-visit> </template> </iron-collapse>
diff --git a/chrome/browser/resources/history/history_clusters/cluster.ts b/chrome/browser/resources/history/history_clusters/cluster.ts index ac8f479..469c3b8c 100644 --- a/chrome/browser/resources/history/history_clusters/cluster.ts +++ b/chrome/browser/resources/history/history_clusters/cluster.ts
@@ -17,7 +17,7 @@ import {BrowserProxyImpl} from './browser_proxy.js'; import {getTemplate} from './cluster.html.js'; import {Cluster, PageCallbackRouter, URLVisit} from './history_clusters.mojom-webui.js'; -import {ClusterAction, MetricsProxyImpl} from './metrics_proxy.js'; +import {ClusterAction, MetricsProxyImpl, VisitAction} from './metrics_proxy.js'; /** * @fileoverview This file provides a custom element displaying a cluster. @@ -138,9 +138,14 @@ ClusterAction.RELATED_SEARCH_CLICKED, this.index); } - private onVisitClicked_() { + private onVisitClicked_(event: CustomEvent<URLVisit>) { MetricsProxyImpl.getInstance().recordClusterAction( ClusterAction.VISIT_CLICKED, this.index); + + const visit = event.detail; + MetricsProxyImpl.getInstance().recordVisitAction( + VisitAction.CLICKED, this.getVisitIndex_(visit), + MetricsProxyImpl.getVisitType(visit)); } private onOpenAllVisits_() { @@ -158,6 +163,21 @@ ClusterAction.OPENED_IN_TAB_GROUP, this.index); } + private onRemoveVisits_(event: CustomEvent<Array<URLVisit>>) { + // The actual removal is handled at in clusters.ts. This is just a good + // place to record the metric. + const visitsToBeRemoved = event.detail; + + // To match the historic semantics, we only record this metric when a single + // visit is requested to be removed by the user. + if (visitsToBeRemoved.length === 1) { + const visit = visitsToBeRemoved[0]; + MetricsProxyImpl.getInstance().recordVisitAction( + VisitAction.DELETED, this.getVisitIndex_(visit), + MetricsProxyImpl.getVisitType(visit)); + } + } + private onToggleButtonKeyDown_(e: KeyboardEvent) { if (e.key !== 'Enter' && e.key !== ' ') { return; @@ -221,6 +241,9 @@ composed: true, detail: this.index, })); + + MetricsProxyImpl.getInstance().recordClusterAction( + ClusterAction.DELETED, this.index); } else { // Reconstitute the cluster by setting the top visit with the // `remainingVisits` as its related visits. @@ -260,11 +283,20 @@ } /** - * Returns the index of `relatedVisit` among the visits in the cluster. + * Returns the index of `visit` among the visits in the cluster. Returns -1 + * if the visit is not found in the cluster at all. */ - private getVisitIndex_(relatedVisit: URLVisit): number { - // Index 0 represents the top visit. - return this.cluster.visit.relatedVisits.indexOf(relatedVisit) + 1; + private getVisitIndex_(visit: URLVisit): number { + if (visit === this.cluster.visit) { + return 0; + } + + const relatedVisitIndex = this.cluster.visit.relatedVisits.indexOf(visit); + if (relatedVisitIndex === -1) { + return -1; + } + // Add one, because the "top visit" is the 0th visit. + return relatedVisitIndex + 1; } }
diff --git a/chrome/browser/resources/history/history_clusters/clusters.ts b/chrome/browser/resources/history/history_clusters/clusters.ts index 1f41a82..a599e8a 100644 --- a/chrome/browser/resources/history/history_clusters/clusters.ts +++ b/chrome/browser/resources/history/history_clusters/clusters.ts
@@ -24,7 +24,6 @@ import {BrowserProxyImpl} from './browser_proxy.js'; import {getTemplate} from './clusters.html.js'; import {Cluster, PageCallbackRouter, PageHandlerRemote, QueryResult, URLVisit} from './history_clusters.mojom-webui.js'; -import {ClusterAction, MetricsProxyImpl} from './metrics_proxy.js'; /** * @fileoverview This file provides a custom element that requests and shows @@ -204,8 +203,6 @@ private onRemoveCluster_(event: CustomEvent<number>) { const index = event.detail; this.splice('result_.clusters', index, 1); - MetricsProxyImpl.getInstance().recordClusterAction( - ClusterAction.DELETED, index); } /**
diff --git a/chrome/browser/resources/history/history_clusters/menu_container.ts b/chrome/browser/resources/history/history_clusters/menu_container.ts index 07b4082..6b2c2c4 100644 --- a/chrome/browser/resources/history/history_clusters/menu_container.ts +++ b/chrome/browser/resources/history/history_clusters/menu_container.ts
@@ -10,9 +10,8 @@ import {CrLazyRenderElement} from 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.m.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {Annotation, URLVisit} from './history_clusters.mojom-webui.js'; +import {URLVisit} from './history_clusters.mojom-webui.js'; import {getTemplate} from './menu_container.html.js'; -import {MetricsProxyImpl, VisitAction, VisitType} from './metrics_proxy.js'; /** * @fileoverview This file provides a custom element displaying an action menu. @@ -45,22 +44,6 @@ static get properties() { return { /** - * The index of the cluster this menu belongs to. - */ - clusterIndex: { - type: Number, - value: -1, // Initialized to an invalid value. - }, - - /** - * The index of the visit in the cluster. - */ - visitIndex: { - type: Number, - value: -1, // Initialized to an invalid value. - }, - - /** * The visit associated with this menu. */ visit: Object, @@ -71,8 +54,6 @@ // Properties //============================================================================ - clusterIndex: number; - visitIndex: number; visit: URLVisit; //============================================================================ @@ -117,23 +98,6 @@ })); this.$.actionMenu.get().close(); - - MetricsProxyImpl.getInstance().recordVisitAction( - VisitAction.DELETED, this.visitIndex, this.getVisitType_()); - } - - //============================================================================ - // Helper methods - //============================================================================ - - /** - * Returns the VisitType based on whether this is a visit to the default - * search provider's results page. - */ - private getVisitType_(): VisitType { - return this.visit.annotations.includes(Annotation.kSearchResultsPage) ? - VisitType.SRP : - VisitType.NON_SRP; } }
diff --git a/chrome/browser/resources/history/history_clusters/metrics_proxy.ts b/chrome/browser/resources/history/history_clusters/metrics_proxy.ts index 08c182b0..bdc38fb 100644 --- a/chrome/browser/resources/history/history_clusters/metrics_proxy.ts +++ b/chrome/browser/resources/history/history_clusters/metrics_proxy.ts
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {Annotation, URLVisit} from './history_clusters.mojom-webui.js'; + /** * @fileoverview This file provides an abstraction layer for logging metrics for * mocking in tests. @@ -70,6 +72,16 @@ static setInstance(obj: MetricsProxy) { instance = obj; } + + /** + * Returns the VisitType based on whether this is a visit to the default + * search provider's results page. + */ + static getVisitType(visit: URLVisit): VisitType { + return visit.annotations.includes(Annotation.kSearchResultsPage) ? + VisitType.SRP : + VisitType.NON_SRP; + } } let instance: MetricsProxy|null = null;
diff --git a/chrome/browser/resources/history/history_clusters/url_visit.html b/chrome/browser/resources/history/history_clusters/url_visit.html index 6f33f25..7ca534f 100644 --- a/chrome/browser/resources/history/history_clusters/url_visit.html +++ b/chrome/browser/resources/history/history_clusters/url_visit.html
@@ -112,9 +112,8 @@ </a> <div class="timestamp-and-menu"> <div class="timestamp" hidden="[[!isTopVisit]]">[[visit.relativeDate]]</div> - <menu-container - is-top-menu$="[[isTopVisit]]" cluster-index="[[clusterIndex]]" - visit-index="[[index]]" visit="[[visit]]"> + <menu-container is-top-menu$="[[isTopVisit]]" + cluster-index="[[clusterIndex]]" visit="[[visit]]"> </menu-container> </div> </div>
diff --git a/chrome/browser/resources/history/history_clusters/url_visit.ts b/chrome/browser/resources/history/history_clusters/url_visit.ts index 81a64af..4ea7c6c 100644 --- a/chrome/browser/resources/history/history_clusters/url_visit.ts +++ b/chrome/browser/resources/history/history_clusters/url_visit.ts
@@ -12,7 +12,6 @@ import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {Annotation, URLVisit} from './history_clusters.mojom-webui.js'; -import {MetricsProxyImpl, VisitAction, VisitType} from './metrics_proxy.js'; import {OpenWindowProxyImpl} from './open_window_proxy.js'; import {getTemplate} from './url_visit.html.js'; @@ -57,14 +56,6 @@ }, /** - * The index of the visit in the cluster. - */ - index: { - type: Number, - value: -1, // Initialized to an invalid value. - }, - - /** * The visit to display. */ visit: Object, @@ -91,7 +82,6 @@ // Properties //============================================================================ - index: number; visit: URLVisit; //============================================================================ @@ -99,13 +89,11 @@ //============================================================================ private onAuxClick_() { - MetricsProxyImpl.getInstance().recordVisitAction( - VisitAction.CLICKED, this.index, this.getVisitType_()); - // Notify the parent <history-cluster> element of this event. this.dispatchEvent(new CustomEvent('visit-clicked', { bubbles: true, composed: true, + detail: this.visit, })); } @@ -173,16 +161,6 @@ return ''; } } - - /** - * Returns the VisitType based on whether this is a visit to the default - * search provider's results page. - */ - private getVisitType_(): VisitType { - return this.visit.annotations.includes(Annotation.kSearchResultsPage) ? - VisitType.SRP : - VisitType.NON_SRP; - } } customElements.define(VisitRowElement.is, VisitRowElement);
diff --git a/chrome/browser/resources/new_tab_page/voice_search_overlay.html b/chrome/browser/resources/new_tab_page/voice_search_overlay.html index 130e0698..85755d3 100644 --- a/chrome/browser/resources/new_tab_page/voice_search_overlay.html +++ b/chrome/browser/resources/new_tab_page/voice_search_overlay.html
@@ -177,11 +177,7 @@ </style> <dialog id="dialog" on-close="onOverlayClose_" on-click="onOverlayClick_" on-keydown="onOverlayKeydown_"> - <!-- Purely exists to capture focus upon opening the dialog. --> - <div tabindex="-1"></div> - <cr-icon-button id="closeButton" class="icon-clear" title="$i18n{close}"> - </cr-icon-button> - <div id="content"> + <div id="content" tabindex="-1"> <iron-selector id="texts" selected="[[getText_(state_)]]" attr-for-selected="text" fallback-selection="none" aria-live="polite" selected-attribute="visible" class="display-stack"> @@ -236,4 +232,6 @@ </cr-button> </div> </div> + <cr-icon-button id="closeButton" class="icon-clear" title="$i18n{close}"> + </cr-icon-button> </dialog>
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.gni b/chrome/browser/resources/settings/chromeos/os_settings.gni index dff0949..6c3d02f 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.gni +++ b/chrome/browser/resources/settings/chromeos/os_settings.gni
@@ -321,7 +321,6 @@ "chrome/browser/resources/settings/chromeos/bluetooth_page/bluetooth_page_browser_proxy.html", "chrome/browser/resources/settings/chromeos/bluetooth_page/bluetooth_subpage.html", "chrome/browser/resources/settings/chromeos/crostini_page/crostini_arc_adb.html", - "chrome/browser/resources/settings/chromeos/crostini_page/crostini_arc_adb.html", "chrome/browser/resources/settings/chromeos/crostini_page/crostini_arc_adb_confirmation_dialog.html", "chrome/browser/resources/settings/chromeos/crostini_page/crostini_browser_proxy.html", "chrome/browser/resources/settings/chromeos/crostini_page/crostini_confirmation_dialog.html",
diff --git a/chrome/browser/supervised_user/supervised_user_features/supervised_user_features.cc b/chrome/browser/supervised_user/supervised_user_features/supervised_user_features.cc index 04c037bb..b339b76 100644 --- a/chrome/browser/supervised_user/supervised_user_features/supervised_user_features.cc +++ b/chrome/browser/supervised_user/supervised_user_features/supervised_user_features.cc
@@ -22,6 +22,11 @@ const base::Feature kLocalWebApprovals{"LocalWebApprovals", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enables child accounts (i.e. Unicorn accounts) to clear their browsing +// history data from Settings. +const base::Feature kAllowHistoryDeletionForChildAccounts{ + "AllowHistoryDeletionForChildAccounts", base::FEATURE_DISABLED_BY_DEFAULT}; + bool IsWebFilterInterstitialRefreshEnabled() { DCHECK(base::FeatureList::IsEnabled(kWebFilterInterstitialRefresh) || !base::FeatureList::IsEnabled(kLocalWebApprovals));
diff --git a/chrome/browser/supervised_user/supervised_user_features/supervised_user_features.h b/chrome/browser/supervised_user/supervised_user_features/supervised_user_features.h index 77de78e..5e2f4851 100644 --- a/chrome/browser/supervised_user/supervised_user_features/supervised_user_features.h +++ b/chrome/browser/supervised_user/supervised_user_features/supervised_user_features.h
@@ -13,6 +13,8 @@ extern const base::Feature kLocalWebApprovals; +extern const base::Feature kAllowHistoryDeletionForChildAccounts; + // Returns whether refreshed version of the website filter interstitial is // enabled. bool IsWebFilterInterstitialRefreshEnabled();
diff --git a/chrome/browser/supervised_user/supervised_user_pref_store.cc b/chrome/browser/supervised_user/supervised_user_pref_store.cc index 6b245a9..5ce51db 100644 --- a/chrome/browser/supervised_user/supervised_user_pref_store.cc +++ b/chrome/browser/supervised_user/supervised_user_pref_store.cc
@@ -10,12 +10,14 @@ #include "base/bind.h" #include "base/command_line.h" +#include "base/feature_list.h" #include "base/metrics/histogram_functions.h" #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/prefs/incognito_mode_prefs.h" #include "chrome/browser/supervised_user/supervised_user_constants.h" +#include "chrome/browser/supervised_user/supervised_user_features/supervised_user_features.h" #include "chrome/browser/supervised_user/supervised_user_settings_service.h" #include "chrome/browser/supervised_user/supervised_user_url_filter.h" #include "chrome/common/chrome_switches.h" @@ -24,6 +26,7 @@ #include "components/feed/core/shared_prefs/pref_names.h" #include "components/prefs/pref_value_map.h" #include "components/signin/public/base/signin_pref_names.h" +#include "components/signin/public/base/signin_switches.h" #include "extensions/buildflags/buildflags.h" namespace { @@ -139,7 +142,15 @@ bool record_history = settings->FindBoolPath(supervised_users::kRecordHistory) .value_or(true); - prefs_->SetBoolean(prefs::kAllowDeletingBrowserHistory, !record_history); + // Allow history deletion for supervised accounts on supported platforms. + bool allow_history_deletion = base::FeatureList::IsEnabled( + supervised_users::kAllowHistoryDeletionForChildAccounts); + prefs_->SetBoolean(prefs::kAllowDeletingBrowserHistory, + allow_history_deletion || !record_history); + // Incognito is disabled for supervised users across platforms. + // First-party sites use signed-in cookies to ensure that parental + // restrictions are applied for Unicorn accounts. + // TODO(crbug.com/1304177): Set to disabled by default. prefs_->SetInteger( prefs::kIncognitoModeAvailability, static_cast<int>(record_history
diff --git a/chrome/browser/supervised_user/supervised_user_pref_store_unittest.cc b/chrome/browser/supervised_user/supervised_user_pref_store_unittest.cc index 68a0922c..9965818 100644 --- a/chrome/browser/supervised_user/supervised_user_pref_store_unittest.cc +++ b/chrome/browser/supervised_user/supervised_user_pref_store_unittest.cc
@@ -7,8 +7,10 @@ #include "base/memory/ref_counted.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" #include "base/values.h" #include "chrome/browser/supervised_user/supervised_user_constants.h" +#include "chrome/browser/supervised_user/supervised_user_features/supervised_user_features.h" #include "chrome/browser/supervised_user/supervised_user_pref_store.h" #include "chrome/browser/supervised_user/supervised_user_settings_service.h" #include "chrome/common/net/safe_search_util.h" @@ -95,6 +97,28 @@ service_.Shutdown(); } +#if BUILDFLAG(ENABLE_SUPERVISED_USERS) +TEST_F(SupervisedUserPrefStoreTest, + ConfigureSettingsWithHistoryDeletionAllowed) { + SupervisedUserPrefStoreFixture fixture(&service_); + EXPECT_FALSE(fixture.initialization_completed()); + + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature( + supervised_users::kAllowHistoryDeletionForChildAccounts); + + pref_store_->SetInitializationCompleted(); + service_.SetActive(true); + + // kAllowDeletingBrowserHistory is based on the state of the feature + // supervised_users::kAllowHistoryDeletionForChildAccounts. + // This is enabled in scope. + EXPECT_THAT(fixture.changed_prefs()->FindBoolPath( + prefs::kAllowDeletingBrowserHistory), + Optional(true)); +} +#endif + TEST_F(SupervisedUserPrefStoreTest, ConfigureSettings) { SupervisedUserPrefStoreFixture fixture(&service_); EXPECT_FALSE(fixture.initialization_completed()); @@ -107,7 +131,9 @@ service_.SetActive(true); - // kAllowDeletingBrowserHistory is hardcoded to false for supervised users. + // kAllowDeletingBrowserHistory is based on the state of the feature + // supervised_users::kAllowHistoryDeletionForChildAccounts. + // This is disabled in scope. EXPECT_THAT(fixture.changed_prefs()->FindBoolPath( prefs::kAllowDeletingBrowserHistory), Optional(false));
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteController.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteController.java index 7ca6ca7..1a40c23 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteController.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteController.java
@@ -93,6 +93,16 @@ } /** + * Issue a prefetch request for zero prefix suggestions. + * + * Prefetch is a fire-and-forget operation that yields no results. + */ + void startPrefetch() { + if (mNativeController == 0) return; + AutocompleteControllerJni.get().startPrefetch(mNativeController); + } + + /** * Given some string |text| that the user wants to use for navigation, determines how it should * be interpreted. This is a fallback in case the user didn't select a visible suggestion (e.g. * the user pressed enter before omnibox suggestions had been shown). @@ -355,7 +365,7 @@ /** * Sends a zero suggest request to the server in order to pre-populate the result cache. */ - void prefetchZeroSuggestResults(); + void startPrefetch(long nativeAutocompleteControllerAndroid); /** * Acquire an instance of AutocompleteController associated with the supplied profile.
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java index 8820efb..e333139 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java
@@ -398,7 +398,7 @@ * Sends a zero suggest request to the server in order to pre-populate the result cache. */ public void prefetchZeroSuggestResults() { - AutocompleteControllerJni.get().prefetchZeroSuggestResults(); + mMediator.startPrefetch(); } /** @return Suggestions Dropdown view, showing the list of suggestions. */
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java index 7a1bfaf..d1b6fae 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
@@ -826,6 +826,14 @@ } /** + * Sends a zero suggest request to the server in order to pre-populate the result cache. + */ + /* package */ void startPrefetch() { + postAutocompleteRequest( + () -> mAutocomplete.startPrefetch(), SCHEDULE_FOR_IMMEDIATE_EXECUTION); + } + + /** * Make a zero suggest request if: * - The URL bar has focus. * - The the tab/overview is not incognito.
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionView.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionView.java index 4d31da1..c6c26c2 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionView.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionView.java
@@ -66,7 +66,6 @@ /** * @return List of Action views. */ - @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) public List<ImageView> getActionButtons() { return mActionButtons; }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/pedal/PedalSuggestionView.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/pedal/PedalSuggestionView.java index 85794f16..2861582 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/pedal/PedalSuggestionView.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/pedal/PedalSuggestionView.java
@@ -7,18 +7,24 @@ import android.content.Context; import android.view.KeyEvent; import android.view.View; +import android.view.ViewGroup.LayoutParams; +import android.view.ViewGroup.MarginLayoutParams; +import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; import androidx.annotation.Px; import androidx.annotation.VisibleForTesting; +import androidx.core.view.MarginLayoutParamsCompat; import org.chromium.chrome.browser.omnibox.R; import org.chromium.chrome.browser.omnibox.suggestions.base.BaseSuggestionView; import org.chromium.chrome.browser.omnibox.suggestions.base.SimpleVerticalLayoutView; import org.chromium.components.browser_ui.widget.chips.ChipView; +import java.util.List; + /** * Base layout for pedals suggestion types. This is a {@link BaseSuggestionView} with a pedal under * it. @@ -45,9 +51,7 @@ R.dimen.omnibox_pedal_suggestion_pedal_height); final @Px int pedalStartPaddingPx = getResources().getDimensionPixelSize(R.dimen.omnibox_suggestion_icon_area_size); - final @Px int pedalEndPaddingPx = - getResources().getDimensionPixelSize(R.dimen.omnibox_suggestion_action_icon_width); - mPedal.setPaddingRelative(pedalStartPaddingPx, 0, pedalEndPaddingPx, 0); + mPedal.setPaddingRelative(pedalStartPaddingPx, 0, 0, 0); mPedal.getChipView().setMinimumHeight(pedalSuggestionSizePx); addView(mPedal); @@ -61,6 +65,27 @@ return mPedal.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event); } + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + updatePedalLayoutMargin(); + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + + private void updatePedalLayoutMargin() { + List<ImageView> buttons = mBaseSuggestionView.getActionButtons(); + int actionButtonsWidth = 0; + if (buttons != null) { + for (ImageView button : buttons) { + actionButtonsWidth += button.getMeasuredWidth(); + } + } + + MarginLayoutParams layoutParams = + new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + MarginLayoutParamsCompat.setMarginEnd(layoutParams, actionButtonsWidth); + mPedal.setLayoutParams(layoutParams); + } + /** @return base suggestion view. */ @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) public BaseSuggestionView<T> getBaseSuggestionView() {
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/pedal/PedalView.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/pedal/PedalView.java index 0a9581f4..fa8467790 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/pedal/PedalView.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/pedal/PedalView.java
@@ -6,10 +6,12 @@ import android.content.Context; import android.view.KeyEvent; +import android.view.ViewGroup.MarginLayoutParams; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.core.content.res.ResourcesCompat; +import androidx.core.view.MarginLayoutParamsCompat; import com.google.android.material.color.MaterialColors; @@ -73,7 +75,10 @@ @Override protected void onMeasure(int widthSpec, int heightSpec) { - final int widthPx = MeasureSpec.getSize(widthSpec); + MarginLayoutParams marginLayoutParams = (MarginLayoutParams) getLayoutParams(); + + final int widthPx = MeasureSpec.getSize(widthSpec) + - MarginLayoutParamsCompat.getMarginEnd(marginLayoutParams); int chipViewWidth = widthPx - getPaddingLeft() - getPaddingRight(); // Measure height of the content view given the width constraint.
diff --git a/chrome/browser/ui/color/chrome_color_id.h b/chrome/browser/ui/color/chrome_color_id.h index f82f6c4d..7584668 100644 --- a/chrome/browser/ui/color/chrome_color_id.h +++ b/chrome/browser/ui/color/chrome_color_id.h
@@ -164,8 +164,13 @@ ThemeProperties::COLOR_OMNIBOX_SECURITY_CHIP_SECURE) \ E(kColorOmniboxText, ThemeProperties::COLOR_OMNIBOX_TEXT) \ E(kColorOmniboxTextDimmed, ThemeProperties::COLOR_OMNIBOX_TEXT_DIMMED) \ + /* Overlay colors. */ \ + E_CPONLY(kColorOverlayWindowBackgroundColor) \ /* Payments colors. */ \ E_CPONLY(kColorPaymentRequestRowBackgroundHighlighted) \ + /* QR code colors. */ \ + E_CPONLY(kColorQrCodeBackground) \ + E_CPONLY(kColorQrCodeBorder) \ /* Read Later button colors. */ \ E(kColorReadLaterButtonHighlight, \ ThemeProperties::COLOR_READ_LATER_BUTTON_HIGHLIGHT) \
diff --git a/chrome/browser/ui/color/chrome_color_mixer.cc b/chrome/browser/ui/color/chrome_color_mixer.cc index e545e36..6405b97ed 100644 --- a/chrome/browser/ui/color/chrome_color_mixer.cc +++ b/chrome/browser/ui/color/chrome_color_mixer.cc
@@ -295,8 +295,11 @@ ui::kColorButtonForeground}; mixer[kColorOmniboxText] = ui::GetColorWithMaxContrast(kColorOmniboxBackground); + mixer[kColorOverlayWindowBackgroundColor] = {SK_ColorBLACK}; mixer[kColorPaymentRequestRowBackgroundHighlighted] = { SkColorSetA(SK_ColorBLACK, 0x0D)}; + mixer[kColorQrCodeBackground] = {SK_ColorWHITE}; + mixer[kColorQrCodeBorder] = {ui::kColorMidground}; mixer[kColorReadLaterButtonHighlight] = {kColorAvatarButtonHighlightNormal}; mixer[kColorScreenshotCapturedImageBackground] = {ui::kColorBubbleBackground}; mixer[kColorScreenshotCapturedImageBorder] = {ui::kColorMidground};
diff --git a/chrome/browser/ui/user_education/feature_promo_controller.cc b/chrome/browser/ui/user_education/feature_promo_controller.cc index aa0ddda..ee56daf6 100644 --- a/chrome/browser/ui/user_education/feature_promo_controller.cc +++ b/chrome/browser/ui/user_education/feature_promo_controller.cc
@@ -235,8 +235,10 @@ const bool was_open = promo_bubble_ && promo_bubble_->is_open(); if (promo_bubble_) promo_bubble_->Close(); - if (iph_feature_bypassing_tracker_ == &iph_feature) + if (!continuing_after_bubble_closed_ && + iph_feature_bypassing_tracker_ == &iph_feature) { iph_feature_bypassing_tracker_ = nullptr; + } return was_open; }
diff --git a/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc b/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc index 23df63b..86d7952 100644 --- a/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc +++ b/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc
@@ -221,4 +221,16 @@ ClickLinkAndWait(web_contents, in_scope_url, LinkTarget::SELF, ""); EXPECT_TRUE(GetIntentChip()->GetVisible()); EXPECT_TRUE(GetIntentChip()->is_fully_collapsed()); + + // Click to open app and reset the counter. + ClickIntentChip(); + + // Open another browser- we should be able to see the expanded chip again. + NavigateToLaunchingPage(browser()); + web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + + // 1st appearance since intent chip counter reset: Expanded. + ClickLinkAndWait(web_contents, in_scope_url, LinkTarget::SELF, ""); + EXPECT_TRUE(GetIntentChip()->GetVisible()); + EXPECT_FALSE(GetIntentChip()->is_fully_collapsed()); }
diff --git a/chrome/browser/ui/views/overlay/document_overlay_window_views.cc b/chrome/browser/ui/views/overlay/document_overlay_window_views.cc index d12f196..0202f96 100644 --- a/chrome/browser/ui/views/overlay/document_overlay_window_views.cc +++ b/chrome/browser/ui/views/overlay/document_overlay_window_views.cc
@@ -4,11 +4,6 @@ #include "chrome/browser/ui/views/overlay/document_overlay_window_views.h" -#include "content/public/browser/document_picture_in_picture_window_controller.h" -#include "content/public/browser/picture_in_picture_window_controller.h" -#include "content/public/browser/web_contents.h" -#include "ui/views/controls/webview/webview.h" - #include <memory> #include <string> @@ -26,6 +21,7 @@ #include "chrome/browser/themes/theme_service.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/color/chrome_color_id.h" #include "chrome/browser/ui/toolbar/chrome_location_bar_model_delegate.h" #include "chrome/browser/ui/views/location_bar/location_bar_view.h" #include "chrome/browser/ui/views/overlay/back_to_tab_image_button.h" @@ -35,17 +31,21 @@ #include "components/omnibox/browser/location_bar_model_impl.h" #include "components/vector_icons/vector_icons.h" #include "content/public/browser/document_picture_in_picture_window_controller.h" +#include "content/public/browser/picture_in_picture_window_controller.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_constants.h" #include "media/base/media_switches.h" #include "media/base/video_util.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/base/metadata/metadata_header_macros.h" +#include "ui/base/metadata/metadata_impl_macros.h" #include "ui/compositor/layer.h" #include "ui/gfx/color_palette.h" #include "ui/gfx/geometry/resize_utils.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/views/controls/button/image_button.h" +#include "ui/views/controls/webview/webview.h" #include "ui/views/layout/box_layout.h" #include "ui/views/vector_icons.h" #include "ui/views/widget/widget_delegate.h" @@ -88,6 +88,25 @@ return static_cast<T*>(views->back().get()); } +class WindowBackgroundView : public views::View { + public: + METADATA_HEADER(WindowBackgroundView); + + WindowBackgroundView() = default; + WindowBackgroundView(const WindowBackgroundView&) = delete; + WindowBackgroundView& operator=(const WindowBackgroundView&) = delete; + ~WindowBackgroundView() override = default; + + void OnThemeChanged() override { + views::View::OnThemeChanged(); + layer()->SetColor( + GetColorProvider()->GetColor(kColorOverlayWindowBackgroundColor)); + } +}; + +BEGIN_METADATA(WindowBackgroundView, views::View) +END_METADATA + } // namespace OverlayLocationBarViewProxy::~OverlayLocationBarViewProxy() = default; @@ -296,10 +315,10 @@ DVLOG(2) << __func__ << ": content WebView=" << web_view.get(); web_view->SetWebContents(pip_contents); - // views::View that is displayed when WebView is hidden. --------------------- + // View that is displayed when WebView is hidden. ---------------------------- // Adding an extra pixel to width/height makes sure controls background cover // entirely window when platform has fractional scale applied. - auto window_background_view = std::make_unique<views::View>(); + auto window_background_view = std::make_unique<WindowBackgroundView>(); auto controls_container_view = std::make_unique<views::View>(); @@ -334,7 +353,6 @@ window_background_view->SetPaintToLayer(ui::LAYER_SOLID_COLOR); window_background_view->layer()->SetName("WindowBackgroundView"); - window_background_view->layer()->SetColor(SK_ColorBLACK); // view::View that holds the WebView. --------------------------------------- web_view->SetPaintToLayer(ui::LAYER_TEXTURED);
diff --git a/chrome/browser/ui/views/overlay/video_overlay_window_views.cc b/chrome/browser/ui/views/overlay/video_overlay_window_views.cc index d25bffe..be0115c 100644 --- a/chrome/browser/ui/views/overlay/video_overlay_window_views.cc +++ b/chrome/browser/ui/views/overlay/video_overlay_window_views.cc
@@ -18,6 +18,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/color/chrome_color_id.h" #include "chrome/browser/ui/views/overlay/back_to_tab_image_button.h" #include "chrome/browser/ui/views/overlay/back_to_tab_label_button.h" #include "chrome/browser/ui/views/overlay/close_image_button.h" @@ -36,6 +37,8 @@ #include "media/base/video_util.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/base/metadata/metadata_header_macros.h" +#include "ui/base/metadata/metadata_impl_macros.h" #include "ui/compositor/compositor.h" #include "ui/compositor/layer.h" #include "ui/gfx/color_palette.h" @@ -98,6 +101,25 @@ return static_cast<T*>(views->back().get()); } +class WindowBackgroundView : public views::View { + public: + METADATA_HEADER(WindowBackgroundView); + + WindowBackgroundView() = default; + WindowBackgroundView(const WindowBackgroundView&) = delete; + WindowBackgroundView& operator=(const WindowBackgroundView&) = delete; + ~WindowBackgroundView() override = default; + + void OnThemeChanged() override { + views::View::OnThemeChanged(); + layer()->SetColor( + GetColorProvider()->GetColor(kColorOverlayWindowBackgroundColor)); + } +}; + +BEGIN_METADATA(WindowBackgroundView, views::View) +END_METADATA + } // namespace // static @@ -196,10 +218,10 @@ } void VideoOverlayWindowViews::SetUpViews() { - // views::View that is displayed when video is hidden. ---------------------- + // View that is displayed when video is hidden. ------------------------------ // Adding an extra pixel to width/height makes sure controls background cover // entirely window when platform has fractional scale applied. - auto window_background_view = std::make_unique<views::View>(); + auto window_background_view = std::make_unique<WindowBackgroundView>(); auto video_view = std::make_unique<views::View>(); auto controls_scrim_view = std::make_unique<views::View>(); auto controls_container_view = std::make_unique<views::View>(); @@ -291,7 +313,6 @@ window_background_view->SetPaintToLayer(ui::LAYER_SOLID_COLOR); window_background_view->layer()->SetName("WindowBackgroundView"); - window_background_view->layer()->SetColor(SK_ColorBLACK); // view::View that holds the video. ----------------------------------------- video_view->SetPaintToLayer(ui::LAYER_TEXTURED);
diff --git a/chrome/browser/ui/views/passwords/password_bubble_view_base.cc b/chrome/browser/ui/views/passwords/password_bubble_view_base.cc index 257da6a7..bbbd81b1 100644 --- a/chrome/browser/ui/views/passwords/password_bubble_view_base.cc +++ b/chrome/browser/ui/views/passwords/password_bubble_view_base.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/views/passwords/password_bubble_view_base.h" +#include "base/notreached.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h" @@ -52,6 +53,11 @@ CreateBubble(web_contents, anchor_view, reason); DCHECK(bubble); DCHECK_EQ(bubble, g_manage_passwords_bubble_); + // TODO(crbug.com/1305276): In non-DCHECK mode we could fall through here and + // hard-crash if we requested a bubble and were in the wrong state. In the + // meantime we will abort if we did not create a bubble. + if (!g_manage_passwords_bubble_) + return; g_manage_passwords_bubble_->SetHighlightedButton( button_provider->GetPageActionIconView(
diff --git a/chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.cc b/chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.cc index 223e443..bfda8e41 100644 --- a/chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.cc +++ b/chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/color/chrome_color_id.h" #include "chrome/browser/ui/qrcode_generator/qrcode_generator_bubble_controller.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" @@ -55,12 +56,11 @@ namespace { -// Rendered QR Code size, pixels. -constexpr int kQRImageSizePx = 240; constexpr int kPaddingTooltipDownloadButtonPx = 10; // Calculates the height of the QR Code with padding. constexpr gfx::Size GetQRCodeImageSize() { + constexpr int kQRImageSizePx = 240; return gfx::Size(kQRImageSizePx, kQRImageSizePx); } @@ -68,15 +68,6 @@ return size.width() == size.height(); } -// Renders a solid square of color {r, g, b} at 100% alpha. -gfx::ImageSkia GetPlaceholderImageSkia(const SkColor color) { - SkBitmap bitmap; - bitmap.allocN32Pixels(kQRImageSizePx, kQRImageSizePx); - bitmap.eraseARGB(0xFF, 0xFF, 0xFF, 0xFF); - bitmap.eraseColor(color); - return gfx::ImageSkia::CreateFromBitmap(bitmap, 1.0f); -} - gfx::ImageSkia CreateBackgroundImageSkia(const gfx::Size& size) { SkBitmap bitmap; bitmap.allocN32Pixels(size.width(), size.height()); @@ -123,6 +114,19 @@ CloseBubble(); } +void QRCodeGeneratorBubble::OnThemeChanged() { + LocationBarBubbleDelegateView::OnThemeChanged(); + + const int border_radius = views::LayoutProvider::Get()->GetCornerRadiusMetric( + views::Emphasis::kHigh); + const auto* color_provider = GetColorProvider(); + qr_code_image_->SetBorder(views::CreateRoundedRectBorder( + /*thickness=*/2, border_radius, + color_provider->GetColor(kColorQrCodeBorder))); + qr_code_image_->SetBackground(views::CreateRoundedRectBackground( + color_provider->GetColor(kColorQrCodeBackground), border_radius, 2)); +} + void QRCodeGeneratorBubble::UpdateQRContent() { if (textfield_url_->GetText().empty()) { DisplayPlaceholderImage(); @@ -169,7 +173,7 @@ } void QRCodeGeneratorBubble::DisplayPlaceholderImage() { - UpdateQRImage(GetPlaceholderImageSkia(gfx::kGoogleGrey100)); + UpdateQRImage(CreateBackgroundImageSkia(GetQRCodeImageSize())); } void QRCodeGeneratorBubble::DisplayError(mojom::QRCodeGeneratorError error) { @@ -218,17 +222,13 @@ // QR Code image, with padding and border. using Alignment = views::ImageView::Alignment; auto qr_code_image = std::make_unique<views::ImageView>(); - const int border_radius = views::LayoutProvider::Get()->GetCornerRadiusMetric( - views::Emphasis::kHigh); - qr_code_image->SetBorder(views::CreateRoundedRectBorder( - /*thickness=*/2, border_radius, gfx::kGoogleGrey200)); qr_code_image->SetHorizontalAlignment(Alignment::kCenter); qr_code_image->SetVerticalAlignment(Alignment::kCenter); qr_code_image->SetImageSize(GetQRCodeImageSize()); + const int border_radius = views::LayoutProvider::Get()->GetCornerRadiusMetric( + views::Emphasis::kHigh); qr_code_image->SetPreferredSize(GetQRCodeImageSize() + gfx::Size(border_radius, border_radius)); - qr_code_image->SetBackground( - views::CreateRoundedRectBackground(SK_ColorWHITE, border_radius, 2)); qr_code_image->SetProperty(views::kCrossAxisAlignmentKey, views::LayoutAlignment::kCenter);
diff --git a/chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.h b/chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.h index 1e094ef..2955ca9 100644 --- a/chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.h +++ b/chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.h
@@ -55,6 +55,7 @@ // QRCodeGeneratorBubbleView: void Hide() override; + void OnThemeChanged() override; // Returns a suggested download filename for a given URL. // e.g.: www.foo.com may suggest qrcode_foo.png.
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 0f4b16e..7475765 100644 --- a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc +++ b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
@@ -769,8 +769,7 @@ // Cancel any pending tab transition. hover_tab_selector_.CancelTabTransition(); - tabstrip_->AddTabAt(index, TabRendererData::FromTabInModel(model_, index), - is_active); + tabstrip_->AddTabAt(index, TabRendererData::FromTabInModel(model_, index)); // Try to show tab groups IPH if needed. if (tabstrip_->GetTabCount() >= 6) { browser_view_->NotifyFeatureEngagementEvent(
diff --git a/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.cc b/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.cc index f100972..989dfaf 100644 --- a/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.cc +++ b/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.cc
@@ -25,7 +25,7 @@ num_tabs_++; tab_groups_.insert(tab_groups_.begin() + index, absl::nullopt); - tab_strip_->AddTabAt(index, TabRendererData(), is_active); + tab_strip_->AddTabAt(index, TabRendererData()); if (is_active) { SelectTab(index, ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::PointF(), gfx::PointF(), @@ -39,7 +39,7 @@ TabRendererData data; data.pinned = true; - tab_strip_->AddTabAt(index, std::move(data), is_active); + tab_strip_->AddTabAt(index, std::move(data)); if (is_active) active_index_ = index; }
diff --git a/chrome/browser/ui/views/tabs/tab_container.cc b/chrome/browser/ui/views/tabs/tab_container.cc index bc4985f..9b59f4d 100644 --- a/chrome/browser/ui/views/tabs/tab_container.cc +++ b/chrome/browser/ui/views/tabs/tab_container.cc
@@ -324,6 +324,17 @@ std::move(tab), GetViewInsertionIndex(group, absl::nullopt, model_index)); tabs_view_model_.Add(tab_ptr, model_index); layout_helper_->InsertTabAt(model_index, tab_ptr, pinned); + + // Don't animate the first tab, it looks weird, and don't animate anything + // if the containing window isn't visible yet. + if (GetTabCount() > 1 && GetWidget() && GetWidget()->IsVisible()) { + StartInsertTabAnimation(model_index); + } else { + CompleteAnimationAndLayout(); + } + + UpdateAccessibleTabIndices(); + return tab_ptr; } @@ -334,12 +345,23 @@ layout_helper_->MoveTab(tab->group(), from_model_index, to_model_index); } -void TabContainer::RemoveTabFromViewModel(int index) { - UpdateHoverCard(nullptr, TabController::HoverCardUpdateType::kTabRemoved); +void TabContainer::RemoveTab(int model_index, bool was_active) { + UpdateClosingModeOnRemovedTab(model_index, was_active); - Tab* tab = GetTabAtModelIndex(index); - tabs_view_model_.Remove(index); - layout_helper_->RemoveTabAt(index, tab); + PrepareForAnimation(); + + Tab* tab = GetTabAtModelIndex(model_index); + tab->SetClosing(true); + + RemoveTabFromViewModel(model_index); + + UpdateIdealBounds(); + AnimateToIdealBounds(); + + // Animate the tab closed. + AnimateTabClosed(tab, model_index); + + UpdateAccessibleTabIndices(); } void TabContainer::ScrollTabToVisible(int model_index) { @@ -753,44 +775,6 @@ } } -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! - const int model_count = GetTabCount() - 1; - const int tab_overlap = TabStyle::GetTabOverlap(); - if (in_tab_close() && model_count > 0 && model_index != model_count) { - // The user closed a tab other than the last tab. Set - // override_available_width_for_tabs_ so that as the user closes tabs with - // the mouse a tab continues to fall under the mouse. - int next_active_index = controller_->GetActiveIndex(); - DCHECK(IsValidModelIndex(next_active_index)); - if (model_index <= next_active_index) { - // At this point, model's internal state has already been updated. - // |contents| has been detached from model and the active index has been - // updated. But the tab for |contents| isn't removed yet. Thus, we need to - // fix up next_active_index based on it. - next_active_index++; - } - Tab* next_active_tab = GetTabAtModelIndex(next_active_index); - Tab* tab_being_removed = GetTabAtModelIndex(model_index); - - int size_delta = tab_being_removed->width(); - if (!tab_being_removed->data().pinned && was_active && - layout_helper_->active_tab_width() > - layout_helper_->inactive_tab_width()) { - // When removing an active, non-pinned tab, an inactive tab will be made - // active and thus given the active width. Thus the width being removed - // from the container is really the current width of whichever inactive - // tab will be made active. - size_delta = next_active_tab->width(); - } - - override_available_width_for_tabs_ = - tabs_view_model_.ideal_bounds(model_count).right() - size_delta + - tab_overlap; - } -} - void TabContainer::Layout() { if (base::FeatureList::IsEnabled(features::kScrollableTabStrip)) { // With tab scrolling, the tab container is solely responsible for its own @@ -926,6 +910,51 @@ return this; } +void TabContainer::StartInsertTabAnimation(int model_index) { + PrepareForAnimation(); + + ExitTabClosingMode(); + + gfx::Rect bounds = GetTabAtModelIndex(model_index)->bounds(); + bounds.set_height(GetLayoutConstant(TAB_HEIGHT)); + + // Adjust the starting bounds of the new tab. + const int tab_overlap = TabStyle::GetTabOverlap(); + if (model_index > 0) { + // If we have a tab to our left, start at its right edge. + bounds.set_x(GetTabAtModelIndex(model_index - 1)->bounds().right() - + tab_overlap); + } else if (model_index + 1 < GetTabCount()) { + // Otherwise, if we have a tab to our right, start at its left edge. + bounds.set_x(GetTabAtModelIndex(model_index + 1)->bounds().x()); + } else { + NOTREACHED() << "First tab inserted into the tabstrip should not animate."; + } + + // Start at the width of the overlap in order to animate at the same speed + // the surrounding tabs are moving, since at this width the subsequent tab + // is naturally positioned at the same X coordinate. + bounds.set_width(tab_overlap); + GetTabAtModelIndex(model_index)->SetBoundsRect(bounds); + + // Animate in to the full width. + UpdateIdealBounds(); + AnimateToIdealBounds(); +} + +void TabContainer::RemoveTabFromViewModel(int index) { + Tab* tab = GetTabAtModelIndex(index); + bool tab_was_active = tab->IsActive(); + + UpdateHoverCard(nullptr, TabController::HoverCardUpdateType::kTabRemoved); + + tabs_view_model_.Remove(index); + layout_helper_->RemoveTabAt(index, tab); + + if (tab_was_active) + tab->ActiveStateChanged(); +} + void TabContainer::OnTabCloseAnimationCompleted(Tab* tab) { DCHECK(tab->closing()); @@ -933,6 +962,45 @@ layout_helper_->OnTabDestroyed(tab); } +void TabContainer::UpdateClosingModeOnRemovedTab(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! + const int model_count = GetTabCount() - 1; + const int tab_overlap = TabStyle::GetTabOverlap(); + if (in_tab_close() && model_count > 0 && model_index != model_count) { + // The user closed a tab other than the last tab. Set + // override_available_width_for_tabs_ so that as the user closes tabs with + // the mouse a tab continues to fall under the mouse. + int next_active_index = controller_->GetActiveIndex(); + DCHECK(IsValidModelIndex(next_active_index)); + if (model_index <= next_active_index) { + // At this point, model's internal state has already been updated. + // |contents| has been detached from model and the active index has been + // updated. But the tab for |contents| isn't removed yet. Thus, we need to + // fix up next_active_index based on it. + next_active_index++; + } + Tab* next_active_tab = GetTabAtModelIndex(next_active_index); + Tab* tab_being_removed = GetTabAtModelIndex(model_index); + + int size_delta = tab_being_removed->width(); + if (!tab_being_removed->data().pinned && was_active && + layout_helper_->active_tab_width() > + layout_helper_->inactive_tab_width()) { + // When removing an active, non-pinned tab, an inactive tab will be made + // active and thus given the active width. Thus the width being removed + // from the container is really the current width of whichever inactive + // tab will be made active. + size_delta = next_active_tab->width(); + } + + override_available_width_for_tabs_ = + tabs_view_model_.ideal_bounds(model_count).right() - size_delta + + tab_overlap; + } +} + int TabContainer::GetViewInsertionIndex( absl::optional<tab_groups::TabGroupId> group, absl::optional<int> from_model_index,
diff --git a/chrome/browser/ui/views/tabs/tab_container.h b/chrome/browser/ui/views/tabs/tab_container.h index 181707d0..01c614c0 100644 --- a/chrome/browser/ui/views/tabs/tab_container.h +++ b/chrome/browser/ui/views/tabs/tab_container.h
@@ -40,10 +40,7 @@ Tab* AddTab(std::unique_ptr<Tab> tab, int model_index, TabPinned pinned); void MoveTab(Tab* tab, int from_model_index, int to_model_index); - - // Remove the tab from |tabs_view_model_|, but *not* from the View hierarchy, - // so it can be animated closed. - void RemoveTabFromViewModel(int index); + void RemoveTab(int index, bool was_active); void ScrollTabToVisible(int model_index); @@ -136,8 +133,6 @@ return override_available_width_for_tabs_; } - void OnTabWillBeRemovedAt(int model_index, bool was_active); - // TODO (1295774): Move callers down into TabContainer so this // encapsulation-breaking getter can be removed. TabStripLayoutHelper* layout_helper() const { return layout_helper_.get(); } @@ -162,8 +157,19 @@ private: class RemoveTabDelegate; + // Invoked from |AddTab| after the newly created tab has been inserted. + void StartInsertTabAnimation(int model_index); + + // Remove the tab from |tabs_view_model_|, but *not* from the View hierarchy, + // so it can be animated closed. + void RemoveTabFromViewModel(int index); + void OnTabCloseAnimationCompleted(Tab* tab); + // Updates |override_available_width_for_tabs_|, if necessary, to account for + // the removal of the tab at |model_index|. + void UpdateClosingModeOnRemovedTab(int model_index, bool was_active); + // Returns the corresponding view index of a |tab| to be inserted at // |to_model_index|. Used to reorder the child views of the tab container // so that focus order stays consistent with the visual tab order.
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view_browsertest.cc b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view_browsertest.cc index c70736f..b65aad43 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view_browsertest.cc
@@ -212,7 +212,7 @@ new_tab_data.title = u"Test Tab 2"; new_tab_data.last_committed_url = GURL("http://example.com/this/should/not/be/seen"); - tab_strip()->AddTabAt(1, new_tab_data, false); + tab_strip()->AddTabAt(1, new_tab_data); // Cycle focus until it reaches a tab. while (!tab_strip()->IsFocusInTabs()) @@ -261,7 +261,7 @@ new_tab_data.title = u"Test Tab 2"; new_tab_data.last_committed_url = GURL("http://example.com/this/should/not/be/seen"); - tab_strip()->AddTabAt(1, new_tab_data, false); + tab_strip()->AddTabAt(1, new_tab_data); ShowUi("default"); @@ -314,8 +314,8 @@ IN_PROC_BROWSER_TEST_F(TabHoverCardBubbleViewBrowserTest, HoverCardsSeenRatioMetric) { - tab_strip()->AddTabAt(1, TabRendererData(), false); - tab_strip()->AddTabAt(2, TabRendererData(), false); + tab_strip()->AddTabAt(1, TabRendererData()); + tab_strip()->AddTabAt(2, TabRendererData()); HoverMouseOverTabAt(0);
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index fcb9c2e..aed490a8 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -855,11 +855,12 @@ tab_at(i)->StepLoadingAnimation(elapsed_time); } -void TabStrip::AddTabAt(int model_index, TabRendererData data, bool is_active) { +void TabStrip::AddTabAt(int model_index, TabRendererData data) { const bool pinned = data.pinned; Tab* tab = tab_container_->AddTab( std::make_unique<Tab>(this), model_index, pinned ? TabPinned::kPinned : TabPinned::kUnpinned); + tab->set_context_menu_controller(&context_menu_controller_); tab->AddObserver(this); selected_tabs_.IncrementFrom(model_index); @@ -869,16 +870,6 @@ // callbacks. tab->SetData(std::move(data)); - // Don't animate the first tab, it looks weird, and don't animate anything - // if the containing window isn't visible yet. - if (GetTabCount() > 1 && GetWidget() && GetWidget()->IsVisible()) { - StartInsertTabAnimation(model_index); - } else { - tab_container_->CompleteAnimationAndLayout(); - } - - tab_container_->UpdateAccessibleTabIndices(); - for (TabStripObserver& observer : observers_) observer.OnTabAdded(model_index); @@ -938,12 +929,12 @@ void TabStrip::RemoveTabAt(content::WebContents* contents, int model_index, bool was_active) { - StartRemoveTabAnimation(model_index, was_active); - - tab_container_->UpdateAccessibleTabIndices(); + tab_container_->RemoveTab(model_index, was_active); UpdateHoverCard(nullptr, HoverCardUpdateType::kTabRemoved); + selected_tabs_.DecrementFrom(model_index); + for (TabStripObserver& observer : observers_) observer.OnTabRemoved(model_index); @@ -1871,54 +1862,6 @@ TouchUMA::RecordGestureAction(TouchUMA::kGestureNewTabTap); } -void TabStrip::StartInsertTabAnimation(int model_index) { - tab_container_->PrepareForAnimation(); - - tab_container_->ExitTabClosingMode(); - - gfx::Rect bounds = tab_at(model_index)->bounds(); - bounds.set_height(GetLayoutConstant(TAB_HEIGHT)); - - // Adjust the starting bounds of the new tab. - const int tab_overlap = TabStyle::GetTabOverlap(); - if (model_index > 0) { - // If we have a tab to our left, start at its right edge. - bounds.set_x(tab_at(model_index - 1)->bounds().right() - tab_overlap); - } else if (model_index + 1 < GetTabCount()) { - // Otherwise, if we have a tab to our right, start at its left edge. - bounds.set_x(tab_at(model_index + 1)->bounds().x()); - } else { - NOTREACHED() << "First tab inserted into the tabstrip should not animate."; - } - - // Start at the width of the overlap in order to animate at the same speed - // the surrounding tabs are moving, since at this width the subsequent tab - // is naturally positioned at the same X coordinate. - bounds.set_width(tab_overlap); - tab_at(model_index)->SetBoundsRect(bounds); - - // Animate in to the full width. - tab_container_->UpdateIdealBounds(); - tab_container_->AnimateToIdealBounds(); -} - -void TabStrip::StartRemoveTabAnimation(int model_index, bool was_active) { - tab_container_->OnTabWillBeRemovedAt(model_index, was_active); - - tab_container_->PrepareForAnimation(); - - Tab* tab = tab_at(model_index); - tab->SetClosing(true); - - RemoveTabFromViewModel(model_index); - - tab_container_->UpdateIdealBounds(); - tab_container_->AnimateToIdealBounds(); - - // Animate the tab closed. - tab_container_->AnimateTabClosed(tab, model_index); -} - void TabStrip::StartMoveTabAnimation() { tab_container_->PrepareForAnimation(); tab_container_->UpdateIdealBounds(); @@ -1997,19 +1940,6 @@ controller_->CloseTab(model_index); } -void TabStrip::RemoveTabFromViewModel(int index) { - Tab* closing_tab = tab_at(index); - bool closing_tab_was_active = closing_tab->IsActive(); - - // We still need to keep the tab alive until the remove tab animation - // completes. Defer destroying it until then. - tab_container_->RemoveTabFromViewModel(index); - selected_tabs_.DecrementFrom(index); - - if (closing_tab_was_active) - closing_tab->ActiveStateChanged(); -} - void TabStrip::StoppedDraggingView(TabSlotView* view, bool* is_first_view) { if (view && view->GetTabSlotViewType() == TabSlotView::ViewType::kTabGroupHeader) {
diff --git a/chrome/browser/ui/views/tabs/tab_strip.h b/chrome/browser/ui/views/tabs/tab_strip.h index e255a25e..8d03c5c 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.h +++ b/chrome/browser/ui/views/tabs/tab_strip.h
@@ -132,7 +132,7 @@ void UpdateLoadingAnimations(const base::TimeDelta& elapsed_time); // Adds a tab at the specified index. - void AddTabAt(int model_index, TabRendererData data, bool is_active); + void AddTabAt(int model_index, TabRendererData data); // Moves a tab. void MoveTab(int from_model_index, int to_model_index, TabRendererData data); @@ -405,17 +405,6 @@ std::map<tab_groups::TabGroupId, TabGroupHeader*> GetGroupHeaders(); - // Invoked from |AddTabAt| after the newly created tab has been inserted. - void StartInsertTabAnimation(int model_index); - - // Animates the removal of the tab at |model_index|. Defers to the old - // animation style when appropriate. - void StartRemoveTabAnimation(int model_index, bool was_active); - - // Animates the removal of the tab at |model_index| using the old animation - // style. - void StartFallbackRemoveTabAnimation(int model_index, bool was_active); - // Invoked from |MoveTab| after |tab_data_| has been updated to animate the // move. void StartMoveTabAnimation(); @@ -440,13 +429,6 @@ // Closes the tab at |model_index|. void CloseTabInternal(int model_index, CloseTabSource source); - // Removes the tab at |index| from |tabs_|. - void RemoveTabFromViewModel(int index); - - // Cleans up the Tab from the TabStrip. This is called from the tab animation - // code and is not a general-purpose method. - void OnTabCloseAnimationCompleted(Tab* tab); - // Invoked from StoppedDraggingTabs to cleanup |view|. If |view| is known // |is_first_view| is set to true. void StoppedDraggingView(TabSlotView* view, bool* is_first_view);
diff --git a/chrome/browser/ui/views/toolbar/webui_tab_counter_button.cc b/chrome/browser/ui/views/toolbar/webui_tab_counter_button.cc index bcb9ff97..629c092a 100644 --- a/chrome/browser/ui/views/toolbar/webui_tab_counter_button.cc +++ b/chrome/browser/ui/views/toolbar/webui_tab_counter_button.cc
@@ -575,14 +575,14 @@ WEBUI_TAB_COUNTER_CXMENU_CLOSE_TAB, l10n_util::GetStringUTF16( IDS_WEBUI_TAB_STRIP_TAB_COUNTER_CXMENU_CLOSE_TAB), - ui::ImageModel::FromImageSkia(gfx::CreateVectorIcon( - vector_icons::kCloseIcon, gfx::kFaviconSize, SK_ColorGRAY))); + ui::ImageModel::FromVectorIcon(vector_icons::kCloseIcon, + ui::kColorMenuIcon, gfx::kFaviconSize)); menu_model_->AddSeparator(ui::MenuSeparatorType::NORMAL_SEPARATOR); menu_model_->AddItemWithIcon( WEBUI_TAB_COUNTER_CXMENU_NEW_TAB, l10n_util::GetStringUTF16(IDS_WEBUI_TAB_STRIP_TAB_COUNTER_CXMENU_NEW_TAB), - ui::ImageModel::FromImageSkia( - gfx::CreateVectorIcon(kAddIcon, gfx::kFaviconSize, SK_ColorGRAY))); + ui::ImageModel::FromVectorIcon(kAddIcon, ui::kColorMenuIcon, + gfx::kFaviconSize)); menu_runner_ = std::make_unique<views::MenuRunner>( menu_model_.get(), views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU |
diff --git a/chrome/browser/ui/views/user_education/tip_marquee_view.cc b/chrome/browser/ui/views/user_education/tip_marquee_view.cc index 78f766b7..54bb664 100644 --- a/chrome/browser/ui/views/user_education/tip_marquee_view.cc +++ b/chrome/browser/ui/views/user_education/tip_marquee_view.cc
@@ -93,8 +93,10 @@ views::View* const placeholder_image = AddChildView(std::make_unique<views::View>()); placeholder_image->SetPreferredSize(gfx::Size(150, 175)); - placeholder_image->SetBackground( - views::CreateSolidBackground(SK_ColorLTGRAY)); + // In real UI, we wouldn't use kColorMidground directly, but rather create + // a new color ID mapped to it (or similar). + placeholder_image->SetBackground(views::CreateThemedSolidBackground( + placeholder_image, ui::kColorMidground)); views::View* const rhs_view = AddChildView(std::make_unique<views::View>()); auto* const rhs_layout =
diff --git a/chrome/browser/ui/views/webauthn/authenticator_qr_sheet_view.cc b/chrome/browser/ui/views/webauthn/authenticator_qr_sheet_view.cc index 61da1403..06157fa 100644 --- a/chrome/browser/ui/views/webauthn/authenticator_qr_sheet_view.cc +++ b/chrome/browser/ui/views/webauthn/authenticator_qr_sheet_view.cc
@@ -6,10 +6,12 @@ #include "base/bind.h" #include "base/callback.h" +#include "chrome/browser/ui/color/chrome_color_id.h" #include "chrome/services/qrcode_generator/public/cpp/qrcode_generator_service.h" #include "chrome/services/qrcode_generator/public/mojom/qrcode_generator.mojom.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/color/color_provider.h" #include "ui/gfx/image/image_skia.h" #include "ui/views/background.h" #include "ui/views/controls/image_view.h" @@ -35,20 +37,13 @@ views::BoxLayout::MainAxisAlignment::kCenter); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kCenter); - const int border_radius = - views::LayoutProvider::Get()->GetCornerRadiusMetric( - views::Emphasis::kHigh); qr_code_image_ = AddChildViewAt(std::make_unique<views::ImageView>(), 0); - qr_code_image_->SetBorder(views::CreateRoundedRectBorder( - /*thickness=*/2, border_radius, gfx::kGoogleGrey200)); qr_code_image_->SetHorizontalAlignment( views::ImageView::Alignment::kCenter); qr_code_image_->SetVerticalAlignment(views::ImageView::Alignment::kCenter); qr_code_image_->SetImageSize(qrCodeImageSize()); qr_code_image_->SetPreferredSize(qrCodeImageSize() + gfx::Size(kQrCodeMargin, kQrCodeMargin)); - qr_code_image_->SetBackground( - views::CreateRoundedRectBackground(SK_ColorWHITE, border_radius, 2)); qrcode_generator::mojom::GenerateQRCodeRequestPtr request = qrcode_generator::mojom::GenerateQRCodeRequest::New(); @@ -74,6 +69,20 @@ AuthenticatorQRViewCentered& operator=(const AuthenticatorQRViewCentered&) = delete; + void OnThemeChanged() override { + views::View::OnThemeChanged(); + + const int border_radius = + views::LayoutProvider::Get()->GetCornerRadiusMetric( + views::Emphasis::kHigh); + const auto* color_provider = GetColorProvider(); + qr_code_image_->SetBorder(views::CreateRoundedRectBorder( + /*thickness=*/2, border_radius, + color_provider->GetColor(kColorQrCodeBorder))); + qr_code_image_->SetBackground(views::CreateRoundedRectBackground( + color_provider->GetColor(kColorQrCodeBackground), border_radius, 2)); + } + private: qrcode_generator::mojom::QRCodeGeneratorService* qr_code_service() { if (!qr_code_service_remote_)
diff --git a/chrome/browser/ui/webui/inspect_ui_browsertest.cc b/chrome/browser/ui/webui/inspect_ui_browsertest.cc index 866ef699..8da5f31 100644 --- a/chrome/browser/ui/webui/inspect_ui_browsertest.cc +++ b/chrome/browser/ui/webui/inspect_ui_browsertest.cc
@@ -52,13 +52,7 @@ } }; -// Disabled due to excessive flakiness. http://crbug.com/1304812 -#if BUILDFLAG(IS_MAC) -#define MAYBE_InspectUIPage DISABLED_InspectUIPage -#else -#define MAYBE_InspectUIPage InspectUIPage -#endif -IN_PROC_BROWSER_TEST_F(InspectUITest, MAYBE_InspectUIPage) { +IN_PROC_BROWSER_TEST_F(InspectUITest, InspectUIPage) { ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIInspectURL))); ASSERT_TRUE(WebUIBrowserTest::RunJavascriptAsyncTest( @@ -113,7 +107,13 @@ GURL(chrome::kChromeUIInspectURL))); } -IN_PROC_BROWSER_TEST_F(InspectUITest, LaunchUIDevtools) { +// Disabled due to excessive flakiness. http://crbug.com/1304812 +#if BUILDFLAG(IS_MAC) +#define MAYBE_LaunchUIDevtools DISABLED_LaunchUIDevtools +#else +#define MAYBE_LaunchUIDevtools LaunchUIDevtools +#endif +IN_PROC_BROWSER_TEST_F(InspectUITest, MAYBE_LaunchUIDevtools) { ASSERT_TRUE(embedded_test_server()->Start()); TabStripModel* tab_strip_model = browser()->tab_strip_model();
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 20d809e7..7266159 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1647280729-30a5e69b6f02e84d85c3385dd2f236d1b96be257.profdata +chrome-mac-arm-main-1647302357-e605e3a470d6c1be450e04cc8d355e7542e6a787.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 66030b9..3e6b884 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1647280729-6ca29980d40a00b4dec37a0127e6e39f12f3abb9.profdata +chrome-mac-main-1647302357-b1d7c9a56e4da5260f62f4ed8df8cccbd9476905.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 8ecd7c9..970311f7 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1647280729-f8d04e15150920cf9b71e316b0ce83b4e0da30ee.profdata +chrome-win32-main-1647291450-a010c9d9fe7047e6aa656acdc543689945887704.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 7f35ab0..0035aa5b 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1647280729-f5550f32a2246dcb9f47e3474436058bf3c16b61.profdata +chrome-win64-main-1647291450-305c59221bb9bcb7144a62d700e9a145017942ed.profdata
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index a2df3ffa..2ef6f5f 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -4979,12 +4979,12 @@ "../browser/policy/messaging_layer/upload/dm_server_upload_service_unittest.cc", "../browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc", "../browser/policy/messaging_layer/upload/record_upload_request_builder_unittest.cc", - "../browser/policy/messaging_layer/upload/test_util.cc", - "../browser/policy/messaging_layer/upload/test_util.h", "../browser/policy/messaging_layer/upload/upload_client_unittest.cc", "../browser/policy/messaging_layer/upload/upload_provider_unittest.cc", "../browser/policy/messaging_layer/util/dm_token_retriever_provider_unittest.cc", "../browser/policy/messaging_layer/util/report_queue_manual_test_context_unittest.cc", + "../browser/policy/messaging_layer/util/test.cc", + "../browser/policy/messaging_layer/util/test.h", "../browser/policy/messaging_layer/util/user_dm_token_retriever_unittest.cc", "../browser/policy/profile_policy_connector_unittest.cc", "../browser/policy/webusb_allow_devices_for_urls_policy_handler_unittest.cc", @@ -8223,6 +8223,7 @@ "//chrome/browser/supervised_user:test_support", "//chrome/browser/supervised_user/kids_chrome_management:proto", "//chrome/browser/supervised_user/supervised_user_error_page:unit_tests", + "//chrome/browser/supervised_user/supervised_user_features", "//chrome/browser/supervised_user/supervised_user_features:unit_tests", ] }
diff --git a/chrome/test/android/test_support/src/org/chromium/chrome/test_support/OWNERS b/chrome/test/android/test_support/src/org/chromium/chrome/test_support/OWNERS index 6c756cb..d655647 100644 --- a/chrome/test/android/test_support/src/org/chromium/chrome/test_support/OWNERS +++ b/chrome/test/android/test_support/src/org/chromium/chrome/test_support/OWNERS
@@ -1,2 +1,2 @@ per-file PaymentRequestTestBridge.java=rouslan@chromium.org -per-file PaymentRequestTestBridge.java=maxlg@chromium.org +per-file PaymentRequestTestBridge.java=nburris@chromium.org
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn index 0e296f5c..9e058b4 100644 --- a/chrome/test/data/webui/BUILD.gn +++ b/chrome/test/data/webui/BUILD.gn
@@ -282,6 +282,7 @@ "$root_gen_dir/chrome/test/data/webui/settings/chromeos/dark_mode_subpage_tests.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/dom_switch_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/main_view_test.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/permission_item_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/pin_to_shelf_item_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/pwa_detail_view_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/supported_links_item_test.m.js",
diff --git a/chrome/test/data/webui/app_settings/BUILD.gn b/chrome/test/data/webui/app_settings/BUILD.gn index f0e750d7..5090821 100644 --- a/chrome/test/data/webui/app_settings/BUILD.gn +++ b/chrome/test/data/webui/app_settings/BUILD.gn
@@ -32,7 +32,6 @@ "app_test.ts", "test_app_management_browser_proxy.ts", ] - definitions = [ "//tools/typescript/definitions/metrics_private.d.ts" ] deps = [ "//chrome/browser/resources/app_settings:build_ts" ] extra_deps = [ "..:generate_definitions" ] }
diff --git a/chrome/test/data/webui/app_settings/test_app_management_browser_proxy.ts b/chrome/test/data/webui/app_settings/test_app_management_browser_proxy.ts index 03da70e..7d69578 100644 --- a/chrome/test/data/webui/app_settings/test_app_management_browser_proxy.ts +++ b/chrome/test/data/webui/app_settings/test_app_management_browser_proxy.ts
@@ -82,8 +82,4 @@ this.fakeHandler = new FakePageHandler(this.callbackRouterRemote, app); this.handler = this.fakeHandler; } - - recordEnumerationValue(metricName: string, value: number, enumSize: number) { - chrome.metricsPrivate.recordEnumerationValue(metricName, value, enumSize); - } }
diff --git a/chrome/test/data/webui/chromeos/personalization_app/ambient_subpage_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/ambient_subpage_element_test.ts index 0170b1c..064aab517 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/ambient_subpage_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/ambient_subpage_element_test.ts
@@ -8,7 +8,7 @@ import {AmbientObserver} from 'chrome://personalization/trusted/ambient/ambient_observer.js'; import {AmbientSubpage} from 'chrome://personalization/trusted/ambient/ambient_subpage_element.js'; import {TopicSourceItem} from 'chrome://personalization/trusted/ambient/topic_source_item_element.js'; -import {TemperatureUnit, TopicSource} from 'chrome://personalization/trusted/personalization_app.mojom-webui.js'; +import {AmbientModeAlbum, TemperatureUnit, TopicSource} from 'chrome://personalization/trusted/personalization_app.mojom-webui.js'; import {Paths, PersonalizationRouter} from 'chrome://personalization/trusted/personalization_router_element.js'; import {emptyState} from 'chrome://personalization/trusted/personalization_state.js'; import {CrRadioButtonElement} from 'chrome://resources/cr_elements/cr_radio_button/cr_radio_button.m.js'; @@ -20,6 +20,13 @@ import {TestAmbientProvider} from './test_ambient_interface_provider.js'; import {TestPersonalizationStore} from './test_personalization_store.js'; + +export function getSelectedAlbums( + albums: AmbientModeAlbum[], topicSource: TopicSource): AmbientModeAlbum[] { + return albums.filter( + album => album.topicSource === topicSource && album.checked); +} + export function AmbientSubpageTest() { let ambientSubpageElement: AmbientSubpage|null; let ambientProvider: TestAmbientProvider; @@ -464,9 +471,23 @@ assertFalse(albums[0].album!.checked); assertFalse(albums[1].album!.checked); assertTrue(albums[2].album!.checked); + let selectedAlbums = getSelectedAlbums( + personalizationStore.data.ambient.albums, + personalizationStore.data.ambient.topicSource); + assertEquals(1, selectedAlbums!.length); + assertEquals('2', selectedAlbums[0]!.title); + personalizationStore.expectAction(AmbientActionName.SET_ALBUM_SELECTED); albums[1].$.image.click(); assertTrue(albums[1].album!.checked); + await personalizationStore.waitForAction( + AmbientActionName.SET_ALBUM_SELECTED); + selectedAlbums = getSelectedAlbums( + personalizationStore.data.ambient.albums, + personalizationStore.data.ambient.topicSource); + assertEquals(2, selectedAlbums!.length); + assertEquals('1', selectedAlbums[0]!.title); + assertEquals('2', selectedAlbums[1]!.title); }); test('not deselect last art album', async () => {
diff --git a/chrome/test/data/webui/cr_components/BUILD.gn b/chrome/test/data/webui/cr_components/BUILD.gn index f9d5287..e2e44c4 100644 --- a/chrome/test/data/webui/cr_components/BUILD.gn +++ b/chrome/test/data/webui/cr_components/BUILD.gn
@@ -20,8 +20,6 @@ # Test files that do not require preprocessing. If adding // <if expr> to any # file below, move it to the list above. non_preprocessed_files = [ - "app_management/app_management_test_support.ts", - "app_management/permission_item_test.ts", "customize_themes_test.ts", "managed_dialog_test.ts", "most_visited_focus_test.ts",
diff --git a/chrome/test/data/webui/cr_components/app_management/app_management_test_support.ts b/chrome/test/data/webui/cr_components/app_management/app_management_test_support.ts deleted file mode 100644 index 21010bc..0000000 --- a/chrome/test/data/webui/cr_components/app_management/app_management_test_support.ts +++ /dev/null
@@ -1,72 +0,0 @@ -// Copyright 2022 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {App, PageCallbackRouter, PageHandlerRemote} from 'chrome://resources/cr_components/app_management/app_management.mojom-webui.js'; -import {BrowserProxy} from 'chrome://resources/cr_components/app_management/browser_proxy.js'; -import {PermissionType, TriState} from 'chrome://resources/cr_components/app_management/permission_constants.js'; -import {createTriStatePermission} from 'chrome://resources/cr_components/app_management/permission_util.js'; -import {AppType, InstallReason, InstallSource, OptionalBool, RunOnOsLoginMode, WindowMode} from 'chrome://resources/cr_components/app_management/types.mojom-webui.js'; -import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js'; - -export class TestAppManagementBrowserProxy extends TestBrowserProxy implements - BrowserProxy { - callbackRouter: PageCallbackRouter; - handler: PageHandlerRemote&TestBrowserProxy; - - constructor() { - super(['recordEnumerationValue']); - this.handler = TestBrowserProxy.fromClass(PageHandlerRemote); - this.callbackRouter = new PageCallbackRouter(); - } - - recordEnumerationValue(metricName: string, value: number, enumSize: number) { - this.methodCalled('recordEnumerationValue', metricName, value, enumSize); - } -} - -export function createTestApp(): App { - const app: App = { - id: 'test_loader.html', - type: AppType.kWeb, - title: 'App Title', - description: '', - version: '5.1', - size: '9.0MB', - isPinned: OptionalBool.kFalse, - isPolicyPinned: OptionalBool.kFalse, - installReason: InstallReason.kUser, - permissions: {}, - hideMoreSettings: false, - hidePinToShelf: false, - isPreferredApp: false, - windowMode: WindowMode.kWindow, - resizeLocked: false, - hideResizeLocked: true, - supportedLinks: [], - runOnOsLogin: {loginMode: RunOnOsLoginMode.kNotRun, isManaged: false}, - fileHandlingState: { - enabled: false, - isManaged: false, - userVisibleTypes: 'TXT', - userVisibleTypesLabel: 'Supported type: TXT', - learnMoreUrl: {url: 'https://google.com/'}, - }, - installSource: InstallSource.kUnknown, - }; - - const permissionTypes = [ - PermissionType.kLocation, - PermissionType.kNotifications, - PermissionType.kMicrophone, - PermissionType.kCamera, - ]; - - for (const permissionType of permissionTypes) { - const permissionValue = TriState.kAsk; - const isManaged = false; - app.permissions[permissionType] = - createTriStatePermission(permissionType, permissionValue, isManaged); - } - return app; -}
diff --git a/chrome/test/data/webui/cr_components/app_management/permission_item_test.ts b/chrome/test/data/webui/cr_components/app_management/permission_item_test.ts deleted file mode 100644 index 40a002da..0000000 --- a/chrome/test/data/webui/cr_components/app_management/permission_item_test.ts +++ /dev/null
@@ -1,46 +0,0 @@ -// 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. - -/** @fileoverview Test suite for app-manageemnt-permission-item. */ -import 'chrome://resources/cr_components/app_management/permission_item.js'; - -import {BrowserProxy} from 'chrome://resources/cr_components/app_management/browser_proxy.js'; -import {AppManagementUserAction} from 'chrome://resources/cr_components/app_management/constants.js'; -import {TriState} from 'chrome://resources/cr_components/app_management/permission_constants.js'; -import {AppManagementPermissionItemElement} from 'chrome://resources/cr_components/app_management/permission_item.js'; -import {getPermissionValueBool} from 'chrome://resources/cr_components/app_management/util.js'; -import {assertEquals, assertFalse} from 'chrome://webui-test/chai_assert.js'; -import {waitAfterNextRender} from 'chrome://webui-test/test_util.js'; - -import {createTestApp, TestAppManagementBrowserProxy} from './app_management_test_support.js'; - -suite('AppManagementPermissionItemTest', function() { - let permissionItem: AppManagementPermissionItemElement; - let testProxy: TestAppManagementBrowserProxy; - - setup(async function() { - document.body.innerHTML = ''; - const app = createTestApp(); - testProxy = new TestAppManagementBrowserProxy(); - BrowserProxy.setInstance(testProxy); - - permissionItem = document.createElement('app-management-permission-item'); - permissionItem.app = app; - permissionItem.permissionType = 'kLocation'; - document.body.appendChild(permissionItem); - await waitAfterNextRender(permissionItem); - }); - - test('Toggle permission', async function() { - assertFalse(getPermissionValueBool( - permissionItem.app, permissionItem.permissionType)); - - permissionItem.click(); - const data = await testProxy.handler.whenCalled('setPermission'); - assertEquals(data[1].value.tristateValue, TriState.kAllow); - - const metricData = await testProxy.whenCalled('recordEnumerationValue'); - assertEquals(metricData[1], AppManagementUserAction.LocationTurnedOn); - }); -});
diff --git a/chrome/test/data/webui/cr_components/chromeos/network/network_config_test.js b/chrome/test/data/webui/cr_components/chromeos/network/network_config_test.js index 3da34878..3a2b1adf 100644 --- a/chrome/test/data/webui/cr_components/chromeos/network/network_config_test.js +++ b/chrome/test/data/webui/cr_components/chromeos/network/network_config_test.js
@@ -29,6 +29,7 @@ const kTestVpnHost = 'test-vpn-host'; const kTestUsername = 'test-username'; const kTestPassword = 'test-password'; + const kTestPsk = 'test-psk'; suiteSetup(function() { mojoApi_ = new FakeNetworkConfig(); @@ -306,7 +307,7 @@ setMandatoryFields(); const configProperties = networkConfig.get('configProperties_'); assertFalse(networkConfig.vpnIsConfigured_()); - configProperties.typeConfig.vpn.ipSec.psk = 'test-psk'; + configProperties.typeConfig.vpn.ipSec.psk = kTestPsk; assertTrue(networkConfig.vpnIsConfigured_()); let props = networkConfig.getPropertiesToSet_(); @@ -317,7 +318,7 @@ assertEquals('PSK', props.typeConfig.vpn.ipSec.authenticationType); assertEquals(2, props.typeConfig.vpn.ipSec.ikeVersion); assertFalse(props.typeConfig.vpn.ipSec.saveCredentials); - assertEquals('test-psk', props.typeConfig.vpn.ipSec.psk); + assertEquals(kTestPsk, props.typeConfig.vpn.ipSec.psk); assertEquals('', props.typeConfig.vpn.ipSec.localIdentity); assertEquals('', props.typeConfig.vpn.ipSec.remoteIdentity); @@ -557,6 +558,7 @@ configProperties.name = kTestVpnName; configProperties.typeConfig.vpn.host = kTestVpnHost; configProperties.typeConfig.vpn.l2tp.username = kTestUsername; + configProperties.typeConfig.vpn.l2tp.password = kTestPassword; } test('Switch Authentication Type', function() { @@ -652,7 +654,82 @@ }); }); - test('Certs', function() { + // Checks if the values of vpnIsConfigured_() and getPropertiesToSet_() are + // correct when the authentication type is PSK. + test('PSK', function() { + initNetworkConfig(); + networkConfig.set('vpnType_', 'L2TP_IPsec'); + Polymer.dom.flush(); + + setMandatoryFields(); + const configProperties = networkConfig.get('configProperties_'); + assertFalse(networkConfig.vpnIsConfigured_()); + configProperties.typeConfig.vpn.ipSec.psk = kTestPsk; + assertTrue(networkConfig.vpnIsConfigured_()); + + let props = networkConfig.getPropertiesToSet_(); + const mojom = chromeos.networkConfig.mojom; + assertEquals(kTestVpnName, props.name); + assertEquals(kTestVpnHost, props.typeConfig.vpn.host); + assertEquals(mojom.VpnType.kL2TPIPsec, props.typeConfig.vpn.type.value); + assertEquals('PSK', props.typeConfig.vpn.ipSec.authenticationType); + assertEquals(1, props.typeConfig.vpn.ipSec.ikeVersion); + assertFalse(props.typeConfig.vpn.ipSec.saveCredentials); + assertEquals(kTestPsk, props.typeConfig.vpn.ipSec.psk); + assertEquals(kTestUsername, props.typeConfig.vpn.l2tp.username); + assertEquals(kTestPassword, props.typeConfig.vpn.l2tp.password); + + networkConfig.set('vpnSaveCredentials_', true); + props = networkConfig.getPropertiesToSet_(); + assertTrue(props.typeConfig.vpn.ipSec.saveCredentials); + assertTrue(props.typeConfig.vpn.l2tp.saveCredentials); + }); + + // Checks if values are read correctly for an existing service of PSK + // authentication. + test('Existing PSK', function() { + const mojom = chromeos.networkConfig.mojom; + const l2tp = OncMojo.getDefaultManagedProperties( + mojom.NetworkType.kVPN, 'someguid', kTestVpnName); + l2tp.typeProperties.vpn.type = mojom.VpnType.kL2TPIPsec; + l2tp.typeProperties.vpn.host = {activeValue: kTestVpnHost}; + l2tp.typeProperties.vpn.ipSec = { + authenticationType: {activeValue: 'PSK'}, + ikeVersion: {activeValue: 1}, + saveCredentials: {activeValue: true}, + }; + l2tp.typeProperties.vpn.l2tp = { + username: {activeValue: kTestUsername}, + saveCredentials: {activeValue: true}, + }; + setNetworkConfig(l2tp); + initNetworkConfig(); + + return flushAsync().then(() => { + assertEquals('L2TP_IPsec', networkConfig.get('vpnType_')); + assertEquals('PSK', networkConfig.get('ipsecAuthType_')); + + // Populate the properties again. The values should be the same to what + // are set above. + const props = networkConfig.getPropertiesToSet_(); + assertEquals('someguid', props.guid); + assertEquals(kTestVpnName, props.name); + assertEquals(kTestVpnHost, props.typeConfig.vpn.host); + assertEquals(mojom.VpnType.kL2TPIPsec, props.typeConfig.vpn.type.value); + assertEquals('PSK', props.typeConfig.vpn.ipSec.authenticationType); + assertEquals(1, props.typeConfig.vpn.ipSec.ikeVersion); + assertEquals(undefined, props.typeConfig.vpn.ipSec.eap); + assertEquals(undefined, props.typeConfig.vpn.ipSec.localIdentity); + assertEquals(undefined, props.typeConfig.vpn.ipSec.remoteIdentity); + assertEquals(kTestUsername, props.typeConfig.vpn.l2tp.username); + assertTrue(props.typeConfig.vpn.ipSec.saveCredentials); + assertTrue(props.typeConfig.vpn.l2tp.saveCredentials); + }); + }); + + // Checks if the values of vpnIsConfigured_() and getPropertiesToSet_() are + // correct when the authentication type is user certificate. + test('Cert', function() { initNetworkConfigWithCerts( /* hasServerCa= */ true, /* hasUserCert= */ true); networkConfig.set('vpnType_', 'L2TP_IPsec'); @@ -666,9 +743,79 @@ // Set all other mandatory fields. vpnIsConfigured_() should be true. setMandatoryFields(); assertTrue(networkConfig.vpnIsConfigured_()); + + const props = networkConfig.getPropertiesToSet_(); + const mojom = chromeos.networkConfig.mojom; + assertEquals(kTestVpnName, props.name); + assertEquals(kTestVpnHost, props.typeConfig.vpn.host); + assertEquals( + mojom.VpnType.kL2TPIPsec, props.typeConfig.vpn.type.value); + assertEquals('Cert', props.typeConfig.vpn.ipSec.authenticationType); + assertEquals(1, props.typeConfig.vpn.ipSec.ikeVersion); + assertEquals(1, props.typeConfig.vpn.ipSec.serverCaPems.length); + assertEquals(kCaPem, props.typeConfig.vpn.ipSec.serverCaPems[0]); + assertEquals('PKCS11Id', props.typeConfig.vpn.ipSec.clientCertType); + assertEquals( + kUserCertId, props.typeConfig.vpn.ipSec.clientCertPkcs11Id); + assertEquals(kTestUsername, props.typeConfig.vpn.l2tp.username); + assertEquals(kTestPassword, props.typeConfig.vpn.l2tp.password); + assertFalse(props.typeConfig.vpn.ipSec.saveCredentials); + assertFalse(props.typeConfig.vpn.l2tp.saveCredentials); }); }); }); + + // Checks if values are read correctly for an existing service of + // certificate authentication. + test('Existing Cert', function() { + const mojom = chromeos.networkConfig.mojom; + const l2tp = OncMojo.getDefaultManagedProperties( + mojom.NetworkType.kVPN, 'someguid', kTestVpnName); + l2tp.typeProperties.vpn.type = mojom.VpnType.kL2TPIPsec; + l2tp.typeProperties.vpn.host = {activeValue: kTestVpnHost}; + l2tp.typeProperties.vpn.ipSec = { + authenticationType: {activeValue: 'Cert'}, + clientCertType: {activeValue: 'PKCS11Id'}, + clientCertPkcs11Id: {activeValue: kUserCertId}, + ikeVersion: {activeValue: 1}, + saveCredentials: {activeValue: true}, + serverCaPems: {activeValue: [kCaPem]}, + }; + l2tp.typeProperties.vpn.l2tp = { + username: {activeValue: kTestUsername}, + saveCredentials: {activeValue: true}, + }; + setNetworkConfig(l2tp); + initNetworkConfigWithCerts( + /* hasServerCa= */ true, /* hasUserCert= */ true); + return mojoApi_.whenCalled('getNetworkCertificates').then(() => { + assertEquals('L2TP_IPsec', networkConfig.get('vpnType_')); + assertEquals('Cert', networkConfig.get('ipsecAuthType_')); + assertEquals(kCaHash, networkConfig.selectedServerCaHash_); + assertEquals(kUserHash1, networkConfig.selectedUserCertHash_); + + // Populate the properties again. The values should be the same to what + // are set above. + const props = networkConfig.getPropertiesToSet_(); + assertEquals('someguid', props.guid); + assertEquals(kTestVpnName, props.name); + assertEquals(kTestVpnHost, props.typeConfig.vpn.host); + assertEquals(mojom.VpnType.kL2TPIPsec, props.typeConfig.vpn.type.value); + assertEquals('Cert', props.typeConfig.vpn.ipSec.authenticationType); + assertEquals(1, props.typeConfig.vpn.ipSec.ikeVersion); + assertEquals(1, props.typeConfig.vpn.ipSec.serverCaPems.length); + assertEquals(kCaPem, props.typeConfig.vpn.ipSec.serverCaPems[0]); + assertEquals('PKCS11Id', props.typeConfig.vpn.ipSec.clientCertType); + assertEquals( + kUserCertId, props.typeConfig.vpn.ipSec.clientCertPkcs11Id); + assertEquals(undefined, props.typeConfig.vpn.ipSec.eap); + assertEquals(undefined, props.typeConfig.vpn.ipSec.localIdentity); + assertEquals(undefined, props.typeConfig.vpn.ipSec.remoteIdentity); + assertEquals(kTestUsername, props.typeConfig.vpn.l2tp.username); + assertTrue(props.typeConfig.vpn.ipSec.saveCredentials); + assertTrue(props.typeConfig.vpn.l2tp.saveCredentials); + }); + }); }); suite('OpenVPN', function() {
diff --git a/chrome/test/data/webui/cr_components/cr_components_browsertest.js b/chrome/test/data/webui/cr_components/cr_components_browsertest.js index bab091c..e4840232 100644 --- a/chrome/test/data/webui/cr_components/cr_components_browsertest.js +++ b/chrome/test/data/webui/cr_components/cr_components_browsertest.js
@@ -113,15 +113,3 @@ TEST_F('CrComponentsLocalizedLinkTest', 'All', function() { mocha.run(); }); - -var CrComponentsAppManagementPermissionItemTest = - class extends CrComponentsBrowserTest { - /** @override */ - get browsePreload() { - return 'chrome://test/test_loader.html?module=cr_components/app_management/permission_item_test.js&host=webui-test'; - } -}; - -TEST_F('CrComponentsAppManagementPermissionItemTest', 'All', function() { - mocha.run(); -});
diff --git a/chrome/test/data/webui/media_internals/media_internals_ui_browsertest.js b/chrome/test/data/webui/media_internals/media_internals_ui_browsertest.js index f8b000c..799081f 100644 --- a/chrome/test/data/webui/media_internals/media_internals_ui_browsertest.js +++ b/chrome/test/data/webui/media_internals/media_internals_ui_browsertest.js
@@ -24,8 +24,7 @@ ], }; -// Flaky on multiple bots: crbug.com/1305510 -TEST_F('MediaInternalsUIBrowserTest', 'DISABLED_Integration', function() { +TEST_F('MediaInternalsUIBrowserTest', 'Integration', function() { suite('integration_tests', function() { // The renderer and player ids are completely arbitrarily. var TEST_RENDERER = 12;
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn index 89aae80d..fff95334 100644 --- a/chrome/test/data/webui/settings/chromeos/BUILD.gn +++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -47,6 +47,7 @@ "app_management/dom_switch_test.js", "app_management/main_view_test.js", "app_management/pwa_detail_view_test.js", + "app_management/permission_item_test.js", "app_management/pin_to_shelf_item_test.js", "app_management/plugin_vm_detail_view_test.js", "app_management/managed_apps_test.js",
diff --git a/chrome/test/data/webui/settings/chromeos/app_management/permission_item_test.js b/chrome/test/data/webui/settings/chromeos/app_management/permission_item_test.js new file mode 100644 index 0000000..008659ae --- /dev/null +++ b/chrome/test/data/webui/settings/chromeos/app_management/permission_item_test.js
@@ -0,0 +1,57 @@ +// 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. + +// clang-format off +// #import 'chrome://os-settings/chromeos/os_settings.js'; + +// #import {AppManagementStore, FakePageHandler, PermissionType, updateSelectedAppId, getPermissionValueBool} from 'chrome://os-settings/chromeos/os_settings.js'; +// #import {setupFakeHandler, replaceStore, replaceBody} from './test_util.m.js'; +// #import {flushTasks} from 'chrome://test/test_util.js'; +// clang-format on + +'use strict'; + +suite('<app-management-permission-item>', () => { + let permissionItem; + let fakeHandler; + + setup(async () => { + fakeHandler = setupFakeHandler(); + replaceStore(); + + const arcOptions = { + type: appManagement.mojom.AppType.kArc, + permissions: app_management.FakePageHandler.createArcPermissions([ + PermissionType.kCamera, + PermissionType.kLocation, + PermissionType.kNotifications, + PermissionType.kContacts, + PermissionType.kStorage, + ]) + }; + + // Add an arc app, and pass it to permissionItem. + const app = await fakeHandler.addApp(null, arcOptions); + + permissionItem = document.createElement('app-management-permission-item'); + permissionItem.app = app; + }); + + test('Toggle permission', async () => { + permissionItem.permissionType = 'kLocation'; + + replaceBody(permissionItem); + await fakeHandler.flushPipesForTesting(); + assertTrue(getPermissionValueBool( + permissionItem.app, permissionItem.permissionType)); + + permissionItem.click(); + await test_util.flushTasks(); + await fakeHandler.flushPipesForTesting(); + // Store gets updated permission. + const storeData = app_management.AppManagementStore.getInstance().data; + assertFalse(getPermissionValueBool( + storeData.apps[permissionItem.app.id], permissionItem.permissionType)); + }); +});
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js index 3993fb9..3f7c6be 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
@@ -318,6 +318,7 @@ ['AppManagementMainView', 'main_view_test.m.js'], ['AppManagementManagedApp', 'managed_apps_test.m.js'], ['AppManagementPage', 'app_management_page_tests.m.js'], + ['AppManagementPermissionItem', 'permission_item_test.m.js'], ['AppManagementPinToShelfItem', 'pin_to_shelf_item_test.m.js'], ['AppManagementPluginVmDetailView', 'plugin_vm_detail_view_test.m.js'], ['AppManagementPwaDetailView', 'pwa_detail_view_test.m.js'],
diff --git a/chromeos/ui/base/file_icon_util.cc b/chromeos/ui/base/file_icon_util.cc index be3ab96d..ec8840c22 100644 --- a/chromeos/ui/base/file_icon_util.cc +++ b/chromeos/ui/base/file_icon_util.cc
@@ -195,6 +195,9 @@ // Archive {".ZIP", IconType::kArchive}, {".RAR", IconType::kArchive}, + {".ISO", IconType::kArchive}, + {".7Z", IconType::kArchive}, + {".CRX", IconType::kArchive}, {".TAR", IconType::kArchive}, {".TAR.BZ2", IconType::kArchive}, {".TBZ2", IconType::kArchive},
diff --git a/components/autofill/core/browser/autofill_field.h b/components/autofill/core/browser/autofill_field.h index 68e828f..98da439 100644 --- a/components/autofill/core/browser/autofill_field.h +++ b/components/autofill/core/browser/autofill_field.h
@@ -210,7 +210,7 @@ // Getter and Setter methods for // |value_not_autofilled_over_existing_value_hash_|. void set_value_not_autofilled_over_existing_value_hash( - size_t value_not_autofilled_over_existing_value_hash) { + absl::optional<size_t> value_not_autofilled_over_existing_value_hash) { value_not_autofilled_over_existing_value_hash_ = value_not_autofilled_over_existing_value_hash; }
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc index 0719de8..54e33cf 100644 --- a/components/autofill/core/browser/browser_autofill_manager.cc +++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -1787,25 +1787,35 @@ // Do not override prefilled text/input field values. Selection fields are // excluded from this check because they may have a non-empty value. + // If the initiating element had a prefilled value but the autofill + // suggestion is present that includes the currently filled value in the + // field as a substring, Autofill would override the filled value in that + // case. if (base::FeatureList::IsEnabled( - features::kAutofillPreventOverridingPrefilledValues) && - form.fields[i].form_control_type != "select-one" && - !form.fields[i].value.empty()) { - buffer << Tr{} << field_number << "Skipped: value is prefilled"; - std::string unused_failure_to_fill; - const std::u16string kEmptyCvc{}; - const std::u16string fill_value = field_filler_.GetValueForFilling( - *cached_field, profile_or_credit_card, &result.fields[i], - optional_cvc ? *optional_cvc : kEmptyCvc, action, - &unused_failure_to_fill); - if (action == mojom::RendererFormDataAction::kFill && - !fill_value.empty() && fill_value != form.fields[i].value) { - // Save the value that was supposed to be autofilled for this field. - form_structure->field(i) - ->set_value_not_autofilled_over_existing_value_hash( - base::FastHash(base::UTF16ToUTF8(fill_value))); + features::kAutofillPreventOverridingPrefilledValues)) { + if (form.fields[i].form_control_type != "select-one" && + !form.fields[i].value.empty() && + !FormFieldData::DeepEqual(form.fields[i], field)) { + buffer << Tr{} << field_number << "Skipped: value is prefilled"; + std::string unused_failure_to_fill; + const std::u16string kEmptyCvc{}; + const std::u16string fill_value = field_filler_.GetValueForFilling( + *cached_field, profile_or_credit_card, &result.fields[i], + optional_cvc ? *optional_cvc : kEmptyCvc, action, + &unused_failure_to_fill); + if (action == mojom::RendererFormDataAction::kFill && + !fill_value.empty() && fill_value != form.fields[i].value) { + // Save the value that was supposed to be autofilled for this field. + form_structure->field(i) + ->set_value_not_autofilled_over_existing_value_hash( + base::FastHash(base::UTF16ToUTF8(fill_value))); + } + continue; } - continue; + + // Clear out the value in case the autofill happens for the field. + form_structure->field(i) + ->set_value_not_autofilled_over_existing_value_hash(absl::nullopt); } // Do not fill fields that have been edited by the user, except if the field
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc index a154050..ccff80df 100644 --- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc +++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -9363,7 +9363,7 @@ form.url = GURL("https://myform.com/form.html"); form.action = GURL("about:blank"); FormFieldData field; - test::CreateTestFormField("Name", "name", "Test Name", "text", &field); + test::CreateTestFormField("Name", "name", "", "text", &field); form.fields.push_back(field); test::CreateTestFormField("City", "city", "Test City", "text", &field); form.fields.push_back(field); @@ -9386,7 +9386,7 @@ FillAutofillFormDataAndSaveResults(kDefaultPageID, form, form.fields[0], MakeFrontendID(std::string(), guid), &response_page_id, &response_data); - EXPECT_EQ(response_data.fields[0].value, u"Test Name"); + EXPECT_EQ(response_data.fields[0].value, u"Elvis Aaron Presley"); EXPECT_EQ(response_data.fields[1].value, u"Test City"); EXPECT_EQ(response_data.fields[2].value, u"Tennessee"); EXPECT_EQ(response_data.fields[3].value, u"Test Country"); @@ -9395,8 +9395,8 @@ { FormStructure* form_structure; AutofillField* autofill_field; - std::vector<std::string> expected_values = { - "Elvis Aaron Presley", "Memphis", "", "United States", ""}; + std::vector<std::string> expected_values = {"", "Memphis", "", + "United States", ""}; bool found = browser_autofill_manager_->GetCachedFormAndField( form, form.fields[0], &form_structure, &autofill_field); ASSERT_TRUE(found); @@ -9412,6 +9412,8 @@ base::FastHash(expected_values[i])); } } + + EXPECT_TRUE(form_structure->field(0)->is_autofilled); // No prefilled value EXPECT_TRUE(form_structure->field(2)->is_autofilled); // Selection field. // Prefilled value is same as the value to be autofilled so @@ -9435,6 +9437,51 @@ EXPECT_EQ(response_data.fields[4].value, u"12345678901"); } +// Tests that the Autofill does override the prefilled field value since the +// field is the initiating field for the Autofill and has a prefilled value +// which is a substring of the autofillable value. +TEST_F(BrowserAutofillManagerTest, AutofillOverridePrefilledValue) { + base::test::ScopedFeatureList features; + features.InitAndEnableFeature( + autofill::features::kAutofillPreventOverridingPrefilledValues); + // Set up our form data. + FormData form; + form.name = u"MyForm"; + form.url = GURL("https://myform.com/form.html"); + form.action = GURL("about:blank"); + FormFieldData field; + test::CreateTestFormField("Name", "name", "Test Name", "text", &field); + form.fields.push_back(field); + test::CreateTestFormField("City", "city", "Test City", "text", &field); + form.fields.push_back(field); + test::CreateTestSelectField("State", "state", "California", + {"Washington", "Tennessee", "California"}, + {"DC", "TN", "CA"}, 3, &field); + form.fields.push_back(field); + test::CreateTestFormField("Country", "country", "Test Country", "text", + &field); + form.fields.push_back(field); + std::vector<FormData> forms(1, form); + FormsSeen(forms); + + // "Elv" is a substring of "Elvis Aaron Presley". + form.fields[0].value = u"Elv"; + // Simulate editing a field. + browser_autofill_manager_->OnTextFieldDidChange( + form, form.fields.front(), gfx::RectF(), AutofillTickClock::NowTicks()); + + const char guid[] = "00000000-0000-0000-0000-000000000001"; + int response_page_id = 0; + FormData response_data; + FillAutofillFormDataAndSaveResults(kDefaultPageID, form, form.fields[0], + MakeFrontendID(std::string(), guid), + &response_page_id, &response_data); + EXPECT_EQ(response_data.fields[0].value, u"Elvis Aaron Presley"); + EXPECT_EQ(response_data.fields[1].value, u"Test City"); + EXPECT_EQ(response_data.fields[2].value, u"Tennessee"); + EXPECT_EQ(response_data.fields[3].value, u"Test Country"); +} + // Desktop only tests. #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) class BrowserAutofillManagerTestForVirtualCardOption
diff --git a/components/breadcrumbs/core/breadcrumb_persistent_storage_manager.cc b/components/breadcrumbs/core/breadcrumb_persistent_storage_manager.cc index 12d4f76b..c393815 100644 --- a/components/breadcrumbs/core/breadcrumb_persistent_storage_manager.cc +++ b/components/breadcrumbs/core/breadcrumb_persistent_storage_manager.cc
@@ -327,9 +327,10 @@ if (time_delta_since_last_write < kMinDelayBetweenWrites) { // If an event was just written, delay writing the event to disk in order to // limit overhead. - write_timer_.Start(FROM_HERE, - kMinDelayBetweenWrites - time_delta_since_last_write, - this, &BreadcrumbPersistentStorageManager::WriteEvents); + write_timer_.Start( + FROM_HERE, kMinDelayBetweenWrites - time_delta_since_last_write, + base::BindOnce(&BreadcrumbPersistentStorageManager::WriteEvents, + weak_ptr_factory_.GetWeakPtr())); } else { // If the event does not fit within |kPersistedFilesizeInBytes|, rewrite the // file to trim old events.
diff --git a/components/feed/core/v2/config.cc b/components/feed/core/v2/config.cc index e9c5ec4b..6c7ab94 100644 --- a/components/feed/core/v2/config.cc +++ b/components/feed/core/v2/config.cc
@@ -4,6 +4,7 @@ #include "components/feed/core/v2/config.h" +#include "base/command_line.h" #include "base/containers/cxx20_erase.h" #include "base/containers/flat_set.h" #include "base/metrics/field_trial_params.h" @@ -29,129 +30,133 @@ } // Override any parameters that may be provided by Finch. -void OverrideWithFinch(Config* config) { - config->max_feed_query_requests_per_day = +void OverrideWithFinch(Config& config) { + config.max_feed_query_requests_per_day = base::GetFieldTrialParamByFeatureAsInt( kInterestFeedV2, "max_feed_query_requests_per_day", - config->max_feed_query_requests_per_day); + config.max_feed_query_requests_per_day); - config->max_next_page_requests_per_day = + config.max_next_page_requests_per_day = base::GetFieldTrialParamByFeatureAsInt( kInterestFeedV2, "max_next_page_requests_per_day", - config->max_next_page_requests_per_day); + config.max_next_page_requests_per_day); - config->max_action_upload_requests_per_day = + config.max_action_upload_requests_per_day = base::GetFieldTrialParamByFeatureAsInt( kInterestFeedV2, "max_action_upload_requests_per_day", - config->max_action_upload_requests_per_day); + config.max_action_upload_requests_per_day); - config->max_list_recommended_web_feeds_requests_per_day = + config.max_list_recommended_web_feeds_requests_per_day = base::GetFieldTrialParamByFeatureAsInt( kWebFeed, "max_list_recommended_web_feeds_requests_per_day", - config->max_list_recommended_web_feeds_requests_per_day); + config.max_list_recommended_web_feeds_requests_per_day); - config->max_list_web_feeds_requests_per_day = + config.max_list_web_feeds_requests_per_day = base::GetFieldTrialParamByFeatureAsInt( kWebFeed, "max_list_web_feeds_requests_per_day", - config->max_list_web_feeds_requests_per_day); + config.max_list_web_feeds_requests_per_day); - config->stale_content_threshold = + config.stale_content_threshold = base::Seconds(base::GetFieldTrialParamByFeatureAsDouble( kInterestFeedV2, "stale_content_threshold_seconds", - config->stale_content_threshold.InSecondsF())); + config.stale_content_threshold.InSecondsF())); - config->content_expiration_threshold = + config.content_expiration_threshold = base::Seconds(base::GetFieldTrialParamByFeatureAsDouble( kInterestFeedV2, "content_expiration_threshold_seconds", - config->content_expiration_threshold.InSecondsF())); + config.content_expiration_threshold.InSecondsF())); - config->background_refresh_window_length = + config.background_refresh_window_length = base::Seconds(base::GetFieldTrialParamByFeatureAsDouble( kInterestFeedV2, "background_refresh_window_length_seconds", - config->background_refresh_window_length.InSecondsF())); + config.background_refresh_window_length.InSecondsF())); - config->default_background_refresh_interval = + config.default_background_refresh_interval = base::Seconds(base::GetFieldTrialParamByFeatureAsDouble( kInterestFeedV2, "default_background_refresh_interval_seconds", - config->default_background_refresh_interval.InSecondsF())); + config.default_background_refresh_interval.InSecondsF())); - config->max_action_upload_attempts = base::GetFieldTrialParamByFeatureAsInt( + config.max_action_upload_attempts = base::GetFieldTrialParamByFeatureAsInt( kInterestFeedV2, "max_action_upload_attempts", - config->max_action_upload_attempts); + config.max_action_upload_attempts); - config->max_action_age = + config.max_action_age = base::Seconds(base::GetFieldTrialParamByFeatureAsDouble( kInterestFeedV2, "max_action_age_seconds", - config->max_action_age.InSecondsF())); + config.max_action_age.InSecondsF())); - config->max_action_upload_bytes = base::GetFieldTrialParamByFeatureAsInt( + config.max_action_upload_bytes = base::GetFieldTrialParamByFeatureAsInt( kInterestFeedV2, "max_action_upload_bytes", - config->max_action_upload_bytes); + config.max_action_upload_bytes); - config->model_unload_timeout = + config.model_unload_timeout = base::Seconds(base::GetFieldTrialParamByFeatureAsDouble( kInterestFeedV2, "model_unload_timeout_seconds", - config->model_unload_timeout.InSecondsF())); + config.model_unload_timeout.InSecondsF())); - config->load_more_trigger_lookahead = base::GetFieldTrialParamByFeatureAsInt( + config.load_more_trigger_lookahead = base::GetFieldTrialParamByFeatureAsInt( kInterestFeedV2, "load_more_trigger_lookahead", - config->load_more_trigger_lookahead); + config.load_more_trigger_lookahead); - config->load_more_trigger_scroll_distance_dp = + config.load_more_trigger_scroll_distance_dp = base::GetFieldTrialParamByFeatureAsInt( kInterestFeedV2Scrolling, "load_more_trigger_scroll_distance_dp", - config->load_more_trigger_scroll_distance_dp); + config.load_more_trigger_scroll_distance_dp); - config->upload_actions_on_enter_background = + config.upload_actions_on_enter_background = base::GetFieldTrialParamByFeatureAsBool( kInterestFeedV2, "upload_actions_on_enter_background", - config->upload_actions_on_enter_background); + config.upload_actions_on_enter_background); - config->send_signed_out_session_logs = - base::GetFieldTrialParamByFeatureAsBool( - kInterestFeedV2, "send_signed_out_session_logs", - config->send_signed_out_session_logs); + config.send_signed_out_session_logs = base::GetFieldTrialParamByFeatureAsBool( + kInterestFeedV2, "send_signed_out_session_logs", + config.send_signed_out_session_logs); - config->session_id_max_age = - base::Days(base::GetFieldTrialParamByFeatureAsInt( - kInterestFeedV2, "session_id_max_age_days", - config->session_id_max_age.InDays())); + config.session_id_max_age = base::Days(base::GetFieldTrialParamByFeatureAsInt( + kInterestFeedV2, "session_id_max_age_days", + config.session_id_max_age.InDays())); - config->max_prefetch_image_requests_per_refresh = + config.max_prefetch_image_requests_per_refresh = base::GetFieldTrialParamByFeatureAsInt( kInterestFeedV2, "max_prefetch_image_requests_per_refresh", - config->max_prefetch_image_requests_per_refresh); + config.max_prefetch_image_requests_per_refresh); - config->webfeed_accelerator_recent_visit_history_days = + config.webfeed_accelerator_recent_visit_history_days = base::GetFieldTrialParamByFeatureAsInt( kWebFeed, "webfeed_accelerator_recent_visit_history_days", - config->webfeed_accelerator_recent_visit_history_days); + config.webfeed_accelerator_recent_visit_history_days); - config->recommended_feeds_staleness_threshold = + config.recommended_feeds_staleness_threshold = base::Days(base::GetFieldTrialParamByFeatureAsInt( kWebFeed, "recommended_feeds_staleness_threshold_days", - config->recommended_feeds_staleness_threshold.InDays())); + config.recommended_feeds_staleness_threshold.InDays())); - config->subscribed_feeds_staleness_threshold = + config.subscribed_feeds_staleness_threshold = base::Days(base::GetFieldTrialParamByFeatureAsInt( kWebFeed, "subscribed_feeds_staleness_threshold_days", - config->subscribed_feeds_staleness_threshold.InDays())); + config.subscribed_feeds_staleness_threshold.InDays())); - config->web_feed_stale_content_threshold = + config.web_feed_stale_content_threshold = base::Seconds(base::GetFieldTrialParamByFeatureAsDouble( kWebFeed, "web_feed_stale_content_threshold_seconds", - config->web_feed_stale_content_threshold.InSecondsF())); + config.web_feed_stale_content_threshold.InSecondsF())); // Erase any capabilities with "enable_CAPABILITY = false" set. - base::EraseIf(config->experimental_capabilities, CapabilityDisabled); + base::EraseIf(config.experimental_capabilities, CapabilityDisabled); - config->max_mid_entities_per_url_entry = + config.max_mid_entities_per_url_entry = base::GetFieldTrialParamByFeatureAsInt( kPersonalizeFeedUnsignedUsers, "max_mid_entities_per_url_entry", - config->max_mid_entities_per_url_entry); - config->max_url_entries_in_cache = GetFieldTrialParamByFeatureAsInt( + config.max_mid_entities_per_url_entry); + config.max_url_entries_in_cache = GetFieldTrialParamByFeatureAsInt( kPersonalizeFeedUnsignedUsers, "max_url_entries_in_cache", - config->max_url_entries_in_cache); + config.max_url_entries_in_cache); +} + +void OverrideWithSwitches(Config& config) { + config.use_feed_query_requests_for_web_feeds = + base::CommandLine::ForCurrentProcess()->HasSwitch( + "webfeed-legacy-feedquery"); } } // namespace @@ -160,7 +165,8 @@ static Config* s_config = nullptr; if (!s_config) { s_config = new Config; - OverrideWithFinch(s_config); + OverrideWithFinch(*s_config); + OverrideWithSwitches(*s_config); } return *s_config; } @@ -177,7 +183,7 @@ } void OverrideConfigWithFinchForTesting() { - OverrideWithFinch(&const_cast<Config&>(GetFeedConfig())); + OverrideWithFinch(const_cast<Config&>(GetFeedConfig())); } Config::Config() = default;
diff --git a/components/feed/core/v2/config.h b/components/feed/core/v2/config.h index e164d84d..0b942e17 100644 --- a/components/feed/core/v2/config.h +++ b/components/feed/core/v2/config.h
@@ -97,6 +97,7 @@ // Until we get the new list contents API working, keep using FeedQuery. // TODO(crbug/1152592): remove this when new endpoint is tested enough. + // Set using snippets-internals, or the --webfeed-legacy-feedquery switch. bool use_feed_query_requests_for_web_feeds = false; // Set of optional capabilities included in requests. See
diff --git a/components/heap_profiling/in_process/heap_profiler_controller_unittest.cc b/components/heap_profiling/in_process/heap_profiler_controller_unittest.cc index d88b577e3..0fff757 100644 --- a/components/heap_profiling/in_process/heap_profiler_controller_unittest.cc +++ b/components/heap_profiling/in_process/heap_profiler_controller_unittest.cc
@@ -267,7 +267,13 @@ EXPECT_EQ(sample_received_, GetParam().expect_stable_sample); } -TEST_P(HeapProfilerControllerFeatureTest, CanaryChannel) { +// TODO(crbug.com/1302007): This test hangs on iPad device. +#if BUILDFLAG(IS_IOS) +#define MAYBE_CanaryChannel DISABLED_CanaryChannel +#else +#define MAYBE_CanaryChannel CanaryChannel +#endif +TEST_P(HeapProfilerControllerFeatureTest, MAYBE_CanaryChannel) { StartHeapProfiling( version_info::Channel::CANARY, base::BindRepeating(&HeapProfilerControllerTest::RecordSampleReceived,
diff --git a/components/optimization_guide/core/optimization_guide_features.cc b/components/optimization_guide/core/optimization_guide_features.cc index 706692fa..3f339b8 100644 --- a/components/optimization_guide/core/optimization_guide_features.cc +++ b/components/optimization_guide/core/optimization_guide_features.cc
@@ -63,14 +63,8 @@ // Enables the syncing of the Optimization Hints component, which provides // hints for what optimizations can be applied on a page load. -const base::Feature kOptimizationHints { - "OptimizationHints", -#if BUILDFLAG(IS_IOS) - base::FEATURE_DISABLED_BY_DEFAULT -#else // !BUILDFLAG(IS_IOS) - base::FEATURE_ENABLED_BY_DEFAULT -#endif // BUILDFLAG(IS_IOS) -}; +const base::Feature kOptimizationHints{"OptimizationHints", + base::FEATURE_ENABLED_BY_DEFAULT}; // Feature flag that contains a feature param that specifies the field trials // that are allowed to be sent up to the Optimization Guide Server. @@ -83,9 +77,9 @@ const base::Feature kRemoteOptimizationGuideFetchingAnonymousDataConsent { "OptimizationHintsFetchingAnonymousDataConsent", -#if BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) base::FEATURE_ENABLED_BY_DEFAULT -#else // !BUILDFLAG(IS_ANDROID) +#else // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) base::FEATURE_DISABLED_BY_DEFAULT #endif // BUILDFLAG(IS_ANDROID) };
diff --git a/components/payments/OWNERS b/components/payments/OWNERS index 1125b0d..5da21fdf 100644 --- a/components/payments/OWNERS +++ b/components/payments/OWNERS
@@ -1,3 +1,3 @@ rouslan@chromium.org -maxlg@chromium.org nburris@chromium.org +smcgruer@chromium.org
diff --git a/components/permissions/android/permission_prompt_android.cc b/components/permissions/android/permission_prompt_android.cc index be3ae4f..0486024 100644 --- a/components/permissions/android/permission_prompt_android.cc +++ b/components/permissions/android/permission_prompt_android.cc
@@ -47,7 +47,6 @@ PermissionPromptAndroid::~PermissionPromptAndroid() { if (message_delegate_) { - message_delegate_.reset(); return; } infobars::InfoBarManager* infobar_manager =
diff --git a/components/permissions/android/permission_prompt_android.h b/components/permissions/android/permission_prompt_android.h index 20f4b0a..375817a 100644 --- a/components/permissions/android/permission_prompt_android.h +++ b/components/permissions/android/permission_prompt_android.h
@@ -12,7 +12,6 @@ #include "base/memory/weak_ptr.h" #include "components/content_settings/core/common/content_settings_types.h" #include "components/infobars/core/infobar_manager.h" -#include "components/messages/android/message_wrapper.h" #include "components/permissions/permission_prompt.h" #include "components/permissions/permission_uma_util.h" #include "components/permissions/permissions_client.h"
diff --git a/components/reporting/storage/storage_queue_unittest.cc b/components/reporting/storage/storage_queue_unittest.cc index 079a0c2e..35bfe77 100644 --- a/components/reporting/storage/storage_queue_unittest.cc +++ b/components/reporting/storage/storage_queue_unittest.cc
@@ -992,7 +992,16 @@ storage_queue_->Flush(); } -TEST_P(StorageQueueTest, WriteIntoNewStorageQueueReopenWriteMoreAndFlush) { +// TODO(crbug.com/1302007): This test crashes on iPad device. +#if BUILDFLAG(IS_IOS) +#define MAYBE_WriteIntoNewStorageQueueReopenWriteMoreAndFlush \ + DISABLED_WriteIntoNewStorageQueueReopenWriteMoreAndFlush +#else +#define MAYBE_WriteIntoNewStorageQueueReopenWriteMoreAndFlush \ + WriteIntoNewStorageQueueReopenWriteMoreAndFlush +#endif +TEST_P(StorageQueueTest, + MAYBE_WriteIntoNewStorageQueueReopenWriteMoreAndFlush) { CreateTestStorageQueueOrDie(BuildStorageQueueOptionsOnlyManual()); WriteStringOrDie(kData[0]); WriteStringOrDie(kData[1]);
diff --git a/components/segmentation_platform/internal/dummy_segmentation_platform_service.cc b/components/segmentation_platform/internal/dummy_segmentation_platform_service.cc index f43f095..705edeb 100644 --- a/components/segmentation_platform/internal/dummy_segmentation_platform_service.cc +++ b/components/segmentation_platform/internal/dummy_segmentation_platform_service.cc
@@ -20,6 +20,7 @@ const std::string& segmentation_key, SegmentSelectionCallback callback) { stats::RecordSegmentSelectionFailure( + segmentation_key, stats::SegmentationSelectionFailureReason::kPlatformDisabled); base::SequencedTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), SegmentSelectionResult()));
diff --git a/components/segmentation_platform/internal/dummy_segmentation_platform_service_unittest.cc b/components/segmentation_platform/internal/dummy_segmentation_platform_service_unittest.cc index 645967d..84288ff 100644 --- a/components/segmentation_platform/internal/dummy_segmentation_platform_service_unittest.cc +++ b/components/segmentation_platform/internal/dummy_segmentation_platform_service_unittest.cc
@@ -42,13 +42,13 @@ SegmentSelectionResult expected; base::RunLoop loop; segmentation_platform_service_->GetSelectedSegment( - "some_key", + "test_key", base::BindOnce( &DummySegmentationPlatformServiceTest::OnGetSelectedSegment, base::Unretained(this), loop.QuitClosure(), expected)); loop.Run(); ASSERT_EQ(expected, - segmentation_platform_service_->GetCachedSegmentResult("some_key")); + segmentation_platform_service_->GetCachedSegmentResult("test_key")); } } // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/execution/model_execution_manager_impl.cc b/components/segmentation_platform/internal/execution/model_execution_manager_impl.cc index 5bb0b3f..bce51f6 100644 --- a/components/segmentation_platform/internal/execution/model_execution_manager_impl.cc +++ b/components/segmentation_platform/internal/execution/model_execution_manager_impl.cc
@@ -128,22 +128,30 @@ auto model_handler_it = model_handlers_.find(segment_id); DCHECK(model_handler_it != model_handlers_.end()); + SegmentationModelHandler& handler = *model_handler_it->second; + // Create an ExecutionState that will stay with this request until it has been // fully processed. auto state = std::make_unique<ExecutionState>(); state->segment_id = segment_id; - state->model_handler = (*model_handler_it).second.get(); + state->model_handler = &handler; state->callback = std::move(callback); state->total_execution_start_time = clock_->Now(); ModelExecutionTraceEvent trace_event( "ModelExecutionManagerImpl::ExecuteModel", *state); + if (!handler.ModelAvailable()) { + RunModelExecutionCallback(std::move(state), 0, + ModelExecutionStatus::kSkippedModelNotReady); + return; + } + // It is required to have a valid and well formed segment info. if (metadata_utils::ValidateSegmentInfo(segment_info) != metadata_utils::ValidationResult::kValidationSuccess) { RunModelExecutionCallback(std::move(state), 0, - ModelExecutionStatus::kInvalidMetadata); + ModelExecutionStatus::kSkippedInvalidMetadata); return; } @@ -161,7 +169,7 @@ if (error) { // Validation error occurred on model's metadata. RunModelExecutionCallback(std::move(state), 0, - ModelExecutionStatus::kInvalidMetadata); + ModelExecutionStatus::kSkippedInvalidMetadata); return; } state->input_tensor.insert(state->input_tensor.end(), input_tensor.begin(),
diff --git a/components/segmentation_platform/internal/execution/model_execution_manager_impl_unittest.cc b/components/segmentation_platform/internal/execution/model_execution_manager_impl_unittest.cc index ad12c12..e4f8356 100644 --- a/components/segmentation_platform/internal/execution/model_execution_manager_impl_unittest.cc +++ b/components/segmentation_platform/internal/execution/model_execution_manager_impl_unittest.cc
@@ -220,11 +220,29 @@ auto segment_id = OptimizationTarget::OPTIMIZATION_TARGET_SEGMENTATION_NEW_TAB; CreateModelExecutionManager({segment_id}, base::DoNothing()); - ExecuteModel(std::make_pair(0, ModelExecutionStatus::kInvalidMetadata)); + EXPECT_CALL(FindHandler(segment_id), ModelAvailable()) + .WillRepeatedly(Return(true)); + ExecuteModel( + std::make_pair(0, ModelExecutionStatus::kSkippedInvalidMetadata)); segment_database_->SetBucketDuration(segment_id, 14, proto::TimeUnit::UNKNOWN_TIME_UNIT); - ExecuteModel(std::make_pair(0, ModelExecutionStatus::kInvalidMetadata)); + ExecuteModel( + std::make_pair(0, ModelExecutionStatus::kSkippedInvalidMetadata)); +} + +TEST_F(ModelExecutionManagerTest, ModelNotReady) { + auto segment_id = + OptimizationTarget::OPTIMIZATION_TARGET_SEGMENTATION_NEW_TAB; + CreateModelExecutionManager({segment_id}, base::DoNothing()); + + segment_database_->SetBucketDuration(segment_id, 3, proto::TimeUnit::HOUR); + + // When the model is unavailable, the execution should fail. + EXPECT_CALL(FindHandler(segment_id), ModelAvailable()) + .WillRepeatedly(Return(false)); + + ExecuteModel(std::make_pair(0, ModelExecutionStatus::kSkippedModelNotReady)); } TEST_F(ModelExecutionManagerTest, OnSegmentationModelUpdatedInvalidMetadata) { @@ -414,12 +432,14 @@ .WillRepeatedly(Return(true)); EXPECT_CALL(FindHandler(segment_id), ExecuteModelWithInput(_, _)).Times(0); - ExecuteModel(std::make_pair(0, ModelExecutionStatus::kInvalidMetadata)); + ExecuteModel( + std::make_pair(0, ModelExecutionStatus::kSkippedInvalidMetadata)); EXPECT_CALL(*feature_list_query_processor_, ProcessFeatureList(_, segment_id, clock_.Now(), _)) .WillOnce(RunOnceCallback<3>(/*error=*/true, std::vector<float>{})); - ExecuteModel(std::make_pair(0, ModelExecutionStatus::kInvalidMetadata)); + ExecuteModel( + std::make_pair(0, ModelExecutionStatus::kSkippedInvalidMetadata)); } TEST_F(ModelExecutionManagerTest, ExecuteModelWithMultipleFeatures) {
diff --git a/components/segmentation_platform/internal/execution/model_execution_status.h b/components/segmentation_platform/internal/execution/model_execution_status.h index fae5afd..ddda882c 100644 --- a/components/segmentation_platform/internal/execution/model_execution_status.h +++ b/components/segmentation_platform/internal/execution/model_execution_status.h
@@ -13,8 +13,13 @@ enum class ModelExecutionStatus { kSuccess = 0, kExecutionError = 1, - kInvalidMetadata = 2, - kMaxValue = kInvalidMetadata, + kSkippedInvalidMetadata = 2, + kSkippedModelNotReady = 3, + kSkippedHasFreshResults = 4, + kSkippedNotEnoughSignals = 5, + kSkippedResultNotExpired = 6, + kFailedToSaveResultAfterSuccess = 7, + kMaxValue = kFailedToSaveResultAfterSuccess, }; } // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/scheduler/model_execution_scheduler_impl.cc b/components/segmentation_platform/internal/scheduler/model_execution_scheduler_impl.cc index e9e8029e..7d54139 100644 --- a/components/segmentation_platform/internal/scheduler/model_execution_scheduler_impl.cc +++ b/components/segmentation_platform/internal/scheduler/model_execution_scheduler_impl.cc
@@ -87,10 +87,6 @@ segment_result.set_timestamp_us( clock_->Now().ToDeltaSinceWindowsEpoch().InMicroseconds()); stats::RecordModelScore(segment_id, result.first); - } else { - stats::RecordSegmentSelectionFailure( - stats::SegmentationSelectionFailureReason:: - kAtLeastOneModelFailedExecution); } segment_database_->SaveSegmentResult( @@ -128,6 +124,9 @@ // Filter out the segments computed recently. if (metadata_utils::HasFreshResults(segment_info, clock_->Now())) { VLOG(1) << "Segmentation model not executed since it has fresh results."; + stats::RecordModelExecutionStatus( + segment_info.segment_id(), + ModelExecutionStatus::kSkippedHasFreshResults); return false; } @@ -135,15 +134,18 @@ if (expired_only && !metadata_utils::HasExpiredOrUnavailableResult( segment_info, clock_->Now())) { VLOG(1) << "Segmentation model not executed since results are not expired."; + stats::RecordModelExecutionStatus( + segment_info.segment_id(), + ModelExecutionStatus::kSkippedResultNotExpired); return false; } // Filter out segments that don't match signal collection min length. if (!signal_storage_config_->MeetsSignalCollectionRequirement( segment_info.model_metadata())) { - stats::RecordSegmentSelectionFailure( - stats::SegmentationSelectionFailureReason:: - kAtLeastOneModelNeedsMoreSignals); + stats::RecordModelExecutionStatus( + segment_info.segment_id(), + ModelExecutionStatus::kSkippedNotEnoughSignals); VLOG(1) << "Segmentation model not executed since metadata requirements " "not met."; return false; @@ -165,8 +167,10 @@ bool success) { stats::RecordModelExecutionSaveResult(segment_id, success); if (!success) { - stats::RecordSegmentSelectionFailure( - stats::SegmentationSelectionFailureReason::kFailedToSaveModelResult); + // TODO(ssid): Consider removing this enum, this is the only case where the + // execution status is recorded twice for the same execution request. + stats::RecordModelExecutionStatus( + segment_id, ModelExecutionStatus::kFailedToSaveResultAfterSuccess); return; }
diff --git a/components/segmentation_platform/internal/segmentation_platform_service_impl.cc b/components/segmentation_platform/internal/segmentation_platform_service_impl.cc index bce9a93b..700358a 100644 --- a/components/segmentation_platform/internal/segmentation_platform_service_impl.cc +++ b/components/segmentation_platform/internal/segmentation_platform_service_impl.cc
@@ -233,8 +233,11 @@ OnServiceStatusChanged(); if (!init_success) { - stats::RecordSegmentSelectionFailure( - stats::SegmentationSelectionFailureReason::kDBInitFailure); + for (const auto& config : configs_) { + stats::RecordSegmentSelectionFailure( + config->segmentation_key, + stats::SegmentationSelectionFailureReason::kDBInitFailure); + } return; }
diff --git a/components/segmentation_platform/internal/segmentation_platform_service_impl_unittest.cc b/components/segmentation_platform/internal/segmentation_platform_service_impl_unittest.cc index d553888a..3320ad0 100644 --- a/components/segmentation_platform/internal/segmentation_platform_service_impl_unittest.cc +++ b/components/segmentation_platform/internal/segmentation_platform_service_impl_unittest.cc
@@ -96,6 +96,7 @@ { // Empty config. std::unique_ptr<Config> config = std::make_unique<Config>(); + config->segmentation_key = "test_key"; configs.push_back(std::move(config)); }
diff --git a/components/segmentation_platform/internal/selection/segment_selector_impl.cc b/components/segmentation_platform/internal/selection/segment_selector_impl.cc index 4024baa..fa78630c 100644 --- a/components/segmentation_platform/internal/selection/segment_selector_impl.cc +++ b/components/segmentation_platform/internal/selection/segment_selector_impl.cc
@@ -43,11 +43,12 @@ selected_segment_last_session_.segment = selected_segment->segment_id; selected_segment_last_session_.is_ready = true; stats::RecordSegmentSelectionFailure( + config_->segmentation_key, stats::SegmentationSelectionFailureReason::kSelectionAvailableInPrefs); } else { stats::RecordSegmentSelectionFailure( - stats::SegmentationSelectionFailureReason:: - kInvalidSelectionResultInPrefs); + config_->segmentation_key, stats::SegmentationSelectionFailureReason:: + kInvalidSelectionResultInPrefs); } } @@ -99,8 +100,8 @@ << OptimizationTarget_Name(segment_info.segment_id()) << " does not meet signal collection requirements."; stats::RecordSegmentSelectionFailure( - stats::SegmentationSelectionFailureReason:: - kAtLeastOneSegmentSignalsNotCollected); + config_->segmentation_key, stats::SegmentationSelectionFailureReason:: + kAtLeastOneSegmentSignalsNotCollected); return false; } @@ -110,8 +111,8 @@ << OptimizationTarget_Name(segment_info.segment_id()) << " has expired or unavailable result."; stats::RecordSegmentSelectionFailure( - stats::SegmentationSelectionFailureReason:: - kAtLeastOneSegmentNotReady); + config_->segmentation_key, stats::SegmentationSelectionFailureReason:: + kAtLeastOneSegmentNotReady); return false; } } @@ -128,6 +129,7 @@ if (!platform_options_.force_refresh_results && previous_selection->selection_time + ttl_to_use > clock_->Now()) { stats::RecordSegmentSelectionFailure( + config_->segmentation_key, stats::SegmentationSelectionFailureReason::kSelectionTtlNotExpired); VLOG(1) << __func__ << ": previous selection of segment=" << OptimizationTarget_Name(previous_selection->segment_id)
diff --git a/components/segmentation_platform/internal/service_proxy_impl_unittest.cc b/components/segmentation_platform/internal/service_proxy_impl_unittest.cc index 96ae137a..a35b13e 100644 --- a/components/segmentation_platform/internal/service_proxy_impl_unittest.cc +++ b/components/segmentation_platform/internal/service_proxy_impl_unittest.cc
@@ -28,6 +28,9 @@ namespace segmentation_platform { namespace { + +constexpr char kTestSegmentationKey[] = "test_key"; + // Adds a segment info into a map, and return a copy of it. proto::SegmentInfo AddSegmentInfo( std::map<std::string, proto::SegmentInfo>* db_entries, @@ -85,7 +88,7 @@ void SetUp() override { auto config = std::make_unique<Config>(); - config->segmentation_key = "test"; + config->segmentation_key = kTestSegmentationKey; configs_.emplace_back(std::move(config)); pref_service_.registry()->RegisterDictionaryPref(kSegmentationResultPref); } @@ -100,8 +103,9 @@ segment_db_ = std::make_unique<SegmentInfoDatabase>(std::move(db)); result_prefs_ = std::make_unique<SegmentationResultPrefs>(&pref_service_); - segment_selectors_["test"] = std::make_unique<FakeSegmentSelectorImpl>( - result_prefs_.get(), configs_.at(0).get()); + segment_selectors_[kTestSegmentationKey] = + std::make_unique<FakeSegmentSelectorImpl>(result_prefs_.get(), + configs_.at(0).get()); service_proxy_impl_ = std::make_unique<ServiceProxyImpl>( segment_db_.get(), nullptr, &configs_, &segment_selectors_); service_proxy_impl_->AddObserver(this); @@ -170,7 +174,7 @@ service_proxy_impl_->OnServiceStatusChanged(true, 7); db_->LoadCallback(true); ASSERT_EQ(client_info_.size(), 1u); - ASSERT_EQ(client_info_.at(0).segmentation_key, "test"); + ASSERT_EQ(client_info_.at(0).segmentation_key, kTestSegmentationKey); ASSERT_EQ(client_info_.at(0).segment_status.size(), 1u); ServiceProxy::SegmentStatus status = client_info_.at(0).segment_status.at(0); ASSERT_EQ(status.segment_id, @@ -265,10 +269,11 @@ db_->LoadCallback(true); service_proxy_impl_->SetSelectedSegment( - "test", OptimizationTarget::OPTIMIZATION_TARGET_SEGMENTATION_NEW_TAB); - ASSERT_EQ( - OptimizationTarget::OPTIMIZATION_TARGET_SEGMENTATION_NEW_TAB, - static_cast<FakeSegmentSelectorImpl*>(segment_selectors_["test"].get()) - ->new_selection()); + kTestSegmentationKey, + OptimizationTarget::OPTIMIZATION_TARGET_SEGMENTATION_NEW_TAB); + ASSERT_EQ(OptimizationTarget::OPTIMIZATION_TARGET_SEGMENTATION_NEW_TAB, + static_cast<FakeSegmentSelectorImpl*>( + segment_selectors_[kTestSegmentationKey].get()) + ->new_selection()); } } // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/stats.cc b/components/segmentation_platform/internal/stats.cc index 2503e7ec..02f4bf5d 100644 --- a/components/segmentation_platform/internal/stats.cc +++ b/components/segmentation_platform/internal/stats.cc
@@ -13,8 +13,7 @@ #include "components/segmentation_platform/internal/proto/types.pb.h" #include "components/segmentation_platform/public/config.h" -namespace segmentation_platform { -namespace stats { +namespace segmentation_platform::stats { namespace { // Should map to SegmentationModel variant in // //tools/metrics/histograms/metadata/segmentation_platform/histograms.xml. @@ -197,18 +196,23 @@ // Should map to ModelExecutionStatus variant string in // //tools/metrics/histograms/metadata/segmentation_platform/histograms.xml. -std::string ModelExecutionStatusToHistogramVariant( +absl::optional<base::StringPiece> ModelExecutionStatusToHistogramVariant( ModelExecutionStatus status) { switch (status) { case ModelExecutionStatus::kSuccess: return "Success"; case ModelExecutionStatus::kExecutionError: return "ExecutionError"; - case ModelExecutionStatus::kInvalidMetadata: - return "InvalidMetadata"; - default: - NOTREACHED(); - return "Unknown"; + + // Only record duration histograms when tflite model is executed. These + // cases mean the execution was skipped. + case ModelExecutionStatus::kSkippedInvalidMetadata: + case ModelExecutionStatus::kSkippedModelNotReady: + case ModelExecutionStatus::kSkippedHasFreshResults: + case ModelExecutionStatus::kSkippedNotEnoughSignals: + case ModelExecutionStatus::kSkippedResultNotExpired: + case ModelExecutionStatus::kFailedToSaveResultAfterSuccess: + return absl::nullopt; } } @@ -423,20 +427,28 @@ base::TimeDelta duration) { ModelExecutionStatus status = success ? ModelExecutionStatus::kSuccess : ModelExecutionStatus::kExecutionError; + absl::optional<base::StringPiece> status_variant = + ModelExecutionStatusToHistogramVariant(status); + if (!status_variant) + return; base::UmaHistogramTimes( - "SegmentationPlatform.ModelExecution.Duration.Model." + - OptimizationTargetToHistogramVariant(segment_id) + "." + - ModelExecutionStatusToHistogramVariant(status), + base::StrCat({"SegmentationPlatform.ModelExecution.Duration.Model.", + OptimizationTargetToHistogramVariant(segment_id), ".", + *status_variant}), duration); } void RecordModelExecutionDurationTotal(OptimizationTarget segment_id, ModelExecutionStatus status, base::TimeDelta duration) { + absl::optional<base::StringPiece> status_variant = + ModelExecutionStatusToHistogramVariant(status); + if (!status_variant) + return; base::UmaHistogramTimes( - "SegmentationPlatform.ModelExecution.Duration.Total." + - OptimizationTargetToHistogramVariant(segment_id) + "." + - ModelExecutionStatusToHistogramVariant(status), + base::StrCat({"SegmentationPlatform.ModelExecution.Duration.Total.", + OptimizationTargetToHistogramVariant(segment_id), ".", + *status_variant}), duration); } @@ -514,9 +526,12 @@ histogram_value_count); } -void RecordSegmentSelectionFailure(SegmentationSelectionFailureReason reason) { - base::UmaHistogramEnumeration("SegmentationPlatform.SelectionFailedReason", - reason); +void RecordSegmentSelectionFailure(const std::string& segmentation_key, + SegmentationSelectionFailureReason reason) { + base::UmaHistogramEnumeration( + base::StrCat({"SegmentationPlatform.SelectionFailedReason.", + SegmentationKeyToUmaName(segmentation_key)}), + reason); } void RecordModelAvailability(OptimizationTarget segment_id, @@ -533,5 +548,4 @@ tensor_size); } -} // namespace stats -} // namespace segmentation_platform +} // namespace segmentation_platform::stats
diff --git a/components/segmentation_platform/internal/stats.h b/components/segmentation_platform/internal/stats.h index fb63787..5e1e707 100644 --- a/components/segmentation_platform/internal/stats.h +++ b/components/segmentation_platform/internal/stats.h
@@ -14,8 +14,7 @@ using optimization_guide::proto::OptimizationTarget; -namespace segmentation_platform { -namespace stats { +namespace segmentation_platform::stats { // Keep in sync with AdaptiveToolbarSegmentSwitch in enums.xml. // Visible for testing. @@ -164,7 +163,8 @@ }; // Records the reason for failure or success to compute a segment selection. -void RecordSegmentSelectionFailure(SegmentationSelectionFailureReason reason); +void RecordSegmentSelectionFailure(const std::string& segmentation_key, + SegmentationSelectionFailureReason reason); // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. Please keep in sync with @@ -183,7 +183,6 @@ // structured metrics. void RecordTooManyInputTensors(int tensor_size); -} // namespace stats -} // namespace segmentation_platform +} // namespace segmentation_platform::stats #endif // COMPONENTS_SEGMENTATION_PLATFORM_INTERNAL_STATS_H_
diff --git a/components/services/app_service/public/cpp/BUILD.gn b/components/services/app_service/public/cpp/BUILD.gn index 13bf72c..624bb2b 100644 --- a/components/services/app_service/public/cpp/BUILD.gn +++ b/components/services/app_service/public/cpp/BUILD.gn
@@ -200,6 +200,8 @@ source_set("intents") { sources = [ + "intent.cc", + "intent.h", "intent_constants.cc", "intent_constants.h", "intent_filter_util.cc",
diff --git a/components/services/app_service/public/cpp/app_types.h b/components/services/app_service/public/cpp/app_types.h index 3db9e0b20..4a7aabf 100644 --- a/components/services/app_service/public/cpp/app_types.h +++ b/components/services/app_service/public/cpp/app_types.h
@@ -241,8 +241,8 @@ const apps::mojom::OptionalBool& mojom_optional_bool); COMPONENT_EXPORT(APP_TYPES) -absl::optional<bool> GetMojomOptionalBool( - const apps::mojom::OptionalBool& mojom_optional_bool); +apps::mojom::OptionalBool GetMojomOptionalBool( + const absl::optional<bool>& mojom_optional_bool); COMPONENT_EXPORT(APP_TYPES) AppPtr ConvertMojomAppToApp(const apps::mojom::AppPtr& mojom_app);
diff --git a/components/services/app_service/public/cpp/intent.cc b/components/services/app_service/public/cpp/intent.cc new file mode 100644 index 0000000..0a6350f --- /dev/null +++ b/components/services/app_service/public/cpp/intent.cc
@@ -0,0 +1,157 @@ +// 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/services/app_service/public/cpp/intent.h" + +#include "base/files/safe_base_name.h" +#include "components/services/app_service/public/cpp/app_types.h" + +namespace apps { + +IntentFile::IntentFile(const GURL& url) : url(url) {} + +IntentFile::~IntentFile() = default; + +Intent::Intent(const std::string& action) : action(action) {} + +Intent::~Intent() = default; + +IntentFilePtr ConvertMojomIntentFileToIntentFile( + const apps::mojom::IntentFilePtr& mojom_intent_file) { + if (!mojom_intent_file) { + return nullptr; + } + + auto intent_file = std::make_unique<IntentFile>(mojom_intent_file->url); + if (mojom_intent_file->mime_type.has_value()) { + intent_file->mime_type = mojom_intent_file->mime_type.value(); + } + if (mojom_intent_file->file_name.has_value()) { + intent_file->file_name = mojom_intent_file->file_name.value(); + } + intent_file->file_size = mojom_intent_file->file_size; + intent_file->is_directory = GetOptionalBool(mojom_intent_file->is_directory); + return intent_file; +} + +apps::mojom::IntentFilePtr ConvertIntentFileToMojomIntentFile( + const IntentFilePtr& intent_file) { + if (!intent_file) { + return nullptr; + } + + auto mojom_intent_file = apps::mojom::IntentFile::New(); + mojom_intent_file->url = intent_file->url; + if (intent_file->mime_type.has_value()) { + mojom_intent_file->mime_type = intent_file->mime_type.value(); + } + if (intent_file->file_name.has_value()) { + mojom_intent_file->file_name = intent_file->file_name.value(); + } + mojom_intent_file->file_size = intent_file->file_size; + mojom_intent_file->is_directory = + GetMojomOptionalBool(intent_file->is_directory); + return mojom_intent_file; +} + +IntentPtr ConvertMojomIntentToIntent( + const apps::mojom::IntentPtr& mojom_intent) { + if (!mojom_intent) { + return nullptr; + } + + auto intent = std::make_unique<Intent>(mojom_intent->action); + + if (mojom_intent->url.has_value()) { + intent->url = mojom_intent->url.value(); + } + if (mojom_intent->mime_type.has_value()) { + intent->mime_type = mojom_intent->mime_type.value(); + } + if (mojom_intent->files.has_value()) { + for (const auto& file : mojom_intent->files.value()) { + intent->files.push_back(ConvertMojomIntentFileToIntentFile(file)); + } + } + if (mojom_intent->activity_name.has_value()) { + intent->activity_name = mojom_intent->activity_name.value(); + } + if (mojom_intent->drive_share_url.has_value()) { + intent->drive_share_url = mojom_intent->drive_share_url.value(); + } + if (mojom_intent->share_text.has_value()) { + intent->share_text = mojom_intent->share_text.value(); + } + if (mojom_intent->share_title.has_value()) { + intent->share_title = mojom_intent->share_title.value(); + } + if (mojom_intent->start_type.has_value()) { + intent->start_type = mojom_intent->start_type.value(); + } + if (mojom_intent->categories.has_value()) { + for (const auto& category : mojom_intent->categories.value()) { + intent->categories.push_back(category); + } + } + if (mojom_intent->data.has_value()) { + intent->data = mojom_intent->data.value(); + } + intent->ui_bypassed = GetOptionalBool(mojom_intent->ui_bypassed); + if (mojom_intent->extras.has_value()) { + for (const auto& extra : mojom_intent->extras.value()) { + intent->extras[extra.first] = extra.second; + } + } + return intent; +} + +apps::mojom::IntentPtr ConvertIntentToMojomIntent(const IntentPtr& intent) { + if (!intent) { + return nullptr; + } + + auto mojom_intent = apps::mojom::Intent::New(); + mojom_intent->action = intent->action; + + if (intent->url.has_value()) { + mojom_intent->url = intent->url.value(); + } + if (intent->mime_type.has_value()) { + mojom_intent->mime_type = intent->mime_type.value(); + } + if (!intent->files.empty()) { + mojom_intent->files = std::vector<apps::mojom::IntentFilePtr>{}; + for (const auto& file : intent->files) { + mojom_intent->files->push_back(ConvertIntentFileToMojomIntentFile(file)); + } + } + if (intent->activity_name.has_value()) { + mojom_intent->activity_name = intent->activity_name.value(); + } + if (intent->drive_share_url.has_value()) { + mojom_intent->drive_share_url = intent->drive_share_url.value(); + } + if (intent->share_text.has_value()) { + mojom_intent->share_text = intent->share_text.value(); + } + if (intent->share_title.has_value()) { + mojom_intent->share_title = intent->share_title.value(); + } + if (intent->start_type.has_value()) { + mojom_intent->start_type = intent->start_type.value(); + } + if (!intent->categories.empty()) { + mojom_intent->categories = intent->categories; + } + if (intent->data.has_value()) { + mojom_intent->data = intent->data.value(); + } + mojom_intent->ui_bypassed = GetMojomOptionalBool(intent->ui_bypassed); + if (!intent->extras.empty()) { + mojom_intent->extras = intent->extras; + } + return mojom_intent; +} + +} // namespace apps
diff --git a/components/services/app_service/public/cpp/intent.h b/components/services/app_service/public/cpp/intent.h new file mode 100644 index 0000000..e61c64c --- /dev/null +++ b/components/services/app_service/public/cpp/intent.h
@@ -0,0 +1,105 @@ +// 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_SERVICES_APP_SERVICE_PUBLIC_CPP_INTENT_H_ +#define COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_INTENT_H_ + +#include <string> +#include <utility> +#include <vector> + +#include "base/containers/flat_map.h" +#include "base/files/safe_base_name.h" +#include "components/services/app_service/public/mojom/types.mojom.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/gurl.h" + +namespace apps { + +// Metadata for a single file shared through an intent. +struct IntentFile { + explicit IntentFile(const GURL& url); + IntentFile(const IntentFile&) = delete; + IntentFile& operator=(const IntentFile&) = delete; + ~IntentFile(); + + // The URL of the file to share. Normally has the filesystem: scheme, but + // could be externalfile: or a different scheme, depending on the source. + GURL url; + + // The following optional fields can be provided to supply additional metadata + // information in cases where fetching the metadata through the file would be + // difficult or expensive. + + // File MIME type. + absl::optional<std::string> mime_type; + // Human readable file name, including extension, and not allow absolute paths + // or references to parent directories. + absl::optional<base::SafeBaseName> file_name; + // File size in bytes. + uint64_t file_size = 0; + // Whether this is a directory or not. + absl::optional<bool> is_directory; +}; + +using IntentFilePtr = std::unique_ptr<IntentFile>; + +// Action and resource handling request. This should be kept in sync with +// ConvertIntentToValue and ConvertValueToIntent in +// components/services/app_service/public/cpp/intent_util.* +struct Intent { + explicit Intent(const std::string& action); + Intent(const Intent&) = delete; + Intent& operator=(const Intent&) = delete; + ~Intent(); + + // Intent action. e.g. view, send. + std::string action; + // The URL of the intent. e.g. https://www.google.com/. + absl::optional<GURL> url; + + // MIME type. e.g. text/plain, image/*. + absl::optional<std::string> mime_type; + + // The files to share. + std::vector<IntentFilePtr> files; + // The activity for the app to launch. + absl::optional<std::string> activity_name; + + // The Drive share URL, this is only filled if the intent contains a file + // from Google Drive. + absl::optional<GURL> drive_share_url; + // Text to share. e.g. Share link to other app. + absl::optional<std::string> share_text; + // Title for the share. + absl::optional<std::string> share_title; + // Start type. + absl::optional<std::string> start_type; + std::vector<std::string> categories; + // URI + absl::optional<std::string> data; + // Whether or not the user saw the UI. + absl::optional<bool> ui_bypassed; + // Optional string extras. + base::flat_map<std::string, std::string> extras; +}; + +using IntentPtr = std::unique_ptr<Intent>; + +// TODO(crbug.com/1253250): Remove these functions after migrating to non-mojo +// AppService. +IntentFilePtr ConvertMojomIntentFileToIntentFile( + const apps::mojom::IntentFilePtr& mojom_intent_file); + +apps::mojom::IntentFilePtr ConvertIntentFileToMojomIntentFile( + const IntentFilePtr& intent_file); + +IntentPtr ConvertMojomIntentToIntent( + const apps::mojom::IntentPtr& mojom_intent); + +apps::mojom::IntentPtr ConvertIntentToMojomIntent(const IntentPtr& intent); + +} // namespace apps + +#endif // COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_INTENT_H_
diff --git a/components/services/app_service/public/cpp/intent_util_unittest.cc b/components/services/app_service/public/cpp/intent_util_unittest.cc index af13bc96..0b097de0 100644 --- a/components/services/app_service/public/cpp/intent_util_unittest.cc +++ b/components/services/app_service/public/cpp/intent_util_unittest.cc
@@ -5,6 +5,7 @@ #include "components/services/app_service/public/cpp/intent_util.h" #include "base/values.h" +#include "components/services/app_service/public/cpp/intent.h" #include "components/services/app_service/public/cpp/intent_filter_util.h" #include "components/services/app_service/public/cpp/intent_test_util.h" #include "testing/gtest/include/gtest/gtest.h" @@ -870,3 +871,56 @@ apps_util::CreateFileFilterForView("inode/directory", "", kLabel); EXPECT_FALSE(apps_util::IsGenericFileHandler(intent3, filter12)); } + +// TODO(crbug.com/1253250): Remove after migrating to non-mojo AppService. +TEST_F(IntentUtilTest, MojomConvert) { + const std::string action = apps_util::kIntentActionSend; + GURL test_url1 = GURL("https://www.google.com/"); + GURL test_url2 = GURL("https://www.abc.com/"); + GURL test_url3 = GURL("https://www.foo.com/"); + const std::string mime_type = "image/jpeg"; + const std::string activity_name = "test"; + const std::string share_text = "share text"; + const std::string share_title = "share title"; + const std::string start_type = "start type"; + const std::string category1 = "category1"; + const std::string data = "data"; + const apps::mojom::OptionalBool ui_bypassed = + apps::mojom::OptionalBool::kTrue; + base::flat_map<std::string, std::string> extras = { + {"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}}; + + auto file1 = apps::mojom::IntentFile::New(); + file1->url = test_url1; + auto file2 = apps::mojom::IntentFile::New(); + file2->url = test_url2; + auto files = std::vector<apps::mojom::IntentFilePtr>(); + files.push_back(std::move(file1)); + files.push_back(std::move(file2)); + + auto src_intent = + CreateIntent(action, test_url1, mime_type, std::move(files), + activity_name, test_url3, share_text, share_title, + start_type, {category1}, data, ui_bypassed, extras); + auto dst_intent = apps::ConvertIntentToMojomIntent( + apps::ConvertMojomIntentToIntent(src_intent)); + + EXPECT_EQ(action, dst_intent->action); + EXPECT_EQ(test_url1, dst_intent->url.value()); + EXPECT_EQ(mime_type, dst_intent->mime_type.value()); + EXPECT_EQ(2u, dst_intent->files->size()); + EXPECT_EQ(test_url1, dst_intent->files.value()[0]->url); + EXPECT_EQ(test_url2, dst_intent->files.value()[1]->url); + EXPECT_EQ(activity_name, dst_intent->activity_name.value()); + EXPECT_EQ(test_url3, dst_intent->drive_share_url.value()); + EXPECT_EQ(share_text, dst_intent->share_text.value()); + EXPECT_EQ(share_title, dst_intent->share_title.value()); + EXPECT_EQ(start_type, dst_intent->start_type.value()); + EXPECT_EQ(1u, dst_intent->categories->size()); + EXPECT_EQ(category1, dst_intent->categories.value()[0]); + EXPECT_EQ(data, dst_intent->data.value()); + EXPECT_EQ(ui_bypassed, dst_intent->ui_bypassed); + EXPECT_TRUE(dst_intent->extras.has_value()); + EXPECT_EQ(3u, dst_intent->extras->size()); + EXPECT_EQ(extras, dst_intent->extras.value()); +}
diff --git a/components/services/app_service/public/mojom/types.mojom b/components/services/app_service/public/mojom/types.mojom index b759fceb..7783e70 100644 --- a/components/services/app_service/public/mojom/types.mojom +++ b/components/services/app_service/public/mojom/types.mojom
@@ -423,6 +423,8 @@ }; // Metadata for a single file shared through an intent. +// Mojom IntentFile struct is DEPRECATED. When adding new fields, please use +// the IntentFile struct in components/services/app_service/public/cpp/intent.h. struct IntentFile { // The URL of the file to share. Normally has the filesystem: scheme, but // could be externalfile: or a different scheme, depending on the source. @@ -445,6 +447,8 @@ // Action and resource handling request. This should // be kept in sync with ConvertIntentToValue and ConvertValueToIntent in // components/services/app_service/public/cpp/intent_util.* +// Mojom Intent struct is DEPRECATED. When adding new fields, please use +// the Intent struct in components/services/app_service/public/cpp/intent.h. struct Intent { string action; // Intent action. e.g. view, send. url.mojom.Url? url; // The URL of the intent. e.g. https://www.google.com/.
diff --git a/components/url_formatter/spoof_checks/top_domains/make_top_domain_list_variables.cc b/components/url_formatter/spoof_checks/top_domains/make_top_domain_list_variables.cc index a6a6438..8557d5e5 100644 --- a/components/url_formatter/spoof_checks/top_domains/make_top_domain_list_variables.cc +++ b/components/url_formatter/spoof_checks/top_domains/make_top_domain_list_variables.cc
@@ -21,6 +21,7 @@ #include <cctype> #include <iostream> +#include <set> #include <sstream> #include <string> #include <vector>
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index b1befbf..1eaf653 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -387,8 +387,8 @@ "attribution_reporting/aggregatable_histogram_contribution.cc", "attribution_reporting/aggregatable_histogram_contribution.h", "attribution_reporting/attribution_aggregatable_key.h", - "attribution_reporting/attribution_aggregatable_sources.cc", - "attribution_reporting/attribution_aggregatable_sources.h", + "attribution_reporting/attribution_aggregatable_source.cc", + "attribution_reporting/attribution_aggregatable_source.h", "attribution_reporting/attribution_aggregatable_trigger.cc", "attribution_reporting/attribution_aggregatable_trigger.h", "attribution_reporting/attribution_cookie_checker.h",
diff --git a/content/browser/aggregation_service/aggregatable_report.cc b/content/browser/aggregation_service/aggregatable_report.cc index 8a9e37b..65ddd1a2 100644 --- a/content/browser/aggregation_service/aggregatable_report.cc +++ b/content/browser/aggregation_service/aggregatable_report.cc
@@ -56,8 +56,7 @@ case AggregationServicePayloadContents::AggregationMode:: kExperimentalPoplar: // TODO(crbug.com/1295705): Update default processing urls. - return {GURL("https://server1.example.com"), - GURL("https://server2.example.com")}; + return {GURL("https://server1.example"), GURL("https://server2.example")}; } }
diff --git a/content/browser/aggregation_service/aggregatable_report_assembler_unittest.cc b/content/browser/aggregation_service/aggregatable_report_assembler_unittest.cc index 1fc2ce5..412e2cd 100644 --- a/content/browser/aggregation_service/aggregatable_report_assembler_unittest.cc +++ b/content/browser/aggregation_service/aggregatable_report_assembler_unittest.cc
@@ -113,8 +113,8 @@ TEST_F(AggregatableReportAssemblerTest, BothKeyFetchesFail_ErrorReturned) { base::HistogramTester histograms; - AggregatableReportRequest request = - aggregation_service::CreateExampleRequest(); + AggregatableReportRequest request = aggregation_service::CreateExampleRequest( + AggregationServicePayloadContents::AggregationMode::kExperimentalPoplar); std::vector<GURL> processing_urls = request.processing_urls(); EXPECT_CALL(*fetcher(), GetPublicKey(processing_urls[0], _)) @@ -139,8 +139,8 @@ TEST_F(AggregatableReportAssemblerTest, FirstKeyFetchFails_ErrorReturned) { base::HistogramTester histograms; - AggregatableReportRequest request = - aggregation_service::CreateExampleRequest(); + AggregatableReportRequest request = aggregation_service::CreateExampleRequest( + AggregationServicePayloadContents::AggregationMode::kExperimentalPoplar); std::vector<GURL> processing_urls = request.processing_urls(); EXPECT_CALL(*fetcher(), GetPublicKey(processing_urls[0], _)) @@ -166,8 +166,8 @@ TEST_F(AggregatableReportAssemblerTest, SecondKeyFetchFails_ErrorReturned) { base::HistogramTester histograms; - AggregatableReportRequest request = - aggregation_service::CreateExampleRequest(); + AggregatableReportRequest request = aggregation_service::CreateExampleRequest( + AggregationServicePayloadContents::AggregationMode::kExperimentalPoplar); std::vector<GURL> processing_urls = request.processing_urls(); EXPECT_CALL(*fetcher(), GetPublicKey(processing_urls[0], _)) @@ -194,8 +194,8 @@ BothKeyFetchesSucceed_ValidReportReturned) { base::HistogramTester histograms; - AggregatableReportRequest request = - aggregation_service::CreateExampleRequest(); + AggregatableReportRequest request = aggregation_service::CreateExampleRequest( + AggregationServicePayloadContents::AggregationMode::kExperimentalPoplar); std::vector<GURL> processing_urls = request.processing_urls(); std::vector<PublicKey> public_keys = { @@ -233,7 +233,7 @@ } TEST_F(AggregatableReportAssemblerTest, - SingleServerKeyFetchSucceeds_ValidReportReturned) { + OnlyKeyFetchSucceeds_ValidReportReturned) { base::HistogramTester histograms; AggregatableReportRequest request = aggregation_service::CreateExampleRequest( @@ -268,8 +268,7 @@ AggregatableReportAssembler::AssemblyStatus::kOk, 1); } -TEST_F(AggregatableReportAssemblerTest, - SingleServerKeyFetchFails_ErrorReturned) { +TEST_F(AggregatableReportAssemblerTest, OnlyKeyFetchFails_ErrorReturned) { base::HistogramTester histograms; AggregatableReportRequest request = aggregation_service::CreateExampleRequest( @@ -292,11 +291,11 @@ } TEST_F(AggregatableReportAssemblerTest, - KeyFetchesReturnInSwappedOrder_ValidReportReturned) { + TwoKeyFetchesReturnInSwappedOrder_ValidReportReturned) { base::HistogramTester histograms; - AggregatableReportRequest request = - aggregation_service::CreateExampleRequest(); + AggregatableReportRequest request = aggregation_service::CreateExampleRequest( + AggregationServicePayloadContents::AggregationMode::kExperimentalPoplar); std::vector<GURL> processing_urls = request.processing_urls(); std::vector<PublicKey> public_keys = { @@ -344,6 +343,7 @@ std::vector<GURL> processing_urls = request.processing_urls(); EXPECT_CALL(callback(), Run).Times(0); + EXPECT_CALL(*fetcher(), GetPublicKey); assembler()->AssembleReport(std::move(request), callback().Get()); ResetAssembler(); @@ -359,31 +359,24 @@ aggregation_service::CreateExampleRequest(); std::vector<GURL> processing_urls = request.processing_urls(); - std::vector<PublicKey> public_keys = { - aggregation_service::GenerateKey("id123").public_key, - aggregation_service::GenerateKey("456abc").public_key}; + PublicKey public_key = aggregation_service::GenerateKey("id123").public_key; absl::optional<AggregatableReport> report = AggregatableReport::Provider().CreateFromRequestAndPublicKeys( - aggregation_service::CloneReportRequest(request), public_keys); + aggregation_service::CloneReportRequest(request), {public_key}); ASSERT_TRUE(report.has_value()); - std::vector<FetchCallback> pending_callbacks_1(2); + std::vector<FetchCallback> pending_callbacks(2); EXPECT_CALL(*fetcher(), GetPublicKey(processing_urls[0], _)) - .WillOnce(MoveArg<1>(&pending_callbacks_1.front())) - .WillOnce(MoveArg<1>(&pending_callbacks_1.back())); - - std::vector<FetchCallback> pending_callbacks_2(2); - EXPECT_CALL(*fetcher(), GetPublicKey(processing_urls[1], _)) - .WillOnce(MoveArg<1>(&pending_callbacks_2.front())) - .WillOnce(MoveArg<1>(&pending_callbacks_2.back())); + .WillOnce(MoveArg<1>(&pending_callbacks.front())) + .WillOnce(MoveArg<1>(&pending_callbacks.back())); EXPECT_CALL(callback(), Run(report, AssemblyStatus::kOk)).Times(2); absl::optional<AggregatableReportRequest> first_request; absl::optional<AggregatableReportRequest> second_request; - EXPECT_CALL(*report_provider(), - CreateFromRequestAndPublicKeys(_, public_keys)) + EXPECT_CALL(*report_provider(), CreateFromRequestAndPublicKeys( + _, std::vector<PublicKey>{public_key})) .WillOnce(MoveRequestAndReturnReport(&first_request, report.value())) .WillOnce(MoveRequestAndReturnReport(&second_request, std::move(report.value()))); @@ -393,15 +386,10 @@ assembler()->AssembleReport(aggregation_service::CloneReportRequest(request), callback().Get()); - std::move(pending_callbacks_1.front()) - .Run(public_keys[0], PublicKeyFetchStatus::kOk); - std::move(pending_callbacks_1.back()) - .Run(public_keys[0], PublicKeyFetchStatus::kOk); - - std::move(pending_callbacks_2.front()) - .Run(public_keys[1], PublicKeyFetchStatus::kOk); - std::move(pending_callbacks_2.back()) - .Run(public_keys[1], PublicKeyFetchStatus::kOk); + std::move(pending_callbacks.front()) + .Run(public_key, PublicKeyFetchStatus::kOk); + std::move(pending_callbacks.back()) + .Run(public_key, PublicKeyFetchStatus::kOk); ASSERT_TRUE(first_request.has_value()); EXPECT_TRUE( @@ -419,12 +407,10 @@ TooManySimultaneousRequests_ErrorCausedForNewRequests) { base::HistogramTester histograms; - std::vector<PublicKey> public_keys = { - aggregation_service::GenerateKey("id123").public_key, - aggregation_service::GenerateKey("456abc").public_key}; + PublicKey public_key = aggregation_service::GenerateKey("id123").public_key; absl::optional<AggregatableReport> report = AggregatableReport::Provider().CreateFromRequestAndPublicKeys( - aggregation_service::CreateExampleRequest(), std::move(public_keys)); + aggregation_service::CreateExampleRequest(), {std::move(public_key)}); ASSERT_TRUE(report.has_value()); std::vector<FetchCallback> pending_callbacks; @@ -437,7 +423,7 @@ int current_check = 1; EXPECT_CALL(*fetcher(), GetPublicKey) - .Times(2 * AggregatableReportAssembler::kMaxSimultaneousRequests) + .Times(AggregatableReportAssembler::kMaxSimultaneousRequests) .WillRepeatedly(Invoke([&](const GURL& url, FetchCallback callback) { pending_callbacks.push_back(std::move(callback)); })); @@ -474,12 +460,10 @@ checkpoint.Call(current_call++); - for (size_t i = 0; i < pending_callbacks.size(); ++i) { - // Every request has 2 pending fetch callbacks. - if (i % 2 == 0) - checkpoint.Call(current_call++); + for (FetchCallback& pending_callback : pending_callbacks) { + checkpoint.Call(current_call++); - std::move(pending_callbacks[i]) + std::move(pending_callback) .Run(aggregation_service::GenerateKey("id123").public_key, PublicKeyFetchStatus::kOk); }
diff --git a/content/browser/aggregation_service/aggregatable_report_unittest.cc b/content/browser/aggregation_service/aggregatable_report_unittest.cc index a2b432b..8327263 100644 --- a/content/browser/aggregation_service/aggregatable_report_unittest.cc +++ b/content/browser/aggregation_service/aggregatable_report_unittest.cc
@@ -191,9 +191,10 @@ } } -TEST(AggregatableReportTest, ValidTwoPartyRequest_ValidReportReturned) { - AggregatableReportRequest request = - aggregation_service::CreateExampleRequest(); +TEST(AggregatableReportTest, + ValidExperimentalPoplarRequest_ValidReportReturned) { + AggregatableReportRequest request = aggregation_service::CreateExampleRequest( + AggregationServicePayloadContents::AggregationMode::kExperimentalPoplar); AggregationServicePayloadContents expected_payload_contents = request.payload_contents(); @@ -213,7 +214,7 @@ expected_num_processing_urls, hpke_keys)); } -TEST(AggregatableReportTest, ValidSingleServerRequest_ValidReportReturned) { +TEST(AggregatableReportTest, ValidTeeBasedRequest_ValidReportReturned) { AggregatableReportRequest request = aggregation_service::CreateExampleRequest( AggregationServicePayloadContents::AggregationMode::kTeeBased); @@ -284,18 +285,16 @@ request->payload_contents(); size_t expected_num_processing_urls = request->processing_urls().size(); - std::vector<aggregation_service::TestHpkeKey> hpke_keys = { - aggregation_service::GenerateKey("id123"), - aggregation_service::GenerateKey("456abc")}; + aggregation_service::TestHpkeKey hpke_key = + aggregation_service::GenerateKey("id123"); absl::optional<AggregatableReport> report = AggregatableReport::Provider().CreateFromRequestAndPublicKeys( - std::move(request.value()), - {hpke_keys[0].public_key, hpke_keys[1].public_key}); + std::move(request.value()), {hpke_key.public_key}); ASSERT_NO_FATAL_FAILURE( VerifyReport(report, expected_payload_contents, expected_shared_info, - expected_num_processing_urls, hpke_keys)); + expected_num_processing_urls, {hpke_key})); } TEST(AggregatableReportTest, @@ -351,8 +350,7 @@ TEST(AggregatableReportTest, RequestCreatedWithZeroContributions) { AggregatableReportRequest example_request = - aggregation_service::CreateExampleRequest( - AggregationServicePayloadContents::AggregationMode::kTeeBased); + aggregation_service::CreateExampleRequest(); AggregationServicePayloadContents payload_contents = example_request.payload_contents();
diff --git a/content/browser/aggregation_service/aggregation_service_features.cc b/content/browser/aggregation_service/aggregation_service_features.cc index 811d703..c332ed5 100644 --- a/content/browser/aggregation_service/aggregation_service_features.cc +++ b/content/browser/aggregation_service/aggregation_service_features.cc
@@ -13,6 +13,6 @@ const base::FeatureParam<std::string> kPrivacySandboxAggregationServiceTrustedServerUrlParam{ &kPrivacySandboxAggregationService, "trusted_server_url", - "https://server.example.com/.well-known/aggregation-service/keys.json"}; + "https://server.example/.well-known/aggregation-service/keys.json"}; } // namespace content
diff --git a/content/browser/aggregation_service/aggregation_service_impl_unittest.cc b/content/browser/aggregation_service/aggregation_service_impl_unittest.cc index c69f2ce..0206bda 100644 --- a/content/browser/aggregation_service/aggregation_service_impl_unittest.cc +++ b/content/browser/aggregation_service/aggregation_service_impl_unittest.cc
@@ -170,9 +170,6 @@ payloads.emplace_back(/*payload=*/kABCD1234AsBytes, /*key_id=*/"key_1", /*debug_cleartext_payload=*/absl::nullopt); - payloads.emplace_back(/*payload=*/kEFGH5678AsBytes, - /*key_id=*/"key_2", - /*debug_cleartext_payload=*/absl::nullopt); AggregatableReport report(std::move(payloads), "example_shared_info"); assembler()->TriggerResponse( @@ -206,9 +203,6 @@ payloads.emplace_back(/*payload=*/kABCD1234AsBytes, /*key_id=*/"key_1", /*debug_cleartext_payload=*/absl::nullopt); - payloads.emplace_back(/*payload=*/kEFGH5678AsBytes, - /*key_id=*/"key_2", - /*debug_cleartext_payload=*/absl::nullopt); AggregatableReport report(std::move(payloads), "example_shared_info");
diff --git a/content/browser/aggregation_service/aggregation_service_test_utils.h b/content/browser/aggregation_service/aggregation_service_test_utils.h index f9e8ffa..0a7039f 100644 --- a/content/browser/aggregation_service/aggregation_service_test_utils.h +++ b/content/browser/aggregation_service/aggregation_service_test_utils.h
@@ -55,11 +55,9 @@ const AggregatableReportSharedInfo& actual); // Returns an example report request, using the given parameters. -// TODO(crbug.com/1303041): Switch default aggregation mode to `kDefault`. AggregatableReportRequest CreateExampleRequest( AggregationServicePayloadContents::AggregationMode aggregation_mode = - AggregationServicePayloadContents::AggregationMode:: - kExperimentalPoplar); + AggregationServicePayloadContents::AggregationMode::kDefault); AggregatableReportRequest CloneReportRequest( const AggregatableReportRequest& request);
diff --git a/content/browser/attribution_reporting/aggregatable_attribution_utils.cc b/content/browser/attribution_reporting/aggregatable_attribution_utils.cc index cae8ac4..18dcd897 100644 --- a/content/browser/attribution_reporting/aggregatable_attribution_utils.cc +++ b/content/browser/attribution_reporting/aggregatable_attribution_utils.cc
@@ -11,7 +11,7 @@ #include "base/check.h" #include "base/containers/flat_map.h" #include "content/browser/attribution_reporting/aggregatable_histogram_contribution.h" -#include "content/browser/attribution_reporting/attribution_aggregatable_sources.h" +#include "content/browser/attribution_reporting/attribution_aggregatable_source.h" #include "content/browser/attribution_reporting/attribution_aggregatable_trigger.h" #include "content/browser/attribution_reporting/attribution_filter_data.h" #include "content/browser/attribution_reporting/attribution_utils.h" @@ -22,14 +22,14 @@ std::vector<AggregatableHistogramContribution> CreateAggregatableHistogram( const AttributionFilterData& source_filter_data, - const AttributionAggregatableSources& sources, + const AttributionAggregatableSource& source, const AttributionAggregatableTrigger& trigger) { // TODO(linnan): Log metrics for early returns. // Pairs of key id and bucket key. std::vector<std::pair<std::string, absl::uint128>> buckets; - buckets.reserve(sources.proto().sources().size()); - for (const auto& [key_id, key] : sources.proto().sources()) { + buckets.reserve(source.proto().keys().size()); + for (const auto& [key_id, key] : source.proto().keys()) { buckets.emplace_back(key_id, absl::MakeUint128(key.high_bits(), key.low_bits())); }
diff --git a/content/browser/attribution_reporting/aggregatable_attribution_utils.h b/content/browser/attribution_reporting/aggregatable_attribution_utils.h index 730781e..05da152 100644 --- a/content/browser/attribution_reporting/aggregatable_attribution_utils.h +++ b/content/browser/attribution_reporting/aggregatable_attribution_utils.h
@@ -12,14 +12,14 @@ namespace content { class AggregatableHistogramContribution; -class AttributionAggregatableSources; +class AttributionAggregatableSource; class AttributionAggregatableTrigger; class AttributionFilterData; // Creates histograms from the specified source and trigger data. CONTENT_EXPORT std::vector<AggregatableHistogramContribution> CreateAggregatableHistogram(const AttributionFilterData& source_filter_data, - const AttributionAggregatableSources& sources, + const AttributionAggregatableSource& source, const AttributionAggregatableTrigger& trigger); } // namespace content
diff --git a/content/browser/attribution_reporting/aggregatable_attribution_utils_unittest.cc b/content/browser/attribution_reporting/aggregatable_attribution_utils_unittest.cc index 7a75c7d..ac00c9f9 100644 --- a/content/browser/attribution_reporting/aggregatable_attribution_utils_unittest.cc +++ b/content/browser/attribution_reporting/aggregatable_attribution_utils_unittest.cc
@@ -9,7 +9,7 @@ #include <vector> #include "content/browser/attribution_reporting/aggregatable_histogram_contribution.h" -#include "content/browser/attribution_reporting/attribution_aggregatable_sources.h" +#include "content/browser/attribution_reporting/attribution_aggregatable_source.h" #include "content/browser/attribution_reporting/attribution_aggregatable_trigger.h" #include "content/browser/attribution_reporting/attribution_filter_data.h" #include "content/browser/attribution_reporting/attribution_reporting.pb.h" @@ -29,8 +29,8 @@ } // namespace TEST(AggregatableAttributionUtilsTest, CreateAggregatableHistogram) { - proto::AttributionAggregatableSources sources_proto = - AggregatableSourcesProtoBuilder() + proto::AttributionAggregatableSource source_proto = + AggregatableSourceProtoBuilder() .AddKey("key1", AggregatableKeyProtoBuilder() .SetHighBits(0) .SetLowBits(345) @@ -97,16 +97,16 @@ AttributionFilterData::FromSourceFilterValues({{"filter", {"value"}}}); ASSERT_TRUE(source_filter_data.has_value()); - absl::optional<AttributionAggregatableSources> sources = - AttributionAggregatableSources::Create(std::move(sources_proto)); - ASSERT_TRUE(sources.has_value()); + absl::optional<AttributionAggregatableSource> source = + AttributionAggregatableSource::Create(std::move(source_proto)); + ASSERT_TRUE(source.has_value()); absl::optional<AttributionAggregatableTrigger> trigger = AttributionAggregatableTrigger::FromMojo(std::move(trigger_mojo)); ASSERT_TRUE(trigger.has_value()); std::vector<AggregatableHistogramContribution> contributions = - CreateAggregatableHistogram(*source_filter_data, *sources, *trigger); + CreateAggregatableHistogram(*source_filter_data, *source, *trigger); // "key3" is not present as no value is found. EXPECT_THAT(
diff --git a/content/browser/attribution_reporting/attribution_aggregatable_source.cc b/content/browser/attribution_reporting/attribution_aggregatable_source.cc new file mode 100644 index 0000000..8d4e251 --- /dev/null +++ b/content/browser/attribution_reporting/attribution_aggregatable_source.cc
@@ -0,0 +1,52 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/attribution_reporting/attribution_aggregatable_source.h" + +#include <utility> + +#include "base/ranges/algorithm.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/attribution_reporting/constants.h" + +namespace content { + +// static +absl::optional<AttributionAggregatableSource> +AttributionAggregatableSource::Create( + proto::AttributionAggregatableSource proto) { + bool is_valid = + proto.keys().size() <= + blink::kMaxAttributionAggregatableKeysPerSourceOrTrigger && + base::ranges::all_of(proto.keys(), [](const auto& key) { + return key.first.size() <= + blink::kMaxBytesPerAttributionAggregatableKeyId && + key.second.has_high_bits() && key.second.has_low_bits(); + }); + return is_valid ? absl::make_optional( + AttributionAggregatableSource(std::move(proto))) + : absl::nullopt; +} + +AttributionAggregatableSource::AttributionAggregatableSource( + proto::AttributionAggregatableSource proto) + : proto_(std::move(proto)) {} + +AttributionAggregatableSource::AttributionAggregatableSource() = default; + +AttributionAggregatableSource::~AttributionAggregatableSource() = default; + +AttributionAggregatableSource::AttributionAggregatableSource( + const AttributionAggregatableSource&) = default; + +AttributionAggregatableSource::AttributionAggregatableSource( + AttributionAggregatableSource&&) = default; + +AttributionAggregatableSource& AttributionAggregatableSource::operator=( + const AttributionAggregatableSource&) = default; + +AttributionAggregatableSource& AttributionAggregatableSource::operator=( + AttributionAggregatableSource&&) = default; + +} // namespace content
diff --git a/content/browser/attribution_reporting/attribution_aggregatable_source.h b/content/browser/attribution_reporting/attribution_aggregatable_source.h new file mode 100644 index 0000000..3336f895 --- /dev/null +++ b/content/browser/attribution_reporting/attribution_aggregatable_source.h
@@ -0,0 +1,42 @@ +// 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_AGGREGATABLE_SOURCE_H_ +#define CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_AGGREGATABLE_SOURCE_H_ + +#include "content/browser/attribution_reporting/attribution_reporting.pb.h" +#include "content/common/content_export.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace content { + +// This is a wrapper of `proto::AttributionAggregatableSource`. +class CONTENT_EXPORT AttributionAggregatableSource { + public: + // Returns `absl::nullopt` if `proto` is invalid. + static absl::optional<AttributionAggregatableSource> Create( + proto::AttributionAggregatableSource proto); + + AttributionAggregatableSource(); + ~AttributionAggregatableSource(); + + AttributionAggregatableSource(const AttributionAggregatableSource&); + AttributionAggregatableSource(AttributionAggregatableSource&&); + + AttributionAggregatableSource& operator=( + const AttributionAggregatableSource&); + AttributionAggregatableSource& operator=(AttributionAggregatableSource&&); + + const proto::AttributionAggregatableSource& proto() const { return proto_; } + + private: + explicit AttributionAggregatableSource( + proto::AttributionAggregatableSource proto); + + proto::AttributionAggregatableSource proto_; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_AGGREGATABLE_SOURCE_H_
diff --git a/content/browser/attribution_reporting/attribution_aggregatable_sources.cc b/content/browser/attribution_reporting/attribution_aggregatable_sources.cc deleted file mode 100644 index fcc3930..0000000 --- a/content/browser/attribution_reporting/attribution_aggregatable_sources.cc +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright 2022 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/attribution_reporting/attribution_aggregatable_sources.h" - -#include <utility> - -#include "base/ranges/algorithm.h" -#include "third_party/abseil-cpp/absl/types/optional.h" -#include "third_party/blink/public/common/attribution_reporting/constants.h" - -namespace content { - -// static -absl::optional<AttributionAggregatableSources> -AttributionAggregatableSources::Create( - proto::AttributionAggregatableSources proto) { - bool is_valid = - proto.sources().size() <= - blink::kMaxAttributionAggregatableKeysPerSourceOrTrigger && - base::ranges::all_of(proto.sources(), [](const auto& source) { - return source.first.size() <= - blink::kMaxBytesPerAttributionAggregatableKeyId && - source.second.has_high_bits() && source.second.has_low_bits(); - }); - return is_valid ? absl::make_optional( - AttributionAggregatableSources(std::move(proto))) - : absl::nullopt; -} - -AttributionAggregatableSources::AttributionAggregatableSources( - proto::AttributionAggregatableSources proto) - : proto_(std::move(proto)) {} - -AttributionAggregatableSources::AttributionAggregatableSources() = default; - -AttributionAggregatableSources::~AttributionAggregatableSources() = default; - -AttributionAggregatableSources::AttributionAggregatableSources( - const AttributionAggregatableSources&) = default; - -AttributionAggregatableSources::AttributionAggregatableSources( - AttributionAggregatableSources&&) = default; - -AttributionAggregatableSources& AttributionAggregatableSources::operator=( - const AttributionAggregatableSources&) = default; - -AttributionAggregatableSources& AttributionAggregatableSources::operator=( - AttributionAggregatableSources&&) = default; - -} // namespace content
diff --git a/content/browser/attribution_reporting/attribution_aggregatable_sources.h b/content/browser/attribution_reporting/attribution_aggregatable_sources.h deleted file mode 100644 index 0c1005e..0000000 --- a/content/browser/attribution_reporting/attribution_aggregatable_sources.h +++ /dev/null
@@ -1,42 +0,0 @@ -// 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_AGGREGATABLE_SOURCES_H_ -#define CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_AGGREGATABLE_SOURCES_H_ - -#include "content/browser/attribution_reporting/attribution_reporting.pb.h" -#include "content/common/content_export.h" -#include "third_party/abseil-cpp/absl/types/optional.h" - -namespace content { - -// This is a wrapper of `proto::AttributionAggregatableSources`. -class CONTENT_EXPORT AttributionAggregatableSources { - public: - // Returns `absl::nullopt` if `proto` is invalid. - static absl::optional<AttributionAggregatableSources> Create( - proto::AttributionAggregatableSources proto); - - AttributionAggregatableSources(); - ~AttributionAggregatableSources(); - - AttributionAggregatableSources(const AttributionAggregatableSources&); - AttributionAggregatableSources(AttributionAggregatableSources&&); - - AttributionAggregatableSources& operator=( - const AttributionAggregatableSources&); - AttributionAggregatableSources& operator=(AttributionAggregatableSources&&); - - const proto::AttributionAggregatableSources& proto() const { return proto_; } - - private: - explicit AttributionAggregatableSources( - proto::AttributionAggregatableSources proto); - - proto::AttributionAggregatableSources proto_; -}; - -} // namespace content - -#endif // CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_AGGREGATABLE_SOURCES_H_
diff --git a/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc b/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc index ad5669a58e..06b6f1a 100644 --- a/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc +++ b/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc
@@ -10,7 +10,7 @@ #include "base/bind.h" #include "base/check.h" #include "base/time/time.h" -#include "content/browser/attribution_reporting/attribution_aggregatable_sources.h" +#include "content/browser/attribution_reporting/attribution_aggregatable_source.h" #include "content/browser/attribution_reporting/attribution_filter_data.h" #include "content/browser/attribution_reporting/attribution_host_utils.h" #include "content/browser/attribution_reporting/attribution_manager.h" @@ -32,17 +32,17 @@ namespace { -proto::AttributionAggregatableSources ConvertToProto( - const blink::mojom::AttributionAggregatableSources& aggregatable_sources) { - proto::AttributionAggregatableSources result; +proto::AttributionAggregatableSource ConvertToProto( + const blink::mojom::AttributionAggregatableSource& aggregatable_source) { + proto::AttributionAggregatableSource result; - for (const auto& [key_id, key_ptr] : aggregatable_sources.sources) { + for (const auto& [key_id, key_ptr] : aggregatable_source.keys) { DCHECK(key_ptr); proto::AttributionAggregatableKey key; key.set_high_bits(key_ptr->high_bits); key.set_low_bits(key_ptr->low_bits); - (*result.mutable_sources())[key_id] = std::move(key); + (*result.mutable_keys())[key_id] = std::move(key); } return result; @@ -117,10 +117,10 @@ if (!filter_data.has_value()) return; - absl::optional<AttributionAggregatableSources> aggregatable_sources = - AttributionAggregatableSources::Create( - ConvertToProto(*data->aggregatable_sources)); - if (!aggregatable_sources.has_value()) + absl::optional<AttributionAggregatableSource> aggregatable_source = + AttributionAggregatableSource::Create( + ConvertToProto(*data->aggregatable_source)); + if (!aggregatable_source.has_value()) return; StorableSource storable_source(CommonSourceInfo( @@ -131,7 +131,7 @@ context.source_type, data->priority, std::move(*filter_data), data->debug_key ? absl::make_optional(data->debug_key->value) : absl::nullopt, - std::move(*aggregatable_sources))); + std::move(*aggregatable_source))); attribution_manager_->HandleSource(std::move(storable_source)); }
diff --git a/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc b/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc index e2fe187..51e88d27 100644 --- a/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc +++ b/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc
@@ -14,7 +14,7 @@ #include "base/containers/flat_map.h" #include "base/strings/string_number_conversions.h" #include "base/test/metrics/histogram_tester.h" -#include "content/browser/attribution_reporting/attribution_aggregatable_sources.h" +#include "content/browser/attribution_reporting/attribution_aggregatable_source.h" #include "content/browser/attribution_reporting/attribution_manager.h" #include "content/browser/attribution_reporting/attribution_source_type.h" #include "content/browser/attribution_reporting/attribution_test_utils.h" @@ -80,8 +80,8 @@ SourceEventIdIs(10), ConversionOriginIs(destination_origin), ImpressionOriginIs(page_origin), SourcePriorityIs(20), SourceDebugKeyIs(789), - AggregatableSourcesAre(AttributionAggregatableSources::Create( - AggregatableSourcesProtoBuilder() + AggregatableSourceAre(AttributionAggregatableSource::Create( + AggregatableSourceProtoBuilder() .AddKey("key", AggregatableKeyProtoBuilder() .SetHighBits(5) .SetLowBits(345) @@ -99,8 +99,8 @@ source_data->priority = 20; source_data->debug_key = blink::mojom::AttributionDebugKey::New(789); source_data->filter_data = blink::mojom::AttributionFilterData::New(); - source_data->aggregatable_sources = - AggregatableSourcesMojoBuilder() + source_data->aggregatable_source = + AggregatableSourceMojoBuilder() .AddKey(/*key_id=*/"key", blink::mojom::AttributionAggregatableKey::New( /*high_bits=*/5, /*low_bits=*/345)) @@ -162,8 +162,8 @@ source_data->reporting_origin = url::Origin::Create(GURL(test_case.reporting_origin)); source_data->filter_data = blink::mojom::AttributionFilterData::New(); - source_data->aggregatable_sources = - blink::mojom::AttributionAggregatableSources::New(); + source_data->aggregatable_source = + blink::mojom::AttributionAggregatableSource::New(); data_host_remote->SourceDataAvailable(std::move(source_data)); data_host_remote.FlushForTesting(); @@ -189,8 +189,8 @@ url::Origin::Create(GURL("https://reporter.example")); source_data->filter_data = blink::mojom::AttributionFilterData::New(test_case.AsMap()); - source_data->aggregatable_sources = - blink::mojom::AttributionAggregatableSources::New(); + source_data->aggregatable_source = + blink::mojom::AttributionAggregatableSource::New(); data_host_remote->SourceDataAvailable(std::move(source_data)); data_host_remote.FlushForTesting(); @@ -233,8 +233,8 @@ url::Origin::Create(GURL("https://reporter.example")); source_data->filter_data = blink::mojom::AttributionFilterData::New(test_case.filter_data); - source_data->aggregatable_sources = - blink::mojom::AttributionAggregatableSources::New(); + source_data->aggregatable_source = + blink::mojom::AttributionAggregatableSource::New(); data_host_remote->SourceDataAvailable(std::move(source_data)); data_host_remote.FlushForTesting(); @@ -270,8 +270,8 @@ source_data->destination = destination_origin; source_data->reporting_origin = reporting_origin; source_data->filter_data = blink::mojom::AttributionFilterData::New(); - source_data->aggregatable_sources = - blink::mojom::AttributionAggregatableSources::New(); + source_data->aggregatable_source = + blink::mojom::AttributionAggregatableSource::New(); data_host_remote->SourceDataAvailable(std::move(source_data)); data_host_remote.FlushForTesting(); @@ -307,8 +307,8 @@ source_data->destination = destination_origin; source_data->reporting_origin = reporting_origin; source_data->filter_data = blink::mojom::AttributionFilterData::New(); - source_data->aggregatable_sources = - blink::mojom::AttributionAggregatableSources::New(); + source_data->aggregatable_source = + blink::mojom::AttributionAggregatableSource::New(); data_host_remote->SourceDataAvailable(source_data.Clone()); data_host_remote.FlushForTesting(); @@ -330,16 +330,16 @@ } TEST_F(AttributionDataHostManagerImplTest, - SourceDataHost_AggregatableSourcesSizeCheckPerformed) { - struct AggregatableSourcesSizeTestCase { + SourceDataHost_AggregatableSourceizeCheckPerformed) { + struct AggregatableSourceizeTestCase { const char* description; bool valid; size_t key_count; size_t key_size; - blink::mojom::AttributionAggregatableSourcesPtr GetAggregatableSources() + blink::mojom::AttributionAggregatableSourcePtr GetAggregatableSource() const { - AggregatableSourcesMojoBuilder builder; + AggregatableSourceMojoBuilder builder; for (size_t i = 0u; i < key_count; ++i) { std::string key(key_size, 'A' + i); builder.AddKey(std::move(key), @@ -350,7 +350,7 @@ } }; - const AggregatableSourcesSizeTestCase kTestCases[] = { + const AggregatableSourceizeTestCase kTestCases[] = { {"empty", true, 0, 0}, {"max_keys", true, blink::kMaxAttributionAggregatableKeysPerSourceOrTrigger, 1}, @@ -378,7 +378,7 @@ source_data->reporting_origin = url::Origin::Create(GURL("https://reporter.example")); source_data->filter_data = blink::mojom::AttributionFilterData::New(); - source_data->aggregatable_sources = test_case.GetAggregatableSources(); + source_data->aggregatable_source = test_case.GetAggregatableSource(); data_host_remote->SourceDataAvailable(std::move(source_data)); data_host_remote.FlushForTesting(); @@ -728,8 +728,8 @@ source_data->destination = destination_origin; source_data->reporting_origin = reporting_origin; source_data->filter_data = blink::mojom::AttributionFilterData::New(); - source_data->aggregatable_sources = - blink::mojom::AttributionAggregatableSources::New(); + source_data->aggregatable_source = + blink::mojom::AttributionAggregatableSource::New(); data_host_remote->SourceDataAvailable(std::move(source_data)); data_host_remote.FlushForTesting(); @@ -768,8 +768,8 @@ source_data->destination = destination_origin; source_data->reporting_origin = reporting_origin; source_data->filter_data = blink::mojom::AttributionFilterData::New(); - source_data->aggregatable_sources = - blink::mojom::AttributionAggregatableSources::New(); + source_data->aggregatable_source = + blink::mojom::AttributionAggregatableSource::New(); data_host_remote->SourceDataAvailable(source_data.Clone()); data_host_remote.FlushForTesting();
diff --git a/content/browser/attribution_reporting/attribution_host_utils.cc b/content/browser/attribution_reporting/attribution_host_utils.cc index b829196..c61a7ba 100644 --- a/content/browser/attribution_reporting/attribution_host_utils.cc +++ b/content/browser/attribution_reporting/attribution_host_utils.cc
@@ -9,7 +9,7 @@ #include "base/strings/string_number_conversions.h" #include "base/time/time.h" -#include "content/browser/attribution_reporting/attribution_aggregatable_sources.h" +#include "content/browser/attribution_reporting/attribution_aggregatable_source.h" #include "content/browser/attribution_reporting/attribution_filter_data.h" #include "content/browser/attribution_reporting/attribution_manager.h" #include "content/browser/attribution_reporting/common_source_info.h" @@ -68,7 +68,7 @@ CommonSourceInfo::GetExpiryTime(impression.expiry, impression_time, source_type), source_type, impression.priority, AttributionFilterData(), - /*debug_key=*/absl::nullopt, AttributionAggregatableSources())); + /*debug_key=*/absl::nullopt, AttributionAggregatableSource())); // TODO(apaseltiner): It would be nice to be able to report an issue in // DevTools in the event that a debug key is present but the corresponding
diff --git a/content/browser/attribution_reporting/attribution_reporting.proto b/content/browser/attribution_reporting/attribution_reporting.proto index 1a74fd5..93dbd76 100644 --- a/content/browser/attribution_reporting/attribution_reporting.proto +++ b/content/browser/attribution_reporting/attribution_reporting.proto
@@ -14,9 +14,9 @@ optional uint64 low_bits = 2; } -// Proto equivalent of `blink::mojom::AttributionAggregatableSources`. -message AttributionAggregatableSources { - map<string, AttributionAggregatableKey> sources = 1; +// Proto equivalent of `blink::mojom::AttributionAggregatableSource`. +message AttributionAggregatableSource { + map<string, AttributionAggregatableKey> keys = 1; } message AttributionFilterValues {
diff --git a/content/browser/attribution_reporting/attribution_src_browsertest.cc b/content/browser/attribution_reporting/attribution_src_browsertest.cc index 3a7cd68..4d89a6ab 100644 --- a/content/browser/attribution_reporting/attribution_src_browsertest.cc +++ b/content/browser/attribution_reporting/attribution_src_browsertest.cc
@@ -152,7 +152,7 @@ EXPECT_EQ(source_data.front()->expiry, absl::nullopt); EXPECT_FALSE(source_data.front()->debug_key); EXPECT_THAT(source_data.front()->filter_data->filter_values, IsEmpty()); - EXPECT_THAT(source_data.front()->aggregatable_sources->sources, IsEmpty()); + EXPECT_THAT(source_data.front()->aggregatable_source->keys, IsEmpty()); } // Ensure that basic source registration works with both the img attributionsrc @@ -205,7 +205,7 @@ IN_PROC_BROWSER_TEST_F( AttributionSrcBrowserTest, - AttributionSrcImg_SourceRegisteredWithAggregatableSources) { + AttributionSrcImg_SourceRegisteredWithAggregatableSource) { GURL page_url = https_server()->GetURL("b.test", "/page_with_impression_creator.html"); EXPECT_TRUE(NavigateToURL(web_contents(), page_url)); @@ -238,7 +238,7 @@ EXPECT_EQ(source_data.front()->expiry, absl::nullopt); EXPECT_FALSE(source_data.front()->debug_key); EXPECT_THAT( - source_data.front()->aggregatable_sources->sources, + source_data.front()->aggregatable_source->keys, UnorderedElementsAre( Pair("key1", Pointee(AllOf( @@ -683,7 +683,7 @@ } IN_PROC_BROWSER_TEST_F(AttributionSrcBrowserTest, - AttributionSrcImg_InvalidAggregatableSourcesDropped) { + AttributionSrcImg_InvalidAggregatableSourceDropped) { // Create a separate server as we cannot register a `ControllableHttpResponse` // after the server starts. auto https_server = std::make_unique<net::EmbeddedTestServer>( @@ -741,7 +741,7 @@ EXPECT_EQ(source_data.back()->source_event_id, 5UL); EXPECT_EQ(source_data.back()->destination, url::Origin::Create(GURL("https://d.test"))); - EXPECT_THAT(source_data.back()->aggregatable_sources->sources, SizeIs(2)); + EXPECT_THAT(source_data.back()->aggregatable_source->keys, SizeIs(2)); } class AttributionSrcPrerenderBrowserTest : public AttributionSrcBrowserTest {
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.cc b/content/browser/attribution_reporting/attribution_storage_sql.cc index 98a7d5eb..ea5155c 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql.cc +++ b/content/browser/attribution_reporting/attribution_storage_sql.cc
@@ -25,7 +25,7 @@ #include "base/ranges/algorithm.h" #include "base/time/time.h" #include "content/browser/attribution_reporting/aggregatable_histogram_contribution.h" -#include "content/browser/attribution_reporting/attribution_aggregatable_sources.h" +#include "content/browser/attribution_reporting/attribution_aggregatable_source.h" #include "content/browser/attribution_reporting/attribution_filter_data.h" #include "content/browser/attribution_reporting/attribution_info.h" #include "content/browser/attribution_reporting/attribution_observer_types.h" @@ -54,18 +54,18 @@ namespace content { // Version number of the database. -const int AttributionStorageSql::kCurrentVersionNumber = 31; +const int AttributionStorageSql::kCurrentVersionNumber = 32; // Earliest version which can use a |kCurrentVersionNumber| database // without failing. -const int AttributionStorageSql::kCompatibleVersionNumber = 31; +const int AttributionStorageSql::kCompatibleVersionNumber = 32; // Latest version of the database that cannot be upgraded to // |kCurrentVersionNumber| without razing the database. // // Note that all versions >=15 were introduced during the transitional state of // the Attribution Reporting API and can be removed when done. -const int AttributionStorageSql::kDeprecatedVersionNumber = 30; +const int AttributionStorageSql::kDeprecatedVersionNumber = 31; namespace { @@ -117,7 +117,7 @@ prefix "debug_key," \ prefix "num_conversions," \ prefix "aggregatable_budget_consumed," \ - prefix "aggregatable_sources," \ + prefix "aggregatable_source," \ prefix "filter_data," \ prefix "event_level_active," \ prefix "aggregatable_active" @@ -222,14 +222,13 @@ DeserializeUint64(statement.ColumnInt64(col))); } -absl::optional<AttributionAggregatableSources> ParseAggregatableSources( +absl::optional<AttributionAggregatableSource> ParseAggregatableSource( const std::string& str) { - proto::AttributionAggregatableSources aggregatable_sources; - if (!aggregatable_sources.ParseFromString(str)) + proto::AttributionAggregatableSource aggregatable_source; + if (!aggregatable_source.ParseFromString(str)) return absl::nullopt; - return AttributionAggregatableSources::Create( - std::move(aggregatable_sources)); + return AttributionAggregatableSource::Create(std::move(aggregatable_source)); } struct StoredSourceData { @@ -266,12 +265,12 @@ absl::optional<uint64_t> debug_key = ColumnUint64OrNull(statement, col++); int num_conversions = statement.ColumnInt(col++); int64_t aggregatable_budget_consumed = statement.ColumnInt64(col++); - absl::optional<AttributionAggregatableSources> aggregatable_sources = - ParseAggregatableSources(statement.ColumnString(col++)); + absl::optional<AttributionAggregatableSource> aggregatable_source = + ParseAggregatableSource(statement.ColumnString(col++)); if (!source_type.has_value() || !attribution_logic.has_value() || num_conversions < 0 || aggregatable_budget_consumed < 0 || - !aggregatable_sources.has_value()) { + !aggregatable_source.has_value()) { return absl::nullopt; } @@ -295,7 +294,7 @@ std::move(reporting_origin), impression_time, expiry_time, *source_type, priority, std::move(*filter_data), debug_key, - std::move(*aggregatable_sources)), + std::move(*aggregatable_source)), *attribution_logic, *active_state, source_id), .num_conversions = num_conversions, .aggregatable_budget_consumed = aggregatable_budget_consumed}; @@ -519,7 +518,7 @@ "reporting_origin,impression_time,expiry_time,source_type," "attributed_truthfully,priority,impression_site," "num_conversions,event_level_active,aggregatable_active,debug_key," - "aggregatable_budget_consumed,aggregatable_sources,filter_data)" + "aggregatable_budget_consumed,aggregatable_source,filter_data)" "VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,0,?,?)"; sql::Statement statement( db_->GetCachedStatement(SQL_FROM_HERE, kInsertImpressionSql)); @@ -546,7 +545,7 @@ DCHECK(active_state.has_value()); statement.BindBlob( - 15, common_info.aggregatable_sources().proto().SerializeAsString()); + 15, common_info.aggregatable_source().proto().SerializeAsString()); statement.BindBlob(16, common_info.filter_data().Serialize()); if (!statement.Run()) @@ -1926,7 +1925,7 @@ "impression_site TEXT NOT NULL," "debug_key INTEGER," "aggregatable_budget_consumed INTEGER NOT NULL," - "aggregatable_sources BLOB NOT NULL," + "aggregatable_source BLOB NOT NULL," "filter_data BLOB NOT NULL)"; if (!db_->Execute(kImpressionTableSql)) return false;
diff --git a/content/browser/attribution_reporting/attribution_storage_unittest.cc b/content/browser/attribution_reporting/attribution_storage_unittest.cc index 6d052b5..2b5810c4 100644 --- a/content/browser/attribution_reporting/attribution_storage_unittest.cc +++ b/content/browser/attribution_reporting/attribution_storage_unittest.cc
@@ -26,7 +26,7 @@ #include "base/time/time.h" #include "build/build_config.h" #include "content/browser/attribution_reporting/aggregatable_histogram_contribution.h" -#include "content/browser/attribution_reporting/attribution_aggregatable_sources.h" +#include "content/browser/attribution_reporting/attribution_aggregatable_source.h" #include "content/browser/attribution_reporting/attribution_filter_data.h" #include "content/browser/attribution_reporting/attribution_observer_types.h" #include "content/browser/attribution_reporting/attribution_report.h" @@ -1812,21 +1812,21 @@ TriggerDebugKeyIs(33)))); } -TEST_F(AttributionStorageTest, AttributionAggregatableSources_RoundTrips) { - proto::AttributionAggregatableSources proto = - AggregatableSourcesProtoBuilder() +TEST_F(AttributionStorageTest, AttributionAggregatableSource_RoundTrips) { + proto::AttributionAggregatableSource proto = + AggregatableSourceProtoBuilder() .AddKey("key", AggregatableKeyProtoBuilder() .SetHighBits(5) .SetLowBits(345) .Build()) .Build(); - absl::optional<AttributionAggregatableSources> aggregatable_sources = - AttributionAggregatableSources::Create(std::move(proto)); - EXPECT_TRUE(aggregatable_sources.has_value()); + absl::optional<AttributionAggregatableSource> aggregatable_source = + AttributionAggregatableSource::Create(std::move(proto)); + EXPECT_TRUE(aggregatable_source.has_value()); storage()->StoreSource( - SourceBuilder().SetAggregatableSources(*aggregatable_sources).Build()); + SourceBuilder().SetAggregatableSource(*aggregatable_source).Build()); EXPECT_THAT(storage()->GetActiveSources(), - ElementsAre(AggregatableSourcesAre(*aggregatable_sources))); + ElementsAre(AggregatableSourceAre(*aggregatable_source))); } TEST_F(AttributionStorageTest, MaybeCreateAndStoreReport_ReturnsNewReport) {
diff --git a/content/browser/attribution_reporting/attribution_test_utils.cc b/content/browser/attribution_reporting/attribution_test_utils.cc index ad48e18..f4679f92 100644 --- a/content/browser/attribution_reporting/attribution_test_utils.cc +++ b/content/browser/attribution_reporting/attribution_test_utils.cc
@@ -467,9 +467,9 @@ return *this; } -SourceBuilder& SourceBuilder::SetAggregatableSources( - AttributionAggregatableSources aggregatable_sources) { - aggregatable_sources_ = std::move(aggregatable_sources); +SourceBuilder& SourceBuilder::SetAggregatableSource( + AttributionAggregatableSource aggregatable_source) { + aggregatable_source_ = std::move(aggregatable_source); return *this; } @@ -478,7 +478,7 @@ source_event_id_, impression_origin_, conversion_origin_, reporting_origin_, impression_time_, /*expiry_time=*/impression_time_ + expiry_, source_type_, priority_, - filter_data_, debug_key_, aggregatable_sources_); + filter_data_, debug_key_, aggregatable_source_); } StorableSource SourceBuilder::Build() const { @@ -654,37 +654,36 @@ return key_; } -AggregatableSourcesProtoBuilder::AggregatableSourcesProtoBuilder() = default; +AggregatableSourceProtoBuilder::AggregatableSourceProtoBuilder() = default; -AggregatableSourcesProtoBuilder::~AggregatableSourcesProtoBuilder() = default; +AggregatableSourceProtoBuilder::~AggregatableSourceProtoBuilder() = default; -AggregatableSourcesProtoBuilder& AggregatableSourcesProtoBuilder::AddKey( +AggregatableSourceProtoBuilder& AggregatableSourceProtoBuilder::AddKey( std::string key_id, proto::AttributionAggregatableKey key) { - (*aggregatable_sources_.mutable_sources())[std::move(key_id)] = - std::move(key); + (*aggregatable_source_.mutable_keys())[std::move(key_id)] = std::move(key); return *this; } -proto::AttributionAggregatableSources AggregatableSourcesProtoBuilder::Build() +proto::AttributionAggregatableSource AggregatableSourceProtoBuilder::Build() const { - return aggregatable_sources_; + return aggregatable_source_; } -AggregatableSourcesMojoBuilder::AggregatableSourcesMojoBuilder() = default; +AggregatableSourceMojoBuilder::AggregatableSourceMojoBuilder() = default; -AggregatableSourcesMojoBuilder::~AggregatableSourcesMojoBuilder() = default; +AggregatableSourceMojoBuilder::~AggregatableSourceMojoBuilder() = default; -AggregatableSourcesMojoBuilder& AggregatableSourcesMojoBuilder::AddKey( +AggregatableSourceMojoBuilder& AggregatableSourceMojoBuilder::AddKey( std::string key_id, blink::mojom::AttributionAggregatableKeyPtr key) { - sources_.sources.emplace(std::move(key_id), std::move(key)); + aggregatable_source_.keys.emplace(std::move(key_id), std::move(key)); return *this; } -blink::mojom::AttributionAggregatableSourcesPtr -AggregatableSourcesMojoBuilder::Build() const { - return sources_.Clone(); +blink::mojom::AttributionAggregatableSourcePtr +AggregatableSourceMojoBuilder::Build() const { + return aggregatable_source_.Clone(); } bool operator==(const AttributionTrigger::EventTriggerData& a, @@ -716,7 +715,7 @@ source.reporting_origin(), source.impression_time(), source.expiry_time(), source.source_type(), source.priority(), source.filter_data(), - source.debug_key(), source.aggregatable_sources()); + source.debug_key(), source.aggregatable_source()); }; return tie(a) == tie(b); } @@ -980,8 +979,7 @@ << ",filter_data=" << source.filter_data() << ",debug_key=" << (source.debug_key() ? base::NumberToString(*source.debug_key()) : "null") - << ",aggregatable_sources=" << source.aggregatable_sources() - << "}"; + << ",aggregatable_source=" << source.aggregatable_source() << "}"; } std::ostream& operator<<(std::ostream& out, @@ -1142,14 +1140,14 @@ return tie(a) == tie(b); } -bool operator==(const AttributionAggregatableSources& a, - const AttributionAggregatableSources& b) { - if (a.sources().size() != b.sources().size()) +bool operator==(const AttributionAggregatableSource& a, + const AttributionAggregatableSource& b) { + if (a.keys().size() != b.keys().size()) return false; - return base::ranges::all_of(a.sources(), [&](const auto& source) { - auto iter = b.sources().find(source.first); - return iter != b.sources().end() && iter->second == source.second; + return base::ranges::all_of(a.keys(), [&](const auto& key) { + auto iter = b.keys().find(key.first); + return iter != b.keys().end() && iter->second == key.second; }); } @@ -1166,11 +1164,11 @@ std::ostream& operator<<( std::ostream& out, - const AttributionAggregatableSources& aggregatable_sources) { - out << "{sources=["; + const AttributionAggregatableSource& aggregatable_source) { + out << "{keys=["; const char* separator = ""; - for (const auto& [key_id, key] : aggregatable_sources.sources()) { + for (const auto& [key_id, key] : aggregatable_source.keys()) { out << separator << key_id << ":" << key; separator = ", "; } @@ -1179,15 +1177,15 @@ } // namespace proto -bool operator==(const AttributionAggregatableSources& a, - const AttributionAggregatableSources& b) { +bool operator==(const AttributionAggregatableSource& a, + const AttributionAggregatableSource& b) { return a.proto() == b.proto(); } std::ostream& operator<<( std::ostream& out, - const AttributionAggregatableSources& aggregatable_sources) { - return out << "{proto=" << aggregatable_sources.proto() << "}"; + const AttributionAggregatableSource& aggregatable_source) { + return out << "{proto=" << aggregatable_source.proto() << "}"; } EventTriggerDataMatcherConfig::~EventTriggerDataMatcherConfig() = default;
diff --git a/content/browser/attribution_reporting/attribution_test_utils.h b/content/browser/attribution_reporting/attribution_test_utils.h index 743e013d..2911cf1 100644 --- a/content/browser/attribution_reporting/attribution_test_utils.h +++ b/content/browser/attribution_reporting/attribution_test_utils.h
@@ -21,7 +21,7 @@ #include "base/task/sequenced_task_runner.h" #include "base/time/time.h" #include "content/browser/attribution_reporting/aggregatable_histogram_contribution.h" -#include "content/browser/attribution_reporting/attribution_aggregatable_sources.h" +#include "content/browser/attribution_reporting/attribution_aggregatable_source.h" #include "content/browser/attribution_reporting/attribution_data_host_manager.h" #include "content/browser/attribution_reporting/attribution_filter_data.h" #include "content/browser/attribution_reporting/attribution_host.h" @@ -362,8 +362,8 @@ SourceBuilder& SetDedupKeys(std::vector<uint64_t> dedup_keys); - SourceBuilder& SetAggregatableSources( - AttributionAggregatableSources aggregatable_sources); + SourceBuilder& SetAggregatableSource( + AttributionAggregatableSource aggregatable_source); StorableSource Build() const; @@ -389,7 +389,7 @@ // Ensure that we don't use uninitialized memory. StoredSource::Id source_id_{0}; std::vector<uint64_t> dedup_keys_; - AttributionAggregatableSources aggregatable_sources_; + AttributionAggregatableSource aggregatable_source_; }; // Returns a AttributionTrigger with default data which matches the default @@ -508,38 +508,37 @@ proto::AttributionAggregatableKey key_; }; -// Helper class to construct a `proto::AttributionAggregatableSources` for +// Helper class to construct a `proto::AttributionAggregatableSource` for // testing. -class AggregatableSourcesProtoBuilder { +class AggregatableSourceProtoBuilder { public: - AggregatableSourcesProtoBuilder(); - ~AggregatableSourcesProtoBuilder(); + AggregatableSourceProtoBuilder(); + ~AggregatableSourceProtoBuilder(); - AggregatableSourcesProtoBuilder& AddKey( - std::string key_id, - proto::AttributionAggregatableKey key); + AggregatableSourceProtoBuilder& AddKey(std::string key_id, + proto::AttributionAggregatableKey key); - proto::AttributionAggregatableSources Build() const; + proto::AttributionAggregatableSource Build() const; private: - proto::AttributionAggregatableSources aggregatable_sources_; + proto::AttributionAggregatableSource aggregatable_source_; }; -// Helper class to construct a `blink::mojom::AttributionAggregatableSources` +// Helper class to construct a `blink::mojom::AttributionAggregatableSource` // for testing. -class AggregatableSourcesMojoBuilder { +class AggregatableSourceMojoBuilder { public: - AggregatableSourcesMojoBuilder(); - ~AggregatableSourcesMojoBuilder(); + AggregatableSourceMojoBuilder(); + ~AggregatableSourceMojoBuilder(); - AggregatableSourcesMojoBuilder& AddKey( + AggregatableSourceMojoBuilder& AddKey( std::string key_id, blink::mojom::AttributionAggregatableKeyPtr key); - blink::mojom::AttributionAggregatableSourcesPtr Build() const; + blink::mojom::AttributionAggregatableSourcePtr Build() const; private: - blink::mojom::AttributionAggregatableSources sources_; + blink::mojom::AttributionAggregatableSource aggregatable_source_; }; bool operator==(const AttributionTrigger::EventTriggerData& a, @@ -636,12 +635,12 @@ std::ostream& operator<<(std::ostream& out, StorableSource::Result status); -bool operator==(const AttributionAggregatableSources& a, - const AttributionAggregatableSources& b); +bool operator==(const AttributionAggregatableSource& a, + const AttributionAggregatableSource& b); std::ostream& operator<<( std::ostream& out, - const AttributionAggregatableSources& aggregatable_sources); + const AttributionAggregatableSource& aggregatable_source); std::vector<AttributionReport> GetAttributionReportsForTesting( AttributionManagerImpl* manager, @@ -697,8 +696,8 @@ return ExplainMatchResult(matcher, arg.dedup_keys(), result_listener); } -MATCHER_P(AggregatableSourcesAre, matcher, "") { - return ExplainMatchResult(matcher, arg.common_info().aggregatable_sources(), +MATCHER_P(AggregatableSourceAre, matcher, "") { + return ExplainMatchResult(matcher, arg.common_info().aggregatable_source(), result_listener); }
diff --git a/content/browser/attribution_reporting/common_source_info.cc b/content/browser/attribution_reporting/common_source_info.cc index f01f42d..d5f32b05 100644 --- a/content/browser/attribution_reporting/common_source_info.cc +++ b/content/browser/attribution_reporting/common_source_info.cc
@@ -43,7 +43,7 @@ int64_t priority, AttributionFilterData filter_data, absl::optional<uint64_t> debug_key, - AttributionAggregatableSources aggregatable_sources) + AttributionAggregatableSource aggregatable_source) : source_event_id_(source_event_id), impression_origin_(std::move(impression_origin)), conversion_origin_(std::move(conversion_origin)), @@ -54,7 +54,7 @@ priority_(priority), filter_data_(std::move(filter_data)), debug_key_(debug_key), - aggregatable_sources_(std::move(aggregatable_sources)) { + aggregatable_source_(std::move(aggregatable_source)) { // 30 days is the max allowed expiry for an impression. DCHECK_GE(base::Days(30), expiry_time - impression_time); // The impression must expire strictly after it occurred.
diff --git a/content/browser/attribution_reporting/common_source_info.h b/content/browser/attribution_reporting/common_source_info.h index fafb82c..8b797c07 100644 --- a/content/browser/attribution_reporting/common_source_info.h +++ b/content/browser/attribution_reporting/common_source_info.h
@@ -8,7 +8,7 @@ #include <stdint.h> #include "base/time/time.h" -#include "content/browser/attribution_reporting/attribution_aggregatable_sources.h" +#include "content/browser/attribution_reporting/attribution_aggregatable_source.h" #include "content/browser/attribution_reporting/attribution_filter_data.h" #include "content/browser/attribution_reporting/attribution_source_type.h" #include "content/common/content_export.h" @@ -39,7 +39,7 @@ int64_t priority, AttributionFilterData filter_data, absl::optional<uint64_t> debug_key, - AttributionAggregatableSources aggregatable_sources); + AttributionAggregatableSource aggregatable_source); ~CommonSourceInfo(); @@ -69,8 +69,8 @@ absl::optional<uint64_t> debug_key() const { return debug_key_; } - const AttributionAggregatableSources& aggregatable_sources() const { - return aggregatable_sources_; + const AttributionAggregatableSource& aggregatable_source() const { + return aggregatable_source_; } void ClearDebugKey() { debug_key_ = absl::nullopt; } @@ -98,7 +98,7 @@ int64_t priority_; AttributionFilterData filter_data_; absl::optional<uint64_t> debug_key_; - AttributionAggregatableSources aggregatable_sources_; + AttributionAggregatableSource aggregatable_source_; // When adding new members, the corresponding `operator==()` definition in // `attribution_test_utils.h` should also be updated.
diff --git a/content/browser/bad_message.h b/content/browser/bad_message.h index b83fe4e..3a156c59 100644 --- a/content/browser/bad_message.h +++ b/content/browser/bad_message.h
@@ -293,6 +293,8 @@ BIBI_BIND_GAMEPAD_HAPTICS_MANAGER_FOR_FENCED_FRAME = 266, BIBI_BIND_BATTERY_MONITOR_FOR_FENCED_FRAME = 267, RFH_CREATE_FENCED_FRAME_IN_SANDBOXED_FRAME = 268, + RFH_UNLOAD_HANDLER_NOT_ALLOWED_IN_FENCED_FRAME = 269, + RFH_BEFOREUNLOAD_HANDLER_NOT_ALLOWED_IN_FENCED_FRAME = 270, // Please add new elements here. The naming convention is abbreviated class // name (e.g. RenderFrameHost becomes RFH) plus a unique description of the
diff --git a/content/browser/cache_storage/cache_storage_context_unittest.cc b/content/browser/cache_storage/cache_storage_context_unittest.cc index 562bd191..7f41427 100644 --- a/content/browser/cache_storage/cache_storage_context_unittest.cc +++ b/content/browser/cache_storage/cache_storage_context_unittest.cc
@@ -133,75 +133,4 @@ EXPECT_GT(result->id.value(), 0); } -TEST_F(CacheStorageContextTest, GetDefaultBucketError) { - // Disable database so it will return errors when getting the default bucket. - quota_manager_->SetDisableDatabase(true); - - mojo::Remote<blink::mojom::CacheStorage> example_remote; - AddReceiver( - example_remote.BindNewPipeAndPassReceiver(), - blink::StorageKey::CreateFromStringForTesting(kExampleStorageKey)); - - storage::QuotaManagerProxySync quota_manager_proxy_sync( - quota_manager_proxy()); - - // CacheStorage::Has - base::RunLoop loop_1; - example_remote->Has( - u"cache_name", /*trace_id=*/0, - base::BindLambdaForTesting([&](blink::mojom::CacheStorageError error) { - EXPECT_EQ(error, blink::mojom::CacheStorageError::kErrorStorage); - loop_1.Quit(); - })); - loop_1.Run(); - - // CacheStorage::Delete - base::RunLoop loop_2; - example_remote->Delete( - u"cache_name", /*trace_id=*/0, - base::BindLambdaForTesting([&](blink::mojom::CacheStorageError error) { - EXPECT_EQ(error, blink::mojom::CacheStorageError::kErrorStorage); - loop_2.Quit(); - })); - loop_2.Run(); - - // CacheStorage::Keys - base::RunLoop loop_3; - example_remote->Keys( - /*trace_id=*/0, - base::BindLambdaForTesting([&](const std::vector<std::u16string>& keys) { - EXPECT_EQ(keys, std::vector<std::u16string>()); - loop_3.Quit(); - })); - loop_3.Run(); - - // CacheStorage::Match - auto options = blink::mojom::MultiCacheQueryOptions::New(); - options->query_options = blink::mojom::CacheQueryOptions::New(); - options->cache_name = u"cache_name"; - - base::RunLoop loop_4; - example_remote->Match( - blink::mojom::FetchAPIRequest::New(), std::move(options), - /*in_related_fetch_event=*/false, /*in_range_fetch_event=*/false, - /*trace_id=*/0, - base::BindLambdaForTesting([&](blink::mojom::MatchResultPtr result) { - EXPECT_EQ(result->get_status(), - blink::mojom::CacheStorageError::kErrorStorage); - loop_4.Quit(); - })); - loop_4.Run(); - - // CacheStorage::Open - base::RunLoop loop_5; - example_remote->Open( - u"cache_name", /*trace_id=*/0, - base::BindLambdaForTesting([&](blink::mojom::OpenResultPtr result) { - EXPECT_EQ(result->get_status(), - blink::mojom::CacheStorageError::kErrorStorage); - loop_5.Quit(); - })); - loop_5.Run(); -} - } // namespace content
diff --git a/content/browser/cache_storage/cache_storage_dispatcher_host.cc b/content/browser/cache_storage/cache_storage_dispatcher_host.cc index 5aa0291..df28f37 100644 --- a/content/browser/cache_storage/cache_storage_dispatcher_host.cc +++ b/content/browser/cache_storage/cache_storage_dispatcher_host.cc
@@ -675,12 +675,6 @@ TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); - // Return error if failed to retrieve bucket from QuotaManager. - if (!bucket_.has_value()) { - std::move(callback).Run(std::vector<std::u16string>()); - return; - } - auto cb = base::BindOnce( [](base::TimeTicks start_time, int64_t trace_id, blink::mojom::CacheStorage::KeysCallback callback, @@ -739,13 +733,6 @@ }, base::TimeTicks::Now(), trace_id, std::move(callback)); - // Return error if failed to retrieve bucket from QuotaManager. - if (!bucket_.has_value()) { - std::move(cb).Run( - MakeErrorStorage(ErrorStorageType::kDefaultBucketError)); - return; - } - content::CacheStorage* cache_storage = GetOrCreateCacheStorage(); if (!cache_storage) { std::move(cb).Run(MakeErrorStorage(ErrorStorageType::kStorageHandleNull)); @@ -785,14 +772,6 @@ }, base::TimeTicks::Now(), trace_id, std::move(callback)); - // Return error if failed to retrieve bucket from QuotaManager. - if (!bucket_.has_value()) { - std::move(cb).Run( - /*has_cache=*/false, - MakeErrorStorage(ErrorStorageType::kDefaultBucketError)); - return; - } - content::CacheStorage* cache_storage = GetOrCreateCacheStorage(); if (!cache_storage) { std::move(cb).Run(/* has_cache = */ false, @@ -879,13 +858,6 @@ !match_options->cache_name, in_related_fetch_event, in_range_fetch_event, trace_id, std::move(callback)); - // Return error if failed to retrieve bucket from QuotaManager. - if (!bucket_.has_value()) { - std::move(cb).Run(MakeErrorStorage(ErrorStorageType::kDefaultBucketError), - nullptr); - return; - } - content::CacheStorage* cache_storage = GetOrCreateCacheStorage(); if (!cache_storage) { std::move(cb).Run(CacheStorageError::kErrorNotFound, nullptr); @@ -965,14 +937,6 @@ weak_factory_.GetWeakPtr(), base::TimeTicks::Now(), trace_id, std::move(callback)); - // Return error if failed to retrieve bucket from QuotaManager. - if (!bucket_.has_value()) { - std::move(cb).Run( - CacheStorageCacheHandle(), - MakeErrorStorage(ErrorStorageType::kDefaultBucketError)); - return; - } - if (!cache_storage) { std::move(cb).Run(CacheStorageCacheHandle(), MakeErrorStorage(ErrorStorageType::kStorageHandleNull));
diff --git a/content/browser/database_browsertest.cc b/content/browser/database_browsertest.cc index 698d9b6..abb23e1 100644 --- a/content/browser/database_browsertest.cc +++ b/content/browser/database_browsertest.cc
@@ -6,8 +6,6 @@ #include "base/strings/utf_string_conversions.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/download_manager.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" @@ -159,9 +157,7 @@ CreateTable(shell()); InsertRecord(shell(), "text"); - WindowedNotificationObserver load_stop_observer( - NOTIFICATION_LOAD_STOP, - NotificationService::AllSources()); + LoadStopObserver load_stop_observer(shell()->web_contents()); shell()->Reload(); load_stop_observer.Wait();
diff --git a/content/browser/fenced_frame/fenced_frame_browsertest.cc b/content/browser/fenced_frame/fenced_frame_browsertest.cc index bf46850..ea996a5 100644 --- a/content/browser/fenced_frame/fenced_frame_browsertest.cc +++ b/content/browser/fenced_frame/fenced_frame_browsertest.cc
@@ -989,6 +989,55 @@ } } +// Tests that an unload/beforeunload event handler won't be set from +// fenced frames. +IN_PROC_BROWSER_TEST_F(FencedFrameBrowserTest, UnloadHandler) { + ASSERT_TRUE(https_server()->Start()); + const GURL main_url = + https_server()->GetURL("c.test", "/fenced_frames/title1.html"); + EXPECT_TRUE( + NavigateToURL(shell(), https_server()->GetURL("c.test", "/title1.html"))); + RenderFrameHostImplWrapper primary_rfh(primary_main_frame_host()); + RenderFrameHostImplWrapper fenced_frame_rfh( + fenced_frame_test_helper().CreateFencedFrame(primary_rfh.get(), + main_url)); + + const char* kConsolePattern = + "unload/beforeunload handlers are prohibited in fenced frames."; + { + WebContentsConsoleObserver console_observer(web_contents()); + console_observer.SetPattern(kConsolePattern); + EXPECT_TRUE(ExecJs(fenced_frame_rfh.get(), + "window.addEventListener('beforeunload', (e) => {});")); + console_observer.Wait(); + EXPECT_EQ(1u, console_observer.messages().size()); + } + { + WebContentsConsoleObserver console_observer(web_contents()); + console_observer.SetPattern(kConsolePattern); + EXPECT_TRUE(ExecJs(fenced_frame_rfh.get(), + "window.addEventListener('unload', (e) => {});")); + console_observer.Wait(); + EXPECT_EQ(1u, console_observer.messages().size()); + } + { + WebContentsConsoleObserver console_observer(web_contents()); + console_observer.SetPattern(kConsolePattern); + EXPECT_TRUE(ExecJs(fenced_frame_rfh.get(), + "window.onbeforeunload = function(e){};")); + console_observer.Wait(); + EXPECT_EQ(1u, console_observer.messages().size()); + } + { + WebContentsConsoleObserver console_observer(web_contents()); + console_observer.SetPattern(kConsolePattern); + EXPECT_TRUE( + ExecJs(fenced_frame_rfh.get(), "window.onunload = function(e){};")); + console_observer.Wait(); + EXPECT_EQ(1u, console_observer.messages().size()); + } +} + INSTANTIATE_TEST_SUITE_P(FencedFrameNestedFrameBrowserTest, FencedFrameNestedFrameBrowserTest, testing::Combine(testing::ValuesIn(kTestParameters),
diff --git a/content/browser/indexed_db/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc index dbdd7912..9472e76 100644 --- a/content/browser/indexed_db/indexed_db_context_impl.cc +++ b/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -870,10 +870,8 @@ const blink::StorageKey& storage_key, mojo::PendingReceiver<blink::mojom::IDBFactory> receiver, storage::QuotaErrorOr<storage::BucketInfo> result) { - absl::optional<storage::BucketLocator> bucket = - result.ok() ? absl::make_optional(result->ToBucketLocator()) - : absl::nullopt; - dispatcher_host_.AddReceiver(storage_key, bucket, std::move(receiver)); + DCHECK(result.ok()); + dispatcher_host_.AddReceiver(storage_key, std::move(receiver)); } void IndexedDBContextImpl::ShutdownOnIDBSequence() {
diff --git a/content/browser/indexed_db/indexed_db_context_unittest.cc b/content/browser/indexed_db/indexed_db_context_unittest.cc index 4a2cffb0..2bf7954 100644 --- a/content/browser/indexed_db/indexed_db_context_unittest.cc +++ b/content/browser/indexed_db/indexed_db_context_unittest.cc
@@ -2,13 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <memory> - #include "base/barrier_closure.h" #include "base/files/scoped_temp_dir.h" #include "base/run_loop.h" -#include "base/test/bind.h" -#include "base/test/gmock_callback_support.h" #include "base/test/task_environment.h" #include "base/threading/thread.h" #include "base/time/default_clock.h" @@ -18,14 +14,11 @@ #include "content/browser/indexed_db/indexed_db_context_impl.h" #include "content/browser/indexed_db/indexed_db_factory_impl.h" #include "content/browser/indexed_db/mock_indexed_db_callbacks.h" -#include "content/browser/indexed_db/mock_mojo_indexed_db_callbacks.h" -#include "content/browser/indexed_db/mock_mojo_indexed_db_database_callbacks.h" #include "mojo/public/cpp/bindings/remote.h" #include "storage/browser/test/mock_quota_manager.h" #include "storage/browser/test/mock_quota_manager_proxy.h" #include "storage/browser/test/mock_special_storage_policy.h" #include "storage/browser/test/quota_manager_proxy_sync.h" -#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/storage_key/storage_key.h" @@ -117,84 +110,4 @@ EXPECT_GT(result->id.value(), 0); } -TEST_F(IndexedDBContextTest, GetDefaultBucketError) { - // Disable database so it will return errors when getting the default bucket. - quota_manager_->SetDisableDatabase(true); - - mojo::Remote<blink::mojom::IDBFactory> example_remote; - indexed_db_context_->BindIndexedDB( - example_storage_key_, example_remote.BindNewPipeAndPassReceiver()); - - // IDBFactory::GetDatabaseInfo - base::RunLoop loop_1; - auto mock_callbacks = - std::make_unique<testing::StrictMock<MockMojoIndexedDBCallbacks>>(); - EXPECT_CALL(*mock_callbacks, - Error(blink::mojom::IDBException::kUnknownError, - std::u16string( - u"Internal error retrieving bucket data directory."))) - .Times(1) - .WillOnce(base::test::RunClosure(loop_1.QuitClosure())); - - example_remote->GetDatabaseInfo(mock_callbacks->CreateInterfacePtrAndBind()); - loop_1.Run(); - - testing::Mock::VerifyAndClear(&mock_callbacks); - - // IDBFactory::Open - base::RunLoop loop_2; - mock_callbacks = - std::make_unique<testing::StrictMock<MockMojoIndexedDBCallbacks>>(); - auto database_callbacks = - std::make_unique<MockMojoIndexedDBDatabaseCallbacks>(); - auto transaction_remote = - mojo::AssociatedRemote<blink::mojom::IDBTransaction>(); - EXPECT_CALL(*mock_callbacks, - Error(blink::mojom::IDBException::kUnknownError, - std::u16string( - u"Internal error retrieving bucket data directory."))) - .Times(1) - .WillOnce(base::test::RunClosure(loop_2.QuitClosure())); - - example_remote->Open(mock_callbacks->CreateInterfacePtrAndBind(), - database_callbacks->CreateInterfacePtrAndBind(), - u"database_name", /*version=*/1, - transaction_remote.BindNewEndpointAndPassReceiver(), - /*transaction_id=*/0); - loop_2.Run(); - - // IDBFactory::DeleteDatabase - base::RunLoop loop_3; - mock_callbacks = - std::make_unique<testing::StrictMock<MockMojoIndexedDBCallbacks>>(); - EXPECT_CALL(*mock_callbacks, - Error(blink::mojom::IDBException::kUnknownError, - std::u16string( - u"Internal error retrieving bucket data directory."))) - .Times(1) - .WillOnce(base::test::RunClosure(loop_3.QuitClosure())); - - example_remote->DeleteDatabase(mock_callbacks->CreateInterfacePtrAndBind(), - u"database_name", /*force_close=*/true); - loop_3.Run(); - - // IDBFactory::AbortTransactionsAndCompactDatabase - base::RunLoop loop_4; - example_remote->AbortTransactionsAndCompactDatabase( - base::BindLambdaForTesting([&](blink::mojom::IDBStatus status) { - EXPECT_EQ(status, blink::mojom::IDBStatus::NotFound); - loop_4.Quit(); - })); - loop_4.Run(); - - // IDBFactory::AbortTransactionsForDatabase - base::RunLoop loop_5; - example_remote->AbortTransactionsForDatabase( - base::BindLambdaForTesting([&](blink::mojom::IDBStatus status) { - EXPECT_EQ(status, blink::mojom::IDBStatus::NotFound); - loop_5.Quit(); - })); - loop_5.Run(); -} - } // namespace content
diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host.cc b/content/browser/indexed_db/indexed_db_dispatcher_host.cc index 9cd295e..9d6cda0 100644 --- a/content/browser/indexed_db/indexed_db_dispatcher_host.cc +++ b/content/browser/indexed_db/indexed_db_dispatcher_host.cc
@@ -214,13 +214,10 @@ void IndexedDBDispatcherHost::AddReceiver( const blink::StorageKey& storage_key, - absl::optional<storage::BucketLocator> bucket, mojo::PendingReceiver<blink::mojom::IDBFactory> pending_receiver) { DCHECK(IDBTaskRunner()->RunsTasksInCurrentSequence()); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (bucket.has_value()) - DCHECK_EQ(bucket->storage_key, storage_key); - receivers_.Add(this, std::move(pending_receiver), bucket); + receivers_.Add(this, std::move(pending_receiver), storage_key); } void IndexedDBDispatcherHost::AddDatabaseBinding( @@ -277,23 +274,10 @@ pending_callbacks) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // Return error if failed to retrieve bucket from the QuotaManager. - if (!receivers_.current_context().has_value()) { - auto callbacks = base::MakeRefCounted<IndexedDBCallbacks>( - this->AsWeakPtr(), blink::StorageKey(), std::move(pending_callbacks), - IDBTaskRunner()); - IndexedDBDatabaseError error = IndexedDBDatabaseError( - blink::mojom::IDBException::kUnknownError, - u"Internal error retrieving bucket data directory."); - callbacks->OnError(error); - return; - } - - const auto storage_key = receivers_.current_context()->storage_key; + const auto& storage_key = receivers_.current_context(); auto callbacks = base::MakeRefCounted<IndexedDBCallbacks>( this->AsWeakPtr(), storage_key, std::move(pending_callbacks), IDBTaskRunner()); - base::FilePath indexed_db_path = indexed_db_context_->data_path(); indexed_db_context_->GetIDBFactory()->GetDatabaseInfo( std::move(callbacks), storage_key, indexed_db_path); @@ -310,19 +294,7 @@ int64_t transaction_id) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // Return error if failed to retrieve bucket from the QuotaManager. - if (!receivers_.current_context().has_value()) { - auto callbacks = base::MakeRefCounted<IndexedDBCallbacks>( - this->AsWeakPtr(), blink::StorageKey(), std::move(pending_callbacks), - IDBTaskRunner()); - IndexedDBDatabaseError error = IndexedDBDatabaseError( - blink::mojom::IDBException::kUnknownError, - u"Internal error retrieving bucket data directory."); - callbacks->OnError(error); - return; - } - - const auto storage_key = receivers_.current_context()->storage_key; + const auto& storage_key = receivers_.current_context(); auto callbacks = base::MakeRefCounted<IndexedDBCallbacks>( this->AsWeakPtr(), storage_key, std::move(pending_callbacks), IDBTaskRunner()); @@ -338,7 +310,6 @@ std::make_unique<IndexedDBPendingConnection>( std::move(callbacks), std::move(database_callbacks), transaction_id, version, std::move(create_transaction_callback)); - // TODO(dgrogan): Don't let a non-existing database be opened (and therefore // created) if this origin is already over quota. indexed_db_context_->GetIDBFactory()->Open(name, std::move(connection), @@ -351,23 +322,10 @@ bool force_close) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // Return error if failed to retrieve bucket from the QuotaManager. - if (!receivers_.current_context().has_value()) { - auto callbacks = base::MakeRefCounted<IndexedDBCallbacks>( - this->AsWeakPtr(), blink::StorageKey(), std::move(pending_callbacks), - IDBTaskRunner()); - IndexedDBDatabaseError error = IndexedDBDatabaseError( - blink::mojom::IDBException::kUnknownError, - u"Internal error retrieving bucket data directory."); - callbacks->OnError(error); - return; - } - - const auto storage_key = receivers_.current_context()->storage_key; + const auto& storage_key = receivers_.current_context(); auto callbacks = base::MakeRefCounted<IndexedDBCallbacks>( this->AsWeakPtr(), storage_key, std::move(pending_callbacks), IDBTaskRunner()); - base::FilePath indexed_db_path = indexed_db_context_->data_path(); indexed_db_context_->GetIDBFactory()->DeleteDatabase( name, std::move(callbacks), storage_key, indexed_db_path, force_close); @@ -377,16 +335,9 @@ AbortTransactionsAndCompactDatabaseCallback mojo_callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // Return error if failed to retrieve bucket from the QuotaManager. - if (!receivers_.current_context().has_value()) { - std::move(mojo_callback).Run(blink::mojom::IDBStatus::NotFound); - return; - } - - const auto storage_key = receivers_.current_context()->storage_key; + const auto& storage_key = receivers_.current_context(); base::OnceCallback<void(leveldb::Status)> callback_on_io = base::BindOnce( &CallCompactionStatusCallbackOnIDBThread, std::move(mojo_callback)); - indexed_db_context_->GetIDBFactory()->AbortTransactionsAndCompactDatabase( std::move(callback_on_io), storage_key); } @@ -395,16 +346,9 @@ AbortTransactionsForDatabaseCallback mojo_callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // Return error if failed to retrieve bucket from the QuotaManager. - if (!receivers_.current_context().has_value()) { - std::move(mojo_callback).Run(blink::mojom::IDBStatus::NotFound); - return; - } - - const auto storage_key = receivers_.current_context()->storage_key; + const auto& storage_key = receivers_.current_context(); base::OnceCallback<void(leveldb::Status)> callback_on_io = base::BindOnce( &CallAbortStatusCallbackOnIDBThread, std::move(mojo_callback)); - indexed_db_context_->GetIDBFactory()->AbortTransactionsForDatabase( std::move(callback_on_io), storage_key); }
diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host.h b/content/browser/indexed_db/indexed_db_dispatcher_host.h index c96115e..4768706 100644 --- a/content/browser/indexed_db/indexed_db_dispatcher_host.h +++ b/content/browser/indexed_db/indexed_db_dispatcher_host.h
@@ -14,7 +14,6 @@ #include <vector> #include "base/sequence_checker.h" -#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "components/services/storage/public/mojom/blob_storage_context.mojom-forward.h" #include "components/services/storage/public/mojom/file_system_access_context.mojom-forward.h" #include "content/browser/indexed_db/indexed_db_external_object.h" @@ -52,7 +51,6 @@ void AddReceiver( const blink::StorageKey& storage_key, - absl::optional<storage::BucketLocator> bucket, mojo::PendingReceiver<blink::mojom::IDBFactory> pending_receiver); void AddDatabaseBinding( @@ -138,9 +136,7 @@ // Shared task runner used to read blob files on. const scoped_refptr<base::TaskRunner> file_task_runner_; - mojo::ReceiverSet<blink::mojom::IDBFactory, - absl::optional<storage::BucketLocator>> - receivers_; + mojo::ReceiverSet<blink::mojom::IDBFactory, blink::StorageKey> receivers_; mojo::UniqueAssociatedReceiverSet<blink::mojom::IDBDatabase> database_receivers_; mojo::UniqueAssociatedReceiverSet<blink::mojom::IDBCursor> cursor_receivers_;
diff --git a/content/browser/renderer_host/browsing_context_state.cc b/content/browser/renderer_host/browsing_context_state.cc index 05e49e4..4ab38bb 100644 --- a/content/browser/renderer_host/browsing_context_state.cc +++ b/content/browser/renderer_host/browsing_context_state.cc
@@ -372,10 +372,10 @@ } void BrowsingContextState::WriteIntoTrace( - perfetto::TracedProto<perfetto::protos::pbzero::BrowsingContextState> - proto) { + perfetto::TracedProto<perfetto::protos::pbzero::BrowsingContextState> proto) + const { if (browsing_instance_id_.has_value()) proto->set_browsing_instance_id(browsing_instance_id_.value().value()); } -} // namespace content \ No newline at end of file +} // namespace content
diff --git a/content/browser/renderer_host/browsing_context_state.h b/content/browser/renderer_host/browsing_context_state.h index 57d5788..6762d21b 100644 --- a/content/browser/renderer_host/browsing_context_state.h +++ b/content/browser/renderer_host/browsing_context_state.h
@@ -232,7 +232,7 @@ void WriteIntoTrace(perfetto::TracedValue ctx) const; void WriteIntoTrace( perfetto::TracedProto<perfetto::protos::pbzero::BrowsingContextState> - proto); + proto) const; protected: friend class base::RefCounted<BrowsingContextState>;
diff --git a/content/browser/renderer_host/frame_tree_browsertest.cc b/content/browser/renderer_host/frame_tree_browsertest.cc index 4ba8386..9648505 100644 --- a/content/browser/renderer_host/frame_tree_browsertest.cc +++ b/content/browser/renderer_host/frame_tree_browsertest.cc
@@ -17,8 +17,6 @@ #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_handle.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/site_isolation_policy.h" #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" @@ -89,10 +87,7 @@ // Frame tree: // Site-A Root -- Site-A frame1 // \-- Site-A frame2 - WindowedNotificationObserver observer1( - content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>( - &shell()->web_contents()->GetController())); + LoadStopObserver observer1(shell()->web_contents()); EXPECT_TRUE(NavigateToURL(shell(), base_url.Resolve("frames-X-X.html"))); observer1.Wait(); ASSERT_EQ(2U, root->child_count());
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 2336568..f507cc5 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -6293,6 +6293,12 @@ switch (disabler_type) { case blink::mojom::SuddenTerminationDisablerType::kBeforeUnloadHandler: DCHECK_NE(has_before_unload_handler_, present); + if (IsNestedWithinFencedFrame()) { + bad_message::ReceivedBadMessage( + GetProcess(), + bad_message::RFH_BEFOREUNLOAD_HANDLER_NOT_ALLOWED_IN_FENCED_FRAME); + return; + } has_before_unload_handler_ = present; break; case blink::mojom::SuddenTerminationDisablerType::kPageHideHandler: @@ -6301,6 +6307,12 @@ break; case blink::mojom::SuddenTerminationDisablerType::kUnloadHandler: DCHECK_NE(has_unload_handler_, present); + if (IsNestedWithinFencedFrame()) { + bad_message::ReceivedBadMessage( + GetProcess(), + bad_message::RFH_UNLOAD_HANDLER_NOT_ALLOWED_IN_FENCED_FRAME); + return; + } has_unload_handler_ = present; break; case blink::mojom::SuddenTerminationDisablerType::kVisibilityChangeHandler:
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 2afcba9d..57e8691 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -3641,7 +3641,9 @@ // died due to fast shutdown versus another cause. fast_shutdown_started_ = true; - ProcessDied(false /* already_dead */, nullptr); + ChildProcessTerminationInfo info = + GetChildTerminationInfo(false /* already_dead */); + ProcessDied(info); return true; } @@ -3740,7 +3742,9 @@ } void RenderProcessHostImpl::OnChannelError() { - ProcessDied(true /* already_dead */, nullptr); + ChildProcessTerminationInfo info = + GetChildTerminationInfo(true /* already_dead */); + ProcessDied(info); } void RenderProcessHostImpl::OnBadMessageReceived(const IPC::Message& message) { @@ -3932,18 +3936,16 @@ // anymore. // Populates Android-only fields and closes the underlying base::Process. ChildProcessTerminationInfo info = - child_process_launcher_->GetChildTerminationInfo( - false /* already_dead */); + GetChildTerminationInfo(false /* already_dead */); info.status = base::TERMINATION_STATUS_NORMAL_TERMINATION; info.exit_code = 0; - PopulateTerminationInfoRendererFields(&info); // Set this before ProcessDied() so observers treat this process exit as // similar to the fast shutdown case. fast_shutdown_started_ = true; // Notify observers using the clean exit info. - ProcessDied(false, &info); + ProcessDied(info); return; } @@ -3973,12 +3975,9 @@ // anymore. if (IsInitializedAndNotDead()) { // Populates Android-only fields and closes the underlying base::Process. - ChildProcessTerminationInfo info = - child_process_launcher_->GetChildTerminationInfo( - false /* already_dead */); + ChildProcessTerminationInfo info = GetChildTerminationInfo(false); info.status = base::TERMINATION_STATUS_NORMAL_TERMINATION; info.exit_code = 0; - PopulateTerminationInfoRendererFields(&info); for (auto& observer : observers_) { observer.RenderProcessExited(this, info); } @@ -4704,11 +4703,36 @@ this, std::move(shm_region)); } +ChildProcessTerminationInfo RenderProcessHostImpl::GetChildTerminationInfo( + bool already_dead) { + DCHECK(child_process_launcher_); + + ChildProcessTerminationInfo info; + + info = child_process_launcher_->GetChildTerminationInfo(already_dead); + if (already_dead && info.status == base::TERMINATION_STATUS_STILL_RUNNING) { + // May be in case of IPC error, if it takes long time for renderer + // to exit. Child process will be killed in any case during + // child_process_launcher_.reset(). Make sure we will not broadcast + // RenderProcessExited with status TERMINATION_STATUS_STILL_RUNNING, + // since this will break WebContentsImpl logic. + info.status = base::TERMINATION_STATUS_PROCESS_CRASHED; + + // TODO(siggi): Remove this once https://crbug.com/806661 is resolved. +#if BUILDFLAG(IS_WIN) + if (info.exit_code == WAIT_TIMEOUT && g_analyze_hung_renderer) + g_analyze_hung_renderer(child_process_launcher_->GetProcess()); +#endif + } + + PopulateTerminationInfoRendererFields(&info); + + return info; +} + void RenderProcessHostImpl::ProcessDied( - bool already_dead, - ChildProcessTerminationInfo* known_info) { - TRACE_EVENT1("content", "RenderProcessHostImpl::ProcessDied", "already_dead", - already_dead); + const ChildProcessTerminationInfo& termination_info) { + TRACE_EVENT0("content", "RenderProcessHostImpl::ProcessDied"); // Our child process has died. If we didn't expect it, it's a crash. // In any case, we need to let everyone know it's gone. // The OnChannelError notification can fire multiple times due to nested @@ -4722,31 +4746,6 @@ // while we are dying. DCHECK(!deleting_soon_); - // child_process_launcher_ can be NULL in single process mode or if fast - // termination happened. - ChildProcessTerminationInfo info; - info.exit_code = 0; - if (known_info) { - info = *known_info; - } else if (child_process_launcher_.get()) { - info = child_process_launcher_->GetChildTerminationInfo(already_dead); - if (already_dead && info.status == base::TERMINATION_STATUS_STILL_RUNNING) { - // May be in case of IPC error, if it takes long time for renderer - // to exit. Child process will be killed in any case during - // child_process_launcher_.reset(). Make sure we will not broadcast - // RenderProcessExited with status TERMINATION_STATUS_STILL_RUNNING, - // since this will break WebContentsImpl logic. - info.status = base::TERMINATION_STATUS_PROCESS_CRASHED; - - // TODO(siggi): Remove this once https://crbug.com/806661 is resolved. -#if BUILDFLAG(IS_WIN) - if (info.exit_code == WAIT_TIMEOUT && g_analyze_hung_renderer) - g_analyze_hung_renderer(child_process_launcher_->GetProcess()); -#endif - } - } - PopulateTerminationInfoRendererFields(&info); - child_process_launcher_.reset(); is_dead_ = true; // Make sure no IPCs or mojo calls from the old process get dispatched after @@ -4756,6 +4755,7 @@ UpdateProcessPriority(); // RenderProcessExited relies on the exit code set during shutdown. + ChildProcessTerminationInfo info = termination_info; if (shutdown_exit_code_ != -1) info.exit_code = shutdown_exit_code_; @@ -4816,12 +4816,12 @@ // OnChannelClosed() to IPC::ChannelProxy::Context on the IO thread. ResetChannelProxy(); - // The PermissionServiceContext holds PermissionSubscriptions originating from - // service workers. These subscriptions observe the PermissionControllerImpl - // that is owned by the Profile corresponding to |this|. At this point, IPC - // are unbound so no new subscriptions can be made. Existing subscriptions - // need to be released here, as the Profile, and with it, the - // PermissionControllerImpl, can be destroyed anytime after + // The PermissionServiceContext holds PermissionSubscriptions originating + // from service workers. These subscriptions observe the + // PermissionControllerImpl that is owned by the Profile corresponding to + // |this|. At this point, IPC are unbound so no new subscriptions can be + // made. Existing subscriptions need to be released here, as the Profile, + // and with it, the PermissionControllerImpl, can be destroyed anytime after // RenderProcessHostImpl::Cleanup() returns. permission_service_context_.reset(); } @@ -5152,7 +5152,7 @@ info.status = base::TERMINATION_STATUS_LAUNCH_FAILED; info.exit_code = error_code; PopulateTerminationInfoRendererFields(&info); - ProcessDied(true, &info); + ProcessDied(info); } // static
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index feb27b0..e463f057a 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -853,9 +853,18 @@ // report those histograms to UMA. void CreateSharedRendererHistogramAllocator(); + // Retrieves the details of the terminating child process. + // + // If the process is no longer running, this will also reset the process + // handle and (where applicable) reap the zombie process. + // + // |already_dead| should be set to true if we already know the process is + // dead. See `ChildProcessLauncher::GetChildTerminationInfo()` for more info + // on this flag. + ChildProcessTerminationInfo GetChildTerminationInfo(bool already_dead); + // Handle termination of our process. - void ProcessDied(bool already_dead, - ChildProcessTerminationInfo* known_details); + void ProcessDied(const ChildProcessTerminationInfo& termination_info); // Destroy all objects that can cause methods to be invoked on this object or // any other that hang off it.
diff --git a/content/browser/renderer_host/render_widget_host_browsertest.cc b/content/browser/renderer_host/render_widget_host_browsertest.cc index bba8d2b..78bd3518 100644 --- a/content/browser/renderer_host/render_widget_host_browsertest.cc +++ b/content/browser/renderer_host/render_widget_host_browsertest.cc
@@ -20,7 +20,6 @@ #include "content/browser/renderer_host/render_widget_host_input_event_router.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/browser/web_contents/web_contents_impl.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/render_widget_host_observer.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" @@ -901,8 +900,7 @@ // Ensure that the environment variables have the correct values in the new // document that is created on reloading the page. - WindowedNotificationObserver load_stop_observer( - NOTIFICATION_LOAD_STOP, NotificationService::AllSources()); + LoadStopObserver load_stop_observer(shell()->web_contents()); shell()->Reload(); load_stop_observer.Wait();
diff --git a/content/browser/service_worker/embedded_worker_test_helper.h b/content/browser/service_worker/embedded_worker_test_helper.h index 28b888e..44f3aa2 100644 --- a/content/browser/service_worker/embedded_worker_test_helper.h +++ b/content/browser/service_worker/embedded_worker_test_helper.h
@@ -110,8 +110,6 @@ // Only used for tests that force creating a new render process. int new_render_process_id() const { return new_mock_render_process_id_; } - storage::MockQuotaManager* quota_manager() { return quota_manager_.get(); } - storage::MockQuotaManagerProxy* quota_manager_proxy() { return quota_manager_proxy_.get(); }
diff --git a/content/browser/service_worker/service_worker_registry.cc b/content/browser/service_worker/service_worker_registry.cc index b6448f5..9c5d8a2 100644 --- a/content/browser/service_worker/service_worker_registry.cc +++ b/content/browser/service_worker/service_worker_registry.cc
@@ -201,11 +201,7 @@ const blink::StorageKey& key, NewRegistrationCallback callback, storage::QuotaErrorOr<storage::BucketInfo> result) { - // Return nullptr if GetOrCreateBucket fails. - if (!result.ok()) { - std::move(callback).Run(nullptr); - return; - } + DCHECK(result.ok()); CreateInvokerAndStartRemoteCall( &storage::mojom::ServiceWorkerStorageControl::GetNewRegistrationId, base::BindOnce(&ServiceWorkerRegistry::DidGetNewRegistrationId,
diff --git a/content/browser/service_worker/service_worker_registry_unittest.cc b/content/browser/service_worker/service_worker_registry_unittest.cc index 77ccc9f..c2f5ead 100644 --- a/content/browser/service_worker/service_worker_registry_unittest.cc +++ b/content/browser/service_worker/service_worker_registry_unittest.cc
@@ -648,30 +648,6 @@ EXPECT_GT(result->id.value(), 0); } -TEST_F(ServiceWorkerRegistryTest, GetOrCreateBucketError) { - const GURL kScope("http://www.test.not/scope/"); - const blink::StorageKey kKey(url::Origin::Create(kScope)); - - scoped_refptr<ServiceWorkerRegistration> registration; - - blink::mojom::ServiceWorkerRegistrationOptions options; - options.scope = kScope; - - helper()->quota_manager()->SetDisableDatabase(true); - storage::QuotaManagerProxySync quota_manager_proxy_sync( - quota_manager_proxy()); - - base::RunLoop loop; - registry()->CreateNewRegistration( - std::move(options), kKey, - base::BindLambdaForTesting( - [&](scoped_refptr<ServiceWorkerRegistration> new_registration) { - EXPECT_EQ(new_registration, nullptr); - loop.Quit(); - })); - loop.Run(); -} - TEST_F(ServiceWorkerRegistryTest, StoreFindUpdateDeleteRegistration) { const GURL kScope("http://www.test.not/scope/"); const blink::StorageKey kKey(url::Origin::Create(kScope));
diff --git a/content/browser/session_history_browsertest.cc b/content/browser/session_history_browsertest.cc index aa66606ff..1442768 100644 --- a/content/browser/session_history_browsertest.cc +++ b/content/browser/session_history_browsertest.cc
@@ -12,8 +12,6 @@ #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/content_navigation_policy.h" #include "content/public/browser/navigation_controller.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_switches.h" #include "content/public/common/url_constants.h" @@ -128,17 +126,13 @@ } void GoBack() { - WindowedNotificationObserver load_stop_observer( - NOTIFICATION_LOAD_STOP, - NotificationService::AllSources()); + LoadStopObserver load_stop_observer(shell()->web_contents()); shell()->web_contents()->GetController().GoBack(); load_stop_observer.Wait(); } void GoForward() { - WindowedNotificationObserver load_stop_observer( - NOTIFICATION_LOAD_STOP, - NotificationService::AllSources()); + LoadStopObserver load_stop_observer(shell()->web_contents()); shell()->web_contents()->GetController().GoForward(); load_stop_observer.Wait(); }
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index f5a11247..befddcf 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -90,9 +90,6 @@ #include "content/public/browser/global_routing_id.h" #include "content/public/browser/javascript_dialog_manager.h" #include "content/public/browser/navigation_handle.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/site_isolation_policy.h" #include "content/public/common/content_client.h" #include "content/public/common/content_features.h" @@ -253,86 +250,6 @@ return EvalJs(ftn, "self.origin;"); } -class RedirectNotificationObserver : public NotificationObserver { - public: - // Register to listen for notifications of the given type from either a - // specific source, or from all sources if |source| is - // NotificationService::AllSources(). - RedirectNotificationObserver(int notification_type, - const NotificationSource& source); - - RedirectNotificationObserver(const RedirectNotificationObserver&) = delete; - RedirectNotificationObserver& operator=(const RedirectNotificationObserver&) = - delete; - - ~RedirectNotificationObserver() override; - - // Wait until the specified notification occurs. If the notification was - // emitted between the construction of this object and this call then it - // returns immediately. - void Wait(); - - // Returns NotificationService::AllSources() if we haven't observed a - // notification yet. - const NotificationSource& source() const { - return source_; - } - - const NotificationDetails& details() const { - return details_; - } - - // NotificationObserver: - void Observe(int type, - const NotificationSource& source, - const NotificationDetails& details) override; - - private: - bool seen_; - bool seen_twice_; - bool running_; - NotificationRegistrar registrar_; - - NotificationSource source_; - NotificationDetails details_; - base::RunLoop run_loop_; -}; - -RedirectNotificationObserver::RedirectNotificationObserver( - int notification_type, - const NotificationSource& source) - : seen_(false), - running_(false), - source_(NotificationService::AllSources()) { - registrar_.Add(this, notification_type, source); -} - -RedirectNotificationObserver::~RedirectNotificationObserver() {} - -void RedirectNotificationObserver::Wait() { - if (seen_ && seen_twice_) - return; - - running_ = true; - run_loop_.Run(); - EXPECT_TRUE(seen_); -} - -void RedirectNotificationObserver::Observe( - int type, - const NotificationSource& source, - const NotificationDetails& details) { - source_ = source; - details_ = details; - seen_twice_ = seen_; - seen_ = true; - if (!running_) - return; - - run_loop_.Quit(); - running_ = false; -} - // This observer detects when WebContents receives notification of a user // gesture having occurred, following a user input event targeted to // a RenderWidgetHost under that WebContents. @@ -2065,9 +1982,7 @@ GURL client_redirect_http_url( embedded_test_server()->GetURL("/client-redirect?" + https_url.spec())); - RedirectNotificationObserver load_observer2( - NOTIFICATION_LOAD_STOP, Source<NavigationController>( - &shell()->web_contents()->GetController())); + LoadStopObserver load_observer2(shell()->web_contents()); EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test", client_redirect_http_url)); @@ -2098,9 +2013,7 @@ // which redirects to same-site page. GURL client_redirect_http_url( embedded_test_server()->GetURL("/client-redirect?" + http_url.spec())); - RedirectNotificationObserver load_observer2( - NOTIFICATION_LOAD_STOP, Source<NavigationController>( - &shell()->web_contents()->GetController())); + LoadStopObserver load_observer2(shell()->web_contents()); EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test", client_redirect_http_url)); @@ -2140,9 +2053,7 @@ "/client-redirect?" + client_redirect_https_url.spec())); // We should wait until second client redirect get cancelled. - RedirectNotificationObserver load_observer2( - NOTIFICATION_LOAD_STOP, Source<NavigationController>( - &shell()->web_contents()->GetController())); + LoadStopObserver load_observer2(shell()->web_contents()); EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test", client_redirect_http_url));
diff --git a/content/browser/web_database/web_database_host_impl.cc b/content/browser/web_database/web_database_host_impl.cc index a5b18e94..346e8cd3 100644 --- a/content/browser/web_database/web_database_host_impl.cc +++ b/content/browser/web_database/web_database_host_impl.cc
@@ -146,11 +146,7 @@ int32_t desired_flags, OpenFileCallback callback, storage::QuotaErrorOr<storage::BucketInfo> bucket) { - // Return invalid file path on GetOrCreateBucket error. - if (!bucket.ok()) { - std::move(callback).Run(base::File()); - return; - } + DCHECK(bucket.ok()); base::File file; const base::File* tracked_file = nullptr;
diff --git a/content/browser/web_database/web_database_host_impl_unittest.cc b/content/browser/web_database/web_database_host_impl_unittest.cc index 36ae993f..516ee07 100644 --- a/content/browser/web_database/web_database_host_impl_unittest.cc +++ b/content/browser/web_database/web_database_host_impl_unittest.cc
@@ -141,8 +141,6 @@ process_id(), url); } - storage::MockQuotaManager* quota_manager() { return quota_manager_.get(); } - storage::QuotaManagerProxy* quota_manager_proxy() { return quota_manager_proxy_.get(); } @@ -201,37 +199,6 @@ EXPECT_GT(result->id.value(), 0); } -TEST_F(WebDatabaseHostImplTest, GetOrCreateBucketError) { - const char* example_url = "http://example.com"; - const GURL example_gurl(example_url); - const url::Origin example_origin = url::Origin::Create(example_gurl); - const std::u16string db_name = u"db_name"; - const std::u16string suffix(u"suffix"); - const std::u16string vfs_file_name = - ConstructVfsFileName(example_origin, db_name, suffix); - - auto* security_policy = ChildProcessSecurityPolicyImpl::GetInstance(); - security_policy->AddFutureIsolatedOrigins( - {example_origin}, ChildProcessSecurityPolicy::IsolatedOriginSource::TEST); - LockProcessToURL(example_gurl); - - quota_manager()->SetDisableDatabase(true); - storage::QuotaManagerProxySync quota_manager_proxy_sync( - quota_manager_proxy()); - - base::RunLoop run_loop; - task_runner()->PostTask( - FROM_HERE, base::BindLambdaForTesting([&]() { - mojo::FakeMessageDispatchContext fake_dispatch_context; - host()->OpenFile(vfs_file_name, /*desired_flags=*/0, - base::BindLambdaForTesting([&](base::File file) { - EXPECT_FALSE(file.IsValid()); - run_loop.Quit(); - })); - })); - run_loop.Run(); -} - TEST_F(WebDatabaseHostImplTest, BadMessagesUnauthorized) { const GURL correct_url("http://correct.com"); const url::Origin correct_origin = url::Origin::Create(correct_url);
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc index a723970..5c7ead2 100644 --- a/content/browser/webid/federated_auth_request_impl.cc +++ b/content/browser/webid/federated_auth_request_impl.cc
@@ -318,7 +318,7 @@ void FederatedAuthRequestImpl::Revoke( const GURL& provider, const std::string& client_id, - const std::string& account_id, + const std::string& hint, blink::mojom::FederatedAuthRequest::RevokeCallback callback) { if (HasPendingRequest()) { RecordRevokeStatus(RevokeStatusForMetrics::kTooManyRequests, @@ -329,7 +329,7 @@ provider_ = provider; client_id_ = client_id; - account_id_ = account_id; + hint_ = hint; delay_timer_.Reset(); revoke_callback_ = std::move(callback); @@ -591,7 +591,7 @@ return; } network_manager_->SendRevokeRequest( - revocation_url, client_id_, account_id_, + revocation_url, client_id_, hint_, base::BindOnce(&FederatedAuthRequestImpl::OnRevokeResponse, weak_ptr_factory_.GetWeakPtr())); } @@ -611,11 +611,11 @@ } if (GetSharingPermissionContext()) { GetSharingPermissionContext()->RevokeSharingPermissionForAccount( - idp_origin, origin_, account_id_); + idp_origin, origin_, hint_); } if (GetActiveSessionPermissionContext()) { GetActiveSessionPermissionContext()->RevokeActiveSession( - origin_, idp_origin, account_id_); + origin_, idp_origin, hint_); } RecordRevokeStatus(RevokeStatusForMetrics::kSuccess, render_frame_host_->GetPageUkmSourceId()); @@ -637,7 +637,7 @@ network_manager_->IsMockIdpNetworkRequestManager(); network_manager_.reset(); provider_ = GURL(); - account_id_ = std::string(); + hint_ = std::string(); client_id_ = std::string(); if (should_run_callback)
diff --git a/content/browser/webid/federated_auth_request_impl.h b/content/browser/webid/federated_auth_request_impl.h index 7fe3a3fe..4b36210 100644 --- a/content/browser/webid/federated_auth_request_impl.h +++ b/content/browser/webid/federated_auth_request_impl.h
@@ -201,6 +201,8 @@ // The account that was selected by the user. This is only applicable to the // mediation flow. std::string account_id_; + // Used by revocation. + std::string hint_; base::TimeTicks start_time_; base::TimeTicks show_accounts_dialog_time_; base::TimeTicks select_account_time_;
diff --git a/content/browser/webid/federated_auth_request_impl_unittest.cc b/content/browser/webid/federated_auth_request_impl_unittest.cc index 73c0c3e..ecab8fcc 100644 --- a/content/browser/webid/federated_auth_request_impl_unittest.cc +++ b/content/browser/webid/federated_auth_request_impl_unittest.cc
@@ -1187,7 +1187,7 @@ } TEST_F(FederatedAuthRequestImplTest, Revoke) { - constexpr char kAccountId[] = "foo@bar.com"; + constexpr char kHint[] = "foo@bar.com"; auto& auth_request = CreateAuthRequest(GURL(kProviderUrl)); auth_request.SetRequestPermissionDelegateForTests( @@ -1213,11 +1213,11 @@ })); EXPECT_CALL(*mock_request_manager_, SendRevokeRequest(_, _, _, _)) .WillOnce(Invoke([&](const GURL& revoke_url, const std::string& client_id, - const std::string& account_id, + const std::string& hint, IdpNetworkRequestManager::RevokeCallback callback) { EXPECT_EQ(kRevocationEndpoint, revoke_url.spec()); EXPECT_EQ(kClientId, client_id); - EXPECT_EQ(kAccountId, account_id); + EXPECT_EQ(kHint, hint); std::move(callback).Run(RevokeResponse::kSuccess); })); @@ -1225,7 +1225,7 @@ ukm_recorder()->SetOnAddEntryCallback(Entry::kEntryName, ukm_loop.QuitClosure()); - auto status = PerformRevokeRequest(kAccountId); + auto status = PerformRevokeRequest(kHint); EXPECT_EQ(RevokeStatus::kSuccess, status); ukm_loop.Run(); @@ -1237,7 +1237,7 @@ } TEST_F(FederatedAuthRequestImplTest, RevokeNoPermission) { - constexpr char kAccountId[] = "foo@bar.com"; + constexpr char kHint[] = "foo@bar.com"; auto& auth_request = CreateAuthRequest(GURL(kProviderUrl)); auth_request.SetRequestPermissionDelegateForTests( @@ -1253,7 +1253,7 @@ ukm_recorder()->SetOnAddEntryCallback(Entry::kEntryName, ukm_loop.QuitClosure()); - auto status = PerformRevokeRequest(kAccountId); + auto status = PerformRevokeRequest(kHint); EXPECT_EQ(RevokeStatus::kError, status); ukm_loop.Run();
diff --git a/content/browser/webid/idp_network_request_manager.cc b/content/browser/webid/idp_network_request_manager.cc index 8ef811e..365b063 100644 --- a/content/browser/webid/idp_network_request_manager.cc +++ b/content/browser/webid/idp_network_request_manager.cc
@@ -525,7 +525,7 @@ void IdpNetworkRequestManager::SendRevokeRequest(const GURL& revoke_url, const std::string& client_id, - const std::string& account_id, + const std::string& hint, RevokeCallback callback) { DCHECK(!url_loader_); DCHECK(!token_request_callback_); @@ -536,16 +536,13 @@ if (!client_id.empty()) revoke_request_body += "client_id=" + client_id; - if (!account_id.empty()) { - if (!revoke_request_body.empty()) - revoke_request_body += "&"; - revoke_request_body += "account_id=" + account_id; - } - - if (revoke_request_body.empty()) { + if (hint.empty()) { std::move(revoke_callback_).Run(RevokeResponse::kError); return; } + if (!revoke_request_body.empty()) + revoke_request_body += "&"; + revoke_request_body += "hint=" + hint; url_loader_ = CreateCredentialedUrlLoader( revoke_url, /* send_referrer= */ true, revoke_request_body);
diff --git a/content/browser/webid/idp_network_request_manager.h b/content/browser/webid/idp_network_request_manager.h index 5b7ca77..1cd0704 100644 --- a/content/browser/webid/idp_network_request_manager.h +++ b/content/browser/webid/idp_network_request_manager.h
@@ -162,7 +162,7 @@ // Send a revoke token request to the IDP. virtual void SendRevokeRequest(const GURL& revoke_url, const std::string& client_id, - const std::string& account_id, + const std::string& hint, RevokeCallback callback); // Send logout request to a single target.
diff --git a/content/browser/webid/idp_network_request_manager_unittest.cc b/content/browser/webid/idp_network_request_manager_unittest.cc index 6784754..954f2eab 100644 --- a/content/browser/webid/idp_network_request_manager_unittest.cc +++ b/content/browser/webid/idp_network_request_manager_unittest.cc
@@ -154,7 +154,7 @@ RevokeResponse SendRevokeRequestAndWaitForResponse( const char* client_id, - const char* account_id, + const char* hint, net::HttpStatusCode http_status = net::HTTP_NO_CONTENT) { GURL revocation_endpoint(kTestRevocationEndpoint); test_url_loader_factory().AddResponse(revocation_endpoint.spec(), "", @@ -167,7 +167,7 @@ status = revoke_status; run_loop.Quit(); }); - manager().SendRevokeRequest(revocation_endpoint, client_id, account_id, + manager().SendRevokeRequest(revocation_endpoint, client_id, hint, std::move(callback)); run_loop.Run(); return status; @@ -684,7 +684,7 @@ ASSERT_EQ(network::DataElement::Tag::kBytes, elem.type()); const network::DataElementBytes& byte_elem = elem.As<network::DataElementBytes>(); - EXPECT_EQ("client_id=xxx&account_id=yyy", byte_elem.AsStringPiece()); + EXPECT_EQ("client_id=xxx&hint=yyy", byte_elem.AsStringPiece()); }); test_url_loader_factory().SetInterceptor(interceptor); RevokeResponse status = SendRevokeRequestAndWaitForResponse("xxx", "yyy");
diff --git a/content/browser/zoom_browsertest.cc b/content/browser/zoom_browsertest.cc index 511a2f7..ba54b7e 100644 --- a/content/browser/zoom_browsertest.cc +++ b/content/browser/zoom_browsertest.cc
@@ -13,8 +13,6 @@ #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/host_zoom_map.h" #include "content/public/browser/navigation_entry.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_types.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" @@ -251,9 +249,7 @@ // Now the actual test: Reload the page and check that the main frame is // still properly zoomed. - WindowedNotificationObserver load_stop_observer( - NOTIFICATION_LOAD_STOP, - NotificationService::AllSources()); + LoadStopObserver load_stop_observer(shell()->web_contents()); shell()->Reload(); load_stop_observer.Wait();
diff --git a/content/public/test/test_utils.cc b/content/public/test/test_utils.cc index 4a3c423..9f3d035 100644 --- a/content/public/test/test_utils.cc +++ b/content/public/test/test_utils.cc
@@ -417,6 +417,21 @@ run_loop_.Quit(); } +LoadStopObserver::LoadStopObserver(WebContents* web_contents) + : WebContentsObserver(web_contents) {} + +void LoadStopObserver::Wait() { + if (!seen_) + run_loop_.Run(); + + EXPECT_TRUE(seen_); +} + +void LoadStopObserver::DidStopLoading() { + seen_ = true; + run_loop_.Quit(); +} + InProcessUtilityThreadHelper::InProcessUtilityThreadHelper() { RenderProcessHost::SetRunRendererInProcess(true); }
diff --git a/content/public/test/test_utils.h b/content/public/test/test_utils.h index aa9a6cd..3c4e89a 100644 --- a/content/public/test/test_utils.h +++ b/content/public/test/test_utils.h
@@ -308,6 +308,36 @@ base::RunLoop run_loop_; }; +// Helper to wait for loading to stop on a WebContents. It should be preferred +// to uses of WindowedNotificationObserver for NOTIFICATION_LOAD_STOP. +// +// This helper class exists to avoid the following common pattern in tests: +// PerformAction() +// WaitForCompletionNotification() +// The pattern leads to flakiness as there is a window between PerformAction +// returning and the observers getting registered, where a notification will be +// missed. +// +// Rather, one can do this: +// LoadStopObserver signal(web_contents) +// PerformAction() +// signal.Wait() +class LoadStopObserver : public WebContentsObserver { + public: + explicit LoadStopObserver(WebContents* web_contents); + + // Wait until at least one load stop has been observed. Return immediately if + // one has been observed since construction. + void Wait(); + + // WebContentsObserver + void DidStopLoading() override; + + private: + bool seen_ = false; + base::RunLoop run_loop_; +}; + // Unit tests can use code which runs in the utility process by having it run on // an in-process utility thread. This eliminates having two code paths in // production code to deal with unit tests, and also helps with the binary
diff --git a/content/test/attribution_simulator_input_parser.cc b/content/test/attribution_simulator_input_parser.cc index e034169..40566c8 100644 --- a/content/test/attribution_simulator_input_parser.cc +++ b/content/test/attribution_simulator_input_parser.cc
@@ -19,7 +19,7 @@ #include "base/test/bind.h" #include "base/time/time.h" #include "base/values.h" -#include "content/browser/attribution_reporting/attribution_aggregatable_sources.h" +#include "content/browser/attribution_reporting/attribution_aggregatable_source.h" #include "content/browser/attribution_reporting/attribution_filter_data.h" #include "content/browser/attribution_reporting/attribution_source_type.h" #include "content/browser/attribution_reporting/attribution_trigger.h" @@ -210,7 +210,7 @@ source_time, CommonSourceInfo::GetExpiryTime(expiry, source_time, *source_type), *source_type, priority, std::move(filter_data), debug_key, - AttributionAggregatableSources())), + AttributionAggregatableSource())), std::move(source)); }
diff --git a/content/test/data/attribution_reporting/databases/version_31.sql b/content/test/data/attribution_reporting/databases/version_31.sql index c71d6be..b3fd863a 100644 --- a/content/test/data/attribution_reporting/databases/version_31.sql +++ b/content/test/data/attribution_reporting/databases/version_31.sql
@@ -48,4 +48,6 @@ CREATE INDEX contribution_aggregation_id_idx ON aggregatable_contributions(aggregation_id); +INSERT INTO conversions VALUES (1,2,3,4,5,6,7,8,9); + COMMIT;
diff --git a/content/test/data/attribution_reporting/databases/version_30.sql b/content/test/data/attribution_reporting/databases/version_32.sql similarity index 77% rename from content/test/data/attribution_reporting/databases/version_30.sql rename to content/test/data/attribution_reporting/databases/version_32.sql index 68a96ec..8f9c6aa 100644 --- a/content/test/data/attribution_reporting/databases/version_30.sql +++ b/content/test/data/attribution_reporting/databases/version_32.sql
@@ -2,7 +2,7 @@ BEGIN TRANSACTION; -CREATE TABLE impressions(impression_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,impression_data INTEGER NOT NULL,impression_origin TEXT NOT NULL,conversion_origin TEXT NOT NULL,reporting_origin TEXT NOT NULL,impression_time INTEGER NOT NULL,expiry_time INTEGER NOT NULL,num_conversions INTEGER NOT NULL,active INTEGER NOT NULL,conversion_destination TEXT NOT NULL,source_type INTEGER NOT NULL,attributed_truthfully INTEGER NOT NULL,priority INTEGER NOT NULL,impression_site TEXT NOT NULL,debug_key INTEGER,aggregatable_budget_consumed INTEGER NOT NULL,aggregatable_sources BLOB NOT NULL,filter_data BLOB NOT NULL); +CREATE TABLE impressions(impression_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,impression_data INTEGER NOT NULL,impression_origin TEXT NOT NULL,conversion_origin TEXT NOT NULL,reporting_origin TEXT NOT NULL,impression_time INTEGER NOT NULL,expiry_time INTEGER NOT NULL,num_conversions INTEGER NOT NULL,event_level_active INTEGER NOT NULL,aggregatable_active INTEGER NOT NULL,conversion_destination TEXT NOT NULL,source_type INTEGER NOT NULL,attributed_truthfully INTEGER NOT NULL,priority INTEGER NOT NULL,impression_site TEXT NOT NULL,debug_key INTEGER,aggregatable_budget_consumed INTEGER NOT NULL,aggregatable_source BLOB NOT NULL,filter_data BLOB NOT NULL); CREATE TABLE conversions(conversion_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,impression_id INTEGER NOT NULL,conversion_data INTEGER NOT NULL,conversion_time INTEGER NOT NULL,report_time INTEGER NOT NULL,priority INTEGER NOT NULL,failed_send_attempts INTEGER NOT NULL,external_report_id TEXT NOT NULL,debug_key INTEGER); @@ -17,16 +17,16 @@ CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); INSERT INTO meta VALUES('mmap_status','-1'); -INSERT INTO meta VALUES('version','30'); -INSERT INTO meta VALUES('last_compatible_version','30'); +INSERT INTO meta VALUES('version','32'); +INSERT INTO meta VALUES('last_compatible_version','32'); -CREATE INDEX conversion_destination_idx ON impressions(active,conversion_destination,reporting_origin); +CREATE INDEX conversion_destination_idx ON impressions(event_level_active,aggregatable_active,conversion_destination,reporting_origin); CREATE INDEX impression_expiry_idx ON impressions(expiry_time); CREATE INDEX impression_origin_idx ON impressions(impression_origin); -CREATE INDEX impression_site_reporting_origin_idx ON impressions(impression_site,reporting_origin)WHERE active=1 AND num_conversions=0; +CREATE INDEX impression_site_reporting_origin_idx ON impressions(impression_site,reporting_origin)WHERE event_level_active=1 AND num_conversions=0 AND aggregatable_active=1 AND aggregatable_budget_consumed=0; CREATE INDEX conversion_report_idx ON conversions(report_time); @@ -48,6 +48,4 @@ CREATE INDEX contribution_aggregation_id_idx ON aggregatable_contributions(aggregation_id); -INSERT INTO conversions VALUES (1,2,3,4,5,6,7,8,9); - COMMIT;
diff --git a/docs/windows_build_instructions.md b/docs/windows_build_instructions.md index 91dd910..59aac88 100644 --- a/docs/windows_build_instructions.md +++ b/docs/windows_build_instructions.md
@@ -93,7 +93,7 @@ Add `C:\src\depot_tools` at the front. Note: If your system PATH has a Python in it, you will be out of luck. -Also, add a DEPOT_TOOLS_WIN_TOOLCHAIN system variable in the same way, and set +Also, add a DEPOT_TOOLS_WIN_TOOLCHAIN environment variable in the same way, and set it to 0. This tells depot_tools to use your locally installed version of Visual Studio (by default, depot_tools will try to use a google-internal version).
diff --git a/extensions/browser/event_router.cc b/extensions/browser/event_router.cc index fed3a765..a843c1f 100644 --- a/extensions/browser/event_router.cc +++ b/extensions/browser/event_router.cc
@@ -34,7 +34,6 @@ #include "extensions/browser/process_manager.h" #include "extensions/browser/process_map.h" #include "extensions/common/constants.h" -#include "extensions/common/event_filtering_info_type_converters.h" #include "extensions/common/extension.h" #include "extensions/common/extension_api.h" #include "extensions/common/extension_messages.h" @@ -163,26 +162,22 @@ UserGestureState user_gesture, mojom::EventFilteringInfoPtr info) { NotifyEventDispatched(browser_context, extension_id, event_name, *event_args); - mojom::DispatchEventParams params; - params.worker_thread_id = worker_thread_id; - params.extension_id = extension_id; - params.event_name = event_name; - params.event_id = event_id; - params.is_user_gesture = user_gesture == USER_GESTURE_ENABLED; - params.filtering_info = info->To<EventFilteringInfo>(); + auto params = mojom::DispatchEventParams::New(); + params->worker_thread_id = worker_thread_id; + params->extension_id = extension_id; + params->event_name = event_name; + params->event_id = event_id; + params->is_user_gesture = user_gesture == USER_GESTURE_ENABLED; + params->filtering_info = std::move(info); - // TODO(crbug/1222550): Remove IPC->Send call after worker_thread_dispatcher - // is also mojofied. - if (worker_thread_id == kMainThreadId) { - Get(browser_context)->RouteDispatchEvent(rph, params.Clone(), *event_args); - } else { - rph->Send(new ExtensionMsg_DispatchEvent(params, *event_args)); - } + Get(browser_context)->RouteDispatchEvent(rph, std::move(params), *event_args); } void EventRouter::RouteDispatchEvent(content::RenderProcessHost* rph, - const mojom::DispatchEventParamsPtr params, - const ListValue& event_args) { + mojom::DispatchEventParamsPtr params, + ListValue& event_args) { + // TODO(crbug.com/1302000) Add bindings for worker threads to be directly + // channel-associated. mojo::AssociatedRemote<mojom::EventDispatcher>& dispatcher = rph_dispatcher_map_[rph]; if (!dispatcher.is_bound()) { @@ -193,7 +188,7 @@ channel->GetRemoteAssociatedInterface( dispatcher.BindNewEndpointAndPassReceiver()); } - dispatcher->DispatchEvent(params.Clone(), event_args.Clone()); + dispatcher->DispatchEvent(std::move(params), event_args.Clone()); } // static
diff --git a/extensions/browser/event_router.h b/extensions/browser/event_router.h index 62def670..82adadd 100644 --- a/extensions/browser/event_router.h +++ b/extensions/browser/event_router.h
@@ -449,8 +449,8 @@ int64_t service_worker_version_id); void RouteDispatchEvent(content::RenderProcessHost* rph, - const mojom::DispatchEventParamsPtr params, - const base::ListValue& event_args); + mojom::DispatchEventParamsPtr params, + base::ListValue& event_args); // static static void DoDispatchEventToSenderBookkeeping(
diff --git a/extensions/common/BUILD.gn b/extensions/common/BUILD.gn index a2a26ee..21575366 100644 --- a/extensions/common/BUILD.gn +++ b/extensions/common/BUILD.gn
@@ -173,18 +173,6 @@ traits_sources = [ "//extensions/common/mojom/activation_sequence_mojom_traits.cc" ] }, - { - types = [ - { - mojom = "extensions.mojom.EventFilteringInfo" - cpp = "::extensions::EventFilteringInfo" - }, - ] - traits_headers = - [ "//extensions/common/mojom/event_dispatcher_mojom_traits.h" ] - traits_sources = - [ "//extensions/common/mojom/event_dispatcher_mojom_traits.cc" ] - }, ] overridden_deps = [ "//content/public/common:interfaces" ] @@ -251,10 +239,6 @@ "error_utils.h", "event_filter.cc", "event_filter.h", - "event_filtering_info.cc", - "event_filtering_info.h", - "event_filtering_info_type_converters.cc", - "event_filtering_info_type_converters.h", "event_matcher.cc", "event_matcher.h", "extension.cc",
diff --git a/extensions/common/event_filtering_info.cc b/extensions/common/event_filtering_info.cc deleted file mode 100644 index 865b2b85..0000000 --- a/extensions/common/event_filtering_info.cc +++ /dev/null
@@ -1,14 +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. - -#include "extensions/common/event_filtering_info.h" - -namespace extensions { - -EventFilteringInfo::EventFilteringInfo() {} -EventFilteringInfo::EventFilteringInfo(const EventFilteringInfo& other) = - default; -EventFilteringInfo::~EventFilteringInfo() {} - -} // namespace extensions
diff --git a/extensions/common/event_filtering_info.h b/extensions/common/event_filtering_info.h deleted file mode 100644 index 04af133..0000000 --- a/extensions/common/event_filtering_info.h +++ /dev/null
@@ -1,53 +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 EXTENSIONS_COMMON_EVENT_FILTERING_INFO_H_ -#define EXTENSIONS_COMMON_EVENT_FILTERING_INFO_H_ - -#include <memory> -#include <string> - -#include "third_party/abseil-cpp/absl/types/optional.h" -#include "url/gurl.h" - -namespace extensions { - -// Extra information about an event that is used in event filtering. -// -// This is the information that is matched against criteria specified in JS -// extension event listeners. Eg: -// -// chrome.someApi.onSomeEvent.addListener(cb, -// {url: [{hostSuffix: 'google.com'}], -// tabId: 1}); -struct EventFilteringInfo { - public: - EventFilteringInfo(); - EventFilteringInfo(const EventFilteringInfo& other); - ~EventFilteringInfo(); - - absl::optional<GURL> url; - absl::optional<std::string> service_type; - absl::optional<int> instance_id; - - // Note: window type & visible are Chrome concepts, so arguably - // doesn't belong in the extensions module. If the number of Chrome - // concept grows, consider a delegation model with a - // ChromeEventFilteringInfo class. - absl::optional<std::string> window_type; - - // By default events related to windows are filtered based on the - // listener's extension. This parameter will be set if the listener - // didn't set any filter on window types. - absl::optional<bool> window_exposed_by_default; - - bool is_empty() const { - return !url && !service_type && !instance_id && !window_type && - !window_exposed_by_default; - } -}; - -} // namespace extensions - -#endif // EXTENSIONS_COMMON_EVENT_FILTERING_INFO_H_
diff --git a/extensions/common/event_filtering_info_type_converters.cc b/extensions/common/event_filtering_info_type_converters.cc deleted file mode 100644 index c6df0a0..0000000 --- a/extensions/common/event_filtering_info_type_converters.cc +++ /dev/null
@@ -1,45 +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 "extensions/common/event_filtering_info_type_converters.h" - -namespace mojo { - -// static -extensions::mojom::EventFilteringInfoPtr -TypeConverter<extensions::mojom::EventFilteringInfoPtr, - extensions::EventFilteringInfo>:: - Convert(const extensions::EventFilteringInfo& input) { - extensions::mojom::EventFilteringInfoPtr output = - extensions::mojom::EventFilteringInfo::New(); - output->url = input.url; - output->service_type = input.service_type; - output->has_instance_id = input.instance_id.has_value(); - if (output->has_instance_id) - output->instance_id = input.instance_id.value(); - output->window_type = input.window_type; - output->has_window_exposed_by_default = - input.window_exposed_by_default.has_value(); - if (output->has_window_exposed_by_default) - output->window_exposed_by_default = input.window_exposed_by_default.value(); - return output; -} - -// static -extensions::EventFilteringInfo -TypeConverter<extensions::EventFilteringInfo, - extensions::mojom::EventFilteringInfo>:: - Convert(const extensions::mojom::EventFilteringInfo& input) { - extensions::EventFilteringInfo output; - output.url = input.url; - output.service_type = input.service_type; - if (input.has_instance_id) - output.instance_id = input.instance_id; - output.window_type = input.window_type; - if (input.has_window_exposed_by_default) - output.window_exposed_by_default = input.window_exposed_by_default; - return output; -} - -} // namespace mojo \ No newline at end of file
diff --git a/extensions/common/event_filtering_info_type_converters.h b/extensions/common/event_filtering_info_type_converters.h deleted file mode 100644 index 5617457..0000000 --- a/extensions/common/event_filtering_info_type_converters.h +++ /dev/null
@@ -1,31 +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. - -#ifndef EXTENSIONS_COMMON_EVENT_FILTERING_INFO_TYPE_CONVERTERS_H_ -#define EXTENSIONS_COMMON_EVENT_FILTERING_INFO_TYPE_CONVERTERS_H_ - -#include "extensions/common/event_filtering_info.h" -#include "extensions/common/mojom/event_dispatcher.mojom.h" -#include "mojo/public/cpp/bindings/type_converter.h" - -namespace mojo { -// TODO(crbug.com/1222550): Remove these converters once -// extensions::EventFilteringInfo is removed. -template <> -struct TypeConverter<extensions::mojom::EventFilteringInfoPtr, - extensions::EventFilteringInfo> { - static extensions::mojom::EventFilteringInfoPtr Convert( - const extensions::EventFilteringInfo& input); -}; - -template <> -struct TypeConverter<extensions::EventFilteringInfo, - extensions::mojom::EventFilteringInfo> { - static extensions::EventFilteringInfo Convert( - const extensions::mojom::EventFilteringInfo& input); -}; - -} // namespace mojo - -#endif // EXTENSIONS_COMMON_EVENT_FILTERING_INFO_TYPE_CONVERTERS_H_ \ No newline at end of file
diff --git a/extensions/common/extension_messages.h b/extensions/common/extension_messages.h index 46c169d..3767ea7e 100644 --- a/extensions/common/extension_messages.h +++ b/extensions/common/extension_messages.h
@@ -28,7 +28,6 @@ #include "extensions/common/common_param_traits.h" #include "extensions/common/constants.h" #include "extensions/common/draggable_region.h" -#include "extensions/common/event_filtering_info.h" #include "extensions/common/extension.h" #include "extensions/common/extension_guid.h" #include "extensions/common/extensions_client.h" @@ -138,27 +137,6 @@ IPC_STRUCT_TRAITS_MEMBER(service_worker_version_id) IPC_STRUCT_TRAITS_END() -IPC_STRUCT_TRAITS_BEGIN(extensions::mojom::DispatchEventParams) - // If this event is for a service worker, then this is the worker thread - // id. Otherwise, this is 0. - IPC_STRUCT_TRAITS_MEMBER(worker_thread_id) - - // The id of the extension to dispatch the event to. - IPC_STRUCT_TRAITS_MEMBER(extension_id) - - // The name of the event to dispatch. - IPC_STRUCT_TRAITS_MEMBER(event_name) - - // The id of the event for use in the EventAck response message. - IPC_STRUCT_TRAITS_MEMBER(event_id) - - // Whether or not the event is part of a user gesture. - IPC_STRUCT_TRAITS_MEMBER(is_user_gesture) - - // Additional filtering info for the event. - IPC_STRUCT_TRAITS_MEMBER(filtering_info) -IPC_STRUCT_TRAITS_END() - // Struct containing information about the sender of connect() calls that // originate from a tab. IPC_STRUCT_BEGIN(ExtensionMsg_TabConnectionInfo) @@ -272,14 +250,6 @@ IPC_STRUCT_TRAITS_MEMBER(serialization_format) IPC_STRUCT_TRAITS_END() -IPC_STRUCT_TRAITS_BEGIN(extensions::EventFilteringInfo) - IPC_STRUCT_TRAITS_MEMBER(url) - IPC_STRUCT_TRAITS_MEMBER(service_type) - IPC_STRUCT_TRAITS_MEMBER(instance_id) - IPC_STRUCT_TRAITS_MEMBER(window_type) - IPC_STRUCT_TRAITS_MEMBER(window_exposed_by_default) -IPC_STRUCT_TRAITS_END() - // Singly-included section for custom IPC traits. #ifndef INTERNAL_EXTENSIONS_COMMON_EXTENSION_MESSAGES_H_ #define INTERNAL_EXTENSIONS_COMMON_EXTENSION_MESSAGES_H_ @@ -307,13 +277,6 @@ // Messages sent from the browser to the renderer: -// Sent to the renderer to dispatch an event to an extension. -// Note: |event_args| is separate from the params to avoid having the message -// take ownership. -IPC_MESSAGE_CONTROL2(ExtensionMsg_DispatchEvent, - extensions::mojom::DispatchEventParams /* params */, - base::ListValue /* event_args */) - // The browser's response to the ExtensionMsg_WakeEventPage IPC. IPC_MESSAGE_CONTROL2(ExtensionMsg_WakeEventPageResponse, int /* request_id */,
diff --git a/extensions/common/mojom/event_dispatcher.mojom b/extensions/common/mojom/event_dispatcher.mojom index 90f9677e..611d762 100644 --- a/extensions/common/mojom/event_dispatcher.mojom +++ b/extensions/common/mojom/event_dispatcher.mojom
@@ -18,9 +18,6 @@ mojo_base.mojom.DeprecatedListValue event_args); }; -// Typemapped to extensions::EventFilteringInfo. -// TODO(yochio): Convert extensions::EventFilteringInfo usage to -// extensions::mojom::EventFilteringInfo (https://crbug.com/1222550) struct EventFilteringInfo { url.mojom.Url? url;
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index 22bf85b..0ae7b02 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc
@@ -32,7 +32,6 @@ #include "extensions/common/api/messaging/message.h" #include "extensions/common/constants.h" #include "extensions/common/cors_util.h" -#include "extensions/common/event_filtering_info_type_converters.h" #include "extensions/common/extension.h" #include "extensions/common/extension_api.h" #include "extensions/common/extension_features.h" @@ -1302,6 +1301,11 @@ void Dispatcher::DispatchEvent(mojom::DispatchEventParamsPtr params, base::Value event_args) { + if (params->worker_thread_id != kMainThreadId) { + WorkerThreadDispatcher::Get()->DispatchEvent(std::move(params), + std::move(event_args)); + return; + } content::RenderFrame* background_frame = ExtensionFrameHelper::GetBackgroundPageFrame(params->extension_id); @@ -1326,7 +1330,7 @@ DispatchEventHelper(params->extension_id, params->event_name, base::Value::AsListValue(event_args), - mojom::EventFilteringInfo::From(params->filtering_info)); + std::move(params->filtering_info)); if (background_frame) { // Tell the browser process when an event has been dispatched with a lazy
diff --git a/extensions/renderer/dispatcher.h b/extensions/renderer/dispatcher.h index e2cb9769..3376c54 100644 --- a/extensions/renderer/dispatcher.h +++ b/extensions/renderer/dispatcher.h
@@ -284,6 +284,8 @@ void OnDispatchOnDisconnect(int worker_thread_id, const PortId& port_id, const std::string& error_message); + + // EventDispatcher implementation. void DispatchEvent(mojom::DispatchEventParamsPtr params, base::Value event_args) override; @@ -381,8 +383,8 @@ // it is dependent on other messages sent on other associated channels. mojo::AssociatedReceiver<mojom::Renderer> receiver_; - // Extensions Dipsatch receiver. This is an associated receiver because - // it is dependent on other messages sent on other associated channels. + // Extensions Dipsatch receiver. This is an associated receiver because it is + // dependent on other messages sent on other associated channels. mojo::AssociatedReceiver<mojom::EventDispatcher> dispatcher_; // Used to hold a service worker information which is ready to execute but the
diff --git a/extensions/renderer/worker_thread_dispatcher.cc b/extensions/renderer/worker_thread_dispatcher.cc index 3486329..40419478 100644 --- a/extensions/renderer/worker_thread_dispatcher.cc +++ b/extensions/renderer/worker_thread_dispatcher.cc
@@ -16,7 +16,6 @@ #include "content/public/renderer/render_thread.h" #include "content/public/renderer/worker_thread.h" #include "extensions/common/constants.h" -#include "extensions/common/event_filtering_info_type_converters.h" #include "extensions/common/extension_features.h" #include "extensions/common/extension_messages.h" #include "extensions/common/mojom/event_dispatcher.mojom.h" @@ -33,8 +32,6 @@ namespace { -base::LazyInstance<WorkerThreadDispatcher>::DestructorAtExit - g_worker_thread_dispatcher_instance = LAZY_INSTANCE_INITIALIZER; base::LazyInstance<base::ThreadLocalPointer<extensions::ServiceWorkerData>>:: DestructorAtExit g_data_tls = LAZY_INSTANCE_INITIALIZER; @@ -122,11 +119,12 @@ } // namespace -WorkerThreadDispatcher::WorkerThreadDispatcher() {} -WorkerThreadDispatcher::~WorkerThreadDispatcher() {} +WorkerThreadDispatcher::WorkerThreadDispatcher() = default; +WorkerThreadDispatcher::~WorkerThreadDispatcher() = default; WorkerThreadDispatcher* WorkerThreadDispatcher::Get() { - return g_worker_thread_dispatcher_instance.Pointer(); + static base::NoDestructor<WorkerThreadDispatcher> dispatcher; + return dispatcher.get(); } void WorkerThreadDispatcher::Init(content::RenderThread* render_thread) { @@ -162,7 +160,6 @@ bool WorkerThreadDispatcher::HandlesMessageOnWorkerThread( const IPC::Message& message) { return message.type() == ExtensionMsg_ResponseWorker::ID || - message.type() == ExtensionMsg_DispatchEvent::ID || message.type() == ExtensionMsg_DispatchOnConnect::ID || message.type() == ExtensionMsg_DeliverMessage::ID || message.type() == ExtensionMsg_DispatchOnDisconnect::ID || @@ -186,6 +183,14 @@ Dispatcher::GetWorkerScriptContextSet()); } +// static +void WorkerThreadDispatcher::DispatchEventOnWorkerThread( + mojom::DispatchEventParamsPtr params, + base::Value event_args) { + auto* dispatcher = WorkerThreadDispatcher::Get(); + dispatcher->DispatchEventHelper(std::move(params), std::move(event_args)); +} + bool WorkerThreadDispatcher::OnControlMessageReceived( const IPC::Message& message) { if (HandlesMessageOnWorkerThread(message)) { @@ -305,7 +310,6 @@ bool handled = true; IPC_BEGIN_MESSAGE_MAP(WorkerThreadDispatcher, message) IPC_MESSAGE_HANDLER(ExtensionMsg_ResponseWorker, OnResponseWorker) - IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchEvent, OnDispatchEvent) IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnConnect, OnDispatchOnConnect) IPC_MESSAGE_HANDLER(ExtensionMsg_DeliverMessage, OnDeliverMessage) IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnDisconnect, @@ -353,9 +357,10 @@ error); } -void WorkerThreadDispatcher::OnDispatchEvent( - const mojom::DispatchEventParams& params, - const base::ListValue& event_args) { +void WorkerThreadDispatcher::DispatchEventHelper( + mojom::DispatchEventParamsPtr params, + base::Value event_args) { + DCHECK_EQ(params->worker_thread_id, content::WorkerThread::GetCurrentId()); ServiceWorkerData* data = g_data_tls.Pointer()->Get(); DCHECK(data); @@ -364,21 +369,32 @@ v8::Isolate* isolate = script_context->isolate(); v8::HandleScope handle_scope(isolate); std::unique_ptr<InteractionProvider::Scope> scoped_extension_interaction; - if (params.is_user_gesture) { + if (params->is_user_gesture) { scoped_extension_interaction = ExtensionInteractionProvider::Scope::ForWorker( script_context->v8_context()); } - mojom::EventFilteringInfoPtr filtering_info = - mojom::EventFilteringInfo::From(params.filtering_info); + data->bindings_system()->DispatchEventInContext( - params.event_name, &event_args, filtering_info, data->context()); + params->event_name, &base::Value::AsListValue(event_args), + std::move(params->filtering_info), data->context()); const int worker_thread_id = content::WorkerThread::GetCurrentId(); Send(new ExtensionHostMsg_EventAckWorker(data->context()->GetExtensionID(), data->service_worker_version_id(), - worker_thread_id, params.event_id)); + worker_thread_id, params->event_id)); } +void WorkerThreadDispatcher::DispatchEvent(mojom::DispatchEventParamsPtr params, + base::Value event_args) { + DCHECK(!worker_thread_util::IsWorkerThread()); + const int worker_thread_id = params->worker_thread_id; + // base::Unretained() is safe because the worker thread dispatcher is a lazily + // constructed global singleton which is never destroyed. + PostTaskToWorkerThread( + worker_thread_id, + base::BindOnce(&WorkerThreadDispatcher::DispatchEventOnWorkerThread, + std::move(params), std::move(event_args))); +} void WorkerThreadDispatcher::OnDispatchOnConnect( int worker_thread_id, const PortId& target_port_id,
diff --git a/extensions/renderer/worker_thread_dispatcher.h b/extensions/renderer/worker_thread_dispatcher.h index 6e42ee9b..11a9375 100644 --- a/extensions/renderer/worker_thread_dispatcher.h +++ b/extensions/renderer/worker_thread_dispatcher.h
@@ -50,7 +50,8 @@ // worker thread (this TODO formerly referred to content::ThreadSafeSender // which no longer exists). class WorkerThreadDispatcher : public content::RenderThreadObserver, - public IPC::Sender { + public IPC::Sender, + public mojom::EventDispatcher { public: WorkerThreadDispatcher(); @@ -154,6 +155,8 @@ static bool HandlesMessageOnWorkerThread(const IPC::Message& message); static void ForwardIPC(int worker_thread_id, const IPC::Message& message); static void UpdateBindingsOnWorkerThread(const ExtensionId& extension_id); + static void DispatchEventOnWorkerThread(mojom::DispatchEventParamsPtr params, + base::Value event_args); void OnMessageReceivedOnWorkerThread(int worker_thread_id, const IPC::Message& message); @@ -166,8 +169,6 @@ bool succeeded, const base::ListValue& response, const std::string& error); - void OnDispatchEvent(const mojom::DispatchEventParams& params, - const base::ListValue& event_args); void OnValidateMessagePort(int worker_thread_id, const PortId& id); void OnDispatchOnConnect(int worker_thread_id, const PortId& target_port_id, @@ -181,6 +182,9 @@ const PortId& port_id, const std::string& error_message); + void DispatchEventHelper(mojom::DispatchEventParamsPtr params, + base::Value event_args); + // IPC sender. Belongs to the render thread, but thread safe. scoped_refptr<IPC::SyncMessageFilter> message_filter_; @@ -189,6 +193,12 @@ base::Lock task_runner_map_lock_; scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; mojo::AssociatedRemote<mojom::EventRouter> event_router_remote_; + + // Mojo interface implementation, called from the main thread. + void DispatchEvent(mojom::DispatchEventParamsPtr params, + base::Value event_args) override; + + friend class Dispatcher; }; } // namespace extensions
diff --git a/gpu/command_buffer/common/gpu_memory_buffer_support.cc b/gpu/command_buffer/common/gpu_memory_buffer_support.cc index bd55657..9ab8841e 100644 --- a/gpu/command_buffer/common/gpu_memory_buffer_support.cc +++ b/gpu/command_buffer/common/gpu_memory_buffer_support.cc
@@ -50,13 +50,13 @@ #if BUILDFLAG(IS_CHROMEOS) // Allow odd size for CrOS. // TODO(https://crbug.com/1208788, https://crbug.com/1224781): Merge this - // with the path that uses gfx::AllowOddHeightMultiPlanarBuffers. + // with the path that uses gfx::IsOddHeightMultiPlanarBuffersAllowed. return true; #else // U and V planes are subsampled by a factor of 2. - if (size.width() % 2) + if (size.width() % 2 && !gfx::IsOddWidthMultiPlanarBuffersAllowed()) return false; - if (size.height() % 2 && !gfx::AllowOddHeightMultiPlanarBuffers()) + if (size.height() % 2 && !gfx::IsOddHeightMultiPlanarBuffersAllowed()) return false; return true; #endif // BUILDFLAG(IS_CHROMEOS)
diff --git a/ios/chrome/app/application_delegate/app_state.mm b/ios/chrome/app/application_delegate/app_state.mm index cd73290f..199c2df7 100644 --- a/ios/chrome/app/application_delegate/app_state.mm +++ b/ios/chrome/app/application_delegate/app_state.mm
@@ -14,7 +14,6 @@ #include "base/mac/foundation_util.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" -#include "base/task/post_task.h" #include "components/feature_engagement/public/event_constants.h" #include "components/feature_engagement/public/tracker.h" #include "components/metrics/metrics_service.h" @@ -59,6 +58,7 @@ #include "ios/public/provider/chrome/browser/signin/chrome_identity_service.h" #import "ios/public/provider/chrome/browser/user_feedback/user_feedback_provider.h" #include "ios/web/public/thread/web_task_traits.h" +#include "ios/web/public/thread/web_thread.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" #include "ui/base/device_form_factor.h" @@ -70,7 +70,7 @@ namespace { // Helper method to post |closure| on the UI thread. void PostTaskOnUIThread(base::OnceClosure closure) { - base::PostTask(FROM_HERE, {web::WebThread::UI}, std::move(closure)); + web::GetUIThreadTaskRunner({})->PostTask(FROM_HERE, std::move(closure)); } NSString* const kStartupAttemptReset = @"StartupAttemptReset"; @@ -286,8 +286,8 @@ if (strongSelf) strongSelf->_savingCookies = NO; })); - base::PostTask( - FROM_HERE, {web::WebThread::IO}, base::BindOnce(^{ + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(^{ net::CookieStoreIOS* store = static_cast<net::CookieStoreIOS*>( getter->GetURLRequestContext()->cookie_store()); // FlushStore() runs its callback on any thread. Jump back to UI.
diff --git a/ios/chrome/browser/application_context_impl.mm b/ios/chrome/browser/application_context_impl.mm index 6f69e10..535c43e 100644 --- a/ios/chrome/browser/application_context_impl.mm +++ b/ios/chrome/browser/application_context_impl.mm
@@ -16,7 +16,6 @@ #include "base/metrics/histogram_functions.h" #include "base/path_service.h" #include "base/strings/sys_string_conversions.h" -#include "base/task/post_task.h" #include "base/task/sequenced_task_runner.h" #include "base/task/thread_pool.h" #include "base/time/default_clock.h" @@ -100,8 +99,8 @@ ApplicationContextImpl* app_context, mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory> receiver) { - base::PostTask(FROM_HERE, {web::WebThread::UI}, - base::BindOnce(&RequestProxyResolvingSocketFactoryOnUIThread, + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&RequestProxyResolvingSocketFactoryOnUIThread, app_context, std::move(receiver))); } @@ -534,7 +533,6 @@ GetSharedURLLoaderFactory(), GetApplicationContext()->GetNetworkConnectionTracker(), ::GetChannel(), IOSChromeGCMProfileServiceFactory::GetProductCategoryForSubtypes(), - base::CreateSingleThreadTaskRunner({web::WebThread::UI}), - base::CreateSingleThreadTaskRunner({web::WebThread::IO}), + web::GetUIThreadTaskRunner({}), web::GetIOThreadTaskRunner({}), blocking_task_runner); }
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state_impl_io_data.mm b/ios/chrome/browser/browser_state/chrome_browser_state_impl_io_data.mm index e55313a5..ba8f366a 100644 --- a/ios/chrome/browser/browser_state/chrome_browser_state_impl_io_data.mm +++ b/ios/chrome/browser/browser_state/chrome_browser_state_impl_io_data.mm
@@ -109,8 +109,8 @@ DCHECK_CURRENTLY_ON(web::WebThread::UI); LazyInitialize(); - base::PostTask( - FROM_HERE, {web::WebThread::IO}, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &ChromeBrowserStateImplIOData::ClearNetworkingHistorySinceOnIOThread, base::Unretained(io_data_), time, std::move(completion)));
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state_io_data.mm b/ios/chrome/browser/browser_state/chrome_browser_state_io_data.mm index b276931..0afe52d 100644 --- a/ios/chrome/browser/browser_state/chrome_browser_state_io_data.mm +++ b/ios/chrome/browser/browser_state/chrome_browser_state_io_data.mm
@@ -21,7 +21,6 @@ #include "base/path_service.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" -#include "base/task/post_task.h" #include "base/task/single_thread_task_runner.h" #include "base/task/thread_pool.h" #include "base/threading/thread_task_runner_handle.h" @@ -106,7 +105,7 @@ pref_service); scoped_refptr<base::SingleThreadTaskRunner> io_task_runner = - base::CreateSingleThreadTaskRunner({web::WebThread::IO}); + web::GetIOThreadTaskRunner({}); chrome_http_user_agent_settings_.reset( new IOSChromeHttpUserAgentSettings(pref_service)); @@ -256,8 +255,7 @@ // read from there. enable_metrics_.Init(metrics::prefs::kMetricsReportingEnabled, GetApplicationContext()->GetLocalState()); - enable_metrics_.MoveToSequence( - base::CreateSingleThreadTaskRunner({web::WebThread::IO})); + enable_metrics_.MoveToSequence(web::GetIOThreadTaskRunner({})); } bool ChromeBrowserStateIOData::GetMetricsEnabledStateOnIOThread() const { @@ -385,13 +383,13 @@ if (!context_getters->empty()) { if (web::WebThread::IsThreadInitialized(web::WebThread::IO)) { - base::PostTask(FROM_HERE, {web::WebThread::IO}, - base::BindOnce(&NotifyContextGettersOfShutdownOnIO, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&NotifyContextGettersOfShutdownOnIO, std::move(context_getters))); } } - bool posted = base::DeleteSoon(FROM_HERE, {web::WebThread::IO}, this); + bool posted = web::GetIOThreadTaskRunner({})->DeleteSoon(FROM_HERE, this); if (!posted) delete this; }
diff --git a/ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_impl.mm b/ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_impl.mm index 34590d3a..e6af9bc 100644 --- a/ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_impl.mm +++ b/ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_impl.mm
@@ -7,7 +7,6 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/user_metrics.h" #include "base/notreached.h" -#include "base/task/post_task.h" #include "base/task/sequenced_task_runner.h" #include "components/keyed_service/ios/browser_state_dependency_manager.h" #include "components/profile_metrics/browser_profile_type.h" @@ -127,6 +126,6 @@ // BrowsingDataRemover will never be destroyed and the dialog will never be // closed. We must do this asynchronously in order to avoid reentrancy issues. if (!completion.is_null()) { - base::PostTask(FROM_HERE, {web::WebThread::UI}, std::move(completion)); + web::GetUIThreadTaskRunner({})->PostTask(FROM_HERE, std::move(completion)); } }
diff --git a/ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_io_data.mm b/ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_io_data.mm index e68e38f..51979a0 100644 --- a/ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_io_data.mm +++ b/ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_io_data.mm
@@ -12,7 +12,6 @@ #include "base/callback_helpers.h" #include "base/check_op.h" #include "base/command_line.h" -#include "base/task/post_task.h" #include "components/net_log/chrome_net_log.h" #include "components/prefs/pref_service.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" @@ -55,8 +54,8 @@ // The cache for the incognito profile is in RAM. scoped_refptr<net::URLRequestContextGetter> getter = main_request_context_getter_; - base::PostTask( - FROM_HERE, {web::WebThread::IO}, base::BindOnce(^{ + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(^{ DCHECK_CURRENTLY_ON(web::WebThread::IO); net::HttpCache* cache = getter->GetURLRequestContext() ->http_transaction_factory()
diff --git a/ios/chrome/browser/browser_state/test_chrome_browser_state.mm b/ios/chrome/browser/browser_state/test_chrome_browser_state.mm index 09a85e67..2b7309ce 100644 --- a/ios/chrome/browser/browser_state/test_chrome_browser_state.mm +++ b/ios/chrome/browser/browser_state/test_chrome_browser_state.mm
@@ -15,7 +15,6 @@ #include "base/memory/ptr_util.h" #include "base/path_service.h" #include "base/run_loop.h" -#include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "base/test/test_file_util.h" #include "base/threading/thread_task_runner_handle.h" @@ -45,8 +44,7 @@ const base::FilePath& browser_state_path = context->GetStatePath(); return std::make_unique<WebDataServiceWrapper>( browser_state_path, GetApplicationContext()->GetApplicationLocale(), - base::CreateSingleThreadTaskRunner({web::WebThread::UI}), - base::DoNothing()); + web::GetUIThreadTaskRunner({}), base::DoNothing()); } } // namespace @@ -239,8 +237,7 @@ net::URLRequestContextGetter* TestChromeBrowserState::CreateRequestContext( ProtocolHandlerMap* protocol_handlers) { - return new net::TestURLRequestContextGetter( - base::CreateSingleThreadTaskRunner({web::WebThread::IO})); + return new net::TestURLRequestContextGetter(web::GetIOThreadTaskRunner({})); } void TestChromeBrowserState::CreateWebDataService() {
diff --git a/ios/chrome/browser/browsing_data/cache_counter.cc b/ios/chrome/browser/browsing_data/cache_counter.cc index 5621c50..141c812 100644 --- a/ios/chrome/browser/browsing_data/cache_counter.cc +++ b/ios/chrome/browser/browsing_data/cache_counter.cc
@@ -4,7 +4,6 @@ #include "ios/chrome/browser/browsing_data/cache_counter.h" #include "base/bind.h" -#include "base/task/post_task.h" #include "components/browsing_data/core/pref_names.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/web/public/browser_state.h" @@ -33,8 +32,8 @@ backend_(nullptr) {} void Count() { - base::PostTask(FROM_HERE, {web::WebThread::IO}, - base::BindRepeating(&IOThreadCacheCounter::CountInternal, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindRepeating(&IOThreadCacheCounter::CountInternal, base::Unretained(this), net::OK)); } @@ -84,8 +83,8 @@ case STEP_CALLBACK: { result_ = rv; - base::PostTask( - FROM_HERE, {web::WebThread::UI}, + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&IOThreadCacheCounter::OnCountingFinished, base::Unretained(this)));
diff --git a/ios/chrome/browser/browsing_data/cache_counter_unittest.cc b/ios/chrome/browser/browsing_data/cache_counter_unittest.cc index bfdee818..bfcb766 100644 --- a/ios/chrome/browser/browsing_data/cache_counter_unittest.cc +++ b/ios/chrome/browser/browsing_data/cache_counter_unittest.cc
@@ -14,7 +14,6 @@ #include "base/bind.h" #include "base/run_loop.h" -#include "base/task/post_task.h" #include "base/time/time.h" #include "build/build_config.h" #include "components/browsing_data/core/browsing_data_utils.h" @@ -63,8 +62,8 @@ current_operation_ = OPERATION_ADD_ENTRY; next_step_ = STEP_GET_BACKEND; - base::PostTask(FROM_HERE, {web::WebThread::IO}, - base::BindOnce(&CacheCounterTest::CacheOperationStep, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&CacheCounterTest::CacheOperationStep, base::Unretained(this), net::OK)); WaitForIOThread(); } @@ -74,8 +73,8 @@ current_operation_ = OPERATION_CLEAR_CACHE; next_step_ = STEP_GET_BACKEND; - base::PostTask(FROM_HERE, {web::WebThread::IO}, - base::BindOnce(&CacheCounterTest::CacheOperationStep, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&CacheCounterTest::CacheOperationStep, base::Unretained(this), net::OK)); WaitForIOThread(); } @@ -198,8 +197,8 @@ if (current_operation_ == OPERATION_ADD_ENTRY) entry_->Close(); - base::PostTask(FROM_HERE, {web::WebThread::UI}, - base::BindOnce(&CacheCounterTest::Callback, + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&CacheCounterTest::Callback, base::Unretained(this))); break;
diff --git a/ios/chrome/browser/gcm/ios_chrome_gcm_profile_service_factory.mm b/ios/chrome/browser/gcm/ios_chrome_gcm_profile_service_factory.mm index 597bef9..0cb442f 100644 --- a/ios/chrome/browser/gcm/ios_chrome_gcm_profile_service_factory.mm +++ b/ios/chrome/browser/gcm/ios_chrome_gcm_profile_service_factory.mm
@@ -8,7 +8,6 @@ #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" #include "base/no_destructor.h" -#include "base/task/post_task.h" #include "base/task/sequenced_task_runner.h" #include "base/task/thread_pool.h" #include "build/branding_buildflags.h" @@ -52,11 +51,10 @@ base::WeakPtr<gcm::GCMProfileService> service, mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory> receiver) { - base::CreateSingleThreadTaskRunner({web::WebThread::UI}) - ->PostTask( - FROM_HERE, - base::BindOnce(&RequestProxyResolvingSocketFactoryOnUIThread, context, - std::move(service), std::move(receiver))); + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce(&RequestProxyResolvingSocketFactoryOnUIThread, context, + std::move(service), std::move(receiver))); } } // namespace @@ -112,7 +110,6 @@ GetProductCategoryForSubtypes(), IdentityManagerFactory::GetForBrowserState(browser_state), base::WrapUnique(new gcm::GCMClientFactory), - base::CreateSingleThreadTaskRunner({web::WebThread::UI}), - base::CreateSingleThreadTaskRunner({web::WebThread::IO}), + web::GetUIThreadTaskRunner({}), web::GetIOThreadTaskRunner({}), blocking_task_runner); }
diff --git a/ios/chrome/browser/ios_chrome_io_thread.mm b/ios/chrome/browser/ios_chrome_io_thread.mm index f70fbdb..f32fd802 100644 --- a/ios/chrome/browser/ios_chrome_io_thread.mm +++ b/ios/chrome/browser/ios_chrome_io_thread.mm
@@ -4,12 +4,12 @@ #include "ios/chrome/browser/ios_chrome_io_thread.h" -#include "base/task/post_task.h" #include "components/variations/net/variations_http_headers.h" #include "ios/chrome/browser/net/ios_chrome_network_delegate.h" #include "ios/chrome/common/channel_info.h" #include "ios/web/public/init/network_context_owner.h" #include "ios/web/public/thread/web_task_traits.h" +#include "ios/web/public/thread/web_thread.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -69,7 +69,7 @@ shared_url_loader_factory_->Detach(); if (network_context_) { - base::DeleteSoon(FROM_HERE, {web::WebThread::IO}, - network_context_owner_.release()); + web::GetIOThreadTaskRunner({})->DeleteSoon( + FROM_HERE, network_context_owner_.release()); } }
diff --git a/ios/chrome/browser/ios_chrome_main_parts.mm b/ios/chrome/browser/ios_chrome_main_parts.mm index 593cfcf8..fbe8b0f9 100644 --- a/ios/chrome/browser/ios_chrome_main_parts.mm +++ b/ios/chrome/browser/ios_chrome_main_parts.mm
@@ -15,7 +15,6 @@ #include "base/metrics/user_metrics.h" #include "base/path_service.h" #include "base/strings/sys_string_conversions.h" -#include "base/task/post_task.h" #include "base/task/sequenced_task_runner.h" #include "base/task/thread_pool.h" #include "base/time/default_tick_clock.h" @@ -387,8 +386,7 @@ // This will be called after the command-line has been mutated by about:flags void IOSChromeMainParts::SetUpFieldTrials() { - base::SetRecordActionTaskRunner( - base::CreateSingleThreadTaskRunner({web::WebThread::UI})); + base::SetRecordActionTaskRunner(web::GetUIThreadTaskRunner({})); // FeatureList requires VariationsIdsProvider to be created. variations::VariationsIdsProvider::Create(
diff --git a/ios/chrome/browser/net/chrome_cookie_store_ios_client.mm b/ios/chrome/browser/net/chrome_cookie_store_ios_client.mm index d638a5e..0b22a35 100644 --- a/ios/chrome/browser/net/chrome_cookie_store_ios_client.mm +++ b/ios/chrome/browser/net/chrome_cookie_store_ios_client.mm
@@ -4,7 +4,6 @@ #include "ios/chrome/browser/net/chrome_cookie_store_ios_client.h" -#include "base/task/post_task.h" #include "ios/web/public/thread/web_task_traits.h" #include "ios/web/public/thread/web_thread.h" @@ -16,5 +15,5 @@ scoped_refptr<base::SequencedTaskRunner> ChromeCookieStoreIOSClient::GetTaskRunner() const { - return base::CreateSingleThreadTaskRunner({web::WebThread::IO}); + return web::GetIOThreadTaskRunner({}); }
diff --git a/ios/chrome/browser/net/cookie_util.mm b/ios/chrome/browser/net/cookie_util.mm index 52a5c625..097c1e8 100644 --- a/ios/chrome/browser/net/cookie_util.mm +++ b/ios/chrome/browser/net/cookie_util.mm
@@ -13,7 +13,6 @@ #include "base/callback_helpers.h" #include "base/check.h" #include "base/memory/ref_counted.h" -#include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #import "ios/net/cookies/cookie_store_ios.h" @@ -46,7 +45,7 @@ net::CookieCryptoDelegate* crypto_delegate) { return scoped_refptr<net::SQLitePersistentCookieStore>( new net::SQLitePersistentCookieStore( - path, base::CreateSingleThreadTaskRunner({web::WebThread::IO}), + path, web::GetIOThreadTaskRunner({}), base::ThreadPool::CreateSequencedTaskRunner( {base::MayBlock(), base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::BLOCK_SHUTDOWN}), @@ -126,7 +125,8 @@ void ClearSessionCookies(ChromeBrowserState* browser_state) { scoped_refptr<net::URLRequestContextGetter> getter = browser_state->GetRequestContext(); - base::PostTask(FROM_HERE, {web::WebThread::IO}, base::BindOnce(^{ + web::GetIOThreadTaskRunner({}) + ->PostTask(FROM_HERE, base::BindOnce(^{ getter->GetURLRequestContext() ->cookie_store() ->DeleteSessionCookiesAsync(base::DoNothing());
diff --git a/ios/chrome/browser/net/ios_chrome_http_user_agent_settings.mm b/ios/chrome/browser/net/ios_chrome_http_user_agent_settings.mm index 07ddc11e..c0ffb3f 100644 --- a/ios/chrome/browser/net/ios_chrome_http_user_agent_settings.mm +++ b/ios/chrome/browser/net/ios_chrome_http_user_agent_settings.mm
@@ -4,7 +4,6 @@ #include "ios/chrome/browser/net/ios_chrome_http_user_agent_settings.h" -#include "base/task/post_task.h" #include "components/language/core/browser/pref_names.h" #include "components/prefs/pref_service.h" #include "ios/web/public/thread/web_task_traits.h" @@ -23,8 +22,7 @@ last_pref_accept_language_ = *pref_accept_language_; last_http_accept_language_ = net::HttpUtil::GenerateAcceptLanguageHeader(last_pref_accept_language_); - pref_accept_language_.MoveToSequence( - base::CreateSingleThreadTaskRunner({web::WebThread::IO})); + pref_accept_language_.MoveToSequence(web::GetIOThreadTaskRunner({})); } IOSChromeHttpUserAgentSettings::~IOSChromeHttpUserAgentSettings() {
diff --git a/ios/chrome/browser/net/ios_chrome_network_delegate.cc b/ios/chrome/browser/net/ios_chrome_network_delegate.cc index c0341dc3..6311f79f 100644 --- a/ios/chrome/browser/net/ios_chrome_network_delegate.cc +++ b/ios/chrome/browser/net/ios_chrome_network_delegate.cc
@@ -14,7 +14,6 @@ #include "base/logging.h" #include "base/metrics/histogram.h" #include "base/path_service.h" -#include "base/task/post_task.h" #include "components/content_settings/core/common/content_settings.h" #include "components/prefs/pref_member.h" #include "components/prefs/pref_service.h" @@ -57,8 +56,7 @@ DCHECK_CURRENTLY_ON(web::WebThread::UI); if (enable_do_not_track) { enable_do_not_track->Init(prefs::kEnableDoNotTrack, pref_service); - enable_do_not_track->MoveToSequence( - base::CreateSingleThreadTaskRunner({web::WebThread::IO})); + enable_do_not_track->MoveToSequence(web::GetIOThreadTaskRunner({})); } }
diff --git a/ios/chrome/browser/net/ios_chrome_url_request_context_getter.cc b/ios/chrome/browser/net/ios_chrome_url_request_context_getter.cc index 7eff447..48e34078 100644 --- a/ios/chrome/browser/net/ios_chrome_url_request_context_getter.cc +++ b/ios/chrome/browser/net/ios_chrome_url_request_context_getter.cc
@@ -6,7 +6,6 @@ #include "base/bind.h" #include "base/compiler_specific.h" -#include "base/task/post_task.h" #include "ios/chrome/browser/browser_state/chrome_browser_state_io_data.h" #include "ios/chrome/browser/ios_chrome_io_thread.h" #include "ios/web/public/thread/web_task_traits.h" @@ -97,7 +96,7 @@ scoped_refptr<base::SingleThreadTaskRunner> IOSChromeURLRequestContextGetter::GetNetworkTaskRunner() const { - return base::CreateSingleThreadTaskRunner({web::WebThread::IO}); + return web::GetIOThreadTaskRunner({}); } // static
diff --git a/ios/chrome/browser/omaha/omaha_service.mm b/ios/chrome/browser/omaha/omaha_service.mm index 281c550..7ba5c07 100644 --- a/ios/chrome/browser/omaha/omaha_service.mm +++ b/ios/chrome/browser/omaha/omaha_service.mm
@@ -20,7 +20,6 @@ #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/system/sys_info.h" -#include "base/task/post_task.h" #include "base/time/time.h" #include "base/values.h" #include "build/branding_buildflags.h" @@ -370,8 +369,8 @@ !service->url_loader_factory_); service->pending_url_loader_factory_ = std::move(pending_url_loader_factory); service->locale_lang_ = GetApplicationContext()->GetApplicationLocale(); - base::PostTask(FROM_HERE, {web::WebThread::IO}, - base::BindOnce(&OmahaService::SendOrScheduleNextPing, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&OmahaService::SendOrScheduleNextPing, base::Unretained(service))); } @@ -497,16 +496,16 @@ base::OnceCallback<void(base::DictionaryValue*)> callback) { if (OmahaService::IsEnabled()) { OmahaService* service = GetInstance(); - base::PostTask( - FROM_HERE, {web::WebThread::IO}, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&OmahaService::GetDebugInformationOnIOThread, base::Unretained(service), std::move(callback))); } else { auto result = std::make_unique<base::DictionaryValue>(); // Invoke the callback with an empty response. - base::PostTask( - FROM_HERE, {web::WebThread::UI}, + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), base::Owned(result.release()))); } } @@ -776,16 +775,16 @@ if (details) { // Use the correct callback based on if a one-off check is ongoing. if (!one_off_check_callback_.is_null()) { - base::PostTask( - FROM_HERE, {web::WebThread::UI}, + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(std::move(one_off_check_callback_), *details)); // Do not schedule another ping for one-off checks, unless // it canceled a scheduled ping. need_to_schedule_ping = scheduled_ping_canceled_; scheduled_ping_canceled_ = false; } else if (!details->is_up_to_date) { - base::PostTask(FROM_HERE, {web::WebThread::UI}, - base::BindOnce(upgrade_recommended_callback_, *details)); + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(upgrade_recommended_callback_, *details)); } } @@ -820,8 +819,8 @@ (timer_.desired_run_time() - base::TimeTicks::Now()))); // Sending the value to the callback. - base::PostTask( - FROM_HERE, {web::WebThread::UI}, + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), base::Owned(result.release()))); }
diff --git a/ios/chrome/browser/policy/chrome_browser_cloud_management_controller_ios.mm b/ios/chrome/browser/policy/chrome_browser_cloud_management_controller_ios.mm index e6da04d..db46789 100644 --- a/ios/chrome/browser/policy/chrome_browser_cloud_management_controller_ios.mm +++ b/ios/chrome/browser/policy/chrome_browser_cloud_management_controller_ios.mm
@@ -7,7 +7,6 @@ #include <utility> #include "base/bind.h" -#include "base/task/post_task.h" #include "base/task/task_traits.h" #include "components/enterprise/browser/reporting/report_generator.h" #include "components/enterprise/browser/reporting/report_scheduler.h" @@ -113,8 +112,7 @@ scoped_refptr<base::SingleThreadTaskRunner> ChromeBrowserCloudManagementControllerIOS::GetBestEffortTaskRunner() { DCHECK_CURRENTLY_ON(web::WebThread::UI); - return base::CreateSingleThreadTaskRunner( - {web::WebThread::UI, base::TaskPriority::BEST_EFFORT}); + return web::GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT}); } std::unique_ptr<enterprise_reporting::ReportingDelegateFactory>
diff --git a/ios/chrome/browser/safe_browsing/fake_safe_browsing_service.mm b/ios/chrome/browser/safe_browsing/fake_safe_browsing_service.mm index f74a5a6..aca24b04a 100644 --- a/ios/chrome/browser/safe_browsing/fake_safe_browsing_service.mm +++ b/ios/chrome/browser/safe_browsing/fake_safe_browsing_service.mm
@@ -5,7 +5,6 @@ #include "ios/chrome/browser/safe_browsing/fake_safe_browsing_service.h" #include "base/callback_helpers.h" -#include "base/task/post_task.h" #include "components/safe_browsing/core/browser/db/test_database_manager.h" #include "components/safe_browsing/core/browser/safe_browsing_url_checker_impl.h" #import "ios/chrome/browser/safe_browsing/url_checker_delegate_impl.h" @@ -33,7 +32,7 @@ []() { return static_cast<web::WebState*>(nullptr); }), /*real_time_lookup_enabled=*/false, /*can_rt_check_subresource_url=*/false, - base::CreateSingleThreadTaskRunner({web::WebThread::UI}), + web::GetUIThreadTaskRunner({}), /*url_lookup_service_on_ui=*/nullptr) {} ~FakeSafeBrowsingUrlCheckerImpl() override = default;
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_query_manager.mm b/ios/chrome/browser/safe_browsing/safe_browsing_query_manager.mm index a498a0c..1594006a 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_query_manager.mm +++ b/ios/chrome/browser/safe_browsing/safe_browsing_query_manager.mm
@@ -6,10 +6,10 @@ #include "base/callback_helpers.h" #include "base/check_op.h" -#include "base/task/post_task.h" #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/safe_browsing/safe_browsing_service.h" #include "ios/web/public/thread/web_task_traits.h" +#include "ios/web/public/thread/web_thread.h" #include "services/network/public/mojom/fetch_api.mojom.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -41,8 +41,8 @@ observer.SafeBrowsingQueryManagerDestroyed(this); } - base::DeleteSoon(FROM_HERE, {web::WebThread::IO}, - url_checker_client_.release()); + web::GetIOThreadTaskRunner({})->DeleteSoon(FROM_HERE, + url_checker_client_.release()); } void SafeBrowsingQueryManager::AddObserver(Observer* observer) { @@ -67,8 +67,8 @@ base::OnceCallback<void(bool proceed, bool show_error_page)> callback = base::BindOnce(&SafeBrowsingQueryManager::UrlCheckFinished, weak_factory_.GetWeakPtr(), query); - base::PostTask( - FROM_HERE, {web::WebThread::IO}, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&UrlCheckerClient::CheckUrl, url_checker_client_->AsWeakPtr(), std::move(url_checker), query.url, query.http_method, std::move(callback))); @@ -203,8 +203,8 @@ DCHECK(url_checker); auto it = active_url_checkers_.find(url_checker); - base::PostTask( - FROM_HERE, {web::WebThread::UI}, + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(std::move(it->second), proceed, showed_interstitial)); active_url_checkers_.erase(it);
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_service_impl.mm b/ios/chrome/browser/safe_browsing/safe_browsing_service_impl.mm index 54a1b63..a74059c 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_service_impl.mm +++ b/ios/chrome/browser/safe_browsing/safe_browsing_service_impl.mm
@@ -7,7 +7,6 @@ #include "base/bind.h" #include "base/files/file_path.h" #include "base/path_service.h" -#include "base/task/post_task.h" #include "build/branding_buildflags.h" #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_service.h" @@ -58,9 +57,8 @@ base::FilePath safe_browsing_data_path = user_data_path.Append(safe_browsing::kSafeBrowsingBaseFilename); safe_browsing_db_manager_ = safe_browsing::V4LocalDatabaseManager::Create( - safe_browsing_data_path, - base::CreateSingleThreadTaskRunner({web::WebThread::UI}), - base::CreateSingleThreadTaskRunner({web::WebThread::IO}), + safe_browsing_data_path, web::GetUIThreadTaskRunner({}), + web::GetIOThreadTaskRunner({}), safe_browsing::ExtendedReportingLevelCallback()); url_checker_delegate_ = @@ -69,8 +67,8 @@ io_thread_enabler_ = base::MakeRefCounted<IOThreadEnabler>(safe_browsing_db_manager_); - base::PostTask( - FROM_HERE, {web::WebThread::IO}, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&IOThreadEnabler::Initialize, io_thread_enabler_, base::WrapRefCounted(this), network_context_client_.BindNewPipeAndPassReceiver(), @@ -107,8 +105,8 @@ DCHECK_CURRENTLY_ON(web::WebThread::UI); pref_change_registrar_.reset(); - base::PostTask( - FROM_HERE, {web::WebThread::IO}, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&IOThreadEnabler::ShutDown, io_thread_enabler_)); network_context_client_.reset(); } @@ -127,8 +125,7 @@ return std::make_unique<safe_browsing::SafeBrowsingUrlCheckerImpl>( request_destination, url_checker_delegate_, web_state->CreateDefaultGetter(), can_perform_full_url_lookup, - can_realtime_check_subresource_url, - base::CreateSingleThreadTaskRunner({web::WebThread::UI}), + can_realtime_check_subresource_url, web::GetUIThreadTaskRunner({}), url_lookup_service ? url_lookup_service->GetWeakPtr() : nullptr); } @@ -151,13 +148,12 @@ base::OnceClosure callback) { if (creation_range.start() == base::Time() && creation_range.end() == base::Time::Max()) { - base::PostTask( - FROM_HERE, - {web::WebThread::IO, base::TaskShutdownBehavior::BLOCK_SHUTDOWN}, - base::BindOnce(&IOThreadEnabler::ClearAllCookies, io_thread_enabler_, - std::move(callback))); + web::GetIOThreadTaskRunner({base::TaskShutdownBehavior::BLOCK_SHUTDOWN}) + ->PostTask(FROM_HERE, + base::BindOnce(&IOThreadEnabler::ClearAllCookies, + io_thread_enabler_, std::move(callback))); } else { - base::PostTask(FROM_HERE, {web::WebThread::IO}, std::move(callback)); + web::GetIOThreadTaskRunner({})->PostTask(FROM_HERE, std::move(callback)); } } @@ -170,8 +166,8 @@ void SafeBrowsingServiceImpl::UpdateSafeBrowsingEnabledState() { bool enabled = pref_change_registrar_->prefs()->GetBoolean(prefs::kSafeBrowsingEnabled); - base::PostTask(FROM_HERE, {web::WebThread::IO}, - base::BindOnce(&IOThreadEnabler::SetSafeBrowsingEnabled, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&IOThreadEnabler::SetSafeBrowsingEnabled, io_thread_enabler_, enabled)); } @@ -270,8 +266,8 @@ void SafeBrowsingServiceImpl::IOThreadEnabler::SetUpURLLoaderFactory( scoped_refptr<SafeBrowsingServiceImpl> safe_browsing_service) { DCHECK_CURRENTLY_ON(web::WebThread::IO); - base::PostTask( - FROM_HERE, {web::WebThread::UI}, + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&SafeBrowsingServiceImpl::SetUpURLLoaderFactory, safe_browsing_service, url_loader_factory_.BindNewPipeAndPassReceiver()));
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_service_unittest.mm b/ios/chrome/browser/safe_browsing/safe_browsing_service_unittest.mm index f6da534b..9ec1269 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_service_unittest.mm +++ b/ios/chrome/browser/safe_browsing/safe_browsing_service_unittest.mm
@@ -7,7 +7,6 @@ #include "base/files/scoped_temp_dir.h" #include "base/path_service.h" #include "base/run_loop.h" -#include "base/task/post_task.h" #include "base/test/bind.h" #include "base/test/scoped_feature_list.h" #include "components/prefs/pref_service.h" @@ -84,8 +83,8 @@ result_pending_ = true; url_checker_ = safe_browsing_service_->CreateUrlChecker( network::mojom::RequestDestination::kDocument, &web_state_); - base::PostTask(FROM_HERE, {web::WebThread::IO}, - base::BindOnce(&TestUrlCheckerClient::CheckUrlOnIOThread, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&TestUrlCheckerClient::CheckUrlOnIOThread, base::Unretained(this), url)); } @@ -93,8 +92,8 @@ result_pending_ = true; url_checker_ = safe_browsing_service_->CreateUrlChecker( network::mojom::RequestDestination::kIframe, &web_state_); - base::PostTask(FROM_HERE, {web::WebThread::IO}, - base::BindOnce(&TestUrlCheckerClient::CheckUrlOnIOThread, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&TestUrlCheckerClient::CheckUrlOnIOThread, base::Unretained(this), url)); } @@ -184,16 +183,16 @@ } void MarkUrlAsMalware(const GURL& bad_url) { - base::PostTask( - FROM_HERE, {web::WebThread::IO}, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&SafeBrowsingServiceTest::MarkUrlAsMalwareOnIOThread, base::Unretained(this), bad_url)); } // Adds the given |safe_url| to the allowlist used by real-time checks. void MarkUrlAsRealTimeSafe(const GURL& safe_url) { - base::PostTask( - FROM_HERE, {web::WebThread::IO}, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&SafeBrowsingServiceTest::MarkUrlAsSafeOnIOThread, base::Unretained(this), safe_url)); }
diff --git a/ios/chrome/browser/safe_browsing/url_checker_delegate_impl.mm b/ios/chrome/browser/safe_browsing/url_checker_delegate_impl.mm index 0e4c112..bc465f6 100644 --- a/ios/chrome/browser/safe_browsing/url_checker_delegate_impl.mm +++ b/ios/chrome/browser/safe_browsing/url_checker_delegate_impl.mm
@@ -4,7 +4,6 @@ #include "ios/chrome/browser/safe_browsing/url_checker_delegate_impl.h" -#include "base/task/post_task.h" #include "components/safe_browsing/core/browser/db/database_manager.h" #include "components/safe_browsing/core/browser/db/v4_protocol_manager_util.h" #import "components/safe_browsing/ios/browser/safe_browsing_url_allow_list.h" @@ -101,8 +100,8 @@ bool has_user_gesture) { // Query the allow list on the UI thread to determine whether the navigation // can proceed. - base::PostTask( - FROM_HERE, {web::WebThread::UI}, + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&HandleBlockingPageRequestOnUIThread, resource)); }
diff --git a/ios/chrome/browser/share_extension/share_extension_item_receiver.mm b/ios/chrome/browser/share_extension/share_extension_item_receiver.mm index 218e0c6..09e08ceda 100644 --- a/ios/chrome/browser/share_extension/share_extension_item_receiver.mm +++ b/ios/chrome/browser/share_extension/share_extension_item_receiver.mm
@@ -13,7 +13,6 @@ #include "base/metrics/user_metrics_action.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" -#include "base/task/post_task.h" #include "base/task/sequenced_task_runner.h" #include "base/task/thread_pool.h" #include "base/threading/scoped_blocking_call.h" @@ -182,9 +181,10 @@ } __weak ShareExtensionItemReceiver* weakSelf = self; - base::PostTask(FROM_HERE, {web::WebThread::UI}, base::BindOnce(^{ - [weakSelf readingListFolderCreated]; - })); + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(^{ + [weakSelf readingListFolderCreated]; + })); } - (void)readingListFolderCreated { @@ -259,12 +259,13 @@ SHARE_EXTENSION_SOURCE_COUNT); __weak ShareExtensionItemReceiver* weakSelf = self; - base::PostTask(FROM_HERE, {web::WebThread::UI}, base::BindOnce(^{ - [weakSelf processEntryWithType:entryType - title:entryTitle - URL:entryURL - completion:completion]; - })); + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(^{ + [weakSelf processEntryWithType:entryType + title:entryTitle + URL:entryURL + completion:completion]; + })); return YES; } @@ -405,9 +406,9 @@ if ([files count]) { __weak ShareExtensionItemReceiver* weakSelf = self; - base::PostTask(FROM_HERE, {web::WebThread::UI}, base::BindOnce(^{ - [weakSelf entriesReceived:files]; - })); + web::GetUIThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(^{ + [weakSelf entriesReceived:files]; + })); } } @@ -422,14 +423,14 @@ __block std::unique_ptr<ReadingListModel::ScopedReadingListBatchUpdate> batchToken(_readingListModel->BeginBatchUpdates()); _taskRunner->PostTask(FROM_HERE, base::BindOnce(^{ - [weakSelf handleFileAtURL:fileURL - withCompletion:^{ - base::PostTask(FROM_HERE, - {web::WebThread::UI}, - base::BindOnce(^{ - batchToken.reset(); - })); - }]; + [weakSelf + handleFileAtURL:fileURL + withCompletion:^{ + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(^{ + batchToken.reset(); + })); + }]; })); } }
diff --git a/ios/chrome/browser/snapshots/snapshot_cache.mm b/ios/chrome/browser/snapshots/snapshot_cache.mm index 262e6f1..6eabcc70 100644 --- a/ios/chrome/browser/snapshots/snapshot_cache.mm +++ b/ios/chrome/browser/snapshots/snapshot_cache.mm
@@ -7,6 +7,8 @@ #import <UIKit/UIKit.h> +#include <set> + #include "base/base_paths.h" #include "base/bind.h" #include "base/containers/contains.h"
diff --git a/ios/chrome/browser/snapshots/snapshot_generator.mm b/ios/chrome/browser/snapshots/snapshot_generator.mm index 63436422..14e2b29f 100644 --- a/ios/chrome/browser/snapshots/snapshot_generator.mm +++ b/ios/chrome/browser/snapshots/snapshot_generator.mm
@@ -13,7 +13,6 @@ #include "base/bind.h" #include "base/check_op.h" -#include "base/task/post_task.h" #import "ios/chrome/browser/snapshots/snapshot_cache.h" #import "ios/chrome/browser/snapshots/snapshot_generator_delegate.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" @@ -132,9 +131,9 @@ if (![self canTakeSnapshot]) { if (completion) { - base::PostTask(FROM_HERE, {web::WebThread::UI}, base::BindOnce(^{ - completion(nil); - })); + web::GetUIThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(^{ + completion(nil); + })); } return; }
diff --git a/ios/chrome/browser/snapshots/snapshot_tab_helper.mm b/ios/chrome/browser/snapshots/snapshot_tab_helper.mm index b6d3db3..87e0a0b 100644 --- a/ios/chrome/browser/snapshots/snapshot_tab_helper.mm +++ b/ios/chrome/browser/snapshots/snapshot_tab_helper.mm
@@ -7,7 +7,6 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" -#include "base/task/post_task.h" #import "ios/chrome/browser/snapshots/snapshot_cache.h" #import "ios/chrome/browser/snapshots/snapshot_generator.h" #include "ios/chrome/browser/ui/util/ui_util.h" @@ -145,8 +144,8 @@ break; bool was_loading = was_loading_during_last_snapshot_; - base::PostDelayedTask( - FROM_HERE, {web::WebThread::UI}, + web::GetUIThreadTaskRunner({})->PostDelayedTask( + FROM_HERE, base::BindOnce( &SnapshotTabHelper::UpdateSnapshotWithCallback, weak_ptr_factory_.GetWeakPtr(),
diff --git a/ios/chrome/browser/sync/glue/sync_start_util.mm b/ios/chrome/browser/sync/glue/sync_start_util.mm index 72e375a..4f074b0c 100644 --- a/ios/chrome/browser/sync/glue/sync_start_util.mm +++ b/ios/chrome/browser/sync/glue/sync_start_util.mm
@@ -7,7 +7,6 @@ #include "base/bind.h" #include "base/files/file_path.h" #include "base/location.h" -#include "base/task/post_task.h" #include "components/sync/driver/sync_service.h" #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" @@ -51,8 +50,8 @@ void StartSyncProxy(const base::FilePath& browser_state_path, syncer::ModelType type) { - base::PostTask( - FROM_HERE, {web::WebThread::UI}, + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&StartSyncOnUIThread, browser_state_path, type)); }
diff --git a/ios/chrome/browser/sync/ios_chrome_sync_client.mm b/ios/chrome/browser/sync/ios_chrome_sync_client.mm index 7e0c885..c4eb725 100644 --- a/ios/chrome/browser/sync/ios_chrome_sync_client.mm +++ b/ios/chrome/browser/sync/ios_chrome_sync_client.mm
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/feature_list.h" #include "base/logging.h" -#include "base/task/post_task.h" #include "components/autofill/core/browser/webdata/autocomplete_sync_bridge.h" #include "components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h" #include "components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.h" @@ -81,8 +80,7 @@ component_factory_ = std::make_unique<browser_sync::SyncApiComponentFactoryImpl>( - this, ::GetChannel(), - base::CreateSingleThreadTaskRunner({web::WebThread::UI}), db_thread_, + this, ::GetChannel(), web::GetUIThreadTaskRunner({}), db_thread_, profile_web_data_service_, account_web_data_service_, password_store_, /*account_password_store=*/nullptr, ios::BookmarkSyncServiceFactory::GetForBrowserState(browser_state_));
diff --git a/ios/chrome/browser/ui/image_util/image_copier.mm b/ios/chrome/browser/ui/image_util/image_copier.mm index 801172b..70bd6b5 100644 --- a/ios/chrome/browser/ui/image_util/image_copier.mm +++ b/ios/chrome/browser/ui/image_util/image_copier.mm
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/metrics/histogram_macros.h" #import "base/strings/sys_string_conversions.h" -#include "base/task/post_task.h" #include "components/strings/grit/components_strings.h" #import "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h" @@ -148,8 +147,8 @@ style:UIAlertActionStyleCancel]; // Delays launching alert by |kAlertDelayInMs|. - base::PostDelayedTask( - FROM_HERE, {web::WebThread::UI}, base::BindOnce(^{ + web::GetUIThreadTaskRunner({})->PostDelayedTask( + FROM_HERE, base::BindOnce(^{ // Checks that the copy has not finished yet. if (callbackID == weakSelf.activeID) { [weakSelf.alertCoordinator start];
diff --git a/ios/chrome/browser/ui/main/scene_controller.mm b/ios/chrome/browser/ui/main/scene_controller.mm index b3434b72..26d1269 100644 --- a/ios/chrome/browser/ui/main/scene_controller.mm +++ b/ios/chrome/browser/ui/main/scene_controller.mm
@@ -15,7 +15,6 @@ #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" #include "base/strings/sys_string_conversions.h" -#include "base/task/post_task.h" #include "base/time/time.h" #include "components/breadcrumbs/core/breadcrumb_manager_keyed_service.h" #include "components/breadcrumbs/core/breadcrumb_persistent_storage_manager.h" @@ -126,6 +125,7 @@ #import "ios/public/provider/chrome/browser/ui_utils/ui_utils_api.h" #import "ios/public/provider/chrome/browser/user_feedback/user_feedback_provider.h" #include "ios/web/public/thread/web_task_traits.h" +#include "ios/web/public/thread/web_thread.h" #import "ios/web/public/web_state.h" #import "net/base/mac/url_conversions.h" #include "ui/base/l10n/l10n_util.h" @@ -2847,8 +2847,8 @@ } }; - base::PostTaskAndReply(FROM_HERE, {web::WebThread::IO}, base::DoNothing(), - base::BindRepeating(cleanup)); + web::GetIOThreadTaskRunner({})->PostTaskAndReply( + FROM_HERE, base::DoNothing(), base::BindRepeating(cleanup)); } // a) The first condition can happen when the last incognito tab is closed
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn index 08065a03..ea6b720 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn
@@ -252,6 +252,7 @@ "//ios/chrome/browser/ui/start_surface:feature_flags", "//ios/chrome/browser/ui/tab_switcher/tab_grid:features", "//ios/chrome/browser/ui/tab_switcher/tab_grid/grid:grid_ui_constants", + "//ios/chrome/browser/ui/table_view/cells:cells_constants", "//ios/chrome/browser/ui/thumb_strip:feature_flags", "//ios/chrome/browser/ui/util", "//ios/chrome/test/earl_grey:eg_test_support+eg2",
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h index bd030d5b..3dccb29 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h
@@ -20,6 +20,12 @@ // Accessibility identifier for the background of the grid. extern NSString* const kGridBackgroundIdentifier; +// Accessibility identifier for the grid section header. +extern NSString* const kGridSectionHeaderIdentifier; + +// Accessibility identifier for the suggested actions cell. +extern NSString* const kSuggestedActionsGridCellIdentifier; + // Grid styling. extern NSString* const kGridBackgroundColor;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.mm index 5ce547a..8113118 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.mm
@@ -18,6 +18,13 @@ // Accessibility identifier for the background of the grid. NSString* const kGridBackgroundIdentifier = @"GridBackgroundIdentifier"; +// Accessibility identifier for the grid section header. +NSString* const kGridSectionHeaderIdentifier = @"GridSectionHeaderIdentifier"; + +// Accessibility identifier for the suggested actions cell. +NSString* const kSuggestedActionsGridCellIdentifier = + @"SuggestedActionsGridCellIdentifier"; + // Grid styling. NSString* const kGridBackgroundColor = @"grid_background_color";
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_header.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_header.mm index 4b54adb..808afba2 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_header.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_header.mm
@@ -29,7 +29,7 @@ self = [super initWithFrame:frame]; if (self) { self.backgroundColor = [UIColor colorNamed:kGridBackgroundColor]; - + self.accessibilityIdentifier = kGridSectionHeaderIdentifier; UILabel* titleLabel = [[UILabel alloc] init]; titleLabel.translatesAutoresizingMaskIntoConstraints = NO; titleLabel.font =
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/suggested_actions/suggested_actions_grid_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/suggested_actions/suggested_actions_grid_cell.mm index 21409742..898461b 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/suggested_actions/suggested_actions_grid_cell.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/suggested_actions/suggested_actions_grid_cell.mm
@@ -22,6 +22,7 @@ self.backgroundView = [[UIView alloc] init]; self.backgroundView.backgroundColor = [UIColor colorNamed:kGridBackgroundColor]; + self.accessibilityIdentifier = kSuggestedActionsGridCellIdentifier; } return self; }
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 be9a64f..e2cc26b 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
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/format_macros.h" #include "base/ios/ios_util.h" #include "base/strings/stringprintf.h" #include "base/strings/sys_string_conversions.h" @@ -11,6 +12,7 @@ #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/table_view/cells/table_view_cells_constants.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_app_interface.h" @@ -45,6 +47,7 @@ using chrome_test_util::TabGridSearchModeToolbar; using chrome_test_util::TabGridSearchTabsButton; using chrome_test_util::TabGridSelectTabsMenuButton; +using chrome_test_util::RegularTabGrid; namespace { char kURL1[] = "http://firstURL"; @@ -67,14 +70,15 @@ grey_sufficientlyVisible(), nil); } -id<GREYMatcher> TabWithTitle(NSString* title) { - return grey_allOf(TabGridCell(), grey_accessibilityLabel(title), - grey_sufficientlyVisible(), nil); +id<GREYMatcher> TabWithTitle(char* title) { + return grey_allOf( + TabGridCell(), + grey_accessibilityLabel([NSString stringWithUTF8String:title]), + grey_sufficientlyVisible(), nil); } id<GREYMatcher> TabWithTitleAndIndex(char* title, unsigned int index) { - return grey_allOf(TabWithTitle([NSString stringWithUTF8String:title]), - TabGridCellAtIndex(index), nil); + return grey_allOf(TabWithTitle(title), TabGridCellAtIndex(index), nil); } // Identifer for cell at given |index| in the tab grid. @@ -123,6 +127,90 @@ return grey_accessibilityID(kTabGridScrimIdentifier); } +// Returns a matcher for the search results header with title set with +// |title_id|. +id<GREYMatcher> SearchSectionHeaderWithTitleID(int title_id) { + id<GREYMatcher> title_matcher = + grey_allOf(grey_accessibilityLabel(l10n_util::GetNSString(title_id)), + grey_sufficientlyVisible(), nil); + return grey_allOf(grey_accessibilityID(kGridSectionHeaderIdentifier), + grey_descendant(title_matcher), grey_sufficientlyVisible(), + nil); +} + +// Returns a matcher for the search results open tabs section header. +id<GREYMatcher> SearchOpenTabsSectionHeader() { + return SearchSectionHeaderWithTitleID( + IDS_IOS_TABS_SEARCH_OPEN_TABS_SECTION_HEADER_TITLE); +} + +// Returns a matcher for the search results suggested actions section header. +id<GREYMatcher> SearchSuggestedActionsSectionHeader() { + return SearchSectionHeaderWithTitleID(IDS_IOS_TABS_SEARCH_SUGGESTED_ACTIONS); +} + +// Returns a matcher for the search results open tabs section header with +// |count| set in the value label . +id<GREYMatcher> SearchOpenTabsHeaderWithValue(size_t count) { + NSString* count_str = [NSString stringWithFormat:@"%" PRIuS, count]; + NSString* value = l10n_util::GetNSStringF( + IDS_IOS_TABS_SEARCH_OPEN_TABS_COUNT, base::SysNSStringToUTF16(count_str)); + id<GREYMatcher> value_matcher = grey_allOf(grey_accessibilityLabel(value), + grey_sufficientlyVisible(), nil); + + return grey_allOf(SearchOpenTabsSectionHeader(), + grey_descendant(value_matcher), grey_sufficientlyVisible(), + nil); +} + +// Returns a matcher for the "Search on web" suggested action. +id<GREYMatcher> SearchOnWebSuggestedAction() { + return grey_allOf(chrome_test_util::StaticTextWithAccessibilityLabelId( + IDS_IOS_TABS_SEARCH_SUGGESTED_ACTION_SEARCH_WEB), + grey_sufficientlyVisible(), nil); +} + +// Returns a matcher for the "Search recent tabs" suggested action. +id<GREYMatcher> SearchRecentTabsSuggestedAction() { + return grey_allOf( + chrome_test_util::StaticTextWithAccessibilityLabelId( + IDS_IOS_TABS_SEARCH_SUGGESTED_ACTION_SEARCH_RECENT_TABS), + grey_sufficientlyVisible(), nil); +} + +// Returns a matcher for the "Search history" suggested action. +id<GREYMatcher> SearchHistorySuggestedAction() { + return grey_allOf( + grey_accessibilityID(kTableViewTabsSearchSuggestedHistoryItemId), + grey_sufficientlyVisible(), nil); +} + +// Returns a matcher for the "Search history (|matches_count| Found)" suggested +// action. +id<GREYMatcher> SearchHistorySuggestedActionWithMatches(size_t matches_count) { + NSString* count_str = [NSString stringWithFormat:@"%" PRIuS, matches_count]; + NSString* history_label = l10n_util::GetNSStringF( + IDS_IOS_TABS_SEARCH_SUGGESTED_ACTION_SEARCH_HISTORY, + base::SysNSStringToUTF16(count_str)); + return grey_allOf(grey_accessibilityLabel(history_label), + grey_sufficientlyVisible(), nil); +} + +// Returns a matcher for the search suggested actions section. +id<GREYMatcher> SearchSuggestedActionsSection() { + return grey_allOf(grey_accessibilityID(kSuggestedActionsGridCellIdentifier), + grey_sufficientlyVisible(), nil); +} + +// Returns a matcher for the search suggested actions section with the history +// item matches count set to |matches_count|. +id<GREYMatcher> SearchSuggestedActionsSectionWithHistoryMatchesCount( + size_t matches_count) { + return grey_allOf( + SearchSuggestedActionsSection(), + grey_descendant(SearchHistorySuggestedActionWithMatches(matches_count)), + grey_sufficientlyVisible(), nil); +} } // namespace @interface TabGridTestCase : WebHttpServerChromeTestCase { @@ -148,7 +236,11 @@ @selector(testSearchOpenTabsContextMenuShare), @selector(testSearchOpenTabsContextMenuAddToReadingList), @selector(testSearchOpenTabsContextMenuAddToBookmarks), - @selector(testSearchOpenTabsContextMenuCloseTab)}; + @selector(testSearchOpenTabsContextMenuCloseTab), + @selector(testOpenTabsHeaderVisibleInSearchModeWhenSearchBarIsNotEmpty), + @selector(testSuggestedActionsVisibleInSearchModeWhenSearchBarIsNotEmpty), + @selector(testSearchSuggestedActionsDisplaysCorrectHistoryMatchesCount), + @selector(testSearchSuggestedActionsSectionContentInRegularGrid)}; for (SEL test : searchTests) { if ([self isRunningTest:test]) { config.features_enabled.push_back(kTabsSearch); @@ -176,6 +268,19 @@ web::test::SetUpSimpleHttpServer(responses); } +- (void)tearDown { + [super tearDown]; + // Ensure that pref set in testTabGridItemContextMenuAddToBookmarkGreyed is + // reset even if the test failed. + if ([self isRunningTest:@selector + (testTabGridItemContextMenuAddToBookmarkGreyed)]) { + [ChromeEarlGreyAppInterface + setBoolValue:YES + forUserPref:base::SysUTF8ToNSString( + bookmarks::prefs::kEditBookmarksEnabled)]; + } +} + // Tests entering and leaving the tab grid. - (void)testEnteringAndLeavingTabGrid { [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] @@ -443,8 +548,7 @@ performAction:grey_tap()]; // Make sure that the tab is no longer present. - [[EarlGrey selectElementWithMatcher:TabWithTitle([NSString - stringWithUTF8String:kTitle1])] + [[EarlGrey selectElementWithMatcher:TabWithTitle(kTitle1)] assertWithMatcher:grey_nil()]; [[EarlGrey selectElementWithMatcher:chrome_test_util:: @@ -946,8 +1050,7 @@ performAction:grey_tap()]; // Make sure that the tab is no longer present. - [[EarlGrey selectElementWithMatcher:TabWithTitle([NSString - stringWithUTF8String:kTitle1])] + [[EarlGrey selectElementWithMatcher:TabWithTitle(kTitle1)] assertWithMatcher:grey_nil()]; [[EarlGrey selectElementWithMatcher:chrome_test_util:: @@ -1348,12 +1451,17 @@ [[EarlGrey selectElementWithMatcher:TabGridSearchTabsButton()] performAction:grey_tap()]; - // Searching with the word "Page" should match only 3 results. [[EarlGrey selectElementWithMatcher:TabGridSearchBar()] performAction:grey_typeText(@"Page")]; - [self verifyVisibleTabsCount:3]; - // Verify that search results are correct and in the expected order. + // Verify that the header of the open tabs section has the correct results + // count. + [[EarlGrey selectElementWithMatcher:SearchOpenTabsHeaderWithValue(3)] + assertWithMatcher:grey_notNil()]; + + // Verify that there are 3 results for the query "Page" and they are in the + // expected order. + [self verifyVisibleTabsCount:3]; [[EarlGrey selectElementWithMatcher:TabWithTitleAndIndex(kTitle1, 0)] assertWithMatcher:grey_notNil()]; [[EarlGrey selectElementWithMatcher:TabWithTitleAndIndex(kTitle2, 1)] @@ -1361,6 +1469,200 @@ [[EarlGrey selectElementWithMatcher:TabWithTitleAndIndex(kTitle4, 2)] assertWithMatcher:grey_notNil()]; + // Update the search query with one that doesn't match any results. + [[EarlGrey selectElementWithMatcher:TabGridSearchBar()] + performAction:grey_typeText(@"Foo")]; + + // Verify that the header of the open tabs section has 0 as the results count. + [[EarlGrey selectElementWithMatcher:SearchOpenTabsHeaderWithValue(0)] + assertWithMatcher:grey_notNil()]; + + // Verify that no tabs are visible and previously shown tabs disappeared. + [self verifyVisibleTabsCount:0]; + + [[EarlGrey selectElementWithMatcher:TabWithTitle(kTitle1)] + assertWithMatcher:grey_nil()]; + [[EarlGrey selectElementWithMatcher:TabWithTitle(kTitle2)] + assertWithMatcher:grey_nil()]; + [[EarlGrey selectElementWithMatcher:TabWithTitle(kTitle4)] + assertWithMatcher:grey_nil()]; +} + +// Tests that open tabs search results header appear only when there is a query +// on the search bar. +- (void)testOpenTabsHeaderVisibleInSearchModeWhenSearchBarIsNotEmpty { + [self loadTestURLsInNewTabs]; + [ChromeEarlGrey showTabSwitcher]; + + // Verify that the header doesn't exist in normal mode. + [[EarlGrey selectElementWithMatcher:SearchOpenTabsSectionHeader()] + assertWithMatcher:grey_nil()]; + + // Enter search mode. + [[EarlGrey selectElementWithMatcher:TabGridSearchTabsButton()] + performAction:grey_tap()]; + + // Upon entry, the search bar is empty. Verify that the header doesn't exist. + [[EarlGrey selectElementWithMatcher:SearchOpenTabsSectionHeader()] + assertWithMatcher:grey_nil()]; + + // Searching with any query should render the header visible. + [[EarlGrey selectElementWithMatcher:TabGridSearchBar()] + performAction:grey_typeText(@"text\n")]; + [[EarlGrey selectElementWithMatcher:SearchOpenTabsSectionHeader()] + assertWithMatcher:grey_notNil()]; + + // Clearing search bar text should render the header invisible again. + [[EarlGrey selectElementWithMatcher:TabGridSearchBar()] + performAction:grey_clearText()]; + [[EarlGrey selectElementWithMatcher:SearchOpenTabsSectionHeader()] + assertWithMatcher:grey_nil()]; + + // Searching a word then canceling the search mode should hide the section + // header. + [[EarlGrey selectElementWithMatcher:TabGridSearchBar()] + performAction:grey_typeText(@"page\n")]; + [[EarlGrey selectElementWithMatcher:TabGridSearchCancelButton()] + performAction:grey_tap()]; + [[self scrollUpViewMatcher:RegularTabGrid() + toSelectMatcher:SearchOpenTabsSectionHeader()] + assertWithMatcher:grey_nil()]; +} + +// Tests that suggested actions section is available whenever there is a query +// in the normal tabs search mode. +- (void)testSuggestedActionsVisibleInSearchModeWhenSearchBarIsNotEmpty { + [self loadTestURLsInNewTabs]; + [ChromeEarlGrey showTabSwitcher]; + + // Verify that the suggested actions section doesn't exist in normal mode. + [[EarlGrey selectElementWithMatcher:SearchSuggestedActionsSectionHeader()] + assertWithMatcher:grey_nil()]; + [[EarlGrey selectElementWithMatcher:SearchSuggestedActionsSection()] + assertWithMatcher:grey_nil()]; + + // Enter search mode. + [[EarlGrey selectElementWithMatcher:TabGridSearchTabsButton()] + performAction:grey_tap()]; + + // Upon entry, the search bar is empty. Verify that the suggested actions + // section doesn't exist. + [[EarlGrey selectElementWithMatcher:SearchSuggestedActionsSectionHeader()] + assertWithMatcher:grey_nil()]; + [[EarlGrey selectElementWithMatcher:SearchSuggestedActionsSection()] + assertWithMatcher:grey_nil()]; + + // Searching with a query with no results should show the suggested actions + // section. + [[EarlGrey selectElementWithMatcher:TabGridSearchBar()] + performAction:grey_typeText(@"text\n")]; + [[EarlGrey selectElementWithMatcher:SearchOpenTabsHeaderWithValue(0)] + assertWithMatcher:grey_notNil()]; + [[EarlGrey selectElementWithMatcher:SearchSuggestedActionsSectionHeader()] + assertWithMatcher:grey_notNil()]; + [[EarlGrey selectElementWithMatcher:SearchSuggestedActionsSection()] + assertWithMatcher:grey_notNil()]; + + // Clearing search bar text should hide the suggested actions section. + [[EarlGrey selectElementWithMatcher:TabGridSearchBar()] + performAction:grey_clearText()]; + [[EarlGrey selectElementWithMatcher:SearchSuggestedActionsSectionHeader()] + assertWithMatcher:grey_nil()]; + [[EarlGrey selectElementWithMatcher:SearchSuggestedActionsSection()] + assertWithMatcher:grey_nil()]; + + // Searching with a query with results should show the suggested actions + // section. + [[EarlGrey selectElementWithMatcher:TabGridSearchBar()] + performAction:grey_clearText()]; + [[EarlGrey selectElementWithMatcher:TabGridSearchBar()] + performAction:grey_typeText(@"page 2\n")]; + + // Check that the header is set correctly. + [[EarlGrey selectElementWithMatcher:SearchOpenTabsHeaderWithValue(1)] + assertWithMatcher:grey_notNil()]; + + [[self scrollDownViewMatcher:RegularTabGrid() + toSelectMatcher:SearchSuggestedActionsSectionHeader()] + assertWithMatcher:grey_notNil()]; + [[self scrollDownViewMatcher:RegularTabGrid() + toSelectMatcher:SearchSuggestedActionsSection()] + assertWithMatcher:grey_notNil()]; + + // Canceling search mode should hide the suggested actions section. + [[EarlGrey selectElementWithMatcher:TabGridSearchCancelButton()] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:SearchSuggestedActionsSectionHeader()] + assertWithMatcher:grey_nil()]; + [[EarlGrey selectElementWithMatcher:SearchSuggestedActionsSection()] + assertWithMatcher:grey_nil()]; +} + +// Tests that the search suggested actions section has the right rows in the +// regular grid. +- (void)testSearchSuggestedActionsSectionContentInRegularGrid { + [self loadTestURLsInNewTabs]; + [ChromeEarlGrey showTabSwitcher]; + + // Enter search mode and enter a search query. + [[EarlGrey selectElementWithMatcher:TabGridSearchTabsButton()] + performAction:grey_tap()]; + // TODO(crbug.com/1306246): Scrolling doesn't work properly in very small + // devices. Once that is fixed a more broad query can be used for searching + // (eg. "page"). + [[EarlGrey selectElementWithMatcher:TabGridSearchBar()] + performAction:grey_typeText(@"page 2\n")]; + + // Verify that the suggested actions section exist and has "Search on web", + // "Search recent tabs", "Search history" rows. + [[self scrollDownViewMatcher:RegularTabGrid() + toSelectMatcher:SearchSuggestedActionsSectionHeader()] + assertWithMatcher:grey_notNil()]; + + [[self + scrollDownViewMatcher:RegularTabGrid() + toSelectMatcher:grey_allOf( + SearchSuggestedActionsSection(), + grey_descendant(SearchOnWebSuggestedAction()), + grey_descendant( + SearchRecentTabsSuggestedAction()), + grey_descendant(SearchHistorySuggestedAction()), + grey_sufficientlyVisible(), nil)] + assertWithMatcher:grey_notNil()]; +} + +// Tests that history row in the search suggested actions section displays the +// correct number of matches. +- (void)testSearchSuggestedActionsDisplaysCorrectHistoryMatchesCount { + [ChromeEarlGrey clearBrowsingHistory]; + [self loadTestURLs]; + [ChromeEarlGrey showTabSwitcher]; + + // Enter search mode. + [[EarlGrey selectElementWithMatcher:TabGridSearchTabsButton()] + performAction:grey_tap()]; + + // Verify that the suggested actions section is not visible. + [[EarlGrey selectElementWithMatcher:SearchSuggestedActionsSection()] + assertWithMatcher:grey_nil()]; + + // Searching the word "page" matches 2 items from history. + [[EarlGrey selectElementWithMatcher:TabGridSearchBar()] + performAction:grey_typeText(@"page\n")]; + [[self scrollDownViewMatcher:RegularTabGrid() + toSelectMatcher: + SearchSuggestedActionsSectionWithHistoryMatchesCount(2)] + assertWithMatcher:grey_notNil()]; + + // Adding to the existing query " 2" will search for "page 2" and should only + // match 1 item from the history. + [[EarlGrey selectElementWithMatcher:TabGridSearchBar()] + performAction:grey_typeText(@" 2\n")]; + [[self scrollDownViewMatcher:RegularTabGrid() + toSelectMatcher: + SearchSuggestedActionsSectionWithHistoryMatchesCount(1)] + assertWithMatcher:grey_notNil()]; + // Cancel search mode. [[EarlGrey selectElementWithMatcher:TabGridSearchCancelButton()] performAction:grey_tap()]; @@ -1380,7 +1682,7 @@ [[EarlGrey selectElementWithMatcher:TabGridSearchBar()] performAction:grey_typeText(title2)]; - [[EarlGrey selectElementWithMatcher:TabWithTitle(title2)] + [[EarlGrey selectElementWithMatcher:TabWithTitle(kTitle2)] performAction:grey_tap()]; [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] @@ -1407,7 +1709,7 @@ [[EarlGrey selectElementWithMatcher:TabGridSearchBar()] performAction:grey_typeText(title2)]; - [[EarlGrey selectElementWithMatcher:TabWithTitle(title2)] + [[EarlGrey selectElementWithMatcher:TabWithTitle(kTitle2)] performAction:grey_tap()]; [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] @@ -1503,7 +1805,7 @@ performAction:grey_tap()]; // Make sure that the tab is no longer present. - [[EarlGrey selectElementWithMatcher:TabWithTitle(title2)] + [[EarlGrey selectElementWithMatcher:TabWithTitle(kTitle2)] assertWithMatcher:grey_nil()]; } @@ -1676,4 +1978,22 @@ nil)] assertWithMatcher:grey_nil()]; } +// Returns an interaction that scrolls down on the view matched by |viewMatcher| +// to search for the given |matcher|. +- (id<GREYInteraction>)scrollDownViewMatcher:(id<GREYMatcher>)viewMatcher + toSelectMatcher:(id<GREYMatcher>)matcher { + return [[EarlGrey selectElementWithMatcher:matcher] + usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 50) + onElementWithMatcher:viewMatcher]; +} + +// Returns an interaction that scrolls up on the view matched by |viewMatcher| +// to search for the given |matcher|. +- (id<GREYInteraction>)scrollUpViewMatcher:(id<GREYMatcher>)viewMatcher + toSelectMatcher:(id<GREYMatcher>)matcher { + return [[EarlGrey selectElementWithMatcher:matcher] + usingSearchAction:grey_scrollInDirection(kGREYDirectionUp, 50) + onElementWithMatcher:viewMatcher]; +} + @end
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h b/ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h index f7e6987e..ffe4d5b 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h +++ b/ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h
@@ -64,6 +64,9 @@ // TableViewInfoButtonCell. extern NSString* const kTableViewCellInfoButtonViewId; +// The accessibility identifier of the TableViewTabsSearchSuggestedHistoryItem. +extern NSString* const kTableViewTabsSearchSuggestedHistoryItemId; + // Returns a padding according to the width of the current device. extern CGFloat HorizontalPadding();
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.mm b/ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.mm index c28556e..48932935 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.mm +++ b/ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.mm
@@ -29,6 +29,8 @@ NSString* const kMaskedPassword = @"••••••••"; NSString* const kTableViewCellInfoButtonViewId = @"kTableViewCellInfoButtonViewId"; +NSString* const kTableViewTabsSearchSuggestedHistoryItemId = + @"kTableViewTabsSearchSuggestedHistoryItemId"; CGFloat HorizontalPadding() { if (!IsSmallDevice())
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_tabs_search_suggested_history_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_tabs_search_suggested_history_item.mm index 5ad4cd8..06550e9 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_tabs_search_suggested_history_item.mm +++ b/ios/chrome/browser/ui/table_view/cells/table_view_tabs_search_suggested_history_item.mm
@@ -6,6 +6,7 @@ #include "base/format_macros.h" #include "base/strings/sys_string_conversions.h" +#import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h" #include "ios/chrome/grit/ios_strings.h" #include "ui/base/l10n/l10n_util_mac.h" @@ -23,6 +24,7 @@ imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; self.title = l10n_util::GetNSString( IDS_IOS_TABS_SEARCH_SUGGESTED_ACTION_SEARCH_HISTORY_UNKNOWN_RESULT_COUNT); + self.accessibilityIdentifier = kTableViewTabsSearchSuggestedHistoryItemId; } return self; }
diff --git a/ios/chrome/browser/web/certificate_policy_app_agent.mm b/ios/chrome/browser/web/certificate_policy_app_agent.mm index 562760a..0fd5354 100644 --- a/ios/chrome/browser/web/certificate_policy_app_agent.mm +++ b/ios/chrome/browser/web/certificate_policy_app_agent.mm
@@ -110,8 +110,7 @@ // Evict all the certificate policies except for the current entries of the // active sessions, for the regular and incognito browsers. CleanCertificatePolicyCache( - &_clearPoliciesTaskTracker, - base::CreateSingleThreadTaskRunner({web::WebThread::IO}), + &_clearPoliciesTaskTracker, web::GetIOThreadTaskRunner({}), web::BrowserState::GetCertificatePolicyCache(browserState), browserList, /*incognito=*/false); @@ -119,8 +118,7 @@ ChromeBrowserState* incognitoBrowserState = browserState->GetOffTheRecordChromeBrowserState(); CleanCertificatePolicyCache( - &_clearPoliciesTaskTracker, - base::CreateSingleThreadTaskRunner({web::WebThread::IO}), + &_clearPoliciesTaskTracker, web::GetIOThreadTaskRunner({}), web::BrowserState::GetCertificatePolicyCache(incognitoBrowserState), browserList, /*incognito=*/true); }
diff --git a/ios/chrome/browser/web/certificate_policy_app_agent_unittest.mm b/ios/chrome/browser/web/certificate_policy_app_agent_unittest.mm index ec655e9a..42872bf 100644 --- a/ios/chrome/browser/web/certificate_policy_app_agent_unittest.mm +++ b/ios/chrome/browser/web/certificate_policy_app_agent_unittest.mm
@@ -169,10 +169,11 @@ __block web::CertPolicy::Judgment judgement = web::CertPolicy::Judgment::UNKNOWN; __block bool completed = false; - base::PostTask(FROM_HERE, {web::WebThread::IO}, base::BindOnce(^{ - completed = true; - judgement = cache->QueryPolicy(cert_.get(), host, status_); - })); + web::GetIOThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(^{ + completed = true; + judgement = cache->QueryPolicy( + cert_.get(), host, status_); + })); EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForActionTimeout, ^{ return completed; })); @@ -184,10 +185,11 @@ void ClearPolicyCache( const scoped_refptr<web::CertificatePolicyCache>& cache) { __block bool policies_cleared = false; - base::PostTask(FROM_HERE, {web::WebThread::IO}, base::BindOnce(^{ - cache->ClearCertificatePolicies(); - policies_cleared = true; - })); + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(^{ + cache->ClearCertificatePolicies(); + policies_cleared = true; + })); EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForActionTimeout, ^{ return policies_cleared; })); @@ -224,8 +226,8 @@ } hosts_added = true; }; - base::PostTask(FROM_HERE, {web::WebThread::IO}, - base::BindOnce(populate_cache)); + web::GetIOThreadTaskRunner({})->PostTask(FROM_HERE, + base::BindOnce(populate_cache)); EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForActionTimeout, ^{ return hosts_added; }));
diff --git a/ios/chrome/browser/web/image_fetch/image_fetch_tab_helper.mm b/ios/chrome/browser/web/image_fetch/image_fetch_tab_helper.mm index 5ad5486..ade554d 100644 --- a/ios/chrome/browser/web/image_fetch/image_fetch_tab_helper.mm +++ b/ios/chrome/browser/web/image_fetch/image_fetch_tab_helper.mm
@@ -10,7 +10,6 @@ #include "base/metrics/histogram_macros.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" -#include "base/task/post_task.h" #include "base/values.h" #include "components/image_fetcher/core/image_data_fetcher.h" #include "ios/chrome/browser/web/image_fetch/image_fetch_java_script_feature.h" @@ -129,8 +128,8 @@ DCHECK_EQ(js_callbacks_.count(call_id_), 0UL); js_callbacks_.insert({call_id_, std::move(callback)}); - base::PostDelayedTask( - FROM_HERE, {web::WebThread::UI}, + web::GetUIThreadTaskRunner({})->PostDelayedTask( + FROM_HERE, base::BindRepeating(&ImageFetchTabHelper::OnJsTimeout, weak_ptr_factory_.GetWeakPtr(), call_id_), timeout);
diff --git a/ios/chrome/browser/webdata_services/web_data_service_factory.mm b/ios/chrome/browser/webdata_services/web_data_service_factory.mm index 38fd0c34..4af18e9 100644 --- a/ios/chrome/browser/webdata_services/web_data_service_factory.mm +++ b/ios/chrome/browser/webdata_services/web_data_service_factory.mm
@@ -9,7 +9,6 @@ #include "base/check.h" #include "base/files/file_path.h" #include "base/no_destructor.h" -#include "base/task/post_task.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/keyed_service/core/service_access_type.h" #include "components/keyed_service/ios/browser_state_dependency_manager.h" @@ -106,8 +105,7 @@ const base::FilePath& browser_state_path = context->GetStatePath(); return std::make_unique<WebDataServiceWrapper>( browser_state_path, GetApplicationContext()->GetApplicationLocale(), - base::CreateSingleThreadTaskRunner({web::WebThread::UI}), - base::DoNothing()); + web::GetUIThreadTaskRunner({}), base::DoNothing()); } web::BrowserState* WebDataServiceFactory::GetBrowserStateToUse(
diff --git a/ios/chrome/test/app/browsing_data_test_util.mm b/ios/chrome/test/app/browsing_data_test_util.mm index 2450ab5c..ff079e9 100644 --- a/ios/chrome/test/app/browsing_data_test_util.mm +++ b/ios/chrome/test/app/browsing_data_test_util.mm
@@ -8,7 +8,6 @@ #include "base/logging.h" #include "base/task/cancelable_task_tracker.h" -#include "base/task/post_task.h" #import "base/test/ios/wait_util.h" #include "components/browsing_data/core/browsing_data_utils.h" #include "components/history/core/browser/history_service.h" @@ -91,10 +90,10 @@ : GetOriginalBrowserState(); auto cache = web::BrowserState::GetCertificatePolicyCache(browser_state); __block BOOL policies_cleared = NO; - base::PostTask(FROM_HERE, {web::WebThread::IO}, base::BindOnce(^{ - cache->ClearCertificatePolicies(); - policies_cleared = YES; - })); + web::GetIOThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(^{ + cache->ClearCertificatePolicies(); + policies_cleared = YES; + })); return WaitUntilConditionOrTimeout(2, ^{ return policies_cleared; });
diff --git a/ios/components/io_thread/ios_io_thread.mm b/ios/components/io_thread/ios_io_thread.mm index 5cfacb9..c189e7b 100644 --- a/ios/components/io_thread/ios_io_thread.mm +++ b/ios/components/io_thread/ios_io_thread.mm
@@ -19,7 +19,6 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" -#include "base/task/post_task.h" #include "base/task/single_thread_task_runner.h" #include "base/threading/thread.h" #include "base/time/time.h" @@ -127,8 +126,7 @@ SystemURLRequestContextGetter::SystemURLRequestContextGetter( IOSIOThread* io_thread) : io_thread_(io_thread), - network_task_runner_( - base::CreateSingleThreadTaskRunner({web::WebThread::IO})) {} + network_task_runner_(web::GetIOThreadTaskRunner({})) {} SystemURLRequestContextGetter::~SystemURLRequestContextGetter() {} @@ -207,8 +205,8 @@ void IOSIOThread::ChangedToOnTheRecord() { DCHECK_CURRENTLY_ON(web::WebThread::UI); - base::PostTask(FROM_HERE, {web::WebThread::IO}, - base::BindOnce(&IOSIOThread::ChangedToOnTheRecordOnIOThread, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&IOSIOThread::ChangedToOnTheRecordOnIOThread, base::Unretained(this))); }
diff --git a/ios/components/security_interstitials/ios_blocking_page_controller_client.mm b/ios/components/security_interstitials/ios_blocking_page_controller_client.mm index c274e942..b1c8efe 100644 --- a/ios/components/security_interstitials/ios_blocking_page_controller_client.mm +++ b/ios/components/security_interstitials/ios_blocking_page_controller_client.mm
@@ -7,7 +7,6 @@ #include "base/bind.h" #include "base/check_op.h" #include "base/notreached.h" -#include "base/task/post_task.h" #include "components/security_interstitials/core/metrics_helper.h" #import "ios/web/public/navigation/navigation_manager.h" #include "ios/web/public/navigation/reload_type.h" @@ -60,8 +59,8 @@ // Closing the tab synchronously is problematic since web state is heavily // involved in the operation and CloseWebState interrupts it, so call // CloseWebState asynchronously. - base::PostTask(FROM_HERE, {web::WebThread::UI}, - base::BindOnce(&IOSBlockingPageControllerClient::Close, + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&IOSBlockingPageControllerClient::Close, weak_factory_.GetWeakPtr())); } }
diff --git a/ios/web/browser_state.mm b/ios/web/browser_state.mm index 3afdc51..c60988b 100644 --- a/ios/web/browser_state.mm +++ b/ios/web/browser_state.mm
@@ -13,7 +13,6 @@ #include "base/memory/ref_counted.h" #include "base/metrics/histogram_functions.h" #include "base/process/process_handle.h" -#include "base/task/post_task.h" #include "base/token.h" #include "components/leveldb_proto/public/proto_database_provider.h" #include "ios/web/public/init/network_context_owner.h" @@ -89,8 +88,8 @@ shared_url_loader_factory_->Detach(); if (network_context_) { - base::DeleteSoon(FROM_HERE, {web::WebThread::IO}, - network_context_owner_.release()); + web::GetIOThreadTaskRunner({})->DeleteSoon( + FROM_HERE, network_context_owner_.release()); } // Delete the URLDataManagerIOSBackend instance on the IO thread if it has @@ -99,8 +98,8 @@ // BrowserState are still accessing it on the IO thread at this point, // they're going to have a bad time anyway. if (url_data_manager_ios_backend_) { - bool posted = base::DeleteSoon(FROM_HERE, {web::WebThread::IO}, - url_data_manager_ios_backend_); + bool posted = web::GetIOThreadTaskRunner({})->DeleteSoon( + FROM_HERE, url_data_manager_ios_backend_); if (!posted) delete url_data_manager_ios_backend_; }
diff --git a/ios/web/download/download_session_task_impl.mm b/ios/web/download/download_session_task_impl.mm index f791e81..4f9e7bde 100644 --- a/ios/web/download/download_session_task_impl.mm +++ b/ios/web/download/download_session_task_impl.mm
@@ -8,7 +8,6 @@ #import "base/mac/foundation_util.h" #include "base/strings/sys_string_conversions.h" -#include "base/task/post_task.h" #include "base/task/thread_pool.h" #import "ios/net/cookies/system_cookie_util.h" #include "ios/web/download/download_result.h" @@ -112,8 +111,8 @@ - (void)URLSession:(NSURLSession*)session task:(NSURLSessionTask*)task didCompleteWithError:(NSError*)error { - base::PostTask(FROM_HERE, {WebThread::UI}, - base::BindOnce(_doneCallback, task, error)); + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(_doneCallback, task, error)); } - (void)URLSession:(NSURLSession*)session @@ -125,8 +124,8 @@ // thread (in net::URLFetcherFileWriter::Write()). dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); - base::PostTask( - FROM_HERE, {WebThread::UI}, + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( [](dispatch_semaphore_t semaphore, DataCallback innerDataCallback, NSURLSessionTask* task, NSData* data) { @@ -306,8 +305,8 @@ web_state_->GetBrowserState()->GetRequestContext()); // net::URLRequestContextGetter must be used in the IO thread. - base::PostTask( - FROM_HERE, {WebThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&DownloadSessionTaskImpl::GetCookiesFromContextGetter, context_getter, std::move(callback))); } @@ -322,8 +321,8 @@ const net::CookieList& cookie_list) { NSArray<NSHTTPCookie*>* cookies = SystemCookiesFromCanonicalCookieList(cookie_list); - base::PostTask(FROM_HERE, {WebThread::UI}, - base::BindOnce(std::move(callback), cookies)); + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), cookies)); }, std::move(callback))); }
diff --git a/ios/web/find_in_page/find_in_page_manager_impl.mm b/ios/web/find_in_page/find_in_page_manager_impl.mm index 95b48f1..77e8802a 100644 --- a/ios/web/find_in_page/find_in_page_manager_impl.mm +++ b/ios/web/find_in_page/find_in_page_manager_impl.mm
@@ -7,7 +7,6 @@ #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" #import "base/strings/sys_string_conversions.h" -#include "base/task/post_task.h" #include "base/values.h" #import "ios/web/find_in_page/find_in_page_constants.h" #import "ios/web/find_in_page/find_in_page_java_script_feature.h" @@ -16,6 +15,7 @@ #include "ios/web/public/js_messaging/web_frame_util.h" #import "ios/web/public/js_messaging/web_frames_manager.h" #include "ios/web/public/thread/web_task_traits.h" +#include "ios/web/public/thread/web_thread.h" #import "ios/web/web_state/web_state_impl.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -102,8 +102,8 @@ if (all_frames.size() == 0) { // No frames to search in. // Call asyncronously to match behavior if find was successful in frames. - base::PostTask( - FROM_HERE, {WebThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&FindInPageManagerImpl::LastFindRequestCompleted, weak_factory_.GetWeakPtr())); return; @@ -122,8 +122,8 @@ last_find_request_.DidReceiveFindResponseFromOneFrame(); if (last_find_request_.AreAllFindResponsesReturned()) { // Call asyncronously to match behavior if find was done in frames. - base::PostTask( - FROM_HERE, {WebThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&FindInPageManagerImpl::LastFindRequestCompleted, weak_factory_.GetWeakPtr())); }
diff --git a/ios/web/init/web_main_loop.mm b/ios/web/init/web_main_loop.mm index 92ab430..3933f84 100644 --- a/ios/web/init/web_main_loop.mm +++ b/ios/web/init/web_main_loop.mm
@@ -17,7 +17,6 @@ #include "base/power_monitor/power_monitor.h" #include "base/power_monitor/power_monitor_device_source.h" #include "base/process/process_metrics.h" -#include "base/task/post_task.h" #include "base/task/single_thread_task_executor.h" #include "base/task/thread_pool/thread_pool_instance.h" #include "base/threading/thread_restrictions.h" @@ -26,6 +25,7 @@ #include "ios/web/public/init/ios_global_state.h" #include "ios/web/public/init/web_main_parts.h" #include "ios/web/public/thread/web_task_traits.h" +#include "ios/web/public/thread/web_thread.h" #import "ios/web/public/web_client.h" #include "ios/web/web_sub_thread.h" #include "ios/web/web_thread_impl.h" @@ -156,8 +156,8 @@ // Teardown may start in PostMainMessageLoopRun, and during teardown we // need to be able to perform IO. base::PermanentThreadAllowance::AllowBlocking(); - base::PostTask(FROM_HERE, {WebThread::IO}, - base::BindOnce(base::IgnoreResult( + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(base::IgnoreResult( &base::PermanentThreadAllowance::AllowBlocking))); // Also allow waiting to join threads. @@ -166,8 +166,8 @@ // persistent work is being done after ThreadPoolInstance::Shutdown() in order // to move towards atomic shutdown. base::PermanentThreadAllowance::AllowBaseSyncPrimitives(); - base::PostTask( - FROM_HERE, {WebThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(base::IgnoreResult( &base::PermanentThreadAllowance::AllowBaseSyncPrimitives)));
diff --git a/ios/web/js_messaging/web_frame_impl.mm b/ios/web/js_messaging/web_frame_impl.mm index cffe11c..868ee44 100644 --- a/ios/web/js_messaging/web_frame_impl.mm +++ b/ios/web/js_messaging/web_frame_impl.mm
@@ -16,13 +16,13 @@ #include "base/strings/stringprintf.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" -#include "base/task/post_task.h" #include "base/values.h" #include "crypto/aead.h" #include "crypto/random.h" #import "ios/web/js_messaging/java_script_content_world.h" #import "ios/web/js_messaging/web_view_js_utils.h" #include "ios/web/public/thread/web_task_traits.h" +#include "ios/web/public/thread/web_thread.h" #include "url/gurl.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -244,9 +244,9 @@ std::move(callback), std::move(timeout_callback)); pending_requests_[message_id] = std::move(callbacks); - base::PostDelayedTask( - FROM_HERE, {web::WebThread::UI}, - pending_requests_[message_id]->timeout_callback->callback(), timeout); + web::GetUIThreadTaskRunner({})->PostDelayedTask( + FROM_HERE, pending_requests_[message_id]->timeout_callback->callback(), + timeout); bool called = CallJavaScriptFunctionInContentWorld(name, parameters, content_world, /*reply_with_result=*/true);
diff --git a/ios/web/net/cookie_notification_bridge.mm b/ios/web/net/cookie_notification_bridge.mm index 79b85a11..178468e 100644 --- a/ios/web/net/cookie_notification_bridge.mm +++ b/ios/web/net/cookie_notification_bridge.mm
@@ -8,7 +8,6 @@ #include "base/bind.h" #include "base/location.h" -#include "base/task/post_task.h" #import "ios/net/cookies/cookie_store_ios.h" #include "ios/web/public/thread/web_task_traits.h" #include "ios/web/public/thread/web_thread.h" @@ -38,8 +37,8 @@ NSNotification* notification) { DCHECK([[notification name] isEqualToString:NSHTTPCookieManagerCookiesChangedNotification]); - base::PostTask( - FROM_HERE, {web::WebThread::IO}, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&net::CookieStoreIOS::NotifySystemCookiesChanged)); }
diff --git a/ios/web/net/cookies/wk_http_system_cookie_store.mm b/ios/web/net/cookies/wk_http_system_cookie_store.mm index f483fa9c..9c8ed33 100644 --- a/ios/web/net/cookies/wk_http_system_cookie_store.mm +++ b/ios/web/net/cookies/wk_http_system_cookie_store.mm
@@ -6,7 +6,6 @@ #include "base/bind.h" #import "base/ios/block_types.h" -#include "base/task/post_task.h" #import "ios/net/cookies/cookie_creation_time_manager.h" #include "ios/net/cookies/system_cookie_util.h" #include "ios/web/public/thread/web_task_traits.h" @@ -29,7 +28,7 @@ // SystemCookieStore should operate on IO thread. void RunBlockOnIOThread(ProceduralBlock block) { DCHECK(block != nil); - base::PostTask(FROM_HERE, {web::WebThread::IO}, base::BindOnce(block)); + web::GetIOThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(block)); } // Returns wether |cookie| should be included for queries about |url|. @@ -101,8 +100,8 @@ creation_time_manager_->GetWeakPtr(); NSHTTPCookie* block_cookie = cookie; __weak __typeof(crw_cookie_store_) block_cookie_store = crw_cookie_store_; - base::PostTask( - FROM_HERE, {web::WebThread::UI}, base::BindOnce(^{ + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(^{ [block_cookie_store deleteCookie:block_cookie completionHandler:^{ @@ -130,8 +129,8 @@ if (optional_creation_time && !optional_creation_time->is_null()) cookie_time = *optional_creation_time; __weak __typeof(crw_cookie_store_) block_cookie_store = crw_cookie_store_; - base::PostTask( - FROM_HERE, {web::WebThread::UI}, base::BindOnce(^{ + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(^{ [block_cookie_store setCookie:block_cookie completionHandler:^{ @@ -153,8 +152,8 @@ base::WeakPtr<net::CookieCreationTimeManager> weak_time_manager = creation_time_manager_->GetWeakPtr(); __weak __typeof(crw_cookie_store_) block_cookie_store = crw_cookie_store_; - base::PostTask( - FROM_HERE, {web::WebThread::UI}, base::BindOnce(^{ + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(^{ [block_cookie_store getAllCookies:^(NSArray<NSHTTPCookie*>* cookies) { ProceduralBlock completionHandler = ^{ RunBlockOnIOThread(^{ @@ -212,8 +211,8 @@ creation_time_manager_->GetWeakPtr(); __weak __typeof(crw_cookie_store_) weak_cookie_store = crw_cookie_store_; GURL block_url = include_url; - base::PostTask( - FROM_HERE, {web::WebThread::UI}, base::BindOnce(^{ + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(^{ __typeof(weak_cookie_store) strong_cookie_store = weak_cookie_store; if (strong_cookie_store) { [strong_cookie_store
diff --git a/ios/web/network_context_owner.cc b/ios/web/network_context_owner.cc index d152200..786ce56 100644 --- a/ios/web/network_context_owner.cc +++ b/ios/web/network_context_owner.cc
@@ -9,7 +9,6 @@ #include <vector> #include "base/bind.h" -#include "base/task/post_task.h" #include "ios/web/public/thread/web_task_traits.h" #include "ios/web/public/thread/web_thread.h" #include "net/url_request/url_request_context_getter.h" @@ -24,8 +23,8 @@ mojo::Remote<network::mojom::NetworkContext>* network_context_client) : request_context_(request_context) { DCHECK_CURRENTLY_ON(WebThread::UI); - base::PostTask( - FROM_HERE, {web::WebThread::IO}, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&NetworkContextOwner::InitializeOnIOThread, // This is safe, since |this| will be deleted on the IO // thread, which would have to happen afterwards.
diff --git a/ios/web/network_context_owner_unittest.cc b/ios/web/network_context_owner_unittest.cc index cb28dd8..a1e9c82 100644 --- a/ios/web/network_context_owner_unittest.cc +++ b/ios/web/network_context_owner_unittest.cc
@@ -9,9 +9,9 @@ #include "base/bind.h" #include "base/run_loop.h" -#include "base/task/post_task.h" #include "ios/web/public/test/web_task_environment.h" #include "ios/web/public/thread/web_task_traits.h" +#include "ios/web/public/thread/web_thread.h" #include "mojo/public/cpp/bindings/remote.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" @@ -26,7 +26,7 @@ NetworkContextOwnerTest() : saw_connection_error_(false), context_getter_(base::MakeRefCounted<net::TestURLRequestContextGetter>( - base::CreateSingleThreadTaskRunner({WebThread::IO}))) {} + GetIOThreadTaskRunner({}))) {} ~NetworkContextOwnerTest() override { // Tests should cleanup after themselves. @@ -61,8 +61,8 @@ base::RunLoop().RunUntilIdle(); EXPECT_FALSE(saw_connection_error_); - base::DeleteSoon(FROM_HERE, {web::WebThread::IO}, - network_context_owner_.release()); + web::GetIOThreadTaskRunner({})->DeleteSoon(FROM_HERE, + network_context_owner_.release()); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(saw_connection_error_); // other end gone } @@ -80,8 +80,8 @@ base::RunLoop().RunUntilIdle(); EXPECT_FALSE(saw_connection_error_); - base::PostTask( - FROM_HERE, {web::WebThread::IO}, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &net::TestURLRequestContextGetter::NotifyContextShuttingDown, context_getter_)); @@ -89,8 +89,8 @@ base::RunLoop().RunUntilIdle(); EXPECT_TRUE(saw_connection_error_); // other end gone post-shutdown. - base::DeleteSoon(FROM_HERE, {web::WebThread::IO}, - network_context_owner_.release()); + web::GetIOThreadTaskRunner({})->DeleteSoon(FROM_HERE, + network_context_owner_.release()); } } // namespace web
diff --git a/ios/web/public/test/fakes/fake_browser_state.cc b/ios/web/public/test/fakes/fake_browser_state.cc index 830aae8..df8976c 100644 --- a/ios/web/public/test/fakes/fake_browser_state.cc +++ b/ios/web/public/test/fakes/fake_browser_state.cc
@@ -5,7 +5,6 @@ #include "ios/web/public/test/fakes/fake_browser_state.h" #include "base/files/file_path.h" -#include "base/task/post_task.h" #include "base/task/single_thread_task_runner.h" #include "ios/web/public/thread/web_task_traits.h" #include "ios/web/public/thread/web_thread.h" @@ -33,7 +32,7 @@ scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() const override { - return base::CreateSingleThreadTaskRunner({web::WebThread::IO}); + return web::GetIOThreadTaskRunner({}); } private:
diff --git a/ios/web/public/test/fakes/fake_cookie_store.cc b/ios/web/public/test/fakes/fake_cookie_store.cc index cef5120..dc90696e 100644 --- a/ios/web/public/test/fakes/fake_cookie_store.cc +++ b/ios/web/public/test/fakes/fake_cookie_store.cc
@@ -4,7 +4,6 @@ #include "ios/web/public/test/fakes/fake_cookie_store.h" -#include "base/task/post_task.h" #include "ios/web/public/thread/web_task_traits.h" #include "ios/web/public/thread/web_thread.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -21,8 +20,8 @@ void FakeCookieStore::GetAllCookiesAsync(GetAllCookiesCallback callback) { DCHECK_CURRENTLY_ON(WebThread::IO); - base::PostTask(FROM_HERE, {WebThread::IO}, - base::BindOnce(std::move(callback), all_cookies_)); + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), all_cookies_)); } void FakeCookieStore::SetCanonicalCookieAsync(
diff --git a/ios/web/security/crw_cert_verification_controller.mm b/ios/web/security/crw_cert_verification_controller.mm index c90db78..448b862 100644 --- a/ios/web/security/crw_cert_verification_controller.mm +++ b/ios/web/security/crw_cert_verification_controller.mm
@@ -141,10 +141,11 @@ DCHECK(cert); } DCHECK(cert->intermediate_buffers().empty()); - base::PostTask(FROM_HERE, {WebThread::IO}, base::BindOnce(^{ - self->_certPolicyCache->AllowCertForHost( - cert.get(), base::SysNSStringToUTF8(host), status); - })); + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(^{ + self->_certPolicyCache->AllowCertForHost( + cert.get(), base::SysNSStringToUTF8(host), status); + })); } #pragma mark - Private
diff --git a/ios/web/session/session_certificate_policy_cache_impl.mm b/ios/web/session/session_certificate_policy_cache_impl.mm index 68baeaf..9c1d5d7 100644 --- a/ios/web/session/session_certificate_policy_cache_impl.mm +++ b/ios/web/session/session_certificate_policy_cache_impl.mm
@@ -5,7 +5,6 @@ #import "ios/web/session/session_certificate_policy_cache_impl.h" #include "base/bind.h" -#include "base/task/post_task.h" #include "ios/web/public/browser_state.h" #include "ios/web/public/security/certificate_policy_cache.h" #import "ios/web/public/session/crw_session_certificate_policy_cache_storage.h" @@ -62,12 +61,13 @@ DCHECK(cache.get()); NSSet* allowed_certs = [NSSet setWithSet:allowed_certs_]; const scoped_refptr<CertificatePolicyCache> cache_copy = cache; - base::PostTask(FROM_HERE, {WebThread::IO}, base::BindOnce(^{ - for (CRWSessionCertificateStorage* cert in allowed_certs) { - cache_copy->AllowCertForHost(cert.certificate, cert.host, - cert.status); - } - })); + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(^{ + for (CRWSessionCertificateStorage* cert in allowed_certs) { + cache_copy->AllowCertForHost(cert.certificate, cert.host, + cert.status); + } + })); } void SessionCertificatePolicyCacheImpl::RegisterAllowedCertificate( @@ -93,8 +93,8 @@ status:status]]; const scoped_refptr<CertificatePolicyCache> cache = GetCertificatePolicyCache(); - base::PostTask( - FROM_HERE, {WebThread::IO}, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&CertificatePolicyCache::AllowCertForHost, cache, base::RetainedRef(certificate.get()), host, status)); }
diff --git a/ios/web/session/session_certificate_policy_cache_impl_unittest.mm b/ios/web/session/session_certificate_policy_cache_impl_unittest.mm index df1812ab..22fd0c21 100644 --- a/ios/web/session/session_certificate_policy_cache_impl_unittest.mm +++ b/ios/web/session/session_certificate_policy_cache_impl_unittest.mm
@@ -5,7 +5,6 @@ #import "ios/web/session/session_certificate_policy_cache_impl.h" #include "base/bind.h" -#include "base/task/post_task.h" #import "base/test/ios/wait_util.h" #include "ios/web/public/security/certificate_policy_cache.h" #import "ios/web/public/session/crw_session_certificate_policy_cache_storage.h" @@ -37,10 +36,11 @@ __block web::CertPolicy::Judgment judgement = web::CertPolicy::Judgment::UNKNOWN; __block bool completed = false; - base::PostTask(FROM_HERE, {web::WebThread::IO}, base::BindOnce(^{ - completed = true; - judgement = cache->QueryPolicy(cert.get(), host, status); - })); + web::GetIOThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(^{ + completed = true; + judgement = cache->QueryPolicy( + cert.get(), host, status); + })); EXPECT_TRUE(WaitUntilConditionOrTimeout(1.0, ^{ return completed; }));
diff --git a/ios/web/shell/shell_browser_state.mm b/ios/web/shell/shell_browser_state.mm index 606dbb2..e5e98f2 100644 --- a/ios/web/shell/shell_browser_state.mm +++ b/ios/web/shell/shell_browser_state.mm
@@ -7,7 +7,6 @@ #include "base/base_paths.h" #include "base/files/file_path.h" #include "base/path_service.h" -#include "base/task/post_task.h" #include "base/threading/thread_restrictions.h" #include "ios/web/public/thread/web_task_traits.h" #include "ios/web/public/thread/web_thread.h" @@ -23,8 +22,7 @@ CHECK(base::PathService::Get(base::DIR_APP_DATA, &path_)); request_context_getter_ = new ShellURLRequestContextGetter( - GetStatePath(), this, - base::CreateSingleThreadTaskRunner({web::WebThread::IO})); + GetStatePath(), this, web::GetIOThreadTaskRunner({})); } ShellBrowserState::~ShellBrowserState() {
diff --git a/ios/web/test/fakes/fake_web_frame_impl.cc b/ios/web/test/fakes/fake_web_frame_impl.cc index 36d17aa..fcf466a4 100644 --- a/ios/web/test/fakes/fake_web_frame_impl.cc +++ b/ios/web/test/fakes/fake_web_frame_impl.cc
@@ -10,9 +10,9 @@ #include "base/bind.h" #include "base/callback.h" #include "base/json/json_writer.h" -#include "base/task/post_task.h" #include "base/values.h" #include "ios/web/public/thread/web_task_traits.h" +#include "ios/web/public/thread/web_thread.h" namespace web { @@ -117,12 +117,11 @@ } if (force_timeout_) { - base::PostDelayedTask(FROM_HERE, {web::WebThread::UI}, - base::BindOnce(std::move(callback), nullptr), - timeout); + web::GetUIThreadTaskRunner({})->PostDelayedTask( + FROM_HERE, base::BindOnce(std::move(callback), nullptr), timeout); } else { - base::PostTask(FROM_HERE, {WebThread::UI}, - base::BindOnce(std::move(callback), result_map_[name])); + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), result_map_[name])); } return true; }
diff --git a/ios/web/web_thread_unittest.cc b/ios/web/web_thread_unittest.cc index 642b6ba..7209d31 100644 --- a/ios/web/web_thread_unittest.cc +++ b/ios/web/web_thread_unittest.cc
@@ -5,7 +5,6 @@ #include "ios/web/public/thread/web_thread.h" #include "base/bind.h" -#include "base/task/post_task.h" #include "ios/web/public/test/web_task_environment.h" #include "ios/web/public/thread/web_task_traits.h" #include "ios/web/public/thread/web_thread.h" @@ -31,10 +30,9 @@ TEST_F(WebThreadTest, BasePostTask) { base::RunLoop run_loop; - EXPECT_TRUE(base::PostTask( - FROM_HERE, {WebThread::IO}, - base::BindOnce(&BasicFunction, run_loop.QuitWhenIdleClosure(), - WebThread::IO))); + EXPECT_TRUE(GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&BasicFunction, run_loop.QuitWhenIdleClosure(), + WebThread::IO))); run_loop.Run(); } @@ -55,8 +53,7 @@ } TEST_F(WebThreadTest, PostTaskViaTaskRunner) { - scoped_refptr<base::TaskRunner> task_runner = - base::CreateTaskRunner({WebThread::IO}); + scoped_refptr<base::TaskRunner> task_runner = GetIOThreadTaskRunner({}); base::RunLoop run_loop; EXPECT_TRUE(task_runner->PostTask( FROM_HERE, base::BindOnce(&BasicFunction, run_loop.QuitWhenIdleClosure(), @@ -66,7 +63,7 @@ TEST_F(WebThreadTest, PostTaskViaSequencedTaskRunner) { scoped_refptr<base::SequencedTaskRunner> task_runner = - base::CreateSequencedTaskRunner({WebThread::IO}); + GetIOThreadTaskRunner({}); base::RunLoop run_loop; EXPECT_TRUE(task_runner->PostTask( FROM_HERE, base::BindOnce(&BasicFunction, run_loop.QuitWhenIdleClosure(), @@ -76,7 +73,7 @@ TEST_F(WebThreadTest, PostTaskViaSingleThreadTaskRunner) { scoped_refptr<base::SingleThreadTaskRunner> task_runner = - base::CreateSingleThreadTaskRunner({WebThread::IO}); + GetIOThreadTaskRunner({}); base::RunLoop run_loop; EXPECT_TRUE(task_runner->PostTask( FROM_HERE, base::BindOnce(&BasicFunction, run_loop.QuitWhenIdleClosure(),
diff --git a/ios/web/webui/url_data_manager_ios.cc b/ios/web/webui/url_data_manager_ios.cc index 230353c8..a128af5a 100644 --- a/ios/web/webui/url_data_manager_ios.cc +++ b/ios/web/webui/url_data_manager_ios.cc
@@ -15,7 +15,6 @@ #include "base/no_destructor.h" #include "base/strings/string_util.h" #include "base/synchronization/lock.h" -#include "base/task/post_task.h" #include "ios/web/public/browser_state.h" #include "ios/web/public/thread/web_task_traits.h" #include "ios/web/public/thread/web_thread.h" @@ -67,8 +66,8 @@ void URLDataManagerIOS::AddDataSource(URLDataSourceIOSImpl* source) { DCHECK_CURRENTLY_ON(web::WebThread::UI); - base::PostTask( - FROM_HERE, {web::WebThread::IO}, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&AddDataSourceOnIOThread, base::Unretained(browser_state_), base::WrapRefCounted(source))); } @@ -109,8 +108,8 @@ } if (schedule_delete) { // Schedule a task to delete the DataSource back on the UI thread. - base::PostTask(FROM_HERE, {web::WebThread::UI}, - base::BindOnce(&URLDataManagerIOS::DeleteDataSources)); + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&URLDataManagerIOS::DeleteDataSources)); } }
diff --git a/ios/web/webui/url_data_manager_ios_backend.mm b/ios/web/webui/url_data_manager_ios_backend.mm index 613a457..5fe5b55 100644 --- a/ios/web/webui/url_data_manager_ios_backend.mm +++ b/ios/web/webui/url_data_manager_ios_backend.mm
@@ -14,7 +14,6 @@ #include "base/memory/ref_counted_memory.h" #include "base/memory/weak_ptr.h" #include "base/strings/string_util.h" -#include "base/task/post_task.h" #include "base/task/single_thread_task_runner.h" #include "base/trace_event/trace_event.h" #include "ios/web/public/browser_state.h" @@ -400,8 +399,8 @@ const base::WeakPtr<URLRequestChromeJob>& job) { DCHECK_CURRENTLY_ON(WebThread::UI); std::string mime_type = source->source()->GetMimeType(path); - base::PostTask(FROM_HERE, {WebThread::IO}, - base::BindOnce(&URLRequestChromeJob::MimeTypeAvailable, job, + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&URLRequestChromeJob::MimeTypeAvailable, job, base::RetainedRef(source), mime_type)); } @@ -521,7 +520,7 @@ // message loop before request for data. And correspondingly their // replies are put on the IO thread in the same order. scoped_refptr<base::SingleThreadTaskRunner> target_runner = - base::CreateSingleThreadTaskRunner({web::WebThread::UI}); + web::GetUIThreadTaskRunner({}); target_runner->PostTask( FROM_HERE, base::BindOnce(&GetMimeTypeOnUI, base::RetainedRef(source), path, job->weak_factory_.GetWeakPtr()));
diff --git a/ios/web/webui/url_data_source_ios_impl.cc b/ios/web/webui/url_data_source_ios_impl.cc index 6ae4184..a8609f4 100644 --- a/ios/web/webui/url_data_source_ios_impl.cc +++ b/ios/web/webui/url_data_source_ios_impl.cc
@@ -8,7 +8,6 @@ #include "base/location.h" #include "base/memory/ref_counted_memory.h" #include "base/strings/string_util.h" -#include "base/task/post_task.h" #include "ios/web/public/thread/web_task_traits.h" #include "ios/web/public/thread/web_thread.h" #include "ios/web/public/webui/url_data_source_ios.h" @@ -42,8 +41,8 @@ // when the object is deleted. return; } - base::PostTask(FROM_HERE, {web::WebThread::IO}, - base::BindOnce(&URLDataSourceIOSImpl::SendResponseOnIOThread, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&URLDataSourceIOSImpl::SendResponseOnIOThread, this, request_id, std::move(bytes))); }
diff --git a/ios/web_view/internal/app/application_context.mm b/ios/web_view/internal/app/application_context.mm index 7bac0968..00e1e05 100644 --- a/ios/web_view/internal/app/application_context.mm +++ b/ios/web_view/internal/app/application_context.mm
@@ -8,7 +8,6 @@ #include "base/command_line.h" #include "base/no_destructor.h" #include "base/path_service.h" -#include "base/task/post_task.h" #include "components/component_updater/component_updater_service.h" #include "components/component_updater/timer_update_scheduler.h" #include "components/flags_ui/pref_service_flags_storage.h" @@ -79,8 +78,8 @@ shared_url_loader_factory_->Detach(); if (network_context_) { - base::DeleteSoon(FROM_HERE, {web::WebThread::IO}, - network_context_owner_.release()); + web::GetIOThreadTaskRunner({})->DeleteSoon( + FROM_HERE, network_context_owner_.release()); } }
diff --git a/ios/web_view/internal/autofill/cwv_autofill_data_manager.mm b/ios/web_view/internal/autofill/cwv_autofill_data_manager.mm index ba5261c..5c990a7 100644 --- a/ios/web_view/internal/autofill/cwv_autofill_data_manager.mm +++ b/ios/web_view/internal/autofill/cwv_autofill_data_manager.mm
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/notreached.h" #include "base/strings/sys_string_conversions.h" -#include "base/task/post_task.h" #include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill/core/browser/personal_data_manager_observer.h" #include "components/password_manager/core/browser/password_manager_util.h" @@ -227,9 +226,9 @@ // |personalDataDidChange| to be invoked. if (_personalDataManager->IsDataLoaded()) { NSArray<CWVAutofillProfile*>* profiles = [self profiles]; - base::PostTask(FROM_HERE, {web::WebThread::UI}, base::BindOnce(^{ - completionHandler(profiles); - })); + web::GetUIThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(^{ + completionHandler(profiles); + })); } else { [_fetchProfilesCompletionHandlers addObject:completionHandler]; } @@ -250,9 +249,9 @@ // |personalDataDidChange| to be invoked. if (_personalDataManager->IsDataLoaded()) { NSArray<CWVCreditCard*>* creditCards = [self creditCards]; - base::PostTask(FROM_HERE, {web::WebThread::UI}, base::BindOnce(^{ - completionHandler(creditCards); - })); + web::GetUIThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(^{ + completionHandler(creditCards); + })); } else { [_fetchCreditCardsCompletionHandlers addObject:completionHandler]; }
diff --git a/ios/web_view/internal/autofill/cwv_credit_card_verifier_unittest.mm b/ios/web_view/internal/autofill/cwv_credit_card_verifier_unittest.mm index 45fbe39f..7b1af74 100644 --- a/ios/web_view/internal/autofill/cwv_credit_card_verifier_unittest.mm +++ b/ios/web_view/internal/autofill/cwv_credit_card_verifier_unittest.mm
@@ -15,7 +15,6 @@ #include "base/path_service.h" #include "base/run_loop.h" #include "base/strings/sys_string_conversions.h" -#include "base/task/post_task.h" #import "base/test/ios/wait_util.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/data_model/credit_card.h" @@ -59,12 +58,12 @@ const UserProvidedUnmaskDetails& unmask_details) override { unmask_details_ = unmask_details; // Fake the actual verification and just respond with success. - base::PostTask(FROM_HERE, {web::WebThread::UI}, base::BindOnce(^{ - autofill::AutofillClient::PaymentsRpcResult result = - autofill::AutofillClient::PaymentsRpcResult::kSuccess; - [credit_card_verifier_ - didReceiveUnmaskVerificationResult:result]; - })); + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(^{ + autofill::AutofillClient::PaymentsRpcResult result = + autofill::AutofillClient::PaymentsRpcResult::kSuccess; + [credit_card_verifier_ didReceiveUnmaskVerificationResult:result]; + })); } void OnUnmaskPromptClosed() override {} bool ShouldOfferFidoAuth() const override { return false; }
diff --git a/ios/web_view/internal/ios_global_state_web_view_configuration.mm b/ios/web_view/internal/ios_global_state_web_view_configuration.mm index fb5c021..c3a6aaf 100644 --- a/ios/web_view/internal/ios_global_state_web_view_configuration.mm +++ b/ios/web_view/internal/ios_global_state_web_view_configuration.mm
@@ -4,7 +4,8 @@ #include "ios/web/public/init/ios_global_state_configuration.h" -#include "base/task/post_task.h" +#include <dispatch/dispatch.h> + #include "base/task/single_thread_task_runner.h" #include "ios/web/public/thread/web_task_traits.h" #include "ios/web/public/thread/web_thread.h" @@ -22,7 +23,7 @@ dispatch_once(&once_token, ^{ ios_web_view::InitializeGlobalState(); }); - return base::CreateSingleThreadTaskRunner({web::WebThread::IO}); + return web::GetIOThreadTaskRunner({}); } } // namespace ios_global_state
diff --git a/ios/web_view/internal/passwords/web_view_account_password_store_factory.mm b/ios/web_view/internal/passwords/web_view_account_password_store_factory.mm index 71eb929..76a389bb 100644 --- a/ios/web_view/internal/passwords/web_view_account_password_store_factory.mm +++ b/ios/web_view/internal/passwords/web_view_account_password_store_factory.mm
@@ -10,7 +10,6 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/no_destructor.h" -#include "base/task/post_task.h" #include "components/keyed_service/ios/browser_state_dependency_manager.h" #include "components/password_manager/core/browser/login_database.h" #include "components/password_manager/core/browser/password_manager_constants.h" @@ -48,8 +47,8 @@ } void SyncEnabledOrDisabled(WebViewBrowserState* browser_state) { - base::PostTask(FROM_HERE, {web::WebThread::UI}, - base::BindOnce(&UpdateFormManager, browser_state)); + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&UpdateFormManager, browser_state)); } } // namespace
diff --git a/ios/web_view/internal/sync/web_view_gcm_profile_service_factory.mm b/ios/web_view/internal/sync/web_view_gcm_profile_service_factory.mm index 4671a4b5..00cecf1 100644 --- a/ios/web_view/internal/sync/web_view_gcm_profile_service_factory.mm +++ b/ios/web_view/internal/sync/web_view_gcm_profile_service_factory.mm
@@ -8,7 +8,6 @@ #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" #include "base/no_destructor.h" -#include "base/task/post_task.h" #include "base/task/sequenced_task_runner.h" #include "base/task/thread_pool.h" #include "components/gcm_driver/gcm_client_factory.h" @@ -52,8 +51,8 @@ base::WeakPtr<gcm::GCMProfileService> service, mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory> receiver) { - base::PostTask( - FROM_HERE, {web::WebThread::UI}, + web::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&RequestProxyResolvingSocketFactoryOnUIThread, context, std::move(service), std::move(receiver))); } @@ -107,8 +106,7 @@ version_info::Channel::STABLE, GetProductCategoryForSubtypes(), WebViewIdentityManagerFactory::GetForBrowserState(browser_state), base::WrapUnique(new gcm::GCMClientFactory), - base::CreateSingleThreadTaskRunner({web::WebThread::UI}), - base::CreateSingleThreadTaskRunner({web::WebThread::IO}), + web::GetUIThreadTaskRunner({}), web::GetIOThreadTaskRunner({}), blocking_task_runner); } } // namespace ios_web_view
diff --git a/ios/web_view/internal/sync/web_view_sync_client.mm b/ios/web_view/internal/sync/web_view_sync_client.mm index 78c1948..2f8ef06 100644 --- a/ios/web_view/internal/sync/web_view_sync_client.mm +++ b/ios/web_view/internal/sync/web_view_sync_client.mm
@@ -11,7 +11,6 @@ #include "base/check_op.h" #include "base/command_line.h" #include "base/notreached.h" -#include "base/task/post_task.h" #include "components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h" #include "components/autofill/core/common/autofill_features.h" #include "components/invalidation/impl/profile_invalidation_provider.h" @@ -102,8 +101,7 @@ sync_invalidations_service_(sync_invalidations_service) { component_factory_ = std::make_unique<browser_sync::SyncApiComponentFactoryImpl>( - this, version_info::Channel::STABLE, - base::CreateSingleThreadTaskRunner({web::WebThread::UI}), + this, version_info::Channel::STABLE, web::GetUIThreadTaskRunner({}), profile_web_data_service_->GetDBTaskRunner(), profile_web_data_service_, account_web_data_service_, profile_password_store_, account_password_store_,
diff --git a/ios/web_view/internal/web_view_browser_state.mm b/ios/web_view/internal/web_view_browser_state.mm index 361819a9..2db6ff3 100644 --- a/ios/web_view/internal/web_view_browser_state.mm +++ b/ios/web_view/internal/web_view_browser_state.mm
@@ -10,7 +10,6 @@ #include "base/files/file_path.h" #include "base/memory/ptr_util.h" #include "base/path_service.h" -#include "base/task/post_task.h" #include "base/threading/thread_restrictions.h" #include "components/autofill/core/common/autofill_prefs.h" #include "components/history/core/common/pref_names.h" @@ -98,7 +97,7 @@ request_context_getter_ = new WebViewURLRequestContextGetter( GetStatePath(), this, ApplicationContext::GetInstance()->GetNetLog(), - base::CreateSingleThreadTaskRunner({web::WebThread::IO})); + web::GetIOThreadTaskRunner({})); // Initialize prefs. scoped_refptr<user_prefs::PrefRegistrySyncable> pref_registry = @@ -125,8 +124,8 @@ BrowserStateDependencyManager::GetInstance()->DestroyBrowserStateServices( this); - base::PostTask(FROM_HERE, {web::WebThread::IO}, - base::BindOnce(&WebViewURLRequestContextGetter::ShutDown, + web::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&WebViewURLRequestContextGetter::ShutDown, request_context_getter_)); }
diff --git a/ios/web_view/internal/webdata_services/web_view_web_data_service_wrapper_factory.mm b/ios/web_view/internal/webdata_services/web_view_web_data_service_wrapper_factory.mm index ee69ed62..7e7d206 100644 --- a/ios/web_view/internal/webdata_services/web_view_web_data_service_wrapper_factory.mm +++ b/ios/web_view/internal/webdata_services/web_view_web_data_service_wrapper_factory.mm
@@ -10,7 +10,6 @@ #include "base/check.h" #include "base/files/file_path.h" #include "base/no_destructor.h" -#include "base/task/post_task.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/keyed_service/core/service_access_type.h" #include "components/keyed_service/ios/browser_state_dependency_manager.h" @@ -89,8 +88,7 @@ return std::make_unique<WebDataServiceWrapper>( browser_state_path, ApplicationContext::GetInstance()->GetApplicationLocale(), - base::CreateSingleThreadTaskRunner({web::WebThread::UI}), - base::DoNothing()); + web::GetUIThreadTaskRunner({}), base::DoNothing()); } bool WebViewWebDataServiceWrapperFactory::ServiceIsNULLWhileTesting() const {
diff --git a/media/formats/BUILD.gn b/media/formats/BUILD.gn index 53b4268..36e7fe3 100644 --- a/media/formats/BUILD.gn +++ b/media/formats/BUILD.gn
@@ -187,8 +187,14 @@ sources += [ "hls/items.cc", "hls/items.h", + "hls/media_playlist.cc", + "hls/media_playlist.h", + "hls/media_segment.cc", + "hls/media_segment.h", "hls/parse_status.cc", "hls/parse_status.h", + "hls/playlist_common.cc", + "hls/playlist_common.h", "hls/source_string.cc", "hls/source_string.h", "hls/tag_name.cc", @@ -199,7 +205,12 @@ "hls/types.h", ] deps += [ "//third_party/re2" ] - public_deps = [ "//third_party/abseil-cpp:absl" ] + public_deps = [ + "//third_party/abseil-cpp:absl", + + # Needed because `hls/media_playlist.h` includes GURL in its public API. + "//url", + ] } static_library("test_support") { @@ -308,6 +319,7 @@ # TODO(https://crbug.com/1266991): This should be gated behind `enable_hls_demuxer`, once that's enabled by default. sources += [ "hls/items_unittest.cc", + "hls/media_playlist_unittest.cc", "hls/tags_unittest.cc", "hls/types_unittest.cc", ] @@ -331,6 +343,15 @@ ] } +# TODO(https://crbug.com/1266991): This should be gated behind `enable_hls_demuxer`, once that's enabled by default. +fuzzer_test("hls_media_playlist_fuzzer") { + sources = [ "hls/media_playlist_fuzzer.cc" ] + deps = [ + "//base", + "//media", + ] +} + if (proprietary_codecs) { fuzzer_test("h264_annex_b_converter_fuzzer") { sources = [ "mp4/h264_annex_b_to_avc_bitstream_converter_fuzztest.cc" ]
diff --git a/media/formats/hls/items_fuzzer.cc b/media/formats/hls/items_fuzzer.cc index 802475d..b5b3d2d 100644 --- a/media/formats/hls/items_fuzzer.cc +++ b/media/formats/hls/items_fuzzer.cc
@@ -34,8 +34,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Create a StringPiece from the given input - const base::StringPiece manifest(reinterpret_cast<const char*>(data), size); - media::hls::SourceLineIterator iterator{manifest}; + const base::StringPiece source(reinterpret_cast<const char*>(data), size); + media::hls::SourceLineIterator iterator{source}; while (true) { const auto prev_iterator = iterator; @@ -46,7 +46,7 @@ CHECK(result == media::hls::ParseStatusCode::kReachedEOF || result == media::hls::ParseStatusCode::kInvalidEOL); - // Ensure that `manifest` is still a substring of the previous manifest + // Ensure that `source` is still a substring of the previous source CHECK(IsSubstring(iterator.SourceForTesting(), prev_iterator.SourceForTesting())); CHECK(iterator.CurrentLineForTesting() >=
diff --git a/media/formats/hls/items_unittest.cc b/media/formats/hls/items_unittest.cc index 6d96d4f1..7b5cc79 100644 --- a/media/formats/hls/items_unittest.cc +++ b/media/formats/hls/items_unittest.cc
@@ -22,8 +22,8 @@ // Calls `GetNextLineItem` for each expectation, and verifies that the result // matches. template <typename T> -void RunTest(base::StringPiece manifest, const T& expectations) { - auto line_iter = SourceLineIterator(manifest); +void RunTest(base::StringPiece source, const T& expectations) { + auto line_iter = SourceLineIterator(source); for (auto expectation : expectations) { auto result = GetNextLineItem(&line_iter);
diff --git a/media/formats/hls/media_playlist.cc b/media/formats/hls/media_playlist.cc new file mode 100644 index 0000000..6ccf8da9 --- /dev/null +++ b/media/formats/hls/media_playlist.cc
@@ -0,0 +1,162 @@ +// 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 "media/formats/hls/media_playlist.h" + +#include "base/notreached.h" +#include "base/time/time.h" +#include "media/formats/hls/media_segment.h" +#include "media/formats/hls/playlist_common.h" +#include "media/formats/hls/types.h" +#include "url/gurl.h" + +namespace media::hls { + +MediaPlaylist::MediaPlaylist(const MediaPlaylist&) = default; + +MediaPlaylist::MediaPlaylist(MediaPlaylist&&) = default; + +MediaPlaylist& MediaPlaylist::operator=(const MediaPlaylist&) = default; + +MediaPlaylist& MediaPlaylist::operator=(MediaPlaylist&&) = default; + +MediaPlaylist::~MediaPlaylist() = default; + +ParseStatus::Or<MediaPlaylist> MediaPlaylist::Parse(base::StringPiece source, + GURL uri) { + CHECK(uri.is_valid()); + + SourceLineIterator src_iter{source}; + + // Parse the first line of the playlist. This must be an M3U tag. + { + auto m3u_tag_result = CheckM3uTag(&src_iter); + if (m3u_tag_result.has_error()) { + return std::move(m3u_tag_result).error(); + } + } + + CommonParserState common_state; + absl::optional<InfTag> inf_tag; + absl::optional<XGapTag> gap_tag; + absl::optional<XDiscontinuityTag> discontinuity_tag; + std::vector<MediaSegment> segments; + + // Get segments out of the playlist + while (true) { + auto item_result = GetNextLineItem(&src_iter); + if (item_result.has_error()) { + auto error = std::move(item_result).error(); + + // Only tolerated error is EOF, in which case we're done. + if (error.code() == ParseStatusCode::kReachedEOF) { + break; + } + + return std::move(error); + } + + auto item = std::move(item_result).value(); + + // Handle tags + if (auto* tag = absl::get_if<TagItem>(&item)) { + switch (GetTagKind(tag->name)) { + case TagKind::kUnknown: + HandleUnknownTag(*tag); + continue; + case TagKind::kCommonTag: { + auto error = ParseCommonTag(*tag, &common_state); + if (error.has_value()) { + return std::move(error).value(); + } + continue; + } + case TagKind::kMultivariantPlaylistTag: + return ParseStatusCode::kMediaPlaylistHasMultivariantPlaylistTag; + case TagKind::kMediaPlaylistTag: + // Handled below + break; + } + + switch (static_cast<MediaPlaylistTagName>(tag->name)) { + case MediaPlaylistTagName::kInf: { + auto error = ParseUniqueTag(*tag, inf_tag); + if (error.has_value()) { + return std::move(error).value(); + } + break; + } + case MediaPlaylistTagName::kXDiscontinuity: { + auto error = ParseUniqueTag(*tag, discontinuity_tag); + if (error.has_value()) { + return std::move(error).value(); + } + break; + } + case MediaPlaylistTagName::kXGap: { + auto error = ParseUniqueTag(*tag, gap_tag); + if (error.has_value()) { + return std::move(error).value(); + } + break; + } + case MediaPlaylistTagName::kXEndList: + // TODO(crbug.com/1266991): Implement the #EXT-X-END-LIST Tag + break; + case MediaPlaylistTagName::kXIFramesOnly: + // TODO(crbug.com/1266991): Implement the #EXT-X-I-FRAMES-ONLY tag + break; + } + + continue; + } + + // Handle URIs + // `GetNextLineItem` should return either a TagItem (handled above) or a + // UriItem. + static_assert(absl::variant_size<GetNextLineItemResult>() == 2); + auto segment_uri_result = + ParseUri(absl::get<UriItem>(std::move(item)), uri); + if (segment_uri_result.has_error()) { + return std::move(segment_uri_result).error(); + } + auto segment_uri = std::move(segment_uri_result).value(); + + // For this to be a valid media segment, we must have parsed an Inf tag + // since the last segment. + if (!inf_tag.has_value()) { + return ParseStatusCode::kMediaSegmentMissingInfTag; + } + + segments.emplace_back(inf_tag->duration, std::move(segment_uri), + discontinuity_tag.has_value(), gap_tag.has_value()); + + // Reset per-segment tags + inf_tag.reset(); + gap_tag.reset(); + discontinuity_tag.reset(); + } + + return MediaPlaylist(std::move(uri), common_state.GetVersion(), + common_state.independent_segments_tag.has_value(), + std::move(segments)); +} + +MediaPlaylist::MediaPlaylist(GURL uri, + types::DecimalInteger version, + bool independent_segments, + std::vector<MediaSegment> segments) + : uri_(std::move(uri)), + version_(version), + independent_segments_(independent_segments), + segments_(std::move(segments)) { + base::TimeDelta duration; + for (const auto& segment : segments_) { + duration += base::Seconds(segment.GetDuration()); + } + + computed_duration_ = duration; +} + +} // namespace media::hls
diff --git a/media/formats/hls/media_playlist.h b/media/formats/hls/media_playlist.h new file mode 100644 index 0000000..98db772 --- /dev/null +++ b/media/formats/hls/media_playlist.h
@@ -0,0 +1,69 @@ +// 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 MEDIA_FORMATS_HLS_MEDIA_PLAYLIST_H_ +#define MEDIA_FORMATS_HLS_MEDIA_PLAYLIST_H_ + +#include <vector> +#include "base/time/time.h" +#include "media/base/media_export.h" +#include "media/formats/hls/types.h" +#include "url/gurl.h" + +namespace media::hls { + +class MediaSegment; + +class MEDIA_EXPORT MediaPlaylist { + public: + MediaPlaylist(const MediaPlaylist&); + MediaPlaylist(MediaPlaylist&&); + MediaPlaylist& operator=(const MediaPlaylist&); + MediaPlaylist& operator=(MediaPlaylist&&); + ~MediaPlaylist(); + + // Returns the resolved URI of this playlist. + const GURL& Uri() const { return uri_; } + + // Returns the HLS version number defined by the playlist. The default version + // is `1`. + types::DecimalInteger GetVersion() const { return version_; } + + // Indicates that all media samples in a Segment can be decoded without + // information from other segments. It applies to every Media Segment in the + // Playlist. + bool AreSegmentsIndependent() const { return independent_segments_; } + + // Returns all segments in this playlist, in chronological order. This vector + // may be copied independently of this Playlist. + const std::vector<MediaSegment>& GetSegments() const { return segments_; } + + // Returns the sum of the duration of all segments in this playlist. + // Computed via the 'EXTINF' attribute, so may be slightly longer than the + // actual duration. + base::TimeDelta GetComputedDuration() const { return computed_duration_; } + + // Attempts to parse the playlist represented by `source`. `uri` must be a + // valid, non-empty GURL referring to the URI of this playlist. If the + // playlist is invalid, returns an error. Otherwise, returns the parsed + // playlist. + static ParseStatus::Or<MediaPlaylist> Parse(base::StringPiece source, + GURL uri); + + private: + MediaPlaylist(GURL uri, + types::DecimalInteger version, + bool independent_segments, + std::vector<MediaSegment> segments); + + GURL uri_; + types::DecimalInteger version_; + bool independent_segments_; + std::vector<MediaSegment> segments_; + base::TimeDelta computed_duration_; +}; + +} // namespace media::hls + +#endif // MEDIA_FORMATS_HLS_MEDIA_PLAYLIST_H_
diff --git a/media/formats/hls/media_playlist_fuzzer.cc b/media/formats/hls/media_playlist_fuzzer.cc new file mode 100644 index 0000000..3601d62a --- /dev/null +++ b/media/formats/hls/media_playlist_fuzzer.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 <cstddef> +#include <cstdint> + +#include "base/check.h" +#include "base/strings/string_piece.h" +#include "media/formats/hls/media_playlist.h" +#include "third_party/abseil-cpp/absl/types/variant.h" +#include "url/gurl.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + // Create a StringPiece from the given input + const base::StringPiece source(reinterpret_cast<const char*>(data), size); + + // Try to parse it as a media playlist + media::hls::MediaPlaylist::Parse(source, + GURL("http://localhost/playlist.m3u8")); + + return 0; +}
diff --git a/media/formats/hls/media_playlist_unittest.cc b/media/formats/hls/media_playlist_unittest.cc new file mode 100644 index 0000000..0d0eb52 --- /dev/null +++ b/media/formats/hls/media_playlist_unittest.cc
@@ -0,0 +1,221 @@ +// 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 "media/formats/hls/media_playlist.h" + +#include <vector> + +#include "base/callback_list.h" +#include "base/location.h" +#include "media/formats/hls/items.h" +#include "media/formats/hls/media_segment.h" +#include "media/formats/hls/source_string.h" +#include "media/formats/hls/tags.h" +#include "media/formats/hls/types.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace media::hls { + +namespace { + +class TestBuilder { + public: + void SetUri(GURL uri) { uri_ = std::move(uri); } + + // Appends a new line to the playlist. + void AppendLine(base::StringPiece line) { + source_.append(line.data(), line.size()); + source_.append("\n"); + } + + // Adds a new expectation for the playlist, which will be checked during + // `ExpectOk`. + template <typename Fn, typename Arg> + void ExpectPlaylist(Fn fn, + Arg arg, + base::Location location = base::Location::Current()) { + playlist_expectations_.emplace_back(base::BindRepeating( + std::move(fn), std::move(arg), std::move(location))); + } + + // Increments the number of segments that are expected to be contained in the + // playlist. + void ExpectAdditionalSegment() { segment_expectations_.push_back({}); } + + // Adds a new expectation for the latest segment in the playlist, which will + // be checked during `ExpectOk`. + template <typename Fn, typename Arg> + void ExpectSegment(Fn fn, + Arg arg, + base::Location location = base::Location::Current()) { + segment_expectations_.back().expectations.emplace_back(base::BindRepeating( + std::move(fn), std::move(arg), std::move(location))); + } + + // Attempts to parse the playlist as-is, checking for the given + // error code. + void ExpectError( + ParseStatusCode code, + const base::Location& from = base::Location::Current()) const { + auto result = MediaPlaylist::Parse(source_, uri_); + ASSERT_TRUE(result.has_error()) << from.ToString(); + EXPECT_EQ(std::move(result).error().code(), code) << from.ToString(); + } + + // Attempts to parse the playlist as-is, checking all playlist and segment + // expectations. + void ExpectOk(const base::Location& from = base::Location::Current()) const { + auto result = MediaPlaylist::Parse(source_, uri_); + ASSERT_TRUE(result.has_value()) + << "Error: " + << ParseStatusCodeToString(std::move(result).error().code()) << "\n" + << from.ToString(); + auto playlist = std::move(result).value(); + + for (const auto& expectation : playlist_expectations_) { + expectation.Run(playlist); + } + + ASSERT_EQ(segment_expectations_.size(), playlist.GetSegments().size()) + << from.ToString(); + for (size_t i = 0; i < segment_expectations_.size(); ++i) { + const auto& segment = playlist.GetSegments().at(i); + const auto& expectations = segment_expectations_.at(i); + for (const auto& expectation : expectations.expectations) { + expectation.Run(segment); + } + } + } + + private: + struct SegmentExpectations { + std::vector<base::RepeatingCallback<void(const MediaSegment&)>> + expectations; + }; + + std::vector<SegmentExpectations> segment_expectations_; + std::vector<base::RepeatingCallback<void(const MediaPlaylist&)>> + playlist_expectations_; + GURL uri_ = GURL("http://localhost/playlist.m3u8"); + std::string source_; +}; + +void HasVersion(types::DecimalInteger version, + const base::Location& from, + const MediaPlaylist& playlist) { + EXPECT_EQ(playlist.GetVersion(), version) << from.ToString(); +} + +void HasDuration(types::DecimalFloatingPoint duration, + const base::Location& from, + const MediaSegment& segment) { + EXPECT_DOUBLE_EQ(segment.GetDuration(), duration) << from.ToString(); +} + +void HasUri(GURL uri, const base::Location& from, const MediaSegment& segment) { + EXPECT_EQ(segment.GetUri(), uri) << from.ToString(); +} + +void HasDiscontinuity(bool value, + const base::Location& from, + const MediaSegment& segment) { + EXPECT_EQ(segment.HasDiscontinuity(), value) << from.ToString(); +} + +void IsGap(bool value, + const base::Location& from, + const MediaSegment& segment) { + EXPECT_EQ(segment.IsGap(), value) << from.ToString(); +} + +} // namespace + +TEST(HlsFormatParserTest, ParseMediaPlaylist_MissingM3u) { + TestBuilder builder; + builder.AppendLine("#EXT-X-VERSION:5"); + builder.ExpectError(ParseStatusCode::kPlaylistMissingM3uTag); +} + +TEST(HlsFormatParserTest, ParseMediaPlaylist_VersionChecks) { + TestBuilder builder; + builder.AppendLine("#EXTM3U"); + + { + // Default version is 1 + auto fork = builder; + fork.ExpectPlaylist(HasVersion, 1); + fork.ExpectOk(); + } + + { + // "-1" is not a valid decimal-integer + auto fork = builder; + fork.AppendLine("#EXT-X-VERSION:-1"); + fork.ExpectError(ParseStatusCode::kMalformedTag); + } + + { + // "0" is not a valid version + auto fork = builder; + fork.AppendLine("#EXT-X-VERSION:0"); + fork.ExpectError(ParseStatusCode::kInvalidPlaylistVersion); + } + + for (int i = 1; i <= 10; ++i) { + auto fork = builder; + fork.AppendLine("#EXT-X-VERSION:" + base::NumberToString(i)); + fork.ExpectPlaylist(HasVersion, i); + fork.ExpectOk(); + } + + for (int i : {11, 12, 100, 999}) { + // Versions 11+ are not supported by this parser + auto fork = builder; + fork.AppendLine("#EXT-X-VERSION:" + base::NumberToString(i)); + fork.ExpectError(ParseStatusCode::kPlaylistHasUnsupportedVersion); + } +} + +TEST(HlsFormatParserTest, ParseMediaPlaylist_Segments) { + TestBuilder builder; + builder.AppendLine("#EXTM3U"); + builder.AppendLine("#EXT-X-VERSION:5"); + builder.ExpectPlaylist(HasVersion, 5); + + builder.AppendLine("#EXTINF:9.2,\t"); + builder.AppendLine("video.ts"); + builder.ExpectAdditionalSegment(); + builder.ExpectSegment(HasDiscontinuity, false); + builder.ExpectSegment(HasDuration, 9.2); + builder.ExpectSegment(HasUri, GURL("http://localhost/video.ts")); + builder.ExpectSegment(IsGap, false); + + // Segments without #EXTINF tags are not allowed + { + auto fork = builder; + fork.AppendLine("foobar.ts"); + fork.ExpectError(ParseStatusCode::kMediaSegmentMissingInfTag); + } + + builder.AppendLine("#EXTINF:9.3,foo"); + builder.AppendLine("#EXT-X-DISCONTINUITY"); + builder.AppendLine("foo.ts"); + builder.ExpectAdditionalSegment(); + builder.ExpectSegment(HasDiscontinuity, true); + builder.ExpectSegment(HasDuration, 9.3); + builder.ExpectSegment(IsGap, false); + builder.ExpectSegment(HasUri, GURL("http://localhost/foo.ts")); + + builder.AppendLine("#EXTINF:9.2,bar"); + builder.AppendLine("http://foo/bar.ts"); + builder.ExpectAdditionalSegment(); + builder.ExpectSegment(HasDiscontinuity, false); + builder.ExpectSegment(HasDuration, 9.2); + builder.ExpectSegment(IsGap, false); + builder.ExpectSegment(HasUri, GURL("http://foo/bar.ts")); + + builder.ExpectOk(); +} + +} // namespace media::hls
diff --git a/media/formats/hls/media_segment.cc b/media/formats/hls/media_segment.cc new file mode 100644 index 0000000..7f278402e --- /dev/null +++ b/media/formats/hls/media_segment.cc
@@ -0,0 +1,26 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/formats/hls/media_segment.h" + +#include "media/formats/hls/types.h" +#include "url/gurl.h" + +namespace media::hls { + +MediaSegment::MediaSegment(types::DecimalFloatingPoint duration, + GURL uri, + bool has_discontinuity, + bool is_gap) + : duration_(duration), + uri_(std::move(uri)), + has_discontinuity_(has_discontinuity), + is_gap_(is_gap) {} +MediaSegment::~MediaSegment() = default; +MediaSegment::MediaSegment(const MediaSegment&) = default; +MediaSegment::MediaSegment(MediaSegment&&) = default; +MediaSegment& MediaSegment::operator=(const MediaSegment&) = default; +MediaSegment& MediaSegment::operator=(MediaSegment&&) = default; + +} // namespace media::hls
diff --git a/media/formats/hls/media_segment.h b/media/formats/hls/media_segment.h new file mode 100644 index 0000000..020b8551 --- /dev/null +++ b/media/formats/hls/media_segment.h
@@ -0,0 +1,51 @@ +// 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 MEDIA_FORMATS_HLS_MEDIA_SEGMENT_H_ +#define MEDIA_FORMATS_HLS_MEDIA_SEGMENT_H_ + +#include "media/base/media_export.h" +#include "media/formats/hls/types.h" +#include "url/gurl.h" + +namespace media::hls { + +class MEDIA_EXPORT MediaSegment { + public: + MediaSegment(types::DecimalFloatingPoint duration, + GURL uri, + bool has_discontinuity, + bool is_gap); + ~MediaSegment(); + MediaSegment(const MediaSegment&); + MediaSegment(MediaSegment&&); + MediaSegment& operator=(const MediaSegment&); + MediaSegment& operator=(MediaSegment&&); + + // The approximate duration of this media segment in seconds. + types::DecimalFloatingPoint GetDuration() const { return duration_; } + + // The URI of the media resource. This will have already been resolved against + // the playlist URI. This is guaranteed to be valid and non-empty, unless + // `gap` is true, in which case this URI should not be used. + const GURL& GetUri() const { return uri_; } + + // Whether there is a decoding discontinuity between the previous media + // segment and this one. + bool HasDiscontinuity() const { return has_discontinuity_; } + + // If this is `true`, it indicates that the resource for this media segment is + // absent and the client should not attempt to fetch it. + bool IsGap() const { return is_gap_; } + + private: + types::DecimalFloatingPoint duration_; + GURL uri_; + bool has_discontinuity_; + bool is_gap_; +}; + +} // namespace media::hls + +#endif // MEDIA_FORMATS_HLS_MEDIA_SEGMENT_H_
diff --git a/media/formats/hls/parse_status.cc b/media/formats/hls/parse_status.cc index 43d4538..ee105a1 100644 --- a/media/formats/hls/parse_status.cc +++ b/media/formats/hls/parse_status.cc
@@ -25,11 +25,12 @@ PARSE_STATUS_CODE_CASE(kMalformedAttributeList); PARSE_STATUS_CODE_CASE(kAttributeListHasDuplicateNames); PARSE_STATUS_CODE_CASE(kMalformedVariableName); + PARSE_STATUS_CODE_CASE(kInvalidUri); PARSE_STATUS_CODE_CASE(kPlaylistMissingM3uTag); PARSE_STATUS_CODE_CASE(kMediaSegmentMissingInfTag); - PARSE_STATUS_CODE_CASE(kMediaSegmentHasMultipleInfTags); - PARSE_STATUS_CODE_CASE(kPlaylistSpecifiesMultipleVersions); + PARSE_STATUS_CODE_CASE(kPlaylistHasDuplicateTags); PARSE_STATUS_CODE_CASE(kPlaylistHasUnsupportedVersion); + PARSE_STATUS_CODE_CASE(kMediaPlaylistHasMultivariantPlaylistTag); } NOTREACHED();
diff --git a/media/formats/hls/parse_status.h b/media/formats/hls/parse_status.h index ea0132e..2f28658 100644 --- a/media/formats/hls/parse_status.h +++ b/media/formats/hls/parse_status.h
@@ -22,11 +22,12 @@ kMalformedAttributeList, kAttributeListHasDuplicateNames, kMalformedVariableName, + kInvalidUri, kPlaylistMissingM3uTag, kMediaSegmentMissingInfTag, - kMediaSegmentHasMultipleInfTags, - kPlaylistSpecifiesMultipleVersions, + kPlaylistHasDuplicateTags, kPlaylistHasUnsupportedVersion, + kMediaPlaylistHasMultivariantPlaylistTag, }; struct ParseStatusTraits {
diff --git a/media/formats/hls/playlist_common.cc b/media/formats/hls/playlist_common.cc new file mode 100644 index 0000000..f174c67 --- /dev/null +++ b/media/formats/hls/playlist_common.cc
@@ -0,0 +1,95 @@ +// 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 "media/formats/hls/playlist_common.h" +#include "base/notreached.h" + +namespace media::hls { + +types::DecimalInteger CommonParserState::GetVersion() const { + if (version_tag.has_value()) { + return version_tag.value().version; + } else { + return 1; + } +} + +ParseStatus::Or<M3uTag> CheckM3uTag(SourceLineIterator* src_iter) { + auto item_result = GetNextLineItem(src_iter); + if (item_result.has_error()) { + return ParseStatus(ParseStatusCode::kPlaylistMissingM3uTag) + .AddCause(std::move(item_result).error()); + } + + auto item = std::move(item_result).value(); + if (auto* tag_item = absl::get_if<TagItem>(&item)) { + // The #EXTM3U tag must be the first line in the playlist + if (tag_item->name != ToTagName(CommonTagName::kM3u) || + tag_item->content.Line() != 1) { + return ParseStatusCode::kPlaylistMissingM3uTag; + } + + // Make sure the M3U tag parses correctly + auto result = M3uTag::Parse(*tag_item); + if (result.has_error()) { + return ParseStatus(ParseStatusCode::kPlaylistMissingM3uTag) + .AddCause(std::move(result).error()); + } + + return result; + } + + return ParseStatusCode::kPlaylistMissingM3uTag; +} + +void HandleUnknownTag(TagItem /*tag*/) { + // Unknown tags are ignored for forward-compatibility purposes. + // TODO(crbug.com/1266991): Should record a metric to discover common + // unrecognized tags. +} + +absl::optional<ParseStatus> ParseCommonTag(TagItem tag, + CommonParserState* state) { + DCHECK(GetTagKind(tag.name) == TagKind::kCommonTag); + + switch (static_cast<CommonTagName>(tag.name)) { + case CommonTagName::kM3u: + // This tag is meant to occur on the first line (which we've already + // checked), however the spec does not explicitly regard this as an + // error if it appears elsewhere as well. + DCHECK(tag.content.Line() != 1); + break; + case CommonTagName::kXVersion: { + auto error = ParseUniqueTag(tag, state->version_tag); + if (error.has_value()) { + return error; + } + + // Max supported playlist version is 10 + if (state->version_tag->version > 10) { + return ParseStatusCode::kPlaylistHasUnsupportedVersion; + } + break; + } + case CommonTagName::kXIndependentSegments: { + return ParseUniqueTag(tag, state->independent_segments_tag); + } + case CommonTagName::kXDefine: + // TODO(crbug.com/1266991): Implement variable substitution. + break; + } + + return absl::nullopt; +} + +ParseStatus::Or<GURL> ParseUri(UriItem item, const GURL& playlist_uri) { + auto resolved_uri = playlist_uri.Resolve(item.content.Str()); + if (!resolved_uri.is_valid()) { + return ParseStatusCode::kInvalidUri; + } + + return resolved_uri; +} + +} // namespace media::hls
diff --git a/media/formats/hls/playlist_common.h b/media/formats/hls/playlist_common.h new file mode 100644 index 0000000..2753fcfb --- /dev/null +++ b/media/formats/hls/playlist_common.h
@@ -0,0 +1,62 @@ +// 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 MEDIA_FORMATS_HLS_PLAYLIST_COMMON_H_ +#define MEDIA_FORMATS_HLS_PLAYLIST_COMMON_H_ + +#include "media/formats/hls/items.h" +#include "media/formats/hls/tag_name.h" +#include "media/formats/hls/tags.h" +#include "media/formats/hls/types.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/gurl.h" + +namespace media::hls { + +// State common to parsing both multivariant and media playlists. +struct CommonParserState { + absl::optional<XVersionTag> version_tag; + absl::optional<XIndependentSegmentsTag> independent_segments_tag; + + // Returns the version specified by `version_tag`, or the default version if + // the playlist did not contain a version tag. + types::DecimalInteger GetVersion() const; +}; + +// Validates that the first line of the given SourceLineIterator contains a +// valid #EXTM3U tag. +ParseStatus::Or<M3uTag> CheckM3uTag(SourceLineIterator* src_iter); + +// Handles an unknown tag. +void HandleUnknownTag(TagItem); + +// Handles parsing for tags that may appear in multivariant or media playlists. +absl::optional<ParseStatus> ParseCommonTag(TagItem, CommonParserState* state); + +// Attempts to parse a tag from the given item, ensuring it has not been +// already appeared in the playlist. +template <typename T> +absl::optional<ParseStatus> ParseUniqueTag(TagItem tag, + absl::optional<T>& out) { + DCHECK(tag.name == ToTagName(T::kName)); + + // Ensure this tag has not already appeared. + if (out.has_value()) { + return ParseStatusCode::kPlaylistHasDuplicateTags; + } + + auto tag_result = T::Parse(tag); + if (tag_result.has_error()) { + return std::move(tag_result).error(); + } + out = std::move(tag_result).value(); + + return absl::nullopt; +} + +ParseStatus::Or<GURL> ParseUri(UriItem item, const GURL& playlist_uri); + +} // namespace media::hls + +#endif // MEDIA_FORMATS_HLS_PLAYLIST_COMMON_H_
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc index d86f49a..9b28dd3 100644 --- a/media/video/gpu_memory_buffer_video_frame_pool.cc +++ b/media/video/gpu_memory_buffer_video_frame_pool.cc
@@ -16,6 +16,7 @@ #include "base/barrier_closure.h" #include "base/bind.h" +#include "base/bits.h" #include "base/callback_helpers.h" #include "base/containers/circular_deque.h" #include "base/containers/stack_container.h" @@ -507,23 +508,25 @@ } void CopyRowsToNV12Buffer(int first_row, - int rows, - int bytes_per_row, + int y_rows, + int uv_rows, + int y_bytes_per_row, + int uv_bytes_per_row, const VideoFrame* source_frame, uint8_t* dest_y, int dest_stride_y, uint8_t* dest_uv, int dest_stride_uv) { - TRACE_EVENT2("media", "CopyRowsToNV12Buffer", "bytes_per_row", bytes_per_row, - "rows", rows); + TRACE_EVENT2("media", "CopyRowsToNV12Buffer", "bytes_per_row", + y_bytes_per_row, "rows", y_rows); if (!dest_y || !dest_uv) return; DCHECK_NE(dest_stride_y, 0); DCHECK_NE(dest_stride_uv, 0); - DCHECK_LE(bytes_per_row, std::abs(dest_stride_y)); - DCHECK_LE(bytes_per_row, std::abs(dest_stride_uv)); + DCHECK_LE(y_bytes_per_row, std::abs(dest_stride_y)); + DCHECK_LE(uv_bytes_per_row, std::abs(dest_stride_uv)); DCHECK_EQ(0, first_row % 2); DCHECK(source_frame->format() == PIXEL_FORMAT_I420 || source_frame->format() == PIXEL_FORMAT_YV12 || @@ -533,16 +536,17 @@ first_row * source_frame->stride(VideoFrame::kYPlane), source_frame->stride(VideoFrame::kYPlane), dest_y + first_row * dest_stride_y, dest_stride_y, - bytes_per_row, rows); + y_bytes_per_row, y_rows); libyuv::CopyPlane( source_frame->visible_data(VideoFrame::kUVPlane) + first_row / 2 * source_frame->stride(VideoFrame::kUVPlane), source_frame->stride(VideoFrame::kUVPlane), - dest_uv + first_row / 2 * dest_stride_uv, dest_stride_uv, bytes_per_row, - rows / 2); + dest_uv + first_row / 2 * dest_stride_uv, dest_stride_uv, + uv_bytes_per_row, uv_rows); return; } + libyuv::I420ToNV12( source_frame->visible_data(VideoFrame::kYPlane) + first_row * source_frame->stride(VideoFrame::kYPlane), @@ -554,8 +558,8 @@ first_row / 2 * source_frame->stride(VideoFrame::kVPlane), source_frame->stride(VideoFrame::kVPlane), dest_y + first_row * dest_stride_y, dest_stride_y, - dest_uv + first_row / 2 * dest_stride_uv, dest_stride_uv, bytes_per_row, - rows); + dest_uv + first_row / 2 * dest_stride_uv, dest_stride_uv, y_bytes_per_row, + y_rows); } void CopyRowsToRGB10Buffer(bool is_argb, @@ -667,28 +671,28 @@ GpuVideoAcceleratorFactories::OutputFormat output_format) { DCHECK(gfx::Rect(video_frame->coded_size()) .Contains(video_frame->visible_rect())); - DCHECK_EQ(video_frame->visible_rect().x() % 2, 0); + + size_t width = video_frame->visible_rect().width(); + size_t height = video_frame->visible_rect().height(); gfx::Size output; switch (output_format) { case GpuVideoAcceleratorFactories::OutputFormat::I420: case GpuVideoAcceleratorFactories::OutputFormat::P010: case GpuVideoAcceleratorFactories::OutputFormat::NV12_SINGLE_GMB: case GpuVideoAcceleratorFactories::OutputFormat::NV12_DUAL_GMB: - if (gfx::AllowOddHeightMultiPlanarBuffers()) { - output = gfx::Size((video_frame->visible_rect().width() + 1) & ~1, - video_frame->visible_rect().height()); - } else { - DCHECK((video_frame->visible_rect().y() & 1) == 0); - output = gfx::Size((video_frame->visible_rect().width() + 1) & ~1, - (video_frame->visible_rect().height() + 1) & ~1); - } + DCHECK_EQ(video_frame->visible_rect().x() % 2, 0); + DCHECK_EQ(video_frame->visible_rect().y() % 2, 0); + if (!gfx::IsOddWidthMultiPlanarBuffersAllowed()) + width = base::bits::AlignUp(width, 2); + if (!gfx::IsOddHeightMultiPlanarBuffersAllowed()) + height = base::bits::AlignUp(height, 2); + output = gfx::Size(width, height); break; case GpuVideoAcceleratorFactories::OutputFormat::XR30: case GpuVideoAcceleratorFactories::OutputFormat::XB30: case GpuVideoAcceleratorFactories::OutputFormat::RGBA: case GpuVideoAcceleratorFactories::OutputFormat::BGRA: - output = gfx::Size((video_frame->visible_rect().width() + 1) & ~1, - video_frame->visible_rect().height()); + output = gfx::Size(base::bits::AlignUp(width, 2), height); break; case GpuVideoAcceleratorFactories::OutputFormat::UNDEFINED: NOTREACHED(); @@ -737,6 +741,7 @@ if (output_format_ == GpuVideoAcceleratorFactories::OutputFormat::UNDEFINED) passthrough = true; + switch (pixel_format) { // Supported cases. case PIXEL_FORMAT_YV12: @@ -781,19 +786,19 @@ } // TODO(https://crbug.com/638906): Handle odd positioned video frame input. - if (video_frame->visible_rect().x() % 2) - passthrough = true; - if (video_frame->visible_rect().y() % 2 && - !gfx::AllowOddHeightMultiPlanarBuffers()) { + if (video_frame->visible_rect().x() % 2 || + video_frame->visible_rect().y() % 2) { passthrough = true; } // TODO(https://crbug.com/webrtc/9033): Eliminate odd size video frame input // cases as they are not valid. - if (video_frame->coded_size().width() % 2) + if (video_frame->coded_size().width() % 2 && + !gfx::IsOddWidthMultiPlanarBuffersAllowed()) { passthrough = true; + } if (video_frame->coded_size().height() % 2 && - !gfx::AllowOddHeightMultiPlanarBuffers()) { + !gfx::IsOddHeightMultiPlanarBuffersAllowed()) { passthrough = true; } @@ -1001,23 +1006,45 @@ static_cast<uint8_t*>(buffer->memory(0)), buffer->stride(0)); break; } + case GpuVideoAcceleratorFactories::OutputFormat::P010: CopyRowsToP010Buffer( row, rows_to_copy, coded_size.width(), video_frame, static_cast<uint8_t*>(buffer->memory(0)), buffer->stride(0), static_cast<uint8_t*>(buffer->memory(1)), buffer->stride(1)); break; - case GpuVideoAcceleratorFactories::OutputFormat::NV12_SINGLE_GMB: + + case GpuVideoAcceleratorFactories::OutputFormat::NV12_SINGLE_GMB: { + const size_t y_rows_to_copy = VideoFrame::Rows( + VideoFrame::kYPlane, VideoFormat(output_format), rows_to_copy); + const size_t uv_rows_to_copy = VideoFrame::Rows( + VideoFrame::kUVPlane, VideoFormat(output_format), rows_to_copy); + const size_t y_bytes_per_row = VideoFrame::RowBytes( + VideoFrame::kYPlane, VideoFormat(output_format), coded_size.width()); + const size_t uv_bytes_per_row = VideoFrame::RowBytes( + VideoFrame::kUVPlane, VideoFormat(output_format), coded_size.width()); CopyRowsToNV12Buffer( - row, rows_to_copy, coded_size.width(), video_frame, + row, y_rows_to_copy, uv_rows_to_copy, y_bytes_per_row, + uv_bytes_per_row, video_frame, static_cast<uint8_t*>(buffer->memory(0)), buffer->stride(0), static_cast<uint8_t*>(buffer->memory(1)), buffer->stride(1)); break; + } + case GpuVideoAcceleratorFactories::OutputFormat::NV12_DUAL_GMB: { + const size_t y_rows_to_copy = VideoFrame::Rows( + VideoFrame::kYPlane, VideoFormat(output_format), rows_to_copy); + const size_t uv_rows_to_copy = VideoFrame::Rows( + VideoFrame::kUVPlane, VideoFormat(output_format), rows_to_copy); + const size_t y_bytes_per_row = VideoFrame::RowBytes( + VideoFrame::kYPlane, VideoFormat(output_format), coded_size.width()); + const size_t uv_bytes_per_row = VideoFrame::RowBytes( + VideoFrame::kUVPlane, VideoFormat(output_format), coded_size.width()); gfx::GpuMemoryBuffer* buffer2 = frame_resources->plane_resources[1].gpu_memory_buffer.get(); CopyRowsToNV12Buffer( - row, rows_to_copy, coded_size.width(), video_frame, + row, y_rows_to_copy, uv_rows_to_copy, y_bytes_per_row, + uv_bytes_per_row, video_frame, static_cast<uint8_t*>(buffer->memory(0)), buffer->stride(0), static_cast<uint8_t*>(buffer2->memory(0)), buffer2->stride(0)); break;
diff --git a/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc b/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc index d94cd64b..b619ccb 100644 --- a/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc +++ b/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc
@@ -47,6 +47,15 @@ gpu_memory_buffer_pool_.reset(); RunUntilIdle(); mock_gpu_factories_.reset(); + + if (y_data_) + delete[] y_data_; + if (u_data_) + delete[] u_data_; + if (v_data_) + delete[] v_data_; + if (uv_data_) + delete[] uv_data_; } void RunUntilIdle() { @@ -89,6 +98,47 @@ return video_frame; } + scoped_refptr<VideoFrame> CreateTestYUVVideoFrameWithOddSize( + int dimension, + size_t bit_depth = 8, + int visible_rect_crop = 0) { + const VideoPixelFormat format = + (bit_depth > 8) ? PIXEL_FORMAT_YUV420P10 : PIXEL_FORMAT_I420; + const int multiplier = format == PIXEL_FORMAT_YUV420P10 ? 2 : 1; + + int dimension_aligned = (dimension + 1) & ~1; + y_data_ = new uint8_t[multiplier * dimension * dimension](); + u_data_ = + new uint8_t[multiplier * dimension_aligned * dimension_aligned / 4](); + v_data_ = + new uint8_t[multiplier * dimension_aligned * dimension_aligned / 4](); + + // Initialize the last pixel of each plane + int y_size = multiplier * dimension * dimension; + y_data_[y_size - multiplier] = kYValue; + int u_v_size = multiplier * dimension_aligned * dimension_aligned / 4; + u_data_[u_v_size - multiplier] = kUValue; + v_data_[u_v_size - multiplier] = kVValue; + + const gfx::Size size(dimension, dimension); + scoped_refptr<VideoFrame> video_frame = VideoFrame::WrapExternalYuvData( + format, // format + size, // coded_size + gfx::Rect(visible_rect_crop, visible_rect_crop, + size.width() - visible_rect_crop * 2, + size.height() - visible_rect_crop * 2), // visible_rect + size, // natural_size + size.width() * multiplier, // y_stride + dimension_aligned * multiplier / 2, // u_stride + dimension_aligned * multiplier / 2, // v_stride + y_data_, // y_data + u_data_, // u_data + v_data_, // v_data + base::TimeDelta()); // timestamp + EXPECT_TRUE(video_frame); + return video_frame; + } + static scoped_refptr<VideoFrame> CreateTestYUVAVideoFrame(int dimension) { const int kDimension = 10; static uint8_t y_data[kDimension * kDimension] = {0}; @@ -119,6 +169,7 @@ } static scoped_refptr<VideoFrame> CreateTestNV12VideoFrame(int dimension) { + // Set the video buffer memory dimension default to 10. const int kDimension = 10; static uint8_t y_data[kDimension * kDimension] = {0}; // Subsampled by 2x2, two components. @@ -142,6 +193,36 @@ return video_frame; } + scoped_refptr<VideoFrame> CreateTestNV12VideoFrameWithOddSize(int dimension) { + // Set the video buffer memory dimension to the same size of the requested + // dimension. + int dimension_aligned = (dimension + 1) & ~1; + y_data_ = new uint8_t[dimension * dimension](); + // Subsampled by 2x2, two components. + uv_data_ = new uint8_t[dimension_aligned * dimension_aligned / 2](); + + // Initialize the last pixel of each plane + y_data_[dimension * dimension - 1] = kYValue; + uv_data_[(dimension_aligned * dimension_aligned / 2) - 2] = kUValue; + uv_data_[(dimension_aligned * dimension_aligned / 2) - 1] = kVValue; + + const VideoPixelFormat format = PIXEL_FORMAT_NV12; + const gfx::Size size(dimension, dimension); + + scoped_refptr<VideoFrame> video_frame = + VideoFrame::WrapExternalYuvData(format, // format + size, // coded_size + gfx::Rect(size), // visible_rect + size, // natural_size + size.width(), // y_stride + dimension_aligned, // uv_stride + y_data_, // y_data + uv_data_, // uv_data + base::TimeDelta()); // timestamp + EXPECT_TRUE(video_frame); + return video_frame; + } + // Note, the X portion is set to 1 since it may use ARGB instead of // XRGB on some platforms. uint32_t as_xr30(uint32_t r, uint32_t g, uint32_t b) { @@ -152,6 +233,15 @@ } protected: + static constexpr uint8_t kYValue = 210; + static constexpr uint8_t kUValue = 50; + static constexpr uint8_t kVValue = 150; + + uint8_t* y_data_ = nullptr; + uint8_t* u_data_ = nullptr; + uint8_t* v_data_ = nullptr; + uint8_t* uv_data_ = nullptr; + base::SimpleTestTickClock test_clock_; std::unique_ptr<MockGpuVideoAcceleratorFactories> mock_gpu_factories_; std::unique_ptr<GpuMemoryBufferVideoFramePool> gpu_memory_buffer_pool_; @@ -203,6 +293,59 @@ EXPECT_EQ(3u, sii_->shared_image_count()); } +TEST_F(GpuMemoryBufferVideoFramePoolTest, CreateOneHardwareFrameWithOddSize) { + scoped_refptr<VideoFrame> software_frame = + CreateTestYUVVideoFrameWithOddSize(9); + scoped_refptr<VideoFrame> frame; + gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( + software_frame, base::BindOnce(MaybeCreateHardwareFrameCallback, &frame)); + + RunUntilIdle(); + + if (gfx::IsOddWidthMultiPlanarBuffersAllowed() && + gfx::IsOddHeightMultiPlanarBuffersAllowed()) { + EXPECT_NE(software_frame.get(), frame.get()); + EXPECT_EQ(PIXEL_FORMAT_I420, frame->format()); + EXPECT_EQ(3u, frame->NumTextures()); + EXPECT_EQ(3u, sii_->shared_image_count()); + + EXPECT_EQ(3u, mock_gpu_factories_->created_memory_buffers().size()); + mock_gpu_factories_->created_memory_buffers()[0]->Map(); + mock_gpu_factories_->created_memory_buffers()[1]->Map(); + mock_gpu_factories_->created_memory_buffers()[2]->Map(); + + const auto* y_memory = reinterpret_cast<uint8_t*>( + mock_gpu_factories_->created_memory_buffers()[0]->memory(0)); + const auto* u_memory = reinterpret_cast<uint8_t*>( + mock_gpu_factories_->created_memory_buffers()[1]->memory(0)); + const auto* v_memory = reinterpret_cast<uint8_t*>( + mock_gpu_factories_->created_memory_buffers()[2]->memory(0)); + + // Y plane = 9x9, U and V plan = 5x5. + EXPECT_EQ(kYValue, software_frame->visible_data(VideoFrame::kYPlane)[80]); + EXPECT_EQ(kUValue, software_frame->visible_data(VideoFrame::kUPlane)[24]); + EXPECT_EQ(kVValue, software_frame->visible_data(VideoFrame::kVPlane)[24]); + + // Compare the last pixel of each plane in |software_frame| and |frame|. + auto y_stride = mock_gpu_factories_->created_memory_buffers()[0]->stride(0); + EXPECT_EQ(software_frame->visible_data(VideoFrame::kYPlane)[80], + y_memory[y_stride * 8 + 8]); + auto u_stride = mock_gpu_factories_->created_memory_buffers()[1]->stride(0); + EXPECT_EQ(software_frame->visible_data(VideoFrame::kUPlane)[24], + u_memory[u_stride * 4 + 4]); + auto v_stride = mock_gpu_factories_->created_memory_buffers()[2]->stride(0); + EXPECT_EQ(software_frame->visible_data(VideoFrame::kVPlane)[24], + v_memory[v_stride * 4 + 4]); + + mock_gpu_factories_->created_memory_buffers()[0]->Unmap(); + mock_gpu_factories_->created_memory_buffers()[1]->Unmap(); + mock_gpu_factories_->created_memory_buffers()[2]->Unmap(); + + } else { + EXPECT_EQ(software_frame.get(), frame.get()); + } +} + // Tests the current workaround for odd positioned video frame input. Once // https://crbug.com/638906 is fixed, output should be different. TEST_F(GpuMemoryBufferVideoFramePoolTest, CreateOneHardwareFrameWithOddOrigin) { @@ -216,6 +359,19 @@ EXPECT_EQ(software_frame.get(), frame.get()); } +TEST_F(GpuMemoryBufferVideoFramePoolTest, + CreateOneHardwareFrameWithOddOriginOddSize) { + scoped_refptr<VideoFrame> software_frame = + CreateTestYUVVideoFrameWithOddSize(11, 8, 1); + scoped_refptr<VideoFrame> frame; + gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( + software_frame, base::BindOnce(MaybeCreateHardwareFrameCallback, &frame)); + + RunUntilIdle(); + + EXPECT_EQ(software_frame.get(), frame.get()); +} + TEST_F(GpuMemoryBufferVideoFramePoolTest, CreateOne10BppHardwareFrame) { scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10, 10); scoped_refptr<VideoFrame> frame; @@ -230,6 +386,66 @@ EXPECT_EQ(3u, sii_->shared_image_count()); } +TEST_F(GpuMemoryBufferVideoFramePoolTest, + CreateOne10BppHardwareFrameWithOddSize) { + scoped_refptr<VideoFrame> software_frame = + CreateTestYUVVideoFrameWithOddSize(17, 10); + scoped_refptr<VideoFrame> frame; + gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( + software_frame, base::BindOnce(MaybeCreateHardwareFrameCallback, &frame)); + + RunUntilIdle(); + + if (gfx::IsOddWidthMultiPlanarBuffersAllowed() && + gfx::IsOddHeightMultiPlanarBuffersAllowed()) { + EXPECT_NE(software_frame.get(), frame.get()); + EXPECT_EQ(PIXEL_FORMAT_I420, frame->format()); + EXPECT_EQ(3u, frame->NumTextures()); + EXPECT_EQ(3u, sii_->shared_image_count()); + + EXPECT_EQ(3u, mock_gpu_factories_->created_memory_buffers().size()); + mock_gpu_factories_->created_memory_buffers()[0]->Map(); + mock_gpu_factories_->created_memory_buffers()[1]->Map(); + mock_gpu_factories_->created_memory_buffers()[2]->Map(); + + // Copy 10 bpp to I420. + const auto* y_memory = reinterpret_cast<uint8_t*>( + mock_gpu_factories_->created_memory_buffers()[0]->memory(0)); + const auto* u_memory = reinterpret_cast<uint8_t*>( + mock_gpu_factories_->created_memory_buffers()[1]->memory(0)); + const auto* v_memory = reinterpret_cast<uint8_t*>( + mock_gpu_factories_->created_memory_buffers()[2]->memory(0)); + + const uint16_t* y_plane_data = reinterpret_cast<uint16_t*>( + software_frame->visible_data(VideoFrame::kYPlane)); + const uint16_t* u_plane_data = reinterpret_cast<uint16_t*>( + software_frame->visible_data(VideoFrame::kUPlane)); + const uint16_t* v_plane_data = reinterpret_cast<uint16_t*>( + software_frame->visible_data(VideoFrame::kVPlane)); + + // Y plane = 17x17 = 289, U and V plan = 9x9. + EXPECT_EQ(kYValue, y_plane_data[288]); + EXPECT_EQ(kUValue, u_plane_data[80]); + EXPECT_EQ(kVValue, v_plane_data[80]); + + // Compare the last pixel of each plane in |software_frame| and |frame|. + // y_memory = 17x17, u_memory/v_memory = 9x9. scale = 10 bits - 8 bits = 2 + auto y_stride = mock_gpu_factories_->created_memory_buffers()[0]->stride(0); + EXPECT_EQ(y_plane_data[288] >> 2, y_memory[y_stride * 16 + 16]); + auto u_stride = mock_gpu_factories_->created_memory_buffers()[1]->stride(0); + EXPECT_EQ(u_plane_data[80] >> 2, u_memory[u_stride * 8 + 8]); + auto v_stride = mock_gpu_factories_->created_memory_buffers()[2]->stride(0); + EXPECT_EQ(v_plane_data[80] >> 2, v_memory[v_stride * 8 + 8]); + + mock_gpu_factories_->created_memory_buffers()[0]->Unmap(); + mock_gpu_factories_->created_memory_buffers()[1]->Unmap(); + mock_gpu_factories_->created_memory_buffers()[2]->Unmap(); + + } else { + EXPECT_EQ(software_frame.get(), frame.get()); + } +} + TEST_F(GpuMemoryBufferVideoFramePoolTest, ReuseFirstResource) { scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10); scoped_refptr<VideoFrame> frame; @@ -318,6 +534,66 @@ EXPECT_TRUE(frame->metadata().read_lock_fences_enabled); } +TEST_F(GpuMemoryBufferVideoFramePoolTest, + CreateOneHardwareNV12FrameWithOddSize) { + scoped_refptr<VideoFrame> software_frame = + CreateTestYUVVideoFrameWithOddSize(13); + scoped_refptr<VideoFrame> frame; + mock_gpu_factories_->SetVideoFrameOutputFormat( + media::GpuVideoAcceleratorFactories::OutputFormat::NV12_SINGLE_GMB); + gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( + software_frame, base::BindOnce(MaybeCreateHardwareFrameCallback, &frame)); + + RunUntilIdle(); + + if (gfx::IsOddWidthMultiPlanarBuffersAllowed() && + gfx::IsOddHeightMultiPlanarBuffersAllowed()) { + EXPECT_NE(software_frame.get(), frame.get()); + EXPECT_EQ(PIXEL_FORMAT_NV12, frame->format()); + if (GpuMemoryBufferVideoFramePool::MultiPlaneVideoSharedImagesEnabled()) { + EXPECT_EQ(2u, frame->NumTextures()); + EXPECT_EQ(2u, sii_->shared_image_count()); + + EXPECT_EQ(1u, mock_gpu_factories_->created_memory_buffers().size()); + mock_gpu_factories_->created_memory_buffers()[0]->Map(); + + const auto* y_memory = reinterpret_cast<uint8_t*>( + mock_gpu_factories_->created_memory_buffers()[0]->memory(0)); + const auto* uv_memory = reinterpret_cast<uint8_t*>( + mock_gpu_factories_->created_memory_buffers()[0]->memory(1)); + + // Y plane = 13x13 = 169, U and V plan = 7x7 = 49. + EXPECT_EQ(kYValue, + software_frame->visible_data(VideoFrame::kYPlane)[168]); + EXPECT_EQ(kUValue, software_frame->visible_data(VideoFrame::kUPlane)[48]); + EXPECT_EQ(kVValue, software_frame->visible_data(VideoFrame::kVPlane)[48]); + + // Compare the last pixel of each plane in |software_frame| and |frame|. + // y_memory = 13x13, uv_memory = 14x 7. + auto y_stride = + mock_gpu_factories_->created_memory_buffers()[0]->stride(0); + EXPECT_EQ(software_frame->visible_data(VideoFrame::kYPlane)[168], + y_memory[y_stride * 12 + 12]); + auto uv_stride = + mock_gpu_factories_->created_memory_buffers()[0]->stride(1); + EXPECT_EQ(software_frame->visible_data(VideoFrame::kUPlane)[48], + uv_memory[uv_stride * 6 + 12]); + EXPECT_EQ(software_frame->visible_data(VideoFrame::kVPlane)[48], + uv_memory[uv_stride * 6 + 13]); + + mock_gpu_factories_->created_memory_buffers()[0]->Unmap(); + } else { + EXPECT_EQ(1u, frame->NumTextures()); + EXPECT_EQ(1u, sii_->shared_image_count()); + } + + EXPECT_TRUE(frame->metadata().read_lock_fences_enabled); + + } else { + EXPECT_EQ(software_frame.get(), frame.get()); + } +} + TEST_F(GpuMemoryBufferVideoFramePoolTest, CreateOneHardwareNV12Frame2) { scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10); scoped_refptr<VideoFrame> frame; @@ -335,6 +611,59 @@ EXPECT_TRUE(frame->metadata().read_lock_fences_enabled); } +TEST_F(GpuMemoryBufferVideoFramePoolTest, + CreateOneHardwareNV12Frame2WithOddSize) { + scoped_refptr<VideoFrame> software_frame = + CreateTestYUVVideoFrameWithOddSize(5); + scoped_refptr<VideoFrame> frame; + mock_gpu_factories_->SetVideoFrameOutputFormat( + media::GpuVideoAcceleratorFactories::OutputFormat::NV12_DUAL_GMB); + gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( + software_frame, base::BindOnce(MaybeCreateHardwareFrameCallback, &frame)); + + RunUntilIdle(); + + if (gfx::IsOddWidthMultiPlanarBuffersAllowed() && + gfx::IsOddHeightMultiPlanarBuffersAllowed()) { + EXPECT_NE(software_frame.get(), frame.get()); + EXPECT_EQ(PIXEL_FORMAT_NV12, frame->format()); + EXPECT_EQ(2u, frame->NumTextures()); + EXPECT_EQ(2u, sii_->shared_image_count()); + EXPECT_TRUE(frame->metadata().read_lock_fences_enabled); + + EXPECT_EQ(2u, mock_gpu_factories_->created_memory_buffers().size()); + mock_gpu_factories_->created_memory_buffers()[0]->Map(); + mock_gpu_factories_->created_memory_buffers()[1]->Map(); + + const auto* y_memory = reinterpret_cast<uint8_t*>( + mock_gpu_factories_->created_memory_buffers()[0]->memory(0)); + const auto* uv_memory = reinterpret_cast<uint8_t*>( + mock_gpu_factories_->created_memory_buffers()[1]->memory(0)); + + // Y plane = 5x5, U and V plan = 3x3. + EXPECT_EQ(kYValue, software_frame->visible_data(VideoFrame::kYPlane)[24]); + EXPECT_EQ(kUValue, software_frame->visible_data(VideoFrame::kUPlane)[8]); + EXPECT_EQ(kVValue, software_frame->visible_data(VideoFrame::kVPlane)[8]); + + // Compare the last pixel of each plane in |software_frame| and |frame|. + // y_memory = 5x5, uv_memory = 6x3. + auto y_stride = mock_gpu_factories_->created_memory_buffers()[0]->stride(0); + EXPECT_EQ(software_frame->visible_data(VideoFrame::kYPlane)[24], + y_memory[y_stride * 4 + 4]); + auto uv_stride = + mock_gpu_factories_->created_memory_buffers()[1]->stride(0); + EXPECT_EQ(software_frame->visible_data(VideoFrame::kUPlane)[8], + uv_memory[uv_stride * 2 + 4]); + EXPECT_EQ(software_frame->visible_data(VideoFrame::kVPlane)[8], + uv_memory[uv_stride * 2 + 5]); + + mock_gpu_factories_->created_memory_buffers()[0]->Unmap(); + mock_gpu_factories_->created_memory_buffers()[1]->Unmap(); + } else { + EXPECT_EQ(software_frame.get(), frame.get()); + } +} + TEST_F(GpuMemoryBufferVideoFramePoolTest, CreateOneHardwareFrameForNV12Input) { scoped_refptr<VideoFrame> software_frame = CreateTestNV12VideoFrame(10); scoped_refptr<VideoFrame> frame; @@ -351,6 +680,62 @@ EXPECT_EQ(2u, sii_->shared_image_count()); } +TEST_F(GpuMemoryBufferVideoFramePoolTest, + CreateOneHardwareFrameForNV12InputWithOddSize) { + scoped_refptr<VideoFrame> software_frame = + CreateTestNV12VideoFrameWithOddSize(135); + scoped_refptr<VideoFrame> frame; + mock_gpu_factories_->SetVideoFrameOutputFormat( + media::GpuVideoAcceleratorFactories::OutputFormat::NV12_DUAL_GMB); + gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( + software_frame, base::BindOnce(MaybeCreateHardwareFrameCallback, &frame)); + + RunUntilIdle(); + + if (gfx::IsOddWidthMultiPlanarBuffersAllowed() && + gfx::IsOddHeightMultiPlanarBuffersAllowed()) { + EXPECT_NE(software_frame.get(), frame.get()); + EXPECT_EQ(PIXEL_FORMAT_NV12, frame->format()); + EXPECT_EQ(2u, frame->NumTextures()); + EXPECT_EQ(2u, sii_->shared_image_count()); + + EXPECT_EQ(2u, mock_gpu_factories_->created_memory_buffers().size()); + mock_gpu_factories_->created_memory_buffers()[0]->Map(); + mock_gpu_factories_->created_memory_buffers()[1]->Map(); + + const auto* y_memory = reinterpret_cast<uint8_t*>( + mock_gpu_factories_->created_memory_buffers()[0]->memory(0)); + const auto* uv_memory = reinterpret_cast<uint8_t*>( + mock_gpu_factories_->created_memory_buffers()[1]->memory(0)); + + // Y plane = 135x135 = 18225, UV plan = 136x68 = 9248. + EXPECT_EQ(kYValue, + software_frame->visible_data(VideoFrame::kYPlane)[18224]); + EXPECT_EQ(kUValue, + software_frame->visible_data(VideoFrame::kUVPlane)[9246]); + EXPECT_EQ(kVValue, + software_frame->visible_data(VideoFrame::kUVPlane)[9247]); + + // Compare the last pixel of each plane in |software_frame| and |frame|. + // y_memory = 135x135, uv_memory = 136x68. + auto y_stride = mock_gpu_factories_->created_memory_buffers()[0]->stride(0); + EXPECT_EQ(software_frame->visible_data(VideoFrame::kYPlane)[18224], + y_memory[y_stride * 134 + 134]); + auto uv_stride = + mock_gpu_factories_->created_memory_buffers()[1]->stride(0); + EXPECT_EQ(software_frame->visible_data(VideoFrame::kUVPlane)[9246], + uv_memory[uv_stride * 67 + 134]); + EXPECT_EQ(software_frame->visible_data(VideoFrame::kUVPlane)[9247], + uv_memory[uv_stride * 67 + 135]); + + mock_gpu_factories_->created_memory_buffers()[0]->Unmap(); + mock_gpu_factories_->created_memory_buffers()[1]->Unmap(); + + } else { + EXPECT_EQ(software_frame.get(), frame.get()); + } +} + TEST_F(GpuMemoryBufferVideoFramePoolTest, CreateOneHardwareXR30Frame) { scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10, 10); scoped_refptr<VideoFrame> frame; @@ -405,6 +790,61 @@ uv_memory[1]); } +TEST_F(GpuMemoryBufferVideoFramePoolTest, + CreateOneHardwareP010FrameWithOddSize) { + scoped_refptr<VideoFrame> software_frame = + CreateTestYUVVideoFrameWithOddSize(7, 10); + scoped_refptr<VideoFrame> frame; + mock_gpu_factories_->SetVideoFrameOutputFormat( + media::GpuVideoAcceleratorFactories::OutputFormat::P010); + gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( + software_frame, base::BindOnce(MaybeCreateHardwareFrameCallback, &frame)); + + RunUntilIdle(); + + if (gfx::IsOddWidthMultiPlanarBuffersAllowed() && + gfx::IsOddHeightMultiPlanarBuffersAllowed()) { + EXPECT_NE(software_frame.get(), frame.get()); + EXPECT_EQ(PIXEL_FORMAT_P016LE, frame->format()); + EXPECT_EQ(1u, frame->NumTextures()); + EXPECT_EQ(1u, sii_->shared_image_count()); + EXPECT_TRUE(frame->metadata().read_lock_fences_enabled); + + EXPECT_EQ(1u, mock_gpu_factories_->created_memory_buffers().size()); + mock_gpu_factories_->created_memory_buffers()[0]->Map(); + + // Copy I010 To P010. + const uint16_t* y_memory = reinterpret_cast<uint16_t*>( + mock_gpu_factories_->created_memory_buffers()[0]->memory(0)); + const uint16_t* uv_memory = reinterpret_cast<uint16_t*>( + mock_gpu_factories_->created_memory_buffers()[0]->memory(1)); + + const uint16_t* y_plane_data = reinterpret_cast<uint16_t*>( + software_frame->visible_data(VideoFrame::kYPlane)); + const uint16_t* u_plane_data = reinterpret_cast<uint16_t*>( + software_frame->visible_data(VideoFrame::kUPlane)); + const uint16_t* v_plane_data = reinterpret_cast<uint16_t*>( + software_frame->visible_data(VideoFrame::kVPlane)); + + // Y plane = 7x7 = 49, U and V plan = 4x4 = 16. + EXPECT_EQ(kYValue, y_plane_data[48]); + EXPECT_EQ(kUValue, u_plane_data[15]); + EXPECT_EQ(kVValue, v_plane_data[15]); + // Compare the last pixel of each plane in |software_frame| and |frame|. + // y_memory = 7x7, uv_memory = 8x4, scale = 16-10 = 6. + auto y_stride = mock_gpu_factories_->created_memory_buffers()[0]->stride(0); + EXPECT_EQ(y_plane_data[48], y_memory[y_stride / 2 * 6 + 6] >> 6); + auto uv_stride = + mock_gpu_factories_->created_memory_buffers()[0]->stride(1); + EXPECT_EQ(u_plane_data[15], uv_memory[uv_stride / 2 * 3 + 6] >> 6); + EXPECT_EQ(v_plane_data[15], uv_memory[uv_stride / 2 * 3 + 7] >> 6); + + mock_gpu_factories_->created_memory_buffers()[0]->Unmap(); + } else { + EXPECT_EQ(software_frame.get(), frame.get()); + } +} + TEST_F(GpuMemoryBufferVideoFramePoolTest, CreateOneHardwareXR30FrameBT709) { scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10, 10); software_frame->set_color_space(gfx::ColorSpace::CreateREC709());
diff --git a/media/video/mock_gpu_video_accelerator_factories.cc b/media/video/mock_gpu_video_accelerator_factories.cc index 0f350c4b..c01a445 100644 --- a/media/video/mock_gpu_video_accelerator_factories.cc +++ b/media/video/mock_gpu_video_accelerator_factories.cc
@@ -39,9 +39,7 @@ gfx::BufferFormat::BGRA_8888 == format_); DCHECK(num_planes_ <= kMaxPlanes); for (int i = 0; i < static_cast<int>(num_planes_); ++i) { - bytes_[i].resize(gfx::RowSizeForBufferFormat(size_.width(), format_, i) * - size_.height() / - gfx::SubsamplingFactorForBufferFormat(format_, i)); + bytes_[i].resize(gfx::PlaneSizeForBufferFormat(size_, format_, i)); } }
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc index f3b51f1..a3f1bcca 100644 --- a/net/quic/quic_stream_factory.cc +++ b/net/quic/quic_stream_factory.cc
@@ -2030,8 +2030,12 @@ // not be simultaneously set. DCHECK(!allow_port_migration || !migrate_sessions_early); - if (allow_port_migration) + if (allow_port_migration) { params_.allow_port_migration = true; + if (migrate_idle_sessions) { + params_.migrate_idle_sessions = true; + } + } if (!NetworkChangeNotifier::AreNetworkHandlesSupported()) return; @@ -2047,8 +2051,7 @@ params_.migrate_sessions_on_network_change_v2 = true; if (!migrate_sessions_early) { - DCHECK(!migrate_idle_sessions && - !retry_on_alternate_network_before_handshake); + DCHECK(!retry_on_alternate_network_before_handshake); return; }
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc index f59fa12..aebe748 100644 --- a/net/quic/quic_stream_factory_test.cc +++ b/net/quic/quic_stream_factory_test.cc
@@ -5739,6 +5739,185 @@ EXPECT_TRUE(quic_data1.AllWriteDataConsumed()); } +TEST_P(QuicStreamFactoryTest, + MigratePortOnPathDegrading_MigrateIdleSession_PathValidator) { + if (!version_.HasIetfQuicFrames()) { + // Path validator is only supported in IETF QUIC. + return; + } + scoped_mock_network_change_notifier_ = + std::make_unique<ScopedMockNetworkChangeNotifier>(); + MockNetworkChangeNotifier* mock_ncn = + scoped_mock_network_change_notifier_->mock_network_change_notifier(); + mock_ncn->ForceNetworkHandlesSupported(); + mock_ncn->SetConnectedNetworksList({kDefaultNetworkForTests}); + // Enable migration on network change. + quic_params_->migrate_sessions_on_network_change_v2 = true; + quic_params_->allow_port_migration = true; + quic_params_->migrate_idle_sessions = true; + SetIetfConnectionMigrationFlagsAndConnectionOptions(); + socket_factory_ = std::make_unique<TestPortMigrationSocketFactory>(); + Initialize(); + + scoped_mock_network_change_notifier_->mock_network_change_notifier() + ->NotifyNetworkMadeDefault(kDefaultNetworkForTests); + + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Using a testing task runner so that we can control time. + auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); + QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get()); + + int packet_number = 1; + MockQuicData quic_data1(version_); + quic_data1.AddWrite(SYNCHRONOUS, + ConstructInitialSettingsPacket(packet_number++)); + quic_data1.AddWrite( + SYNCHRONOUS, + ConstructGetRequestPacket(packet_number++, + GetNthClientInitiatedBidirectionalStreamId(0), + true, true)); + quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause + // The client session will receive the response first and closes its only + // stream. + quic_data1.AddRead( + ASYNC, ConstructOkResponsePacket( + 1, GetNthClientInitiatedBidirectionalStreamId(0), false, + /*fin = */ true)); + quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Pause + quic_data1.AddSocketDataToFactory(socket_factory_.get()); + + // Set up the second socket data provider that is used after migration. + // The response to the earlier request is read on the new socket. + MockQuicData quic_data2(version_); + quic::QuicConnectionId cid_on_new_path = + quic::test::TestConnectionId(12345678); + client_maker_.set_connection_id(cid_on_new_path); + // Connectivity probe to be sent on the new path. + quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket( + packet_number++, true)); + quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause + // Connectivity probe to receive from the server. + quic_data2.AddRead(ASYNC, + server_maker_.MakeConnectivityProbingPacket(2, false)); + quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + // Ping packet to send after migration is completed. + quic_data2.AddWrite(ASYNC, client_maker_.MakeAckAndPingPacket( + packet_number++, + /*include_version=*/false, 2, 1)); + + quic_data2.AddWrite( + SYNCHRONOUS, + client_maker_.MakeRetireConnectionIdPacket( + packet_number++, /*include_version=*/false, /*sequence_number=*/0u)); + quic_data2.AddSocketDataToFactory(socket_factory_.get()); + + // Create request and QuicHttpStream. + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request( + scheme_host_port_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), NetworkIsolationKey(), SecureDnsPolicy::kAllow, + true /* use_dns_aliases */, + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback())); + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + std::unique_ptr<HttpStream> stream = CreateStream(&request); + EXPECT_TRUE(stream.get()); + + // Cause QUIC stream to be created. + HttpRequestInfo request_info; + request_info.method = "GET"; + request_info.url = url_; + request_info.traffic_annotation = + MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); + EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY, + net_log_, CompletionOnceCallback())); + + // Ensure that session is alive and active. + QuicChromiumClientSession* session = GetActiveSession(scheme_host_port_); + EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session)); + EXPECT_TRUE(HasActiveSession(scheme_host_port_)); + MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session); + + // Send GET request on stream. + HttpResponseInfo response; + HttpRequestHeaders request_headers; + EXPECT_EQ(OK, stream->SendRequest(request_headers, &response, + callback_.callback())); + // Disable connection migration on the request streams. + // This should have no effect for port migration. + QuicChromiumClientStream* chrome_stream = + static_cast<QuicChromiumClientStream*>( + quic::test::QuicSessionPeer::GetStream( + session, GetNthClientInitiatedBidirectionalStreamId(0))); + EXPECT_TRUE(chrome_stream); + chrome_stream->DisableConnectionMigrationToCellularNetwork(); + + EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get())); + + // Manually initialize the connection's self address. In real life, the + // initialization will be done during crypto handshake. + IPEndPoint ip; + session->GetDefaultSocket()->GetLocalAddress(&ip); + quic::test::QuicConnectionPeer::SetSelfAddress(session->connection(), + ToQuicSocketAddress(ip)); + + // Cause the connection to report path degrading to the session. + // Session will start to probe a different port. + session->connection()->OnPathDegradingDetected(); + EXPECT_EQ(1u, session->GetNumActiveStreams()); + EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback())); + // A response will be received on the current path and closes the request + // stream. + quic_data1.Resume(); + base::RunLoop().RunUntilIdle(); + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + EXPECT_EQ(200, response.headers->response_code()); + EXPECT_EQ(0u, session->GetNumActiveStreams()); + + EXPECT_EQ(1u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get())); + + // The retry mechanism is internal to path validator. + EXPECT_EQ(0u, task_runner->GetPendingTaskCount()); + + // The connection should still be alive, and not marked as going away. + EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session)); + EXPECT_TRUE(HasActiveSession(scheme_host_port_)); + + // Resume quic data and a connectivity probe response will be read on the new + // socket. + quic_data2.Resume(); + + EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session)); + EXPECT_TRUE(HasActiveSession(scheme_host_port_)); + // Successful port migration causes the path no longer degrading on the same + // network. + EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get())); + + // There should be pending tasks, the nearest one will complete + // migration to the new port. + task_runner->RunUntilIdle(); + + // Fire any outstanding quic alarms. + base::RunLoop().RunUntilIdle(); + + // Now there may be one pending task to send connectivity probe that has been + // cancelled due to successful migration. + task_runner->FastForwardUntilNoTasksRemain(); + + // Verify that the session is still alive. + EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session)); + EXPECT_TRUE(HasActiveSession(scheme_host_port_)); + + EXPECT_TRUE(quic_data1.AllReadDataConsumed()); + EXPECT_TRUE(quic_data1.AllWriteDataConsumed()); + EXPECT_TRUE(quic_data2.AllReadDataConsumed()); + EXPECT_TRUE(quic_data2.AllWriteDataConsumed()); +} + // This test verifies that the session marks itself GOAWAY on path degrading // and it does not receive any new request TEST_P(QuicStreamFactoryTest, GoawayOnPathDegrading) {
diff --git a/printing/printing_features.cc b/printing/printing_features.cc index e5a9011..b14fac7 100644 --- a/printing/printing_features.cc +++ b/printing/printing_features.cc
@@ -32,6 +32,10 @@ const base::Feature kPrintWithReducedRasterization{ "PrintWithReducedRasterization", base::FEATURE_DISABLED_BY_DEFAULT}; +// Read printer capabilities with XPS when use XPS for printing. +const base::Feature kReadPrinterCapabilitiesWithXps{ + "ReadPrinterCapabilitiesWithXps", base::FEATURE_DISABLED_BY_DEFAULT}; + // Use XPS for printing instead of GDI. const base::Feature kUseXpsForPrinting{"UseXpsForPrinting", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/printing/printing_features.h b/printing/printing_features.h index 9003dab..efe6b46 100644 --- a/printing/printing_features.h +++ b/printing/printing_features.h
@@ -28,6 +28,8 @@ COMPONENT_EXPORT(PRINTING_BASE) extern const base::Feature kPrintWithReducedRasterization; COMPONENT_EXPORT(PRINTING_BASE) +extern const base::Feature kReadPrinterCapabilitiesWithXps; +COMPONENT_EXPORT(PRINTING_BASE) extern const base::Feature kUseXpsForPrinting; COMPONENT_EXPORT(PRINTING_BASE) extern const base::Feature kUseXpsForPrintingFromPdf;
diff --git a/services/network/first_party_sets/first_party_sets_loader.cc b/services/network/first_party_sets/first_party_sets_loader.cc index eeb86641..47d775a 100644 --- a/services/network/first_party_sets/first_party_sets_loader.cc +++ b/services/network/first_party_sets/first_party_sets_loader.cc
@@ -4,6 +4,7 @@ #include "services/network/first_party_sets/first_party_sets_loader.h" +#include <set> #include <utility> #include <vector>
diff --git a/sql/error_delegate_util.cc b/sql/error_delegate_util.cc index edd4681..e88deb61 100644 --- a/sql/error_delegate_util.cc +++ b/sql/error_delegate_util.cc
@@ -201,9 +201,11 @@ // the user if we run our recovery code or delete our databases. [[fallthrough]]; case SQLITE_PROTOCOL: - // Timed out while attempting to grab a lock on the database. This should - // not be a problem for exclusive databases, which are strongly - // recommended for Chrome features. + // Gave up while attempting to grab a lock on a WAL database at the + // beginning of a transaction. In theory, this should not be a problem in + // Chrome, because we'll only allow enabling WAL on databases with + // exclusive locking. However, other software on the user's system may + // lock our databases in a way that triggers this error. [[fallthrough]]; case SQLITE_SCHEMA: // The database schema was changed between the time when a prepared
diff --git a/storage/browser/file_system/file_system_context.cc b/storage/browser/file_system/file_system_context.cc index 4b22d56..808295d 100644 --- a/storage/browser/file_system/file_system_context.cc +++ b/storage/browser/file_system/file_system_context.cc
@@ -446,11 +446,6 @@ OpenFileSystemMode mode, OpenFileSystemCallback callback, QuotaErrorOr<BucketInfo> result) { - if (!result.ok()) { - std::move(callback).Run(GURL(), std::string(), - base::File::FILE_ERROR_FAILED); - return; - } ResolveURLOnOpenFileSystem(storage_key, type, mode, std::move(callback)); }
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 7db6a9b9..a1688c6 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -35214,7 +35214,9 @@ }, "android-pie-arm64-coverage-experimental-rel": { "additional_compile_targets": [ - "validate_expectations" + "monochrome_static_initializers", + "validate_expectations", + "weblayer_shell" ], "gtest_tests": [ {
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 8c5f98a..8f8a639 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -2185,24 +2185,6 @@ }, }, }, - 'monochrome_public_bundle_fake_modules_smoke_test' : { - 'remove_from': [ - 'android-pie-arm64-coverage-experimental-rel', # TODO(crbug.com/1190999): - # GLIBC_2.28 Not found. - ], - }, - 'monochrome_public_bundle_smoke_test' : { - 'remove_from': [ - 'android-pie-arm64-coverage-experimental-rel', # TODO(crbug.com/1190999): - # GLIBC_2.28 Not found. - ], - }, - 'monochrome_public_smoke_test' : { - 'remove_from': [ - 'android-pie-arm64-coverage-experimental-rel', # TODO(crbug.com/1190999): - # GLIBC_2.28 Not found. - ], - }, 'monochrome_public_test_ar_apk': { 'modifications': { 'Nougat Phone Tester': { @@ -3617,8 +3599,6 @@ 'webview_cts_tests': { 'remove_from': [ 'android-11-x86-rel', # crbug.com/1165280 - 'android-pie-arm64-coverage-experimental-rel', # TODO(crbug.com/1190999): - # GLIBC_2.28 Not found. ], 'modifications': { 'android-pie-arm64-rel': {
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index a62139c3..7f4cbdd 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -966,7 +966,9 @@ 'walleye', ], 'additional_compile_targets': [ + 'monochrome_static_initializers', 'validate_expectations', + 'weblayer_shell', ], 'test_suites': { 'gtest_tests': 'chromium_android_gtests',
diff --git a/testing/scripts/run_finch_smoke_tests_android.py b/testing/scripts/run_finch_smoke_tests_android.py index cf5032d..53255691 100755 --- a/testing/scripts/run_finch_smoke_tests_android.py +++ b/testing/scripts/run_finch_smoke_tests_android.py
@@ -119,7 +119,6 @@ 'dom/collections/HTMLCollection-delete.html', 'dom/collections/HTMLCollection-supported-property-names.html', 'dom/collections/HTMLCollection-supported-property-indices.html', - 'svg/pservers/reftests/radialgradient-basic-002.svg', ] @property @@ -182,6 +181,7 @@ rest_args.extend(['run', self.wpt_product_name(), '--tests=' + wpt_common.TESTS_ROOT_DIR, + '--test-type=' + 'testharness', '--device-serial', self._device.serial, '--webdriver-binary',
diff --git a/third_party/blink/public/mojom/conversions/attribution_data_host.mojom b/third_party/blink/public/mojom/conversions/attribution_data_host.mojom index 4538221..206c9f2 100644 --- a/third_party/blink/public/mojom/conversions/attribution_data_host.mojom +++ b/third_party/blink/public/mojom/conversions/attribution_data_host.mojom
@@ -26,9 +26,9 @@ }; // Defines a list of named histogram contributions. -struct AttributionAggregatableSources { +struct AttributionAggregatableSource { // Map of key id to the key. - map<string, AttributionAggregatableKey> sources; + map<string, AttributionAggregatableKey> keys; }; // Struct containing the trigger-side aggregatable data. @@ -72,7 +72,7 @@ AttributionFilterData filter_data; // Contains source-side aggregatable key pieces. - AttributionAggregatableSources aggregatable_sources; + AttributionAggregatableSource aggregatable_source; }; // Deduplication key set by a reporting origin which prevents duplicate triggers
diff --git a/third_party/blink/renderer/core/dom/events/event_target.cc b/third_party/blink/renderer/core/dom/events/event_target.cc index ab104b0..24d968b 100644 --- a/third_party/blink/renderer/core/dom/events/event_target.cc +++ b/third_party/blink/renderer/core/dom/events/event_target.cc
@@ -454,6 +454,20 @@ if (options->hasSignal() && options->signal()->aborted()) return false; + // Unload/Beforeunload handlers are not allowed in fenced frames. + if (event_type == event_type_names::kUnload || + event_type == event_type_names::kBeforeunload) { + if (const LocalDOMWindow* window = ExecutingWindow()) { + if (const LocalFrame* frame = window->GetFrame()) { + if (frame->IsInFencedFrameTree()) { + window->PrintErrorMessage( + "unload/beforeunload handlers are prohibited in fenced frames."); + return false; + } + } + } + } + if (event_type == event_type_names::kTouchcancel || event_type == event_type_names::kTouchend || event_type == event_type_names::kTouchmove ||
diff --git a/third_party/blink/renderer/core/frame/attribution_response_parsing.cc b/third_party/blink/renderer/core/frame/attribution_response_parsing.cc index dcd66bb..2bb9445c 100644 --- a/third_party/blink/renderer/core/frame/attribution_response_parsing.cc +++ b/third_party/blink/renderer/core/frame/attribution_response_parsing.cc
@@ -119,9 +119,9 @@ } // namespace -bool ParseAttributionAggregatableSources( +bool ParseAttributionAggregatableSource( const AtomicString& json_string, - mojom::blink::AttributionAggregatableSources& sources) { + mojom::blink::AttributionAggregatableSource& source) { std::unique_ptr<JSONValue> json = ParseJSON(json_string); if (!json) return false; @@ -134,7 +134,7 @@ const wtf_size_t num_keys = array->size(); - sources.sources.ReserveCapacityForSize(num_keys); + source.keys.ReserveCapacityForSize(num_keys); for (wtf_size_t i = 0; i < num_keys; ++i) { JSONValue* value = array->at(i); @@ -156,7 +156,7 @@ if (!key) return false; - sources.sources.insert(std::move(key_id), std::move(key)); + source.keys.insert(std::move(key_id), std::move(key)); } return true;
diff --git a/third_party/blink/renderer/core/frame/attribution_response_parsing.h b/third_party/blink/renderer/core/frame/attribution_response_parsing.h index 4d43f592..afa6669 100644 --- a/third_party/blink/renderer/core/frame/attribution_response_parsing.h +++ b/third_party/blink/renderer/core/frame/attribution_response_parsing.h
@@ -33,9 +33,9 @@ // }] // // Returns whether parsing was successful. -CORE_EXPORT bool ParseAttributionAggregatableSources( +CORE_EXPORT bool ParseAttributionAggregatableSource( const AtomicString& json_string, - mojom::blink::AttributionAggregatableSources& sources); + mojom::blink::AttributionAggregatableSource& source); // Parses a debug key, which is a 64-bit unsigned integer encoded as a base-10 // string. Returns `nullptr` on failure.
diff --git a/third_party/blink/renderer/core/frame/attribution_response_parsing_test.cc b/third_party/blink/renderer/core/frame/attribution_response_parsing_test.cc index 8c656cf6..b85456b 100644 --- a/third_party/blink/renderer/core/frame/attribution_response_parsing_test.cc +++ b/third_party/blink/renderer/core/frame/attribution_response_parsing_test.cc
@@ -19,24 +19,24 @@ namespace { -class AggregatableSourcesBuilder { +class AggregatableSourceBuilder { public: - AggregatableSourcesBuilder() = default; - ~AggregatableSourcesBuilder() = default; + AggregatableSourceBuilder() = default; + ~AggregatableSourceBuilder() = default; - AggregatableSourcesBuilder& AddKey( + AggregatableSourceBuilder& AddKey( String key_id, mojom::blink::AttributionAggregatableKeyPtr key) { - sources_.sources.insert(std::move(key_id), std::move(key)); + source_.keys.insert(std::move(key_id), std::move(key)); return *this; } - mojom::blink::AttributionAggregatableSourcesPtr Build() const { - return sources_.Clone(); + mojom::blink::AttributionAggregatableSourcePtr Build() const { + return source_.Clone(); } private: - mojom::blink::AttributionAggregatableSources sources_; + mojom::blink::AttributionAggregatableSource source_; }; class AttributionFilterDataBuilder { @@ -80,25 +80,25 @@ } // namespace -TEST(AttributionResponseParsingTest, ParseAttributionAggregatableSources) { +TEST(AttributionResponseParsingTest, ParseAttributionAggregatableSource) { const struct { String description; AtomicString header; bool valid; - mojom::blink::AttributionAggregatableSourcesPtr sources; + mojom::blink::AttributionAggregatableSourcePtr source; } kTestCases[] = { {"Empty header", "", false, - mojom::blink::AttributionAggregatableSources::New()}, + mojom::blink::AttributionAggregatableSource::New()}, {"Invalid JSON", "{", false, - mojom::blink::AttributionAggregatableSources::New()}, + mojom::blink::AttributionAggregatableSource::New()}, {"Missing id field", R"([{"key_piece":"0x159"}])", false, - mojom::blink::AttributionAggregatableSources::New()}, + mojom::blink::AttributionAggregatableSource::New()}, {"Missing key_piece field", R"([{"id":"key"}])", false, - mojom::blink::AttributionAggregatableSources::New()}, + mojom::blink::AttributionAggregatableSource::New()}, {"Invalid key", R"([{"id":"key","key_piece":"0xG59"}])", false, - mojom::blink::AttributionAggregatableSources::New()}, + mojom::blink::AttributionAggregatableSource::New()}, {"One valid key", R"([{"id":"key","key_piece":"0x159"}])", true, - AggregatableSourcesBuilder() + AggregatableSourceBuilder() .AddKey(/*key_id=*/"key", mojom::blink::AttributionAggregatableKey::New( /*high_bits=*/0, /*low_bits=*/345)) @@ -107,7 +107,7 @@ AtomicString(R"([{"id":"key1","key_piece":"0x159"},)") + R"({"id":"key2","key_piece":"0x50000000000000159"}])", true, - AggregatableSourcesBuilder() + AggregatableSourceBuilder() .AddKey(/*key_id=*/"key1", mojom::blink::AttributionAggregatableKey::New( /*high_bits=*/0, /*low_bits=*/345)) @@ -118,22 +118,21 @@ {"Second key invalid", AtomicString(R"([{"id":"key1","key_piece":"0x159"},)") + R"({"id":"key2","key_piece":""}])", - false, mojom::blink::AttributionAggregatableSources::New()}, + false, mojom::blink::AttributionAggregatableSource::New()}, }; for (const auto& test_case : kTestCases) { - auto sources = mojom::blink::AttributionAggregatableSources::New(); - bool valid = - ParseAttributionAggregatableSources(test_case.header, *sources); + auto source = mojom::blink::AttributionAggregatableSource::New(); + bool valid = ParseAttributionAggregatableSource(test_case.header, *source); EXPECT_EQ(test_case.valid, valid) << test_case.description; if (test_case.valid) - EXPECT_EQ(test_case.sources, sources) << test_case.description; + EXPECT_EQ(test_case.source, source) << test_case.description; } } TEST(AttributionResponseParsingTest, - ParseAttributionAggregatableSources_CheckSize) { - struct AttributionAggregatableSourcesSizeTestCase { + ParseAttributionAggregatableSource_CheckSize) { + struct AttributionAggregatableSourceSizeTestCase { String description; bool valid; wtf_size_t key_count; @@ -154,8 +153,8 @@ return "[" + builder.ToAtomicString() + "]"; } - mojom::blink::AttributionAggregatableSourcesPtr GetSources() const { - AggregatableSourcesBuilder builder; + mojom::blink::AttributionAggregatableSourcePtr GetSource() const { + AggregatableSourceBuilder builder; if (!valid) return builder.Build(); @@ -177,7 +176,7 @@ } }; - const AttributionAggregatableSourcesSizeTestCase kTestCases[] = { + const AttributionAggregatableSourceSizeTestCase kTestCases[] = { {"empty", true, 0, 0}, {"max_keys", true, blink::kMaxAttributionAggregatableKeysPerSourceOrTrigger, 1}, @@ -190,12 +189,12 @@ }; for (const auto& test_case : kTestCases) { - auto sources = mojom::blink::AttributionAggregatableSources::New(); + auto source = mojom::blink::AttributionAggregatableSource::New(); bool valid = - ParseAttributionAggregatableSources(test_case.GetHeader(), *sources); + ParseAttributionAggregatableSource(test_case.GetHeader(), *source); EXPECT_EQ(test_case.valid, valid) << test_case.description; if (test_case.valid) - EXPECT_EQ(test_case.GetSources(), sources) << test_case.description; + EXPECT_EQ(test_case.GetSource(), source) << test_case.description; } } @@ -514,7 +513,7 @@ /*priority=*/0, /*debug_key=*/nullptr, /*filter_data=*/AttributionFilterDataBuilder().Build(), - /*aggregatable_sources=*/AggregatableSourcesBuilder().Build()), + /*aggregatable_source=*/AggregatableSourceBuilder().Build()), }, { "valid_filter_data", @@ -535,7 +534,7 @@ AttributionFilterDataBuilder() .AddFilter("SOURCE_TYPE", {}) .Build(), - /*aggregatable_sources=*/AggregatableSourcesBuilder().Build()), + /*aggregatable_source=*/AggregatableSourceBuilder().Build()), }, { "invalid_source_type_key_in_filter_data",
diff --git a/third_party/blink/renderer/core/frame/attribution_src_loader.cc b/third_party/blink/renderer/core/frame/attribution_src_loader.cc index ce4aec7..16873cc 100644 --- a/third_party/blink/renderer/core/frame/attribution_src_loader.cc +++ b/third_party/blink/renderer/core/frame/attribution_src_loader.cc
@@ -265,14 +265,14 @@ return; } - source_data->aggregatable_sources = - mojom::blink::AttributionAggregatableSources::New(); + source_data->aggregatable_source = + mojom::blink::AttributionAggregatableSource::New(); - const AtomicString& aggregatable_sources_json = response.HttpHeaderField( + const AtomicString& aggregatable_source_json = response.HttpHeaderField( http_names::kAttributionReportingRegisterAggregatableSource); - if (!aggregatable_sources_json.IsNull() && - !attribution_response_parsing::ParseAttributionAggregatableSources( - aggregatable_sources_json, *source_data->aggregatable_sources)) { + if (!aggregatable_source_json.IsNull() && + !attribution_response_parsing::ParseAttributionAggregatableSource( + aggregatable_source_json, *source_data->aggregatable_source)) { return; }
diff --git a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_item_iterator.cc b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_item_iterator.cc index 100035d..3971fd686 100644 --- a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_item_iterator.cc +++ b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_item_iterator.cc
@@ -128,10 +128,7 @@ break; flex_line_idx_++; - if (flex_line_idx_ < next_item_idx_for_line_.size()) - flex_item_idx_ = next_item_idx_for_line_[flex_line_idx_]; - else - flex_item_idx_ = 0; + AdjustItemIndexForNewLine(); } // We handle break tokens for all columns before moving to the unprocessed @@ -152,8 +149,15 @@ if (flex_item_idx_ == 0) return; flex_line_idx_++; - flex_item_idx_ = 0; + AdjustItemIndexForNewLine(); next_unstarted_item_ = FindNextItem(); } +void NGFlexItemIterator::AdjustItemIndexForNewLine() { + if (flex_line_idx_ < next_item_idx_for_line_.size()) + flex_item_idx_ = next_item_idx_for_line_[flex_line_idx_]; + else + flex_item_idx_ = 0; +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_item_iterator.h b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_item_iterator.h index 528e96e..92d55fa 100644 --- a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_item_iterator.h +++ b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_item_iterator.h
@@ -48,6 +48,7 @@ private: NGFlexItem* FindNextItem(const NGBlockBreakToken* item_break_token = nullptr); + void AdjustItemIndexForNewLine(); NGFlexItem* next_unstarted_item_ = nullptr; const HeapVector<NGFlexLine>& flex_lines_;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc index e3daafa..043508f 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc
@@ -417,8 +417,16 @@ DCHECK_EQ(result->Status(), NGLayoutResult::kSuccess); LogicalOffset offset(borders_.inline_start, intrinsic_block_size_); container_builder_.AddResult(*result, offset); + + const auto& fragment = + To<NGPhysicalBoxFragment>(result->PhysicalFragment()); + if (auto baseline = fragment.Baseline()) + container_builder_.SetBaseline(offset.block_offset + *baseline); + if (auto last_baseline = fragment.LastBaseline()) + container_builder_.SetLastBaseline(offset.block_offset + *last_baseline); + intrinsic_block_size_ += - NGFragment(writing_direction_, result->PhysicalFragment()).BlockSize(); + NGFragment(writing_direction_, fragment).BlockSize(); container_builder_.SetHasSeenAllChildren(); } else if (break_status == NGBreakStatus::kBrokeBefore) { ConsumeRemainingFragmentainerSpace(); @@ -533,6 +541,7 @@ builder.SetPercentageResolutionSize( ConstraintSpace().PercentageResolutionSize()); builder.SetIsFixedBlockSize(padding_box_size.block_size != kIndefiniteSize); + builder.SetBaselineAlgorithmType(ConstraintSpace().BaselineAlgorithmType()); if (ConstraintSpace().HasBlockFragmentation()) { SetupSpaceBuilderForFragmentation(
diff --git a/third_party/blink/renderer/modules/credentialmanager/federated_credential.cc b/third_party/blink/renderer/modules/credentialmanager/federated_credential.cc index 499b750f..81a4dc4 100644 --- a/third_party/blink/renderer/modules/credentialmanager/federated_credential.cc +++ b/third_party/blink/renderer/modules/credentialmanager/federated_credential.cc
@@ -337,6 +337,7 @@ } ScriptPromise FederatedCredential::revoke(ScriptState* script_state, + const String& hint, ExceptionState& exception_state) { ExecutionContext* context = ExecutionContext::From(script_state); auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); @@ -353,10 +354,9 @@ return promise; } - if (id().IsEmpty()) { + if (hint.IsEmpty()) { resolver->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidStateError, - "No account hint was provided to navigator.credentials.get")); + DOMExceptionCode::kInvalidStateError, "hint cannot be empty")); return promise; } @@ -371,7 +371,7 @@ if (!MaybeRejectDueToCSP(policy, resolver, provider_url_)) return promise; - auth_request->Revoke(provider_url_, client_id_, id(), + auth_request->Revoke(provider_url_, client_id_, hint, WTF::Bind(&OnRevoke, WrapPersistent(resolver))); return promise; }
diff --git a/third_party/blink/renderer/modules/credentialmanager/federated_credential.h b/third_party/blink/renderer/modules/credentialmanager/federated_credential.h index dbaee1f3..8fe4aa2 100644 --- a/third_party/blink/renderer/modules/credentialmanager/federated_credential.h +++ b/third_party/blink/renderer/modules/credentialmanager/federated_credential.h
@@ -73,7 +73,7 @@ ScriptPromise logout(ScriptState* script_state); - ScriptPromise revoke(ScriptState*, ExceptionState&); + ScriptPromise revoke(ScriptState*, const String& hint, ExceptionState&); static ScriptPromise logoutRps( ScriptState*,
diff --git a/third_party/blink/renderer/modules/credentialmanager/federated_credential.idl b/third_party/blink/renderer/modules/credentialmanager/federated_credential.idl index 67b0536..64bc68a 100644 --- a/third_party/blink/renderer/modules/credentialmanager/federated_credential.idl +++ b/third_party/blink/renderer/modules/credentialmanager/federated_credential.idl
@@ -31,7 +31,7 @@ // https://fedidcg.github.io/FedCM/#browser-api-revocation [RuntimeEnabled=FedCm, CallWith=ScriptState, RaisesException] - Promise<void> revoke(); + Promise<void> revoke(USVString hint); // Allows IDPs to logout the user out of all of the logged in RPs. [RuntimeEnabled=FedCmIdpSignout, CallWith=ScriptState]
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_decoder.cc b/third_party/blink/renderer/modules/webcodecs/audio_decoder.cc index 17c10797..7def338 100644 --- a/third_party/blink/renderer/modules/webcodecs/audio_decoder.cc +++ b/third_party/blink/renderer/modules/webcodecs/audio_decoder.cc
@@ -48,6 +48,17 @@ return true; } + // https://www.w3.org/TR/webcodecs-flac-codec-registration + // https://www.w3.org/TR/webcodecs-vorbis-codec-registration + bool description_required = false; + if (config.codec() == "flac" || config.codec() == "vorbis") + description_required = true; + + if (description_required && !config.hasDescription()) { + out_console_message = "Description is required."; + return false; + } + media::AudioCodec codec = media::AudioCodec::kUnknown; bool is_codec_ambiguous = true; const bool parse_succeeded = ParseAudioCodecString(
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc b/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc index d7ef31c1..e3745d0 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc +++ b/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc
@@ -7,6 +7,7 @@ #include "base/check.h" #include "base/notreached.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_index_format.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_predefined_color_space.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { @@ -603,6 +604,14 @@ } } +WGPUPredefinedColorSpace AsDawnEnum( + const V8GPUPredefinedColorSpace& webgpu_enum) { + switch (webgpu_enum.AsEnum()) { + case V8GPUPredefinedColorSpace::Enum::kSRGB: + return WGPUPredefinedColorSpace_Srgb; + } +} + template <> WGPUPrimitiveTopology AsDawnEnum<WGPUPrimitiveTopology>( const WTF::String& webgpu_enum) {
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.h b/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.h index 74e79ef7..3ef556d 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.h +++ b/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.h
@@ -10,6 +10,7 @@ namespace blink { class V8GPUIndexFormat; +class V8GPUPredefinedColorSpace; // Convert WebGPU bitfield values to Dawn enums. These have the same value. template <typename DawnEnum> @@ -21,6 +22,8 @@ template <typename DawnEnum> DawnEnum AsDawnEnum(const WTF::String& webgpu_enum); WGPUIndexFormat AsDawnEnum(const V8GPUIndexFormat& webgpu_enum); +WGPUPredefinedColorSpace AsDawnEnum( + const V8GPUPredefinedColorSpace& webgpu_enum); } // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc index 7fee352..531eecd 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
@@ -29,6 +29,7 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_device.h" #include "third_party/blink/renderer/modules/webgpu/gpu_texture.h" #include "third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.h" +#include "third_party/blink/renderer/platform/graphics/graphics_types.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" namespace blink { @@ -97,6 +98,17 @@ } } +PredefinedColorSpace GetPredefinedColorSpace( + WGPUPredefinedColorSpace color_space) { + switch (color_space) { + case WGPUPredefinedColorSpace_Srgb: + return PredefinedColorSpace::kSRGB; + default: + NOTREACHED(); + return PredefinedColorSpace::kSRGB; + } +} + WGPUTextureFormat SkColorTypeToDawnColorFormat(SkColorType sk_color_type) { switch (sk_color_type) { case SkColorType::kRGBA_8888_SkColorType: @@ -495,10 +507,13 @@ "({width|height|depthOrArrayLayers} equals to 0)."); } + WGPUPredefinedColorSpace dawn_predefined_color_space = + AsDawnEnum(destination->colorSpace()); + if (!UploadContentToTexture( static_bitmap_image.get(), origin_in_external_image, dawn_copy_size, dawn_destination, destination->premultipliedAlpha(), - copyImage->flipY())) { + dawn_predefined_color_space, copyImage->flipY())) { exception_state.ThrowTypeError( "Failed to copy content from external image."); return; @@ -510,6 +525,7 @@ const WGPUExtent3D& copy_size, const WGPUImageCopyTexture& destination, bool dst_premultiplied_alpha, + WGPUPredefinedColorSpace dst_color_space, bool flipY) { PaintImage paint_image = image->PaintImageForCurrentFrame(); SkColorType source_color_type = paint_image.GetSkImageInfo().colorType(); @@ -534,17 +550,63 @@ ? WGPUAlphaMode_Premultiplied : WGPUAlphaMode_Unpremultiplied; + // Set color space conversion params + sk_sp<SkColorSpace> sk_src_color_space = + paint_image.GetSkImageInfo().refColorSpace(); + + // If source input discard the color space info(e.g. ImageBitmap created with + // flag colorSpaceConversion: none). Treat the source color space as sRGB. + if (sk_src_color_space == nullptr) { + sk_src_color_space = SkColorSpace::MakeSRGB(); + } + sk_sp<SkColorSpace> sk_dst_color_space = PredefinedColorSpaceToSkColorSpace( + GetPredefinedColorSpace(dst_color_space)); + std::array<float, 7> gamma_decode_params; + std::array<float, 7> gamma_encode_params; + std::array<float, 9> conversion_matrix; + if (!SkColorSpace::Equals(sk_src_color_space.get(), + sk_dst_color_space.get())) { + skcms_TransferFunction src_transfer_fn = {}; + skcms_TransferFunction dst_transfer_fn = {}; + + // Row major matrix + skcms_Matrix3x3 transfer_matrix = {}; + + sk_src_color_space->transferFn(&src_transfer_fn); + sk_dst_color_space->invTransferFn(&dst_transfer_fn); + sk_src_color_space->gamutTransformTo(sk_dst_color_space.get(), + &transfer_matrix); + gamma_decode_params = {src_transfer_fn.g, src_transfer_fn.a, + src_transfer_fn.b, src_transfer_fn.c, + src_transfer_fn.d, src_transfer_fn.e, + src_transfer_fn.f}; + gamma_encode_params = {dst_transfer_fn.g, dst_transfer_fn.a, + dst_transfer_fn.b, dst_transfer_fn.c, + dst_transfer_fn.d, dst_transfer_fn.e, + dst_transfer_fn.f}; + + // From row major matrix to col major matrix + conversion_matrix = {transfer_matrix.vals[0][0], transfer_matrix.vals[1][0], + transfer_matrix.vals[2][0], transfer_matrix.vals[0][1], + transfer_matrix.vals[1][1], transfer_matrix.vals[2][1], + transfer_matrix.vals[0][2], transfer_matrix.vals[1][2], + transfer_matrix.vals[2][2]}; + + options.needsColorSpaceConversion = true; + options.srcTransferFunctionParameters = gamma_decode_params.data(); + options.dstTransferFunctionParameters = gamma_encode_params.data(); + options.conversionMatrix = conversion_matrix.data(); + } + // Handling GPU resource. if (image->IsTextureBacked()) { - // TODO(crbug.com/1197369): Delegate color space conversion to - // copyTextureForBrowser(). scoped_refptr<WebGPUMailboxTexture> mailbox_texture = WebGPUMailboxTexture::FromStaticBitmapImage( GetDawnControlClient(), device_->GetHandle(), static_cast<WGPUTextureUsage>(WGPUTextureUsage_CopyDst | WGPUTextureUsage_CopySrc | WGPUTextureUsage_TextureBinding), - image, PredefinedColorSpace::kSRGB, source_color_type); + image, source_color_type); if (mailbox_texture != nullptr) { WGPUImageCopyTexture src = {}; @@ -604,13 +666,6 @@ auto dest_pixels = base::span<uint8_t>(static_cast<uint8_t*>(data), size); - // TODO(crbug.com/1197369): Delegate color space conversion to - // copyTextureForBrowser(). - SkImageInfo info = SkImageInfo::Make( - image->width(), image->height(), source_color_type, - image->IsPremultiplied() ? kPremul_SkAlphaType : kUnpremul_SkAlphaType, - SkColorSpace::MakeSRGB()); - bool success = paint_image.readPixels( paint_image.GetSkImageInfo(), dest_pixels.data(), wgpu_bytes_per_row, source_image_rect.x(), source_image_rect.y());
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_queue.h b/third_party/blink/renderer/modules/webgpu/gpu_queue.h index e516257..cfa1b38 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_queue.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_queue.h
@@ -11,6 +11,7 @@ #include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h" #include "third_party/blink/renderer/modules/webgpu/dawn_object.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/graphics/graphics_types.h" namespace blink { @@ -83,7 +84,8 @@ const WGPUExtent3D& copy_size, const WGPUImageCopyTexture& destination, bool dst_premultiplied_alpha, - bool flipY = false); + WGPUPredefinedColorSpace dst_color_space, + bool flipY); void WriteBufferImpl(GPUBuffer* buffer, uint64_t buffer_offset, uint64_t data_byte_length,
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.cc b/third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.cc index 17bb0860..80405c5 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.cc
@@ -18,7 +18,6 @@ WGPUDevice device, WGPUTextureUsage usage, scoped_refptr<StaticBitmapImage> image, - PredefinedColorSpace color_space, SkColorType color_type) { DCHECK(image->IsTextureBacked()); @@ -34,16 +33,11 @@ context_provider_wrapper->ContextProvider()->IsContextLost()) return nullptr; - // Keep the same config as source image. - SkImageInfo info = SkImageInfo::Make( - image->Size().width(), image->Size().height(), color_type, - image->IsPremultiplied() ? kPremul_SkAlphaType : kUnpremul_SkAlphaType, - PredefinedColorSpaceToSkColorSpace(color_space)); - // Get a recyclable resource for producing WebGPU-compatible shared images. std::unique_ptr<RecyclableCanvasResource> recyclable_canvas_resource = - dawn_control_client->GetOrCreateCanvasResource(info, - image->IsOriginTopLeft()); + dawn_control_client->GetOrCreateCanvasResource( + image->PaintImageForCurrentFrame().GetSkImageInfo(), + image->IsOriginTopLeft()); // Fallback to unstable intermediate resource copy path. if (!recyclable_canvas_resource) {
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.h b/third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.h index fb16afd..522b98c 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.h +++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.h
@@ -30,7 +30,6 @@ WGPUDevice device, WGPUTextureUsage usage, scoped_refptr<StaticBitmapImage> image, - PredefinedColorSpace color_space, SkColorType color_type); static scoped_refptr<WebGPUMailboxTexture> FromCanvasResource(
diff --git a/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc b/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc index 62a77276..cd3d2b0 100644 --- a/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc +++ b/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc
@@ -137,7 +137,11 @@ for (const auto* t = &destination.Transform(); t != &source.Transform(); t = t->UnaliasedParent()) { - DCHECK(t); + // TODO(wangxianzhu): This should be DCHECK(t), but for now we need to + // work around crbug.com/1262837 etc. Also see the TODO in + // FragmentData::LocalBorderBoxProperties(). + if (!t) + return false; if (t == &root.Transform()) { abnormal_hierarchy = true; break;
diff --git a/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer_unittest.py b/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer_unittest.py index a43f125..b0da230f 100644 --- a/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer_unittest.py +++ b/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer_unittest.py
@@ -63,10 +63,6 @@ 'port_name': 'win-win10.20h2', 'specifiers': ['Win10.20h2', 'Release'] }, - 'Fake Test Win11': { - 'port_name': 'win-win11', - 'specifiers': ['Win11', 'Release'] - }, 'Fake Test Linux': { 'port_name': 'linux-trusty', 'specifiers': ['Trusty', 'Release'] @@ -97,7 +93,7 @@ # tests need to be adjusted accordingly. self.assertEqual(sorted(self.host.port_factory.all_port_names()), [ 'linux-trusty', 'mac-mac10.12', 'mac-mac10.13', 'mac-mac10.14', - 'mac-mac10.15', 'mac-mac11', 'win-win10.20h2', 'win-win11' + 'mac-mac10.15', 'mac-mac11', 'win-win10.20h2' ]) def _assert_optimization(self,
diff --git a/third_party/blink/tools/blinkpy/common/system/crash_logs_unittest.py b/third_party/blink/tools/blinkpy/common/system/crash_logs_unittest.py index c84fbea..776235e 100644 --- a/third_party/blink/tools/blinkpy/common/system/crash_logs_unittest.py +++ b/third_party/blink/tools/blinkpy/common/system/crash_logs_unittest.py
@@ -86,17 +86,17 @@ make_mock_crash_report_darwin('DumpRenderTree', 28526)[200:] files = { '/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150718_quadzen.crash': - older_mock_crash_report, + older_mock_crash_report.encode('utf8', 'replace'), '/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150719_quadzen.crash': - mock_crash_report, + mock_crash_report.encode('utf8', 'replace'), '/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150720_quadzen.crash': - newer_mock_crash_report, + newer_mock_crash_report.encode('utf8', 'replace'), '/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150721_quadzen.crash': None, '/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150722_quadzen.crash': - other_process_mock_crash_report, + other_process_mock_crash_report.encode('utf8', 'replace'), '/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150723_quadzen.crash': - misformatted_mock_crash_report, + misformatted_mock_crash_report.encode('utf8', 'replace'), } filesystem = MockFileSystem(files) crash_logs = CrashLogs(MockSystemHost(filesystem=filesystem))
diff --git a/third_party/blink/tools/blinkpy/common/system/executive.py b/third_party/blink/tools/blinkpy/common/system/executive.py index 67140fbd..ce05bfe 100644 --- a/third_party/blink/tools/blinkpy/common/system/executive.py +++ b/third_party/blink/tools/blinkpy/common/system/executive.py
@@ -223,7 +223,8 @@ stdout=self.PIPE, stderr=self.PIPE) stdout, _ = tasklist_process.communicate() - stdout_reader = csv.reader(stdout.splitlines()) + stdout_reader = csv.reader( + stdout.decode('utf8', 'replace').splitlines()) for line in stdout_reader: processes.append([column for column in line]) else:
diff --git a/third_party/blink/tools/blinkpy/common/system/executive_unittest.py b/third_party/blink/tools/blinkpy/common/system/executive_unittest.py index 55c902b9..2bdf07cd 100644 --- a/third_party/blink/tools/blinkpy/common/system/executive_unittest.py +++ b/third_party/blink/tools/blinkpy/common/system/executive_unittest.py
@@ -31,6 +31,7 @@ import subprocess import sys import unittest +import six # Since we execute this script directly as part of the unit tests, we need to # ensure that blink/tools is in sys.path for the next imports to work correctly. @@ -118,7 +119,7 @@ # Elsewhere, the 'mbcs' encoding is skipped, but then we must escape any # non-ascii unicode characters by encoding with 'unicode_escape'. This # results in an extra \ on non-Win platforms. - if sys.platform == 'win32': + if sys.platform == 'win32' and six.PY2: expected_result = u'echo 1 a\xac' else: expected_result = u'echo 1 a\\xac' @@ -136,15 +137,18 @@ to Executive.run* methods, and they will return unicode() objects by default unless decode_output=False """ + # TODO(crbug/1306209): Needs more investigation. skipping for now. + if sys.platform == 'win32' and six.PY3: + return unicode_tor_input = u"WebKit \u2661 Tor Arne Vestb\u00F8!" - if sys.platform == 'win32': + if sys.platform == 'win32' and six.PY2: encoding = 'mbcs' else: encoding = 'utf-8' encoded_tor = unicode_tor_input.encode(encoding) # On Windows, we expect the unicode->mbcs->unicode roundtrip to be # lossy. On other platforms, we expect a lossless roundtrip. - if sys.platform == 'win32': + if sys.platform == 'win32' and six.PY2: unicode_tor_output = encoded_tor.decode(encoding) else: unicode_tor_output = unicode_tor_input
diff --git a/third_party/blink/tools/blinkpy/common/system/filesystem_mock.py b/third_party/blink/tools/blinkpy/common/system/filesystem_mock.py index c38f483..0ce9caf 100644 --- a/third_party/blink/tools/blinkpy/common/system/filesystem_mock.py +++ b/third_party/blink/tools/blinkpy/common/system/filesystem_mock.py
@@ -488,8 +488,6 @@ class WritableTextFileObject(WritableBinaryFileObject): def __init__(self, fs, path, append=False): super(WritableTextFileObject, self).__init__(fs, path, append) - if path not in self.fs.files or not append: - self.setup_path(path) def write(self, string): WritableBinaryFileObject.write(self, string) @@ -509,6 +507,13 @@ self.closed = False self.data = data self.offset = 0 + try: + # Maintain a text version if possible to + # support readline. + data_str = data.decode('utf8', 'replace') + self.text = StringIO(data_str) + except: + pass def __enter__(self): return self @@ -526,6 +531,12 @@ self.offset += num_bytes return self.data[start:self.offset] + def readline(self, length=None): + return self.text.readline(length).encode('utf8', 'replace') + + def readlines(self): + return self.text.readlines().encode('utf8', 'replace') + def seek(self, offset, whence=os.SEEK_SET): if whence == os.SEEK_SET: self.offset = offset
diff --git a/third_party/blink/tools/blinkpy/common/system/platform_info.py b/third_party/blink/tools/blinkpy/common/system/platform_info.py index 1f35add..3ad768f 100644 --- a/third_party/blink/tools/blinkpy/common/system/platform_info.py +++ b/third_party/blink/tools/blinkpy/common/system/platform_info.py
@@ -200,11 +200,12 @@ def _determine_win_version(self, win_version_tuple): if win_version_tuple[:2] == (10, 0): - # For win11 platform.win32_ver() returns (10, 0, 22000) - if win_version_tuple[2] >= 22000: - return '11' - else: + # came across instances where build number was 15063. + # Treat those as 1909. + if win_version_tuple[2] > 19000: return '10.20h2' + else: + return '10.1909' if win_version_tuple[:2] == (6, 3): return '8.1' if win_version_tuple[:2] == (6, 2):
diff --git a/third_party/blink/tools/blinkpy/common/system/platform_info_unittest.py b/third_party/blink/tools/blinkpy/common/system/platform_info_unittest.py index 1d72885..04de9c3 100644 --- a/third_party/blink/tools/blinkpy/common/system/platform_info_unittest.py +++ b/third_party/blink/tools/blinkpy/common/system/platform_info_unittest.py
@@ -201,7 +201,7 @@ self.make_info( fake_sys('win32', tuple([10, 0, 1234])), fake_platform(win_version_string="10.0.1234")).os_version, - '10.20h2') + '10.1909') self.assertEqual( self.make_info( fake_sys('win32', tuple([10, 0, 19042])), @@ -209,11 +209,6 @@ '10.20h2') self.assertEqual( self.make_info( - fake_sys('win32', tuple([10, 0, 23000])), - fake_platform(win_version_string="10.0.23000")).os_version, - '11') - self.assertEqual( - self.make_info( fake_sys('win32', tuple([6, 3, 1234])), fake_platform(win_version_string="6.3.1234")).os_version, '8.1')
diff --git a/third_party/blink/tools/blinkpy/w3c/import_notifier_unittest.py b/third_party/blink/tools/blinkpy/w3c/import_notifier_unittest.py index 77ee480..bc3c1934 100644 --- a/third_party/blink/tools/blinkpy/w3c/import_notifier_unittest.py +++ b/third_party/blink/tools/blinkpy/w3c/import_notifier_unittest.py
@@ -25,7 +25,7 @@ # Mock a virtual test suite at virtual/gpu/external/wpt/foo. self.host.filesystem = MockFileSystem({ MOCK_WEB_TESTS + 'VirtualTestSuites': - '[{"prefix": "gpu", "bases": ["external/wpt/foo"], "args": ["--foo"]}]' + b'[{"prefix": "gpu", "bases": ["external/wpt/foo"], "args": ["--foo"]}]' }) self.git = self.host.git() self.local_wpt = MockLocalWPT()
diff --git a/third_party/blink/tools/blinkpy/web_tests/breakpad/dump_reader_multipart.py b/third_party/blink/tools/blinkpy/web_tests/breakpad/dump_reader_multipart.py index 59162de..a1f724e 100644 --- a/third_party/blink/tools/blinkpy/web_tests/breakpad/dump_reader_multipart.py +++ b/third_party/blink/tools/blinkpy/web_tests/breakpad/dump_reader_multipart.py
@@ -67,7 +67,7 @@ self._generate_breakpad_symbols_if_necessary() f, temp_name = self._host.filesystem.open_binary_tempfile('dmp') - f.write('\r\n'.join(dump['upload_file_minidump'])) + f.write(b'\r\n'.join(dump['upload_file_minidump'])) f.close() cmd = [
diff --git a/third_party/blink/tools/blinkpy/web_tests/breakpad/dump_reader_multipart_unittest.py b/third_party/blink/tools/blinkpy/web_tests/breakpad/dump_reader_multipart_unittest.py index 1abf688..414ab4b 100644 --- a/third_party/blink/tools/blinkpy/web_tests/breakpad/dump_reader_multipart_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/breakpad/dump_reader_multipart_unittest.py
@@ -80,9 +80,6 @@ host.filesystem.maybe_make_directory(build_dir) host.filesystem.exists = lambda x: True - # The mock file object returned by open_binary_file_for_reading doesn't - # have readline(), however, the real File object does. - host.filesystem.open_binary_file_for_reading = host.filesystem.open_text_file_for_reading dump_reader = DumpReaderMultipart(host, build_dir) dump_reader._file_extension = lambda: 'dmp' dump_reader._binaries_to_symbolize = lambda: ['content_shell'] @@ -101,9 +98,6 @@ host.filesystem.maybe_make_directory(build_dir) host.filesystem.exists = lambda x: True - # The mock file object returned by open_binary_file_for_reading doesn't - # have readline(), however, the real File object does. - host.filesystem.open_binary_file_for_reading = host.filesystem.open_text_file_for_reading dump_reader = DumpReaderMultipart(host, build_dir) dump_reader._file_extension = lambda: 'dmp' dump_reader._binaries_to_symbolize = lambda: ['content_shell']
diff --git a/third_party/blink/tools/blinkpy/web_tests/breakpad/dump_reader_win_unittest.py b/third_party/blink/tools/blinkpy/web_tests/breakpad/dump_reader_win_unittest.py index c531930f..31c227d0 100644 --- a/third_party/blink/tools/blinkpy/web_tests/breakpad/dump_reader_win_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/breakpad/dump_reader_win_unittest.py
@@ -49,9 +49,9 @@ dump_file = '/crash-dumps/dump.txt' expected_pid = '4711' - host.filesystem.write_text_file( - dump_file, 'channel:\npid:%s\nplat:Win32\nprod:content_shell\n' % - expected_pid) + with host.filesystem.open_text_file_for_writing(dump_file) as f: + f.write('channel:\npid:%s\nplat:Win32\nprod:content_shell\n' % + expected_pid) build_dir = "/mock-checkout/out/Debug" host.filesystem.maybe_make_directory(build_dir) dump_reader = DumpReaderWin(host, build_dir)
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/base.py b/third_party/blink/tools/blinkpy/web_tests/port/base.py index b798b3f8..814be9f2 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/base.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/base.py
@@ -149,7 +149,6 @@ ('mac11-arm64', 'arm64'), ('win7', 'x86'), ('win10.20h2', 'x86'), - ('win11', 'x86'), ('trusty', 'x86_64'), ('fuchsia', 'x86_64'), ) @@ -159,7 +158,7 @@ 'mac10.12', 'mac10.13', 'mac10.14', 'mac10.15', 'mac11', 'mac11-arm64' ], - 'win': ['win7', 'win10.20h2', 'win11'], + 'win': ['win7', 'win10.20h2'], 'linux': ['trusty'], 'fuchsia': ['fuchsia'], }
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/server_process_unittest.py b/third_party/blink/tools/blinkpy/web_tests/port/server_process_unittest.py index 158343a..fe4c9e19 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/server_process_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/server_process_unittest.py
@@ -138,7 +138,7 @@ port_obj.host.platform.os_name = 'win' server_process = FakeServerProcess( port_obj=port_obj, name="test", cmd=["test"]) - server_process.write("should break") + server_process.write(b"should break") self.assertTrue(server_process.has_crashed()) self.assertIsNotNone(server_process.pid()) self.assertIsNone(server_process._proc) @@ -147,7 +147,7 @@ port_obj.host.platform.os_name = 'mac' server_process = FakeServerProcess( port_obj=port_obj, name="test", cmd=["test"]) - server_process.write("should break") + server_process.write(b"should break") self.assertTrue(server_process.has_crashed()) self.assertIsNone(server_process._proc) self.assertEqual(server_process.broken_pipes, [server_process.stdin])
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/win.py b/third_party/blink/tools/blinkpy/web_tests/port/win.py index 1a0b5dd..1fcb45cd 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/win.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/win.py
@@ -51,11 +51,10 @@ class WinPort(base.Port): port_name = 'win' - SUPPORTED_VERSIONS = ('win7', 'win10.20h2', 'win11') + SUPPORTED_VERSIONS = ('win7', 'win10.20h2') FALLBACK_PATHS = {} - FALLBACK_PATHS['win11'] = ['win'] - FALLBACK_PATHS['win10.20h2'] = ['win10'] + FALLBACK_PATHS['win11'] + FALLBACK_PATHS['win10.20h2'] = ['win'] FALLBACK_PATHS['win7'] = ['win7'] + FALLBACK_PATHS['win10.20h2'] BUILD_REQUIREMENTS_URL = 'https://chromium.googlesource.com/chromium/src/+/main/docs/windows_build_instructions.md' @@ -68,11 +67,9 @@ if host.platform.os_version in ('vista', '7sp0', '7sp1'): version = 'win7' # Same for win8, win10.1909 we treat it as win10. - elif host.platform.os_version in ('8', '8.1', '10.1909', - '10.20h2'): + elif host.platform.os_version in ('8', '8.1', '10.1909', '10.20h2', + 'future'): version = 'win10.20h2' - elif host.platform.os_version in ('11', 'future'): - version = 'win11' else: version = host.platform.os_version port_name = port_name + '-' + version
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/win_unittest.py b/third_party/blink/tools/blinkpy/web_tests/port/win_unittest.py index 6def3ff..d2cb460 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/win_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/win_unittest.py
@@ -91,12 +91,9 @@ self.assert_name('win-win7', '7sp0', 'win-win7') self.assert_name('win-win7', 'vista', 'win-win7') - self.assert_name(None, 'win11', 'win-win11') - self.assert_name('win', 'win11', 'win-win11') - - self.assert_name(None, 'future', 'win-win11') - self.assert_name('win', 'future', 'win-win11') - self.assert_name('win-win11', 'future', 'win-win11') + self.assert_name(None, 'future', 'win-win10.20h2') + self.assert_name('win', 'future', 'win-win10.20h2') + self.assert_name('win-win10.20h2', 'future', 'win-win10.20h2') with self.assertRaises(AssertionError): self.assert_name(None, 'w2k', 'win-win7') @@ -110,8 +107,8 @@ self.assertTrue(port.baseline_search_path()[i].endswith(path)) def test_baseline_path(self): - self.assert_baseline_paths('win-win7', 'win7', 'win10', '/win') - self.assert_baseline_paths('win-win10.20h2', 'win10', 'win') + self.assert_baseline_paths('win-win7', 'win7', '/win') + self.assert_baseline_paths('win-win10.20h2', 'win') def test_operating_system(self): self.assertEqual('win', self.make_port().operating_system())
diff --git a/third_party/blink/tools/blinkpy/web_tests/print_web_test_times_unittest.py b/third_party/blink/tools/blinkpy/web_tests/print_web_test_times_unittest.py index 425b8b9b..f3e19b4 100644 --- a/third_party/blink/tools/blinkpy/web_tests/print_web_test_times_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/print_web_test_times_unittest.py
@@ -98,6 +98,6 @@ def test_path_to_file(self): # Tests that we can use a custom file rather than the port's default. - self.check(['/tmp/times_ms.json'], + self.check([b'/tmp/times_ms.json'], 'foo/bar.html 1\n', - files={'/tmp/times_ms.json': '{"foo":{"bar.html": 1}}'}) + files={b'/tmp/times_ms.json': b'{"foo":{"bar.html": 1}}'})
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng index aef99bd5..3019fe6e 100644 --- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng +++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -13,6 +13,7 @@ # Tests that fail in legacy but pass in NG # ====== New tests from wpt-importer added here ====== +crbug.com/626703 virtual/prerender/external/wpt/speculation-rules/prerender/opt-out.html [ Crash ] crbug.com/626703 virtual/no-forced-frame-updates/external/wpt/html/dom/render-blocking/header-inserted-preload-link.tentative.html [ Timeout ] crbug.com/626703 external/wpt/geolocation-API/getCurrentPosition_permission_allow.https.html [ Timeout ] crbug.com/626703 external/wpt/geolocation-API/enabled-by-feature-policy-attribute-redirect-on-load.https.sub.html [ Timeout ] @@ -857,6 +858,7 @@ crbug.com/591099 fast/writing-mode/flipped-blocks-inline-map-local-to-container.html [ Failure ] ### external/wpt/html/rendering +crbug.com/591099 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-baseline.html [ Failure ] crbug.com/591099 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-block-size.html [ Failure ] crbug.com/880062 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-before-legend.html [ Failure ] crbug.com/880062 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-generated-content.html [ Failure ] @@ -1382,6 +1384,7 @@ crbug.com/591099 external/wpt/appmanifest/start_url-member/start_url-member-pass-manual.html [ Failure ] ### external/wpt/css/css-flexbox/ +crbug.com/591099 external/wpt/css/css-flexbox/fieldset-baseline-alignment.html [ Failure ] crbug.com/591099 external/wpt/css/css-flexbox/percentage-size-quirks-002.html [ Failure ] crbug.com/591099 external/wpt/css/css-flexbox/abspos/position-absolute-014.html [ Failure ] crbug.com/591099 external/wpt/css/css-flexbox/abspos/position-absolute-015.html [ Failure ]
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-site-isolation-trials b/third_party/blink/web_tests/FlagExpectations/disable-site-isolation-trials index 1ff1887..9e9bb4d 100644 --- a/third_party/blink/web_tests/FlagExpectations/disable-site-isolation-trials +++ b/third_party/blink/web_tests/FlagExpectations/disable-site-isolation-trials
@@ -47,6 +47,7 @@ crbug.com/1209223 external/wpt/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-security-check-same-origin-domain.sub.html [ Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 virtual/prerender/external/wpt/speculation-rules/prerender/opt-out.html [ Crash ] crbug.com/626703 virtual/no-forced-frame-updates/external/wpt/html/dom/render-blocking/header-inserted-preload-link.tentative.html [ Timeout ] crbug.com/626703 external/wpt/geolocation-API/getCurrentPosition_permission_allow.https.html [ Timeout ] crbug.com/626703 external/wpt/geolocation-API/enabled-by-feature-policy-attribute-redirect-on-load.https.sub.html [ Timeout ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 0f2ecbba..672a0ef 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1317,7 +1317,6 @@ crbug.com/1284251 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-border-top-left-radius-001.html [ Failure ] crbug.com/1284270 [ Fuchsia ] external/wpt/css/css-ui/compute-kind-widget-no-fallback-props-001.html [ Failure ] crbug.com/1284270 [ Linux ] external/wpt/css/css-ui/compute-kind-widget-no-fallback-props-001.html [ Failure ] -crbug.com/1284270 [ Mac10.12 ] external/wpt/css/css-ui/compute-kind-widget-no-fallback-props-001.html [ Failure ] crbug.com/1284270 [ Mac10.13 ] external/wpt/css/css-ui/compute-kind-widget-no-fallback-props-001.html [ Failure ] crbug.com/1284270 [ Mac10.14 ] external/wpt/css/css-ui/compute-kind-widget-no-fallback-props-001.html [ Failure ] crbug.com/1284270 [ Mac10.15 ] external/wpt/css/css-ui/compute-kind-widget-no-fallback-props-001.html [ Failure ] @@ -1629,6 +1628,8 @@ virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/flex-container-fragmentation-003.html [ Pass ] virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/flex-container-fragmentation-004.html [ Pass ] virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/flex-container-fragmentation-007.tentative.html [ Pass ] +virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/multi-line-column-flex-fragmentation-015.html [ Pass ] +virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/multi-line-column-flex-fragmentation-016.html [ Pass ] virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-007.html [ Pass ] virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-008.html [ Pass ] virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-010.html [ Pass ] @@ -3371,6 +3372,13 @@ crbug.com/626703 [ Win ] virtual/partitioned-cookies/http/tests/inspector-protocol/network/disabled-cache-navigation.js [ Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 [ Mac10.12 ] external/wpt/css/css-ui/compute-kind-widget-no-fallback-props-001.html [ Timeout ] +crbug.com/626703 [ Mac10.12 ] virtual/fenced-frame-mparch/wpt_internal/fenced_frame/maxframes.https.html [ Timeout ] +crbug.com/626703 [ Mac10.12 ] virtual/portals/external/wpt/portals/history/history-manipulation-inside-portal-with-subframes.html [ Timeout ] +crbug.com/626703 [ Mac10.12 ] virtual/portals/wpt_internal/portals/create-many-portals.html [ Timeout ] +crbug.com/626703 [ Linux ] virtual/prerender/external/wpt/speculation-rules/prerender/opt-out.html [ Crash ] +crbug.com/626703 [ Win10.20h2 ] virtual/prerender/external/wpt/speculation-rules/prerender/opt-out.html [ Crash ] +crbug.com/626703 [ Mac11 ] virtual/prerender/external/wpt/speculation-rules/prerender/opt-out.html [ Crash Skip Timeout ] crbug.com/626703 external/wpt/css/css-grid/subgrid/auto-track-sizing-002.html [ Failure ] crbug.com/626703 [ Linux ] external/wpt/css/css-masking/clip-path/clip-path-shape-001.html [ Failure ] crbug.com/626703 [ Mac10.12 ] external/wpt/css/css-masking/clip-path/clip-path-shape-001.html [ Failure ] @@ -3410,7 +3418,6 @@ crbug.com/626703 [ Win ] virtual/prerender/external/wpt/speculation-rules/prerender/media-autoplay.html [ Skip Timeout ] crbug.com/626703 [ Mac10.12 ] external/wpt/html/browsers/browsing-the-web/back-forward-cache/eligibility/broadcast-channel.html [ Timeout ] crbug.com/626703 [ Mac10.12 ] external/wpt/html/cross-origin-embedder-policy/cross-origin-isolated-permission.https.html [ Timeout ] -crbug.com/626703 [ Mac11 ] external/wpt/scroll-to-text-fragment/force-load-at-top.html [ Timeout ] crbug.com/626703 external/wpt/geolocation-API/idlharness.https.window.html [ Skip Timeout ] crbug.com/626703 external/wpt/geolocation-API/enabled-by-feature-policy-attribute-redirect-on-load.https.sub.html [ Timeout ] crbug.com/626703 external/wpt/geolocation-API/enabled-by-feature-policy-attribute.https.sub.html [ Timeout ] @@ -3447,7 +3454,6 @@ crbug.com/626703 [ Mac10.12 ] virtual/portals/external/wpt/portals/portal-activate-data.html [ Timeout ] crbug.com/626703 [ Mac10.12 ] external/wpt/mediacapture-streams/MediaDevices-enumerateDevices-per-origin-ids.sub.https.html [ Timeout ] crbug.com/626703 [ Mac10.12 ] virtual/fenced-frame-mparch/external/wpt/html/cross-origin-embedder-policy/anonymous-iframe/web-lock.tentative.https.window.html [ Timeout ] -crbug.com/626703 [ Mac11-arm64 ] external/wpt/scroll-to-text-fragment/force-load-at-top.html [ Timeout ] crbug.com/626703 external/wpt/css/css-content/quotes-030.html [ Failure ] crbug.com/626703 [ Mac11-arm64 ] external/wpt/fetch/private-network-access/fetch.https.window.html?include=from-public [ Timeout ] crbug.com/626703 [ Mac11-arm64 ] external/wpt/fetch/private-network-access/service-worker.https.window.html [ Timeout ] @@ -4343,6 +4349,8 @@ crbug.com/660611 external/wpt/css/css-break/flexbox/flex-container-fragmentation-003.html [ Failure ] crbug.com/660611 external/wpt/css/css-break/flexbox/flex-container-fragmentation-004.html [ Failure ] crbug.com/660611 external/wpt/css/css-break/flexbox/flex-container-fragmentation-007.tentative.html [ Failure ] +crbug.com/660611 external/wpt/css/css-break/flexbox/multi-line-column-flex-fragmentation-015.html [ Failure ] +crbug.com/660611 external/wpt/css/css-break/flexbox/multi-line-column-flex-fragmentation-016.html [ Failure ] crbug.com/660611 external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-007.html [ Failure ] crbug.com/660611 external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-008.html [ Failure ] crbug.com/660611 external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-010.html [ Failure ] @@ -5402,7 +5410,6 @@ # Sheriff 2019-05-01 crbug.com/958347 [ Linux ] external/wpt/editing/run/removeformat.html [ Crash Pass ] -crbug.com/958426 [ Mac10.13 ] virtual/text-antialias/line-break-ascii.html [ Pass Timeout ] # This test might need to be removed. crbug.com/954349 fast/forms/autofocus-in-sandbox-with-allow-scripts.html [ Timeout ] @@ -7651,10 +7658,6 @@ # Sheriff 2022-03-01 crbug.com/1302043 [ Linux ] virtual/plz-dedicated-worker/external/wpt/resource-timing/object-not-found-after-cross-origin-redirect.html [ Pass Timeout ] -# Temporarily disable to land related CL in DevTools -crbug.com/1288883 http/tests/devtools/elements/styles-3/spectrum.js [ Skip ] -crbug.com/1288883 http/tests/devtools/elements/styles-4/styles-invalid-color-values.js [ Skip ] - # Sheriff 2022-03-03 crbug.com/1302571 virtual/threaded/http/tests/devtools/isolated-code-cache/cross-origin-test.js [ Skip ] @@ -7670,4 +7673,11 @@ # Sheriff 2022-03-10 crbug.com/1304956 storage/indexeddb/dont-wedge.html [ Failure Pass ] -crbug.com/1305023 [ Mac10.12 ] virtual/partitioned-cookies-first-party-sets/http/tests/inspector-protocol/network/cross-origin-isolation/coep-load-error-reporting-worker.js [ Failure Pass ] + +# Sheriff 2022-03-15 +crbug.com/626703 external/wpt/scroll-to-text-fragment/force-load-at-top.html [ Pass Timeout ] +crbug.com/1269534 fast/spatial-navigation/snav-zero-margin-content.html [ Failure Pass ] +crbug.com/1295980 virtual/fenced-frame-mparch/wpt_internal/fenced_frame/user-activation.https.html [ Failure Pass Timeout ] +crbug.com/1280537 virtual/first-party-sets/http/tests/inspector-protocol/network/blocked-cookie-same-site-lax.js [ Failure Pass Timeout ] +crbug.com/1277877 virtual/partitioned-cookies-first-party-sets/http/tests/inspector-protocol/network/blocked-cookie-same-site-strict.js [ Failure Pass Timeout ] +crbug.com/1298633 http/tests/inspector-protocol/network/cross-origin-isolation/coep-load-error-reporting-worker.js [ Pass Timeout ]
diff --git a/third_party/blink/web_tests/external/Version b/third_party/blink/web_tests/external/Version index 14ecd50..e82251c 100644 --- a/third_party/blink/web_tests/external/Version +++ b/third_party/blink/web_tests/external/Version
@@ -1 +1 @@ -Version: f0d3621b1a7981b26229568c093b2a2f508eef90 +Version: e0cf318a60e583451b0cc045099749b5e2d8802e
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index f1cc6fd..3fe115b 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -376,6 +376,13 @@ {} ] ], + "break-after-in-parallel-flow-crash.html": [ + "b59563295028f487543d79524ea81543b8a78046", + [ + null, + {} + ] + ], "break-before-with-no-fragmentation-crash.html": [ "fb80ec45bceec093481fa54513c606c5952628b1", [ @@ -214086,6 +214093,86 @@ ] ] }, + "context-attributes": { + "clearRect_alpha_false.html": [ + "a328fbf97a4f3e2d93bf120098b0a7d76b83ffc5", + [ + null, + [ + [ + "/html/canvas/element/manual/context-attributes/clearRect_alpha_false-ref.html", + "==" + ] + ], + {} + ] + ], + "drawImage_alpha_false.html": [ + "64f38bceb1e7880aec6ad5f797063f39c2cb5e9a", + [ + null, + [ + [ + "/html/canvas/element/manual/context-attributes/drawImage_alpha_false-ref.html", + "==" + ] + ], + {} + ] + ], + "fillRect_alpha_false.html": [ + "143756eb0c7aa45e7002cc10ad90caa32876f1f9", + [ + null, + [ + [ + "/html/canvas/element/manual/context-attributes/fillRect_alpha_false-ref.html", + "==" + ] + ], + {} + ] + ], + "fill_alpha_false.html": [ + "7872a7938039f7c576a47e5e06c1655aa68b5874", + [ + null, + [ + [ + "/html/canvas/element/manual/context-attributes/fill_alpha_false-ref.html", + "==" + ] + ], + {} + ] + ], + "initial_color_alpha_false.html": [ + "9e86e5ce2c55afbed445843a3f41c79d3247c041", + [ + null, + [ + [ + "/html/canvas/element/manual/context-attributes/initial_color_alpha_false-ref.html", + "==" + ] + ], + {} + ] + ], + "reset_color_alpha_false.html": [ + "191975e0f48e68a3cd9c91ee25a0f3aa4e10ea77", + [ + null, + [ + [ + "/html/canvas/element/manual/context-attributes/reset_color_alpha_false-ref.html", + "==" + ] + ], + {} + ] + ] + }, "drawing-images-to-the-canvas": { "drawimage_canvas_self.html": [ "83cf53583ce12716fec3bef5ce483efc4506bfbb", @@ -231904,146 +231991,6 @@ [] ] }, - "app-history": { - "META.yml": [ - "de4f6c9a335bd4b7d5e99d14d37b904fe5d54182", - [] - ], - "OWNERS": [ - "cc6a94b332a04fdf400165265f41194abaf67d3e", - [] - ], - "app-history-entry": { - "resources": { - "is_uuid.js": [ - "3b855c01b075608e27766173a2783092493bbed6", - [] - ], - "key-navigate-back-cross-document-helper.html": [ - "f61f9a829820411a8323fe5b3f49cab4cd1d4e32", - [] - ], - "no-referrer-meta.html": [ - "bd5ec391cce892199b0d448b516f6dd087c99665", - [] - ], - "no-referrer.html": [ - "c8b7661f42212985888d1dfdf1d8729f89c4fc35", - [] - ], - "no-referrer.html.headers": [ - "7ffbf17d6be5a59e5b3636adc0eb14f3e2e528c2", - [] - ], - "opaque-origin-page.html": [ - "5e8a71981c5f6ce101e8c3f131373d77cf17717a", - [] - ], - "post-entries-length-to-top.html": [ - "348a8984fe10199b12839931d4a1299c5272dd08", - [] - ], - "post-key-to-top.html": [ - "023141f76a3a06363fd69dd46788679c61edde3c", - [] - ] - } - }, - "focus-reset": { - "resources": { - "helpers.mjs": [ - "e3012a0b12e618615ed90ab77528be2e8de41974", - [] - ] - } - }, - "navigate": { - "reload-service-worker-fetch-event-expected.txt": [ - "cf4b285328a985e8413570fcc80e16d4501b3d09", - [] - ], - "resources": { - "fetch-event-test-worker.js": [ - "98b7dd0fb58b4142f90eca341356eb0efbd09d2f", - [] - ], - "page-with-base-url-common.html": [ - "8d9fedcc2b40d2eaeff55727ffa476a6e7c0e479", - [] - ], - "service-worker-page.html": [ - "a10ff35dce7768c6e7b6f68647207a8fa35c2a6d", - [] - ] - }, - "return-value": { - "resources": { - "back-forward-opaque-origin-page.html": [ - "6cdf0a8b9866bdbf4452bacb79eb6f04aafe2b62", - [] - ], - "helpers.js": [ - "bf711b18ade2c881fbfa40fc8e44ddf456fa37d2", - [] - ], - "navigate-opaque-origin-page.html": [ - "380258769d8a45613b8f9a3aab3b3a1c26525faf", - [] - ] - } - }, - "state": { - "updateCurrent": { - "resources": { - "opaque-origin-page.html": [ - "d9c273a2171ab386459bff8e35091b1d1e33fee4", - [] - ] - } - } - } - }, - "navigate-event": { - "cross-window": { - "resources": { - "cross-origin-iframe-helper.html": [ - "48a5e1d63d9d2ed0f5b70ad204ec9c247b927005", - [] - ], - "document-domain-setter.sub.html": [ - "abe32ad8fbee196bfc6d49865750eaf827e8edc0", - [] - ] - } - }, - "resources": { - "meta-refresh.html": [ - "fd453e663f94e43e2d3afbbd87b902ed657b16b9", - [] - ], - "navigatesuccess-cross-document-helper.html": [ - "c073184b9b343e4db8bb15e4f0a648e5e224faac", - [] - ] - } - }, - "ordering-and-transition": { - "README.md": [ - "ec65b9ddbd1aebd0c0ae419b9cadd8902007d714", - [] - ], - "resources": { - "helpers.mjs": [ - "1cbf6e7460dd359ab1b20c2eb23bb047425f5699", - [] - ], - "notify-top-early.html": [ - "0dd796f609c0659bd489e10cb02ac4816a88960b", - [] - ] - } - } - }, "appmanifest": { "META.yml": [ "bef14c3c795aa5a8befd4d95aeb8573f4af07ad7", @@ -289440,7 +289387,7 @@ "overlapping-navigations-and-traversals": { "tentative": { "README.md": [ - "02d2e94a0dff2f28425b35a109a3fd9834a86bb9", + "cdd7975c81ad0ee468b46970aaac2a57dc683337", [] ], "cross-document-traversal-same-document-nav-expected.txt": [ @@ -291702,6 +291649,32 @@ [] ] }, + "context-attributes": { + "clearRect_alpha_false-ref.html": [ + "eccfc4e2ccadd6344d6593d41fa7abe30769c792", + [] + ], + "drawImage_alpha_false-ref.html": [ + "2c9e5620b2ef3e8bab6342e4ac062b446855d96f", + [] + ], + "fillRect_alpha_false-ref.html": [ + "eccfc4e2ccadd6344d6593d41fa7abe30769c792", + [] + ], + "fill_alpha_false-ref.html": [ + "03265a656eb6f4f06e02853cf0bed0d19223137c", + [] + ], + "initial_color_alpha_false-ref.html": [ + "b67513c464865f82621ba028b41098f08401b8e9", + [] + ], + "reset_color_alpha_false-ref.html": [ + "d663131148a2c062c79ad98c1060daa32ce82ca0", + [] + ] + }, "drawing-images-to-the-canvas": { "drawimage_canvas_self_ref.html": [ "9f297cacdcd81bef7093f79ebed6992110dab4d7", @@ -307111,7 +307084,7 @@ ] }, "lint.ignore": [ - "d273dcf68418a3b8ad5bf7dac07f25dbdab7f043", + "bc320dcd71e42da152519358865499226919fb4a", [] ], "loading": { @@ -309506,6 +309479,148 @@ ] } }, + "navigation-api": { + "META.yml": [ + "de4f6c9a335bd4b7d5e99d14d37b904fe5d54182", + [] + ], + "OWNERS": [ + "cc6a94b332a04fdf400165265f41194abaf67d3e", + [] + ], + "README.md": [ + "068ae5b7114745e50c7c8a86fec8ef684ee02f61", + [] + ], + "focus-reset": { + "resources": { + "helpers.mjs": [ + "e7e9a52009dd4c5cba642d2165fa451208304e8a", + [] + ] + } + }, + "navigate-event": { + "cross-window": { + "resources": { + "cross-origin-iframe-helper.html": [ + "96e8a0c1e65432f661378037dfe977e8c4d45e0b", + [] + ], + "document-domain-setter.sub.html": [ + "abe32ad8fbee196bfc6d49865750eaf827e8edc0", + [] + ] + } + }, + "resources": { + "meta-refresh.html": [ + "fd453e663f94e43e2d3afbbd87b902ed657b16b9", + [] + ], + "navigatesuccess-cross-document-helper.html": [ + "aabc5015a963f65d1de8e6e9f8c2742639958dac", + [] + ] + } + }, + "navigation-history-entry": { + "resources": { + "is_uuid.js": [ + "3b855c01b075608e27766173a2783092493bbed6", + [] + ], + "key-navigate-back-cross-document-helper.html": [ + "79f3c3da0ae9076b8dccfefc2d2f626e86c1a64f", + [] + ], + "no-referrer-meta.html": [ + "bd5ec391cce892199b0d448b516f6dd087c99665", + [] + ], + "no-referrer.html": [ + "c8b7661f42212985888d1dfdf1d8729f89c4fc35", + [] + ], + "no-referrer.html.headers": [ + "7ffbf17d6be5a59e5b3636adc0eb14f3e2e528c2", + [] + ], + "opaque-origin-page.html": [ + "98e2c1b3175722ce87bc7694bc1915ceadc52920", + [] + ], + "post-entries-length-to-top.html": [ + "c8fe005d8ef0908490b66ca7417222bafc02859a", + [] + ], + "post-key-to-top.html": [ + "285f345dc1fc5ccbfb75b6c513f2b5184d23d9ea", + [] + ] + } + }, + "navigation-methods": { + "reload-service-worker-fetch-event-expected.txt": [ + "cf4b285328a985e8413570fcc80e16d4501b3d09", + [] + ], + "resources": { + "fetch-event-test-worker.js": [ + "98b7dd0fb58b4142f90eca341356eb0efbd09d2f", + [] + ], + "page-with-base-url-common.html": [ + "8d9fedcc2b40d2eaeff55727ffa476a6e7c0e479", + [] + ], + "service-worker-page.html": [ + "a10ff35dce7768c6e7b6f68647207a8fa35c2a6d", + [] + ] + }, + "return-value": { + "resources": { + "back-forward-opaque-origin-page.html": [ + "ec633639524aaa04917eb38505e47a59d9686e24", + [] + ], + "helpers.js": [ + "bf711b18ade2c881fbfa40fc8e44ddf456fa37d2", + [] + ], + "navigate-opaque-origin-page.html": [ + "831eefdb6123a19700badfbbb08c64fc953e1b6f", + [] + ] + } + } + }, + "ordering-and-transition": { + "README.md": [ + "653dd2198c3a23d4d6d949a9262bb48b4e630dd4", + [] + ], + "resources": { + "helpers.mjs": [ + "b5a1e6b03186bfcc063a0a49ec46575d03bae969", + [] + ], + "notify-top-early.html": [ + "0dd796f609c0659bd489e10cb02ac4816a88960b", + [] + ] + } + }, + "updateCurrentEntry-method": { + "resources": { + "opaque-origin-page.html": [ + "59931458a6b8632ae7ce17286d1ebca80b88235a", + [] + ] + } + } + }, "navigation-timing": { "DIR_METADATA": [ "c907af0b21f16fa5683875467904fd498879089c", @@ -317954,7 +318069,11 @@ [] ], "exec.html": [ - "757dba1688b982b44bbfe1eac22cd3f6d0f9937f", + "80e0c5999e7f06fb1899984f247010f8cba0e5c9", + [] + ], + "exec.py": [ + "835a3f07aafa9664f763c5ebd9f10209dc8579d9", [] ], "iframe-added-post-activation.html": [ @@ -317973,6 +318092,10 @@ "03e36f06c134e1ee0ced6c703d1b8e20f1c7511b", [] ], + "prerender-response-code.html": [ + "c3a680bba841294f7204d22897cca5cfcc03d4f7", + [] + ], "prerender-state.html": [ "914db2a9ed900ece42982c12913576086f7db928", [] @@ -317994,7 +318117,7 @@ [] ], "utils.js": [ - "bbb9448190c5e1978eeebe42c008dcfc075fd3d0", + "6952c3b9a327aac0c20d4de68dba9857761d35e2", [] ], "visibility-state-check.html": [ @@ -341865,2086 +341988,6 @@ ] ] }, - "app-history": { - "app-history-entry": { - "after-detach.html": [ - "07591f96ae51c4095833ccec2158c68e88356b4e", - [ - null, - {} - ] - ], - "current-basic.html": [ - "102fbbb270d7e1379cb7c4d5309e87e3df2adcfa", - [ - null, - {} - ] - ], - "entries-across-origins.html": [ - "b6e8e9ee7340ea07137d7f069ccc087a70e86777", - [ - null, - {} - ] - ], - "entries-after-bfcache-in-iframe.html": [ - "5644d12a34090960f35d2174966c1036fb77ba9a", - [ - null, - {} - ] - ], - "entries-after-bfcache.html": [ - "3cfe0393ae76a4f834c630a220e4c609cdfa2865", - [ - null, - {} - ] - ], - "entries-after-blank-navigation.html": [ - "60068561d14cfd309a0d72c59c558752963edb27", - [ - null, - {} - ] - ], - "entries-after-blob-navigation.html": [ - "c1ce46d1fbd31cbcaa63d1f35b790ac46e5ea4a4", - [ - null, - {} - ] - ], - "entries-after-cross-document-forward-pruning.html": [ - "4888a5be738558bf444ae0730a17035e6ff3b9aa", - [ - null, - {} - ] - ], - "entries-after-javascript-url-navigation.html": [ - "2ed1d81fe94e9e8ad8a1b5b825dcc984d82c2124", - [ - null, - {} - ] - ], - "entries-after-navigations-in-multiple-windows.html": [ - "55cb58ea0022d60fcd6f4295542d5f5bcf84d59b", - [ - null, - {} - ] - ], - "entries-after-srcdoc-navigation.html": [ - "cfb1337cabfb624bb299b6bbcec769e3b0318b28", - [ - null, - {} - ] - ], - "entries-array-equality.html": [ - "e6eb99863d037f77f5f465077f486639a3f8cba1", - [ - null, - {} - ] - ], - "entries-in-new-javascript-url-iframe.html": [ - "de7d68173cc1fe85eeccf01dce5f2217f613e7dc", - [ - null, - {} - ] - ], - "entries-in-new-srcdoc-iframe.html": [ - "7ef6b4d511fce4176782d35c29d9004fd4d4ada2", - [ - null, - {} - ] - ], - "entries-when-inactive.html": [ - "a7073778fb5aebd97a94c91d9913c44cb60f55fc", - [ - null, - {} - ] - ], - "entry-after-detach.html": [ - "dc31f1a695b013fd8e135d12814ce3bc5e8348e3", - [ - null, - {} - ] - ], - "index-not-in-entries.html": [ - "394dfa9763685e90dd1e6766a1429f0739846846", - [ - null, - {} - ] - ], - "key-id-back-cross-document.html": [ - "9fbb7334cbb0a37c71f29d0ab8e8f5098d33fed7", - [ - null, - {} - ] - ], - "key-id-back-same-document.html": [ - "94319c3592e08a0e6a2cbf855ad8ddc232c6d1b3", - [ - null, - {} - ] - ], - "key-id-location-reload-transitionWhile.html": [ - "b26e279d33b6a86b6ec5e09dd1cf6805df4889b7", - [ - null, - {} - ] - ], - "key-id-location-reload.html": [ - "660427011d43eb48bcdfff0235f42c3f2dce19e1", - [ - null, - {} - ] - ], - "key-id-location-replace-cross-origin.html": [ - "b49c601dc26d29b921f45d20ffcb20c30bc2dccb", - [ - null, - {} - ] - ], - "key-id-location-replace.html": [ - "9d245b1e837de7f920a16377bfb5392aa41396e7", - [ - null, - {} - ] - ], - "no-referrer-dynamic-url-censored.html": [ - "91484daa00eeda75a279fb4aed1b2057ef0d9927", - [ - null, - {} - ] - ], - "no-referrer-from-meta-url-censored.html": [ - "0f23f3b539b064178df159cafd53f6e1584cae35", - [ - null, - {} - ] - ], - "no-referrer-url-censored.html": [ - "2db425368f6a0436b0e713d8bed96f7a98e98967", - [ - null, - {} - ] - ], - "opaque-origin-data-url.html": [ - "a1e765dd1bb75f2ee20a7efae64f2b7cbd464e40", - [ - null, - {} - ] - ], - "opaque-origin.html": [ - "898ca27e4fab1d34bfe9c148ff53880a8a35d8cd", - [ - null, - {} - ] - ], - "sameDocument-after-fragment-navigate.html": [ - "732b10964efe99898b4628aa892c3d6ee9950be7", - [ - null, - {} - ] - ], - "sameDocument-after-navigate-restore.html": [ - "0c8abb4eb0b0e94c32762251484049f01dd70261", - [ - null, - {} - ] - ], - "sameDocument-after-navigate.html": [ - "1e984b336a671c66caa771190ba064d8ceee9001", - [ - null, - {} - ] - ], - "state-after-navigate-restore.html": [ - "aad065034f06a840a8581b154329a13def9480f9", - [ - null, - {} - ] - ] - }, - "currentchange-event": { - "currentchange-anchor-href.html": [ - "2a93abf9937942200d4c2d28c8051456de438003", - [ - null, - {} - ] - ], - "currentchange-app-history-back-forward-cross-doc.html": [ - "7782d11b0c31a578637f9b7c17c00f95fe6f3cec", - [ - null, - {} - ] - ], - "currentchange-app-history-back-forward-same-doc.html": [ - "8cfe2dca1ffa4914da8503bf6bfda5b6dca087df", - [ - null, - {} - ] - ], - "currentchange-app-history-navigate-cross-doc.html": [ - "d6a657a1b1174ce0f3ced3bba8fd617620fefc3d", - [ - null, - {} - ] - ], - "currentchange-app-history-navigate-preventDefault.html": [ - "82f10006832e16522844cdb7fa0bcf2e6a3a8578", - [ - null, - {} - ] - ], - "currentchange-app-history-navigate-replace-cross-doc.html": [ - "3d8ceb746b80da1564a539e080ae965aa30d03b9", - [ - null, - {} - ] - ], - "currentchange-app-history-navigate-replace-same-doc.html": [ - "fa7006b4ebb8b09017806b71073e38147e106b87", - [ - null, - {} - ] - ], - "currentchange-app-history-navigate-replace-transitionWhile.html": [ - "86079e777cb9059b13e6763ea31877475142d368", - [ - null, - {} - ] - ], - "currentchange-app-history-navigate-same-doc.html": [ - "d74048a0121fbc5d226c6cc35d0562c5d4c5eae8", - [ - null, - {} - ] - ], - "currentchange-app-history-navigate-transitionWhile.html": [ - "d6a39d204ed72c6d578556798e1b9527f58ba219", - [ - null, - {} - ] - ], - "currentchange-app-history-reload-cross-doc.html": [ - "ae142fb5d3bc4d600037077cf5bbbbcece64b6f2", - [ - null, - {} - ] - ], - "currentchange-app-history-reload-transitionWhile.html": [ - "d1f022f584218fec9fb6fb584175adabd7a1a286", - [ - null, - {} - ] - ], - "currentchange-app-history-updateCurrent.html": [ - "9e3a3ec387a2ce682e433dc39c6d2e94bfb3f27e", - [ - null, - {} - ] - ], - "currentchange-history-back-same-doc.html": [ - "a90ee1eb5ddf86ef06393eef32f651a575088c5a", - [ - null, - {} - ] - ], - "currentchange-history-pushState.html": [ - "e5468eafc3938f71c907410ed33fad1a184141ce", - [ - null, - {} - ] - ], - "currentchange-history-replaceState.html": [ - "5a99561ebd2f929e082cfd6b7938898f03243747", - [ - null, - {} - ] - ], - "currentchange-location-api.html": [ - "8cf52ca6d288387036a5d93a007f33c1c79deef3", - [ - null, - {} - ] - ], - "currentchange-navigate-from-initial-about-blank-same-doc-popup.html": [ - "8473e0b272db092c9308f65b5aa11f8cbc3c5238", - [ - null, - {} - ] - ], - "currentchange-navigate-from-initial-about-blank-same-doc.html": [ - "e595868954a64e490fb2cc851afb5676fc5c6366", - [ - null, - {} - ] - ], - "currentchange-navigate-from-initial-about-blank.html": [ - "415fb0c6e1c104ffbb20046b79d9111791fec284", - [ - null, - {} - ] - ], - "currentchange-properties.html": [ - "a5417fa312c1b43db84b90c7f67fa1ab88be9333", - [ - null, - {} - ] - ], - "event-constructor.html": [ - "6c489363567fd61d210ad92e8336605ea02f1704", - [ - null, - {} - ] - ] - }, - "focus-reset": { - "autofocus.html": [ - "57fdf865ab40d7c6a6ceba5470f5542ed713a735", - [ - null, - {} - ] - ], - "basic.html": [ - "fb57cf864482a1b9297c432da8687fcfcfe7edb2", - [ - null, - {} - ] - ], - "multiple-transitionWhile.html": [ - "d38df573e59536b48cc9618ad20722a5d3c22978", - [ - null, - {} - ] - ] - }, - "navigate": { - "back-forward-multiple-frames.html": [ - "80a8fb65a05fb622988e8f64ac78f16c9172869d", - [ - null, - {} - ] - ], - "disambigaute-back.html": [ - "7a4a37db4216fbbe928cd25d422aca8bf2fd3967", - [ - null, - {} - ] - ], - "disambigaute-forward.html": [ - "b6508ed3406b6d5309f382e427fbc46cc3522427", - [ - null, - {} - ] - ], - "disambigaute-goto-back-multiple.html": [ - "c39da7914f12a8a42a8471861cbcb32b6163011b", - [ - null, - {} - ] - ], - "disambigaute-goto-forward-multiple.html": [ - "08c00582d8fd3459114518ba9b6447b1a8e269a7", - [ - null, - {} - ] - ], - "forward-to-pruned-entry.html": [ - "0e33360c8674f968652b6fee70c873fa32913410", - [ - null, - {} - ] - ], - "goTo-after-adding-iframe.html": [ - "9921bcf447fb6e8c3b3b95f8d7c09c5639078de6", - [ - null, - {} - ] - ], - "goTo-after-data-url.html": [ - "ba2b56d1912abd59f8c7db1f900c7d2af13f06a0", - [ - null, - {} - ] - ], - "goTo-cross-document.html": [ - "0a7bbbe1bf97ac0bbdd3c3b314857556cc8d8bda", - [ - null, - {} - ] - ], - "goTo-detach-between-navigate-and-navigatesuccess.html": [ - "2849ee1e9a21d7889ceab67a3373b23e193fe1a9", - [ - null, - {} - ] - ], - "goTo-multiple-steps.html": [ - "562a775d2298f6e87076ef00b0a83f7ad2fc2ae3", - [ - null, - {} - ] - ], - "goTo-same-document.html": [ - "a9af0c2ae22904858f76fa6f15573c5c61d99f39", - [ - null, - {} - ] - ], - "goTo-with-cross-origin-in-history.html": [ - "3da29550b3e8a33eaf79813dd0bac7c203de04db", - [ - null, - {} - ] - ], - "navigate-base-url.html": [ - "b11a71a9312785fc0b151a1c3e294a18f4cfabf4", - [ - null, - {} - ] - ], - "navigate-from-initial-about-blank-src.html": [ - "83cd77678a544f7356a283911aa17931a1e40350", - [ - null, - {} - ] - ], - "navigate-from-initial-about-blank.html": [ - "fd163ddf8ceb26ae705dc0be254e4921fedf6880", - [ - null, - {} - ] - ], - "navigate-history-state-replace.html": [ - "b4b9559fb56cb782941210eefbaef379afdb7e5a", - [ - null, - {} - ] - ], - "navigate-history-state.html": [ - "8853c0616e3949119edccbb71d5ac32061a023d1", - [ - null, - {} - ] - ], - "navigate-info-and-state.html": [ - "8890c9b9ca4c7f2673e311458a26cb5b717f2e9a", - [ - null, - {} - ] - ], - "navigate-relative-url.html": [ - "b426da595088bc1016faf7ae3ecf5088092bac48", - [ - null, - {} - ] - ], - "navigate-replace-cross-document.html": [ - "0b20dc850863a6b81ccca8205f6e7b9f353e185f", - [ - null, - {} - ] - ], - "navigate-replace-same-document.html": [ - "dea17f43ff61141fd8cd6f17b0189b8b00389643", - [ - null, - {} - ] - ], - "navigate-same-document.html": [ - "bad420272c40b7e0ccf4df73e0c4cea38615debd", - [ - null, - {} - ] - ], - "navigate-state-repeated-await.html": [ - "d81dd054f836ded2f73237bdfb4bdd2e626dfaf9", - [ - null, - {} - ] - ], - "navigate-state-repeated.html": [ - "ed655d2086dfdd1d1c8b4517c88b0f3d1b8800db", - [ - null, - {} - ] - ], - "navigate-transitionWhile-history-state.html": [ - "56d9ea11791a89836304dfc30cf68e7f53fe69d5", - [ - null, - {} - ] - ], - "reload-base-url.html": [ - "35b29b9d2fb032f97f7bd8ba607f928aec60571e", - [ - null, - {} - ] - ], - "reload-info.html": [ - "412655f6de12df4b9fbc56e286e00a39fb90062f", - [ - null, - {} - ] - ], - "reload-navigation-timing.html": [ - "a24e33ff11a7f103d4462b8520822aef83d9282f", - [ - null, - {} - ] - ], - "reload-no-args.html": [ - "e4f7bd628b21406a5035ded3523bc7a32e9d5f13", - [ - null, - {} - ] - ], - "reload-service-worker-fetch-event.html": [ - "4d078e45f6b8d4848afcaf54a71007c0b649f54b", - [ - null, - {} - ] - ], - "reload-state-and-info.html": [ - "0811f3d9cde2fc0dab15b481d96e5b5bd04896b8", - [ - null, - {} - ] - ], - "reload-state-undefined.html": [ - "47b336ba9ee615974288974449c6ea0b48a07bd4", - [ - null, - {} - ] - ], - "return-value": { - "back-already-detached.html": [ - "dd665e15f66278a476cbd7083e5ea16232203b93", - [ - null, - {} - ] - ], - "back-beforeunload.html": [ - "424d353803e9984aa860f6806ea18c5947f16727", - [ - null, - {} - ] - ], - "back-forward-initial-about-blank.html": [ - "902090e3a38c673c1bf5c8db825bf5706478ea6a", - [ - null, - {} - ] - ], - "back-forward-opaque-origin.html": [ - "59849e961d76a0151959836870fb7eda47ce8867", - [ - null, - {} - ] - ], - "back-forward-out-of-bounds.html": [ - "bef0d7e71790fb25c63e87932d06eb249645bde2", - [ - null, - {} - ] - ], - "back-transitionWhile-rejected.html": [ - "b617f0bbad17f9b49afefb0868d46fe720b66b1c", - [ - null, - {} - ] - ], - "back-transitionWhile.html": [ - "a6680f6ba6f82404923cc0745ad17be1fc6a513a", - [ - null, - {} - ] - ], - "back.html": [ - "1be1d421724b6f1ed168776b9437bd92d9ee0b52", - [ - null, - {} - ] - ], - "forward-already-detached.html": [ - "c3b7de84935e64722f119293d1accc30702f35f8", - [ - null, - {} - ] - ], - "forward-beforeunload.html": [ - "c97b796e2754ea3077ce957fa1c8abb2f2faefa8", - [ - null, - {} - ] - ], - "forward-transitionWhile-rejected.html": [ - "76cbfe44fcce3cc1c4177084b1dcd75190b5a388", - [ - null, - {} - ] - ], - "forward-transitionWhile.html": [ - "86bf5470953b1b164cc824772ec6082910efee1b", - [ - null, - {} - ] - ], - "forward.html": [ - "15d454c146152aa83d13bbef7a8467724ab7a57f", - [ - null, - {} - ] - ], - "goTo-already-detached.html": [ - "9752cbb3aebf906abf26c4889259c74dac5fea8c", - [ - null, - {} - ] - ], - "goTo-beforeunload.html": [ - "2a63ab161137da4e655cf4212664ffd0783e0a95", - [ - null, - {} - ] - ], - "goTo-cross-document-preventDefault.html": [ - "9c2301728deef44e0e5e8e76d1a419c408ff1648", - [ - null, - {} - ] - ], - "goTo-current.html": [ - "0601dbefa6b8eee7e7822329d10904f351109b7a", - [ - null, - {} - ] - ], - "goTo-detach-cross-document.html": [ - "95b2ec8f40d2580fedc60e618134a5faa7656434", - [ - null, - {} - ] - ], - "goTo-detach-same-document.html": [ - "441f9371d036db8f50cab4834a58a86c0614a6d8", - [ - null, - {} - ] - ], - "goTo-invalid-key.html": [ - "ee4d66f9aed32a1706cecb5c2090f54b75474149", - [ - null, - {} - ] - ], - "goTo-repeated.html": [ - "80d43d6477741fbb52cb897a665ada5d6aca2766", - [ - null, - {} - ] - ], - "goTo-transitionWhile-rejected.html": [ - "9e306043470a43e25d10056b33f386f108f7dd23", - [ - null, - {} - ] - ], - "goTo-transitionWhile.html": [ - "4b98a27b3da8d783a84cdf860e10cb1f4a6f49bf", - [ - null, - {} - ] - ], - "goTo.html": [ - "81a3ef2df709facec59698e727e1c76fd73f0fb2", - [ - null, - {} - ] - ], - "navigate-already-detached.html": [ - "cc077e2e3fe2df73a6adf3e9ee1360e7a24d72c0", - [ - null, - {} - ] - ], - "navigate-beforeunload.html": [ - "2c9af273af7858ec0752d4816ec6efd8d27205ec", - [ - null, - {} - ] - ], - "navigate-cross-document.html": [ - "0735a23e713d814cc9695f5fa546a7188d99d934", - [ - null, - {} - ] - ], - "navigate-detach.html": [ - "84b1d2c0de620411943bc0a559200d973ebceb59", - [ - null, - {} - ] - ], - "navigate-file-url.html": [ - "1dc383509adc3260d9e55ce78ceeae3bfafcbb3b", - [ - null, - {} - ] - ], - "navigate-initial-about-blank-cross-document.html": [ - "d70890aedf23aa6514ae31dd2f64d5c13b88950a", - [ - null, - {} - ] - ], - "navigate-initial-about-blank.html": [ - "6c976039f6158c59f5cb8aecb134f9971c73372e", - [ - null, - {} - ] - ], - "navigate-interrupted-within-onnavigate.html": [ - "cfd3e13cef38457aa671d4d0f4f008f1633cdee0", - [ - null, - {} - ] - ], - "navigate-interrupted.html": [ - "0d419c0fd1498c557f6b5889000701830a538dc9", - [ - null, - {} - ] - ], - "navigate-invalid-url.html": [ - "a9d47d05ce3cd72d610d57484cba81cb32652ec4", - [ - null, - {} - ] - ], - "navigate-opaque-origin.html": [ - "51500eb8d83c121241bbcf467e010fbda43daa55", - [ - null, - {} - ] - ], - "navigate-preventDefault.html": [ - "e27bde78610f4d9a99b6245a43fc3fe69cf8c71c", - [ - null, - {} - ] - ], - "navigate-rejection-order-beforeunload-unserializablestate.html": [ - "b7005709aa6d56a8de05011f6ab3ae9f8ad32e96", - [ - null, - {} - ] - ], - "navigate-rejection-order-detached-unserializablestate.html": [ - "69fe45278522507e8f597be26f0cf1aaaab40eb6", - [ - null, - {} - ] - ], - "navigate-rejection-order-invalidurl-beforeunload.html": [ - "5346ecd02f9c5e1fbbb7f7dda3f055fc1c4e6f48", - [ - null, - {} - ] - ], - "navigate-rejection-order-invalidurl-detached.html": [ - "bd7981d8bc147487c76027d36a497e0d2ec9df39", - [ - null, - {} - ] - ], - "navigate-rejection-order-invalidurl-unload.html": [ - "8cf6c0179155fe596ce29c24fe0157063522a29e", - [ - null, - {} - ] - ], - "navigate-rejection-order-invalidurl-unserializablestate.html": [ - "f1ccb0c73b4ffe45d85aed5c4ea5a7a09ac84c68", - [ - null, - {} - ] - ], - "navigate-rejection-order-unload-unserializablestate.html": [ - "ac7976052314a48e60c5c103717789eab7841d22", - [ - null, - {} - ] - ], - "navigate-transitionWhile-interrupted.html": [ - "0e274d5591e8f7e0d1cf9e86207326403ee2abc5", - [ - null, - {} - ] - ], - "navigate-transitionWhile-rejected.html": [ - "36d95698f549225480d88e44ace3b3bdf7f09056", - [ - null, - {} - ] - ], - "navigate-transitionWhile.html": [ - "7809be1dec3307c0c551fca80b8833cfad07bb85", - [ - null, - {} - ] - ], - "navigate-unload.html": [ - "641de2c16bee44ea6914495dfa938341bcc18706", - [ - null, - {} - ] - ], - "navigate-unserializable-state.html": [ - "e6060ce891c5c1aeefc35f50fe585ac43593e4b1", - [ - null, - {} - ] - ], - "navigate.html": [ - "eab1e8a0a127f3df225a62aa4c9301fa833cb021", - [ - null, - {} - ] - ], - "reload-already-detached.html": [ - "7ecd31ae06bfe80689f91ac0e675492cd031c015", - [ - null, - {} - ] - ], - "reload-beforeunload.html": [ - "7a3d9e3a0eda59eb96dd59a51b2878c7218812a5", - [ - null, - {} - ] - ], - "reload-detach.html": [ - "f5b999134bcf5155bf50e7609f3a88806becdc00", - [ - null, - {} - ] - ], - "reload-initial-about-blank.html": [ - "e1b9f14285ba0d777cfe03963d5b0ede115237e0", - [ - null, - {} - ] - ], - "reload-preventDefault.html": [ - "3eeb72f27c9b54d54b8b480ca6677b415622df02", - [ - null, - {} - ] - ], - "reload-rejection-order-beforeunload-unserializablestate.html": [ - "89c60472de7f1982cabd68757ef387260078a768", - [ - null, - {} - ] - ], - "reload-rejection-order-detached-unserializablestate.html": [ - "12e5ac2d6df6a4cbafec0a306851b26e66d83ad5", - [ - null, - {} - ] - ], - "reload-rejection-order-unload-unserializablestate.html": [ - "f528a68b4f77cf64e925bd1668dda349c446934e", - [ - null, - {} - ] - ], - "reload-transitionWhile-rejected.html": [ - "6ad452e9cfbdf3e0137c396fed917226ce29113a", - [ - null, - {} - ] - ], - "reload-transitionWhile.html": [ - "d5563d9fff730269c19dd8a16d8bf63e9d863799", - [ - null, - {} - ] - ], - "reload-unload.html": [ - "a62796b5db9d8c2a6e5bf2b24ee3440f0080157a", - [ - null, - {} - ] - ], - "reload-unserializable-state.html": [ - "e87071b94f77675fc3f46a4795ec03a7cccb07ce", - [ - null, - {} - ] - ], - "reload.html": [ - "55836e790519dd583bd1a9d256068f4c67c39c39", - [ - null, - {} - ] - ] - }, - "state": { - "navigate-state-after-history-pushState.html": [ - "e24fc0f31c14c990b89b5e5d1fdd4ce503b923eb", - [ - null, - {} - ] - ], - "navigate-state-after-history-replaceState.html": [ - "23f037e57a0cdc9d762e8b47cd1a63e3506ae56d", - [ - null, - {} - ] - ], - "navigate-state-after-reload.html": [ - "28b2424e93ab072e287cd520f78795f1f9389927", - [ - null, - {} - ] - ], - "navigate-state-after-same-document-location-api-navigation.html": [ - "49e4507211a9b4c2a4d24fc66fde3a81c524ae27", - [ - null, - {} - ] - ], - "navigate-state-after-same-document-navigation.html": [ - "e2c1471efed48ed759a7d0d2836cf138159eb288", - [ - null, - {} - ] - ], - "navigate-state-cross-document-location-navigate.html": [ - "384d8d940eebcba92ce8077dab44438d54a1ec9c", - [ - null, - {} - ] - ], - "navigate-state-cross-document-restore.html": [ - "e1f70dc27bed59205b58f8af79983f754e60904c", - [ - null, - {} - ] - ], - "updateCurrent": { - "basic.html": [ - "00d3f59741d237416fe8605f5e65ecfa2e3a0046", - [ - null, - {} - ] - ], - "exception-order-initial-about-blank-unserializablestate.html": [ - "9ecb79793a01528eea377c0904ba5117eb725076", - [ - null, - {} - ] - ], - "exception-order-not-fully-active-unserializablestate.html": [ - "bd13b59e49feb2785aa7e2940208ea4a32be3007", - [ - null, - {} - ] - ], - "initial-about-blank.html": [ - "1c1d91453aeb9fc4d3430dc4f1d22e06e85c4c91", - [ - null, - {} - ] - ], - "no-args.html": [ - "435f260925a213e7cec711c1ce03eb882fdfca50", - [ - null, - {} - ] - ], - "not-fully-active.html": [ - "ba1df86e3ff1885f9fb61644e54bdecda0dde762", - [ - null, - {} - ] - ], - "opaque-origin.html": [ - "898ca27e4fab1d34bfe9c148ff53880a8a35d8cd", - [ - null, - {} - ] - ], - "state-after-history-pushState.html": [ - "e24fc0f31c14c990b89b5e5d1fdd4ce503b923eb", - [ - null, - {} - ] - ], - "state-after-history-replaceState.html": [ - "440cd4897f649ec1d8d703034e87f69d1441375c", - [ - null, - {} - ] - ], - "state-after-reload.html": [ - "43d452d6b3c86d782bb32243351f690c148b889d", - [ - null, - {} - ] - ], - "state-after-same-document-location-api-navigation.html": [ - "5d57ea0dee8b2f4f513a090a4c66d7b7d8f4b79d", - [ - null, - {} - ] - ], - "state-cross-document-location-navigate.html": [ - "6e70b48063c848500c2a98663cd51df5b12e5103", - [ - null, - {} - ] - ], - "state-cross-document-restore.html": [ - "f872e6107960e03ccf5d99c82f0c4f9b5d4d61ce", - [ - null, - {} - ] - ], - "state-invalid.html": [ - "469b7d2206a4c76aa9ad1bdeeae7bc01dce9cea7", - [ - null, - {} - ] - ] - } - } - }, - "navigate-event": { - "cross-window": { - "click-crossdocument-crossorigin-sameorigindomain.sub.html": [ - "24abe7f2ef8aa5af592540760e409e03247befaa", - [ - null, - {} - ] - ], - "click-crossdocument-crossorigin.html": [ - "6fb559ceb12b347b874b825f4d327f4559a1a227", - [ - null, - {} - ] - ], - "click-crossdocument-sameorigin.html": [ - "ed1e8a37cda9f15cf42bb3e2c69e49f787b5802e", - [ - null, - {} - ] - ], - "click-samedocument-crossorigin-sameorigindomain.sub.html": [ - "0df9ec6234bd70e238af27417f9eabbc23c5a811", - [ - null, - {} - ] - ], - "click-samedocument-crossorigin.html": [ - "7973f0d38cf5dd6fe953f18c9ec25b648ee786a9", - [ - null, - {} - ] - ], - "click-samedocument-sameorigin.html": [ - "a2532fc0269587e4efd42b75bb45e5b483336312", - [ - null, - {} - ] - ], - "location-crossdocument-crossorigin-sameorigindomain.sub.html": [ - "2623b4bbbce07623e2d1a3613e027708d5fb307e", - [ - null, - {} - ] - ], - "location-crossdocument-crossorigin.html": [ - "b0f031cf92478dff59aabb1f2de23fa8d813e073", - [ - null, - {} - ] - ], - "location-crossdocument-sameorigin.html": [ - "02329697a39e7348772974b6d3caae78467be66b", - [ - null, - {} - ] - ], - "location-samedocument-crossorigin-sameorigindomain.sub.html": [ - "ec9723619f2e29360c9e2b25e77c21a0806bb5aa", - [ - null, - {} - ] - ], - "location-samedocument-crossorigin.html": [ - "b5d4fbfd07af9dd0c1321486876b46bc035ee5be", - [ - null, - {} - ] - ], - "location-samedocument-sameorigin.html": [ - "634b4f77567334f9d53d7807fe6f63c0f4d4c241", - [ - null, - {} - ] - ], - "open-crossdocument-crossorigin-sameorigindomain.sub.html": [ - "edbcee53ef7446af8c12673c1cb6a47619e8a940", - [ - null, - {} - ] - ], - "open-crossdocument-crossorigin.html": [ - "88e975ae5dcf8b25ef1d72023ac3cfa6c58b113c", - [ - null, - {} - ] - ], - "open-crossdocument-sameorigin.html": [ - "8a23dce24192dbb43a9009c8656b687bcf98a306", - [ - null, - {} - ] - ], - "open-samedocument-crossorigin-sameorigindomain.sub.html": [ - "c072ed9d5fec43f9a823a7a0af27ac43b76a5756", - [ - null, - {} - ] - ], - "open-samedocument-crossorigin.html": [ - "e7fe633e0da5c1f91e0c6082c9b98310e3fdda7d", - [ - null, - {} - ] - ], - "open-samedocument-sameorigin.html": [ - "bab81615cbefb19161b8e42f721e5beb93063f08", - [ - null, - {} - ] - ], - "submit-crossdocument-crossorigin-sameorigindomain.sub.html": [ - "794eccfb64652a8431c44c317dc2a78c941856ef", - [ - null, - {} - ] - ], - "submit-crossdocument-crossorigin.html": [ - "4356a127bdcf9da96d36b220742500919ca71950", - [ - null, - {} - ] - ], - "submit-crossdocument-sameorigin.html": [ - "45523532243b971ed2762ed8014ed37ec072b194", - [ - null, - {} - ] - ], - "submit-samedocument-crossorigin-sameorigindomain.sub.html": [ - "4f84e6aef354bcd56a07fca945c1dc2e803de6c5", - [ - null, - {} - ] - ], - "submit-samedocument-crossorigin.html": [ - "7e25d174713420473dd01fda477811cac38b2ed0", - [ - null, - {} - ] - ], - "submit-samedocument-sameorigin.html": [ - "12de577cb66bff7edbe0fdd3217c0313cc5c401b", - [ - null, - {} - ] - ] - }, - "event-constructor.html": [ - "7a8803fab41e3ee659a86f2a227a6b2fc261d8d6", - [ - null, - {} - ] - ], - "navigate-anchor-cross-origin.html": [ - "a6d395a35eb8b549faf4c9e4ab94cd197bdc6c63", - [ - null, - {} - ] - ], - "navigate-anchor-fragment.html": [ - "77cf94a40592bba55d7d0c021db80b012a6332d9", - [ - null, - {} - ] - ], - "navigate-anchor-same-origin-cross-document.html": [ - "ac8f548239cdaa01eae547190c615271019ca9c0", - [ - null, - {} - ] - ], - "navigate-anchor-userInitiated.html": [ - "8afe01d4c564f5d3ad087b6244bfd62c792adc07", - [ - null, - { - "testdriver": true - } - ] - ], - "navigate-anchor-with-target.html": [ - "cf693583104681235ab57f9ab51898a8464aab0c", - [ - null, - {} - ] - ], - "navigate-appHistory-back-cross-document.html": [ - "2be9cb9b889ace4c9576b67d24093eb0dc2ba0c5", - [ - null, - {} - ] - ], - "navigate-appHistory-back-same-document.html": [ - "acc71ad3fe2cda228d91ade85e162af0d23266c3", - [ - null, - {} - ] - ], - "navigate-appHistory-navigate.html": [ - "b48e816cdff93c6a1655ab502af3fde2990f69a5", - [ - null, - {} - ] - ], - "navigate-destination-getState-back-forward.html": [ - "07e66b8a5ffea676865c62df4192e5bf5531dfb9", - [ - null, - {} - ] - ], - "navigate-destination-getState-navigate.html": [ - "43ca7b42c47a0b4d78c44c49411a14df28d4b888", - [ - null, - {} - ] - ], - "navigate-form-get.html": [ - "843849154d1ec4f0b08d7b422d0268c6018e0545", - [ - null, - {} - ] - ], - "navigate-form-reload.html": [ - "fbab4d2136fc61db9bd8f3244bd73facc4983ed7", - [ - null, - {} - ] - ], - "navigate-form-traverse.html": [ - "1514b2bcf93828cef25e94190d1bcf5495b50ff3", - [ - null, - {} - ] - ], - "navigate-form-userInitiated.html": [ - "e1c8c2825a5ab5538e4f96bf7bf3ba84756670a0", - [ - null, - { - "testdriver": true - } - ] - ], - "navigate-form-with-target.html": [ - "dcbbdc02b183b832d36142576946436391feb359", - [ - null, - {} - ] - ], - "navigate-form.html": [ - "8413c48ef46d414364ce9c137bbf430d8e89bbb8", - [ - null, - {} - ] - ], - "navigate-history-back-after-fragment.html": [ - "307fe5761bc04d39ad4e7393033e58c5d10704dc", - [ - null, - {} - ] - ], - "navigate-history-back-after-pushState.html": [ - "74f353d50513403b05eb75d48c2e96344e6e871c", - [ - null, - {} - ] - ], - "navigate-history-back-cross-document.html": [ - "c6c8322a35ace2358157607e6a7a7774961e8a0e", - [ - null, - {} - ] - ], - "navigate-history-go-0.html": [ - "2070614deb9e1836348f4ddac1e6603867a2ab3a", - [ - null, - {} - ] - ], - "navigate-history-pushState.html": [ - "b7940f17564be054325800697412752a2aabb033", - [ - null, - {} - ] - ], - "navigate-history-replaceState.html": [ - "dda602dcc466f22b6b5e1a94765add8f0dc4edf3", - [ - null, - {} - ] - ], - "navigate-iframe-location.html": [ - "8abaabb847717744d8253f3794b1bdb590b031ab", - [ - null, - {} - ] - ], - "navigate-location.html": [ - "ec17dcfbafe3a0f87f08cd1b4b1f600c7e83f921", - [ - null, - {} - ] - ], - "navigate-meta-refresh.html": [ - "4f3769d946af45dfa7082282fd20c15033622b25", - [ - null, - {} - ] - ], - "navigate-to-javascript.html": [ - "53ce37a0220f78eebd84d9d734770a375af0b86c", - [ - null, - {} - ] - ], - "navigate-to-srcdoc.html": [ - "b9d315dad428e32e251915e20aec8dcc32bfbec3", - [ - null, - {} - ] - ], - "navigate-window-open-self.html": [ - "1523ed81374f2a5cf380e00f830986200d6755d0", - [ - null, - {} - ] - ], - "navigate-window-open.html": [ - "03cd14e34b85dbe3e088e05441dae9138c79aa18", - [ - null, - {} - ] - ], - "navigatesuccess-cross-document.html": [ - "1d528c1f5f9154c1bc089315a0ae11d72b7d3820", - [ - null, - {} - ] - ], - "navigatesuccess-same-document.html": [ - "033308940d4233ec897c1b533d5be9351ee99d4a", - [ - null, - {} - ] - ], - "signal-abort-detach-in-onnavigate.html": [ - "19ab7ae414b61545bfa11e5e86ba9f812e8c9767", - [ - null, - {} - ] - ], - "signal-abort-preventDefault.html": [ - "f9a1cd7015de038d56af0b1975c535ce9e135e6c", - [ - null, - {} - ] - ], - "signal-abort-transitionWhile.html": [ - "82d0c07eb74e4eb26c9fca718e45549ebf3481ad", - [ - null, - {} - ] - ], - "signal-abort-window-stop-after-transitionWhile.html": [ - "108ef39ffee8138caf094cf3c5ee7faac2ca8a97", - [ - null, - {} - ] - ], - "signal-abort-window-stop-in-onnavigate.html": [ - "00be9925ea9b131d08b824172986a6da2be37db8", - [ - null, - {} - ] - ], - "signal-abort-window-stop.html": [ - "03c36f7f6d683a598be27befa1919f3715b1cd59", - [ - null, - {} - ] - ], - "transitionWhile-after-dispatch.html": [ - "f4cc707a48dabd22e537826e1abcbeebd8e5be8f", - [ - null, - {} - ] - ], - "transitionWhile-and-navigate.html": [ - "65e9d0492784368687dc53d4ae75716d279073fe", - [ - null, - {} - ] - ], - "transitionWhile-appHistory-back.html": [ - "c05e7d3bc63c3f6a1bd64046852553612c100322", - [ - null, - {} - ] - ], - "transitionWhile-canceled-event.html": [ - "79ed0571a450c640f2dcf36ab8cd3a46669b7ac1", - [ - null, - {} - ] - ], - "transitionWhile-cross-document-same-origin.html": [ - "249641d0ca06376a6a38f116db8e0c284ba7c0be", - [ - null, - {} - ] - ], - "transitionWhile-cross-origin.html": [ - "d828c5cd0ee2fc0b0ff543779b088ccfa611360e", - [ - null, - {} - ] - ], - "transitionWhile-detach.html": [ - "76b624134cbe8d25ea5868b3ae638ff573c02204", - [ - null, - {} - ] - ], - "transitionWhile-history-pushState.html": [ - "81da433de04760504ff9abe442ae2b60ab30ae17", - [ - null, - {} - ] - ], - "transitionWhile-history-replaceState.html": [ - "41c4949537edd8b3a5f99b342816100563ab9107", - [ - null, - {} - ] - ], - "transitionWhile-multiple-times-reject.html": [ - "6f40cf63d21af0ddf35596067ff8015b5e670b90", - [ - null, - {} - ] - ], - "transitionWhile-multiple-times.html": [ - "a409db86a5147113b625a5a09d46576f5512dd5f", - [ - null, - {} - ] - ], - "transitionWhile-on-synthetic-event.html": [ - "a3bb80fe66ccf1ddc4335e28697b1ade17be97f4", - [ - null, - {} - ] - ], - "transitionWhile-reject.html": [ - "33e0214d46c075a785224259cdf6c8a5ce388420", - [ - null, - {} - ] - ], - "transitionWhile-resolve.html": [ - "32a47ec2854efe47827ab39d0226f4ab090eb64d", - [ - null, - {} - ] - ], - "transitionWhile-same-document-history-back.html": [ - "587a6bd379108e7f3aca78332f3a267e859fa5ba", - [ - null, - {} - ] - ] - }, - "ordering-and-transition": { - "back-same-document-transitionWhile-reject.html": [ - "1255dbef7d279ff4a055b6544e4e7e86bc940a4e", - [ - null, - {} - ], - [ - "app-history/ordering-and-transition/back-same-document-transitionWhile-reject.html?currentchange", - {} - ] - ], - "back-same-document-transitionWhile.html": [ - "e83ac55e9e8c37d2b1814217631e36d677b6a99e", - [ - null, - {} - ], - [ - "app-history/ordering-and-transition/back-same-document-transitionWhile.html?currentchange", - {} - ] - ], - "back-same-document.html": [ - "b2bec4ddc3d152a457717f2d277a8ab0356baeaf", - [ - null, - {} - ], - [ - "app-history/ordering-and-transition/back-same-document.html?currentchange", - {} - ] - ], - "currentchange-before-popsate-transitionWhile.html": [ - "2a0155a6ed52bff80ce06b1a797615c2d5191e01", - [ - null, - {} - ] - ], - "currentchange-dispose-ordering.html": [ - "f9d23f7dd5da79afb95bd998c618685c225c9e6a", - [ - null, - {} - ] - ], - "location-href-canceled.html": [ - "ed776ffcad637de40399c82777e769b7b9d995e2", - [ - null, - {} - ] - ], - "location-href-double-transitionWhile.html": [ - "0168dc9347911052221af99e8489eb7f4fad9d7e", - [ - null, - {} - ], - [ - "app-history/ordering-and-transition/location-href-double-transitionWhile.html?currentchange", - {} - ] - ], - "location-href-transitionWhile-reentrant.html": [ - "3b6215d7809494e27502174c69c30ef004555bd7", - [ - null, - {} - ], - [ - "app-history/ordering-and-transition/location-href-transitionWhile-reentrant.html?currentchange", - {} - ] - ], - "location-href-transitionWhile-reject.html": [ - "e0495b45fc8d4d1a95e2cbbcef8e635eb4319998", - [ - null, - {} - ], - [ - "app-history/ordering-and-transition/location-href-transitionWhile-reject.html?currentchange", - {} - ] - ], - "location-href-transitionWhile.html": [ - "988a025348268466625ad9143d53e2f5a4e9fdad", - [ - null, - {} - ], - [ - "app-history/ordering-and-transition/location-href-transitionWhile.html?currentchange", - {} - ] - ], - "navigate-canceled.html": [ - "550284139a94de0894306e190e2deb7ea36ffb52", - [ - null, - {} - ] - ], - "navigate-cross-document-double.html": [ - "ba1edceead52cb79b9bcb77c317dca5e2636d817", - [ - null, - {} - ] - ], - "navigate-cross-document-event-order.html": [ - "1c1758a002eb8ac5e8ba8945dc6163d32a1a70f4", - [ - null, - {} - ] - ], - "navigate-double-transitionWhile.html": [ - "eb54f9e0ba4f4e6672330725889585cc9ec9227e", - [ - null, - {} - ], - [ - "app-history/ordering-and-transition/navigate-double-transitionWhile.html?currentchange", - {} - ] - ], - "navigate-in-transition-finished.html": [ - "f84be14b545b62ae119ae26934489749a659a34d", - [ - null, - {} - ], - [ - "app-history/ordering-and-transition/navigate-in-transition-finished.html?currentchange", - {} - ] - ], - "navigate-same-document-transitionWhile-reentrant.html": [ - "0170dec95ffe997ef63ca0ba3147e3c183b8bd8a", - [ - null, - {} - ], - [ - "app-history/ordering-and-transition/navigate-same-document-transitionWhile-reentrant.html?currentchange", - {} - ] - ], - "navigate-same-document-transitionWhile-reject.html": [ - "f46f926de14c637e921c84ea1bba03ca6a8109d7", - [ - null, - {} - ], - [ - "app-history/ordering-and-transition/navigate-same-document-transitionWhile-reject.html?currentchange", - {} - ] - ], - "navigate-same-document.html": [ - "1fa2709ecb355a10043f0335156a54950d414e09", - [ - null, - {} - ], - [ - "app-history/ordering-and-transition/navigate-same-document.html?currentchange", - {} - ] - ], - "navigate-transitionWhile-stop.html": [ - "382dc9e2dd07f3574d7ef9a1b8da0249786aee05", - [ - null, - {} - ], - [ - "app-history/ordering-and-transition/navigate-transitionWhile-stop.html?currentchange", - {} - ] - ], - "navigate-transitionWhile.html": [ - "fdc7428f5b60b51e80ee02fe8f6f196fb9a3a3bf", - [ - null, - {} - ], - [ - "app-history/ordering-and-transition/navigate-transitionWhile.html?currentchange", - {} - ] - ], - "reload-canceled.html": [ - "0e060d227653b2b743d8c58c5ccef624e400ec19", - [ - null, - {} - ] - ], - "reload-transitionWhile-reject.html": [ - "88fbe9a4f4606c2a89cd52a28b60e3f4236fca2c", - [ - null, - {} - ], - [ - "app-history/ordering-and-transition/reload-transitionWhile-reject.html?currentchange", - {} - ] - ], - "reload-transitionWhile.html": [ - "235cfd0f96990d8a9744eaf0d77d68c8139ee112", - [ - null, - {} - ], - [ - "app-history/ordering-and-transition/reload-transitionWhile.html?currentchange", - {} - ] - ], - "transition-cross-document.html": [ - "400cccec25e5400f56c828ac6a0fdba46817811c", - [ - null, - {} - ] - ], - "transition-finished-mark-as-handled.html": [ - "c3b2723191aa51fd9a73157b826159584f444595", - [ - null, - {} - ] - ], - "transition-realms-and-identity.html": [ - "8b825dab1a44631b8d211708873521126e6978ae", - [ - null, - {} - ] - ] - }, - "per-entry-events": { - "dispose-after-bfcache.html": [ - "db24158085953186ef874411285317a3c612d09c", - [ - null, - {} - ] - ], - "dispose-cross-document.html": [ - "22ea15bae9846d0075ef3c8092f62a732c727d2b", - [ - null, - {} - ] - ], - "dispose-same-document-navigate-during.html": [ - "e539eabda99cc42c2925a09087cb77700edd74d2", - [ - null, - {} - ] - ], - "dispose-same-document-reload-with-transitionWhile.html": [ - "a9b01eb3485f84484f5f96bded1a988563648a08", - [ - null, - {} - ] - ], - "dispose-same-document-replace-with-transitionWhile.html": [ - "7efac924ef2281a5e25e366605bcefb9c43935ff", - [ - null, - {} - ] - ], - "dispose-same-document-replaceState.html": [ - "6da4c8e98926ca854499e0c6db16caf336ae09fa", - [ - null, - {} - ] - ], - "dispose-same-document-transitionWhile.html": [ - "97ed346f8f717f457c589bf70d0fa39952e45021", - [ - null, - {} - ] - ], - "dispose-same-document.html": [ - "85e1293c2fe4fe92b647fcd2b9aef1d7d9405852", - [ - null, - {} - ] - ] - } - }, "audio-output": { "enumerateDevices-permissions-policy.https.html": [ "4e5652e68f5e0e72ae892df46195090206f62185", @@ -365433,49 +363476,49 @@ ] ], "container-units-animation.html": [ - "75178bb99950cc0054d4df5c69838eb343a85492", + "cf1b9a8f345ebfeb1217237f078e5e4e55f96250", [ null, {} ] ], "container-units-basic.html": [ - "09f662438d768be8e9b39bb8ce37f0b2c344ad86", + "166a003a29b2eb1bc0c017815a36cdcb1361c2aa", [ null, {} ] ], "container-units-computational-independence.html": [ - "5f22a290a0677bdd56077f6b25552242b7c6c945", + "694b665c793c820f5f80aa2c19ff4be146f72a08", [ null, {} ] ], "container-units-invalidation.html": [ - "257573a9269f2add840bb66466f12a05a094ed4e", + "0cb5b15f4a8e3666a5fbf60542e65fe6a5c31da8", [ null, {} ] ], "container-units-selection.html": [ - "7471ec4dbf1b84f87bcd3ec899a3b51eec53ca5b", + "16a44cd176618d0ed21e6cb8921fd286234441fb", [ null, {} ] ], "container-units-small-viewport-fallback.html": [ - "f78dbc1772dcd94b13dc19f60ffb5563e1aca04a", + "6c8851681fb62fc133a2635796e38c367e866dcb", [ null, {} ] ], "container-units-typed-om.html": [ - "9baf12d1c9059e58fb8103a8baa0d1d9997a4deb", + "6da3306fdfa3e88dde176d43c81813c3959a0306", [ null, {} @@ -365503,7 +363546,7 @@ ] ], "display-none.html": [ - "bae21bc3241e48392d875eb198ad47004774d78e", + "9a91b7c40910f92e09267274d8ed42a475ba474c", [ null, {} @@ -365635,6 +363678,13 @@ {} ] ], + "sibling-layout-dependency.html": [ + "5e30a998d23b03dd73f1ff290876243bd2eb9417", + [ + null, + {} + ] + ], "size-container-no-principal-box.html": [ "a1b875918bd86219edab1a0803ad1d383ebb4bc8", [ @@ -482587,6 +480637,2086 @@ ] ] }, + "navigation-api": { + "currententrychange-event": { + "anchor-click.html": [ + "55e45561351ff1c6f43d211f1b8d7c78cfa098cc", + [ + null, + {} + ] + ], + "constructor.html": [ + "64ea8cf37ebd545cb349e4b0d863be3061851b99", + [ + null, + {} + ] + ], + "history-back-same-doc.html": [ + "bee3649395a8b1f4802de17d7fb4b21f894863e2", + [ + null, + {} + ] + ], + "history-pushState.html": [ + "c0e2d9a783cbe508bd065792ff115f62e26770a6", + [ + null, + {} + ] + ], + "history-replaceState.html": [ + "da5505a6c14a2485b2ba194d0060bdfadef53a5c", + [ + null, + {} + ] + ], + "location-api.html": [ + "f06dc8ec615942aa277a602b7070502e74396725", + [ + null, + {} + ] + ], + "navigate-from-initial-about-blank-same-doc-popup.html": [ + "a8aa2a25fb51c0bfc0a40c953d50dc3786ddd409", + [ + null, + {} + ] + ], + "navigate-from-initial-about-blank-same-doc.html": [ + "e2c56743588e0bb1919565495fed603ff6b2becf", + [ + null, + {} + ] + ], + "navigate-from-initial-about-blank.html": [ + "7b406c733c4a11712cabc7596daacc7eb769d5ce", + [ + null, + {} + ] + ], + "navigation-back-forward-cross-doc.html": [ + "df230bd9acb5daae40f30a2dfe625ebe0f8aa78f", + [ + null, + {} + ] + ], + "navigation-back-forward-same-doc.html": [ + "41cc4afd446e6338792a0f4cceb285082903d858", + [ + null, + {} + ] + ], + "navigation-navigate-cross-doc.html": [ + "2f804a307f6cbeef899411f6fd58c382b2f7f1cf", + [ + null, + {} + ] + ], + "navigation-navigate-preventDefault.html": [ + "997fb559492c7383e630e41c399a2106bcf58732", + [ + null, + {} + ] + ], + "navigation-navigate-replace-cross-doc.html": [ + "52478f22799b0593749a2b59963ed0de43ee0ff9", + [ + null, + {} + ] + ], + "navigation-navigate-replace-same-doc.html": [ + "a4027709687949140948681c9115d9eeff8d9307", + [ + null, + {} + ] + ], + "navigation-navigate-replace-transitionWhile.html": [ + "55b314a554d2542c3a8de9388135180fae2cada0", + [ + null, + {} + ] + ], + "navigation-navigate-same-doc.html": [ + "96de3de6d3d62b2d33d566c2e38568cb8d327f36", + [ + null, + {} + ] + ], + "navigation-navigate-transitionWhile.html": [ + "2132016404dd17968100315ec78fc4bf998bfb84", + [ + null, + {} + ] + ], + "navigation-reload-cross-doc.html": [ + "cb4279cfe53f44146bca35f6aa529997f70207fb", + [ + null, + {} + ] + ], + "navigation-reload-transitionWhile.html": [ + "cfa6258dc578de7fe011ed8a938b333ea8e38388", + [ + null, + {} + ] + ], + "navigation-updateCurrentEntry.html": [ + "8d548706be938d26e459cb4c5c7bf69620517f3e", + [ + null, + {} + ] + ], + "properties.html": [ + "7048034e4f051bf1f302383fbc0d5828ede3a837", + [ + null, + {} + ] + ] + }, + "focus-reset": { + "autofocus.html": [ + "4418dfa76cde71028a8dab07fef6995f8652f86e", + [ + null, + {} + ] + ], + "basic.html": [ + "8a62d88ba659831f8abc1579ef7b1793b025baac", + [ + null, + {} + ] + ], + "multiple-transitionWhile.html": [ + "c1d028524a5e8c0711b912f447f492193b9e8246", + [ + null, + {} + ] + ] + }, + "navigate-event": { + "cross-window": { + "click-crossdocument-crossorigin-sameorigindomain.sub.html": [ + "d162d8ddb883bea30aa034a41b78df626fd082a7", + [ + null, + {} + ] + ], + "click-crossdocument-crossorigin.html": [ + "2f40238912657585642363fc86bc8d355e6a78cc", + [ + null, + {} + ] + ], + "click-crossdocument-sameorigin.html": [ + "928d202045e3427afbd6462ce6cf4b3d58e6e244", + [ + null, + {} + ] + ], + "click-samedocument-crossorigin-sameorigindomain.sub.html": [ + "b7d284088081e846cadb65558bc7ed665bf6ce61", + [ + null, + {} + ] + ], + "click-samedocument-crossorigin.html": [ + "32bc4cd291ac64bea9dfb9c03b30dcb4202eeac6", + [ + null, + {} + ] + ], + "click-samedocument-sameorigin.html": [ + "fc815abb39eb182ad376ccfb55dc920f73522fd1", + [ + null, + {} + ] + ], + "location-crossdocument-crossorigin-sameorigindomain.sub.html": [ + "24824b12177d94b411cd0abff93bdb3b2d7a45fa", + [ + null, + {} + ] + ], + "location-crossdocument-crossorigin.html": [ + "79df86fdc9befb693a7db4e2bceda950373f620a", + [ + null, + {} + ] + ], + "location-crossdocument-sameorigin.html": [ + "1ac3eef874770ac61fd9acd8cc071eecc8c03991", + [ + null, + {} + ] + ], + "location-samedocument-crossorigin-sameorigindomain.sub.html": [ + "96032c14ac60a9365799fd8bfda9cdbe99f44a24", + [ + null, + {} + ] + ], + "location-samedocument-crossorigin.html": [ + "8a58be7a2b4120f64e8fdc1f8939b6cb3bc3e19e", + [ + null, + {} + ] + ], + "location-samedocument-sameorigin.html": [ + "3901b9ddbccc49323bfe4731700fa96634ccb6d0", + [ + null, + {} + ] + ], + "open-crossdocument-crossorigin-sameorigindomain.sub.html": [ + "d386e487a333c23692f21263ccfade40ac47dfa1", + [ + null, + {} + ] + ], + "open-crossdocument-crossorigin.html": [ + "73ede89cbf039e340e5000b6fd8df4fd16ca3070", + [ + null, + {} + ] + ], + "open-crossdocument-sameorigin.html": [ + "a899dd86a3a773dfc07d1d514444ac73f2e61c74", + [ + null, + {} + ] + ], + "open-samedocument-crossorigin-sameorigindomain.sub.html": [ + "b44303c18b8b8100880d22cb673454b1e3d5e4ec", + [ + null, + {} + ] + ], + "open-samedocument-crossorigin.html": [ + "65f062fcd578ba38c7c86d0dbbdeeba502cbd89d", + [ + null, + {} + ] + ], + "open-samedocument-sameorigin.html": [ + "3f3c38d85062d67dad5527d33be83783f1943cce", + [ + null, + {} + ] + ], + "submit-crossdocument-crossorigin-sameorigindomain.sub.html": [ + "36101a400041bcdcb0005b5cab4687f37bd4be87", + [ + null, + {} + ] + ], + "submit-crossdocument-crossorigin.html": [ + "007f58b1fbe473d4a8d5b5a3b0201ccfad93840d", + [ + null, + {} + ] + ], + "submit-crossdocument-sameorigin.html": [ + "93b97351d752cd063b3b7fc7ec6f68bfe0c7ef4b", + [ + null, + {} + ] + ], + "submit-samedocument-crossorigin-sameorigindomain.sub.html": [ + "9f5ba8b44afc346ca4f5a1c7817256763a0b307d", + [ + null, + {} + ] + ], + "submit-samedocument-crossorigin.html": [ + "51a313ac18147b3eaaa8ad37f1b893e749a9e64d", + [ + null, + {} + ] + ], + "submit-samedocument-sameorigin.html": [ + "f0b7b7393711a3a453954e675005a0e6a7ac518c", + [ + null, + {} + ] + ] + }, + "event-constructor.html": [ + "501857feba4471575531965c865bcaf163d17985", + [ + null, + {} + ] + ], + "navigate-anchor-cross-origin.html": [ + "55ecbe749b72d9912aaf50cc69587995984b4eca", + [ + null, + {} + ] + ], + "navigate-anchor-fragment.html": [ + "b61edbe2c6f615e475a1b93b127a3678d669670e", + [ + null, + {} + ] + ], + "navigate-anchor-same-origin-cross-document.html": [ + "ff5f0ad4b853be022e7d853fba6f531423dcfb1b", + [ + null, + {} + ] + ], + "navigate-anchor-userInitiated.html": [ + "c54f525ea58ae829c9d02d726abe7eb7ff765875", + [ + null, + { + "testdriver": true + } + ] + ], + "navigate-anchor-with-target.html": [ + "b2eb813cc467bbe98a124833c86cc6e7db417346", + [ + null, + {} + ] + ], + "navigate-destination-getState-back-forward.html": [ + "8fc0f2d12810a5b14dc7d028a33bcb77d6595b22", + [ + null, + {} + ] + ], + "navigate-destination-getState-navigate.html": [ + "9c34c5753a1197631cd1770284dfb012bb0192f6", + [ + null, + {} + ] + ], + "navigate-form-get.html": [ + "3c76accaabb3ad5c2bcf42d9965338c4f8ece74b", + [ + null, + {} + ] + ], + "navigate-form-reload.html": [ + "f18a11ebdaca671566db4722e537054dd7d315df", + [ + null, + {} + ] + ], + "navigate-form-traverse.html": [ + "d673537503e02f2440aabe55f303560c570c9e3b", + [ + null, + {} + ] + ], + "navigate-form-userInitiated.html": [ + "74fc7501dd7681be697de352c36119e37749993d", + [ + null, + { + "testdriver": true + } + ] + ], + "navigate-form-with-target.html": [ + "a02487ba7df5e49b900f75911bc26719e949263f", + [ + null, + {} + ] + ], + "navigate-form.html": [ + "3aee2d7ddd2e93bb0822581a5bc492d735548fa5", + [ + null, + {} + ] + ], + "navigate-history-back-after-fragment.html": [ + "31107fba2ff585de046b5cf64ede1795e5b0dccd", + [ + null, + {} + ] + ], + "navigate-history-back-after-pushState.html": [ + "0232517181a6b77cc8717db262c3662191dd2815", + [ + null, + {} + ] + ], + "navigate-history-back-cross-document.html": [ + "5d7c662caabb806932222e8ac1035f930ccea657", + [ + null, + {} + ] + ], + "navigate-history-go-0.html": [ + "6f7b277517656836813f4b92e16540524ce9b967", + [ + null, + {} + ] + ], + "navigate-history-pushState.html": [ + "5cd4ed8bccbd1c787f5e0e94ebb2732c573f8cf8", + [ + null, + {} + ] + ], + "navigate-history-replaceState.html": [ + "b5637d6c3c48220786bba75b83b8ed4dc44385f9", + [ + null, + {} + ] + ], + "navigate-iframe-location.html": [ + "e566cdd229dea62d6eb43734b29abd2bbfb96529", + [ + null, + {} + ] + ], + "navigate-location.html": [ + "e0c22d3299d3cc029a29ee2abe148bf18d47bf60", + [ + null, + {} + ] + ], + "navigate-meta-refresh.html": [ + "0f2994a9d9dcab3bd13665c9c04f3b90786a0129", + [ + null, + {} + ] + ], + "navigate-navigation-back-cross-document.html": [ + "a3641d5fcc829273ef7f680fa985b690b4fa073c", + [ + null, + {} + ] + ], + "navigate-navigation-back-same-document.html": [ + "22fe9fa02ec0749637175a91cca15528f6b2f761", + [ + null, + {} + ] + ], + "navigate-navigation-navigate.html": [ + "5629f765f69d9ec8e037be536fe0bad0d5dfee90", + [ + null, + {} + ] + ], + "navigate-to-javascript.html": [ + "78f490d87b95d6e1109d00e84ba320dc93a218c5", + [ + null, + {} + ] + ], + "navigate-to-srcdoc.html": [ + "344d130ca41d67d8617463f01d05cd245629b695", + [ + null, + {} + ] + ], + "navigate-window-open-self.html": [ + "4409cb2334c424e60e14b243a1b9bf61b31a361e", + [ + null, + {} + ] + ], + "navigate-window-open.html": [ + "b0cac1821f7f886997e6a4c4d9f670d709445e5f", + [ + null, + {} + ] + ], + "navigatesuccess-cross-document.html": [ + "1d528c1f5f9154c1bc089315a0ae11d72b7d3820", + [ + null, + {} + ] + ], + "navigatesuccess-same-document.html": [ + "6007170ec153d94957b4f6bddd7f14a24b70357d", + [ + null, + {} + ] + ], + "signal-abort-detach-in-onnavigate.html": [ + "adef895565b9bc283cbc570323c617acf763104a", + [ + null, + {} + ] + ], + "signal-abort-preventDefault.html": [ + "f281617866c0cd6a8e7e2a61ef6ba8e58cf38115", + [ + null, + {} + ] + ], + "signal-abort-transitionWhile.html": [ + "d90ee5b0837c41bd3bdce5f28284037e76aa0e0c", + [ + null, + {} + ] + ], + "signal-abort-window-stop-after-transitionWhile.html": [ + "aad3be34d7e80bc6e613f309f45089c180fb8fc4", + [ + null, + {} + ] + ], + "signal-abort-window-stop-in-onnavigate.html": [ + "dde666c93386175a50d08da6296a8d8121d73243", + [ + null, + {} + ] + ], + "signal-abort-window-stop.html": [ + "49399fb663777ea87b6c5b0686a1168557ed5e97", + [ + null, + {} + ] + ], + "transitionWhile-after-dispatch.html": [ + "7f4a25cef528a1609731b2b1cc8c5139eee56a12", + [ + null, + {} + ] + ], + "transitionWhile-and-navigate.html": [ + "f226371d79b35785de110a128914361785585a4b", + [ + null, + {} + ] + ], + "transitionWhile-canceled-event.html": [ + "ed6dbdc85cfe0796e26fc519ca2b498fd0fdf526", + [ + null, + {} + ] + ], + "transitionWhile-cross-document-same-origin.html": [ + "79e03f1c397c5d3bc6b5ee82695e188575400542", + [ + null, + {} + ] + ], + "transitionWhile-cross-origin.html": [ + "ece79d263571838352ab74244df296a798708629", + [ + null, + {} + ] + ], + "transitionWhile-detach.html": [ + "d6a7d536276b6af21a96de2b20d5abd05e544a7e", + [ + null, + {} + ] + ], + "transitionWhile-history-pushState.html": [ + "fb6152fc2289ffe74082307a439ca6de004832d1", + [ + null, + {} + ] + ], + "transitionWhile-history-replaceState.html": [ + "00f85dcc0fcc958f4224cf8b3ae4f0b5a5a757f2", + [ + null, + {} + ] + ], + "transitionWhile-multiple-times-reject.html": [ + "c325829001572dfd082c98d1b64fec117c3b12b4", + [ + null, + {} + ] + ], + "transitionWhile-multiple-times.html": [ + "0f6caf16f1411e850522df207289c4f933b80b65", + [ + null, + {} + ] + ], + "transitionWhile-navigation-back.html": [ + "a0bc453d36e3095fcb0d5c76f6fabb0c6ad3f612", + [ + null, + {} + ] + ], + "transitionWhile-on-synthetic-event.html": [ + "21a32e7b4c93946f7c8a899a78d12133c2a2dfb9", + [ + null, + {} + ] + ], + "transitionWhile-reject.html": [ + "2cdea05072911cf6883f90071547f20b5693c01a", + [ + null, + {} + ] + ], + "transitionWhile-resolve.html": [ + "2ee4fb39713cffe36724b85beda4cba9c0ca3287", + [ + null, + {} + ] + ], + "transitionWhile-same-document-history-back.html": [ + "5e8ac39ef20ec07b78fd3ee58437dbe90a0a6a45", + [ + null, + {} + ] + ] + }, + "navigation-history-entry": { + "after-detach.html": [ + "c4ecfec44d69eaf7183691e69a1d21dd544d8ff7", + [ + null, + {} + ] + ], + "current-basic.html": [ + "78bbbb05607c3b8c5338d1c062c192936de69407", + [ + null, + {} + ] + ], + "entries-across-origins.html": [ + "447273bff2c8447f40cdf038dea70165459f5064", + [ + null, + {} + ] + ], + "entries-after-bfcache-in-iframe.html": [ + "b54a74995099eac8db164357c6309566707cfbc2", + [ + null, + {} + ] + ], + "entries-after-bfcache.html": [ + "11bd7df931d56880163f42af33676ef76a0b74e9", + [ + null, + {} + ] + ], + "entries-after-blank-navigation.html": [ + "6f6dbcc20df9bb8c0beb4921d84da359b8dbc01d", + [ + null, + {} + ] + ], + "entries-after-blob-navigation.html": [ + "77c25174da2f87a04c9c642e0fa732717bc1937e", + [ + null, + {} + ] + ], + "entries-after-cross-document-forward-pruning.html": [ + "ddd1ad571ddb268b0ea4a147f77b3a08096f2fa6", + [ + null, + {} + ] + ], + "entries-after-javascript-url-navigation.html": [ + "27a07c9e55d37c364595b393cf4282e425854f6a", + [ + null, + {} + ] + ], + "entries-after-navigations-in-multiple-windows.html": [ + "d1d4d86eb382cab6d9f538a6aa35cc51e64da5a0", + [ + null, + {} + ] + ], + "entries-after-srcdoc-navigation.html": [ + "434b376224c6bd121c28e2667050f8fd263a4a04", + [ + null, + {} + ] + ], + "entries-array-equality.html": [ + "98efb6b20c0a1ecb7f3c9fdcee9400656217a57b", + [ + null, + {} + ] + ], + "entries-in-new-javascript-url-iframe.html": [ + "cd4279a7f31fb4264b01a372e62cad9fad94c660", + [ + null, + {} + ] + ], + "entries-in-new-srcdoc-iframe.html": [ + "d261efd0778a787df0194fb40c59cd979680d01a", + [ + null, + {} + ] + ], + "entries-when-inactive.html": [ + "c70b6d8bf870fbbffc7214d14e436ad83613368b", + [ + null, + {} + ] + ], + "entry-after-detach.html": [ + "83962d2a8e146244720f687b5980fec6e5b0bc15", + [ + null, + {} + ] + ], + "index-not-in-entries.html": [ + "37cccd39d829be865485649762b91cc6687710af", + [ + null, + {} + ] + ], + "key-id-back-cross-document.html": [ + "f0dc182be41f27d5abae0b67e0d3fe38d06a135a", + [ + null, + {} + ] + ], + "key-id-back-same-document.html": [ + "b5137f3e51bfcce5e29a72766f230eae1da328d7", + [ + null, + {} + ] + ], + "key-id-location-reload-transitionWhile.html": [ + "a06b645fa6f2f190cb91d4f8bb462a79c972db4e", + [ + null, + {} + ] + ], + "key-id-location-reload.html": [ + "267906d2c38cc4cc65d3c56c8dca0c77bb551fff", + [ + null, + {} + ] + ], + "key-id-location-replace-cross-origin.html": [ + "ee0f749a9edc3435e454f96ef83a366494a1de99", + [ + null, + {} + ] + ], + "key-id-location-replace.html": [ + "ec96371e5648b2bc5e64802cdfc134ff18b18efa", + [ + null, + {} + ] + ], + "no-referrer-dynamic-url-censored.html": [ + "7a5544c4196be057e372f523c77e293de70c6292", + [ + null, + {} + ] + ], + "no-referrer-from-meta-url-censored.html": [ + "51eed0800fb02814ef90342bc2a87bb36b01c161", + [ + null, + {} + ] + ], + "no-referrer-url-censored.html": [ + "20397b8ef9c8af8bf2188257e9a57e687ef6694d", + [ + null, + {} + ] + ], + "opaque-origin-data-url.html": [ + "3275a30ef420f7220aacf85788e1ef9e3b486def", + [ + null, + {} + ] + ], + "opaque-origin.html": [ + "898ca27e4fab1d34bfe9c148ff53880a8a35d8cd", + [ + null, + {} + ] + ], + "sameDocument-after-fragment-navigate.html": [ + "acb67ee72c705563fe850b41f9aa166e634c3313", + [ + null, + {} + ] + ], + "sameDocument-after-navigate-restore.html": [ + "fd21bc222f4c5db9466b9fc56ffee5571b6e4680", + [ + null, + {} + ] + ], + "sameDocument-after-navigate.html": [ + "e1376a07f2550210be1304ae16a37df28ed3daa6", + [ + null, + {} + ] + ], + "state-after-navigate-restore.html": [ + "57fe38a426f1c4f3174b2eccaca8b0baaaff1ca5", + [ + null, + {} + ] + ] + }, + "navigation-methods": { + "back-forward-multiple-frames.html": [ + "738bfd37dcc720aa3c6b1b11208c5d8426860ece", + [ + null, + {} + ] + ], + "disambigaute-back.html": [ + "d44d435896dd8723677db8724478d862468e1cec", + [ + null, + {} + ] + ], + "disambigaute-forward.html": [ + "e252e309941037d42e3f3310c6ce9e140433db77", + [ + null, + {} + ] + ], + "disambigaute-traverseTo-back-multiple.html": [ + "03a8eb10edeb854bc3444136817256180b40709a", + [ + null, + {} + ] + ], + "disambigaute-traverseTo-forward-multiple.html": [ + "f8e78c4b1d951d7c29f326bcdacbf1c688d3635c", + [ + null, + {} + ] + ], + "forward-to-pruned-entry.html": [ + "b8bd36ef061e8936b3dc1dbfdfb3766949cccc3d", + [ + null, + {} + ] + ], + "navigate-base-url.html": [ + "00fefa6608f27fe10f796f316882a628e5a0cb69", + [ + null, + {} + ] + ], + "navigate-from-initial-about-blank-src.html": [ + "2044b33cf027271bbedcff7462114c3b63e0d69b", + [ + null, + {} + ] + ], + "navigate-from-initial-about-blank.html": [ + "d494ec468cebf87a33ab9c5f1de6d0f3184a3879", + [ + null, + {} + ] + ], + "navigate-history-state-replace.html": [ + "f3dbce80bd1e6594fd1a712bc4b802a17a593cf4", + [ + null, + {} + ] + ], + "navigate-history-state.html": [ + "0541636de509c2055b1eee112322d989506de5d8", + [ + null, + {} + ] + ], + "navigate-info-and-state.html": [ + "828d7daea57bda8e00ad775f534e52a9e2ce6273", + [ + null, + {} + ] + ], + "navigate-relative-url.html": [ + "cc95d5e003826b0a309b647107a30d0054a01285", + [ + null, + {} + ] + ], + "navigate-replace-cross-document.html": [ + "02068d994e82747d5a5f72b1e70e7afcdae4b04d", + [ + null, + {} + ] + ], + "navigate-replace-same-document.html": [ + "cc2ea3ab13f54551adb688a873c4bc64052f6979", + [ + null, + {} + ] + ], + "navigate-same-document.html": [ + "9ffd8248f843bc42ec3f251bcf590d6d38ad2b22", + [ + null, + {} + ] + ], + "navigate-state-repeated-await.html": [ + "a003992d66a3b0065ff9382edef612d1636b43e0", + [ + null, + {} + ] + ], + "navigate-state-repeated.html": [ + "29c3f68eeb0caa33e0bec02527edcead675cde6f", + [ + null, + {} + ] + ], + "navigate-transitionWhile-history-state.html": [ + "c5e1036bff4fc7fa771d8d7cb91c0616a461f83e", + [ + null, + {} + ] + ], + "reload-base-url.html": [ + "936ad75c832a13b3aff1f05d21fbf7e9a8f2f728", + [ + null, + {} + ] + ], + "reload-info.html": [ + "637f6976adbbefb08b678ec866cc25360e91f7b5", + [ + null, + {} + ] + ], + "reload-navigation-timing.html": [ + "ce03e7a7ca3db4670ed0053bcd57208c2657fa1c", + [ + null, + {} + ] + ], + "reload-no-args.html": [ + "c94eae0b935d3495c8acf239432a6b7926e50b4c", + [ + null, + {} + ] + ], + "reload-service-worker-fetch-event.html": [ + "67535c70bf79c4ed28a50c9e8ee5de384fac2161", + [ + null, + {} + ] + ], + "reload-state-and-info.html": [ + "3ee6a8b8fa0218767e4322e2e4014d12db68d93e", + [ + null, + {} + ] + ], + "reload-state-undefined.html": [ + "ac204d4731b5d5784ca729b732caf23554b879fe", + [ + null, + {} + ] + ], + "return-value": { + "back-already-detached.html": [ + "f9ff04f923c80b3d224a11c155f87f391ad1fe2d", + [ + null, + {} + ] + ], + "back-beforeunload.html": [ + "82c1f589ccf58ad495715ad3fd29e5895619bf93", + [ + null, + {} + ] + ], + "back-forward-initial-about-blank.html": [ + "dfdb6611ab3f9c50b5c5aafe32acd96600850be9", + [ + null, + {} + ] + ], + "back-forward-opaque-origin.html": [ + "59849e961d76a0151959836870fb7eda47ce8867", + [ + null, + {} + ] + ], + "back-forward-out-of-bounds.html": [ + "015c090bf97e567ab3b4acd4f9858cd79fc9c725", + [ + null, + {} + ] + ], + "back-transitionWhile-rejected.html": [ + "fc171af54b986c2654ca26774fa0cfdf8f4a871d", + [ + null, + {} + ] + ], + "back-transitionWhile.html": [ + "c1161f895a54dc4b4002b775f6cadcceeb0ef2f0", + [ + null, + {} + ] + ], + "back.html": [ + "a2b13db901bfa11e438edbe89b15058b3be582e1", + [ + null, + {} + ] + ], + "forward-already-detached.html": [ + "4dfa74d9f9b9153f23ac36aeeafeb08316e902e4", + [ + null, + {} + ] + ], + "forward-beforeunload.html": [ + "87fa4baa935a7f1739b44db9a4685065f6d0a47c", + [ + null, + {} + ] + ], + "forward-transitionWhile-rejected.html": [ + "7ff0c70f0b9ae859cc9539ae4e74e028e3bbd3cd", + [ + null, + {} + ] + ], + "forward-transitionWhile.html": [ + "2b8175b619d61afee69099d710f833df398ce1aa", + [ + null, + {} + ] + ], + "forward.html": [ + "36bdba8daafd877b6ad274dfab8167110e524c03", + [ + null, + {} + ] + ], + "navigate-already-detached.html": [ + "33cdd6922d3f8eb90fde4cbf64cffd9c51d1fb8d", + [ + null, + {} + ] + ], + "navigate-beforeunload.html": [ + "f0a9069677f7cc63b6f33a6c9ac9555e7afe62dc", + [ + null, + {} + ] + ], + "navigate-cross-document.html": [ + "b83b1e941fd9c594adb174d9d0f2edc9cc7fcb7b", + [ + null, + {} + ] + ], + "navigate-detach.html": [ + "0e80e1b1305c3a257e69b81a7dbdbf2984392629", + [ + null, + {} + ] + ], + "navigate-file-url.html": [ + "138f6ffc124355ee9aa343e4b96097bfd0b9626f", + [ + null, + {} + ] + ], + "navigate-initial-about-blank-cross-document.html": [ + "8ec76b11ddb6b8c24b2c47cded029cb8a07ccea1", + [ + null, + {} + ] + ], + "navigate-initial-about-blank.html": [ + "9734a09d015127463af3b546e31ab5a2e92ee3b1", + [ + null, + {} + ] + ], + "navigate-interrupted-within-onnavigate.html": [ + "3db02c6931e41da69f8a7581ee65a5851d102cec", + [ + null, + {} + ] + ], + "navigate-interrupted.html": [ + "2c928254e0b64e8b5f3750cd366cf73e7edb2998", + [ + null, + {} + ] + ], + "navigate-invalid-url.html": [ + "5b5b442c9133016759d61ff9e7196161a0f48733", + [ + null, + {} + ] + ], + "navigate-opaque-origin.html": [ + "51500eb8d83c121241bbcf467e010fbda43daa55", + [ + null, + {} + ] + ], + "navigate-preventDefault.html": [ + "6257c5a03d6757345d1a29bd4e9115d14f6b847e", + [ + null, + {} + ] + ], + "navigate-rejection-order-beforeunload-unserializablestate.html": [ + "3039c92a08acd51da0dac300e4d3db1b62c18ae9", + [ + null, + {} + ] + ], + "navigate-rejection-order-detached-unserializablestate.html": [ + "f14df84aa3ae472390b0de855f36c517ebdc2047", + [ + null, + {} + ] + ], + "navigate-rejection-order-invalidurl-beforeunload.html": [ + "4873e85a2f8e05097ab2c8fbbd8e7cb30ed03068", + [ + null, + {} + ] + ], + "navigate-rejection-order-invalidurl-detached.html": [ + "2250a541147308c8c1116d21cc358b8e0bf4850a", + [ + null, + {} + ] + ], + "navigate-rejection-order-invalidurl-unload.html": [ + "d778dd662c8b80a74dd81c447dff40e537187e26", + [ + null, + {} + ] + ], + "navigate-rejection-order-invalidurl-unserializablestate.html": [ + "07e194ca4192cc7fbd95b2aa88fd4604cbf77d8f", + [ + null, + {} + ] + ], + "navigate-rejection-order-unload-unserializablestate.html": [ + "287434a7ca91a70d28fe690ef53cccb0c9092ace", + [ + null, + {} + ] + ], + "navigate-transitionWhile-interrupted.html": [ + "fa818b484d327c02f08762a52b0be3455985abcc", + [ + null, + {} + ] + ], + "navigate-transitionWhile-rejected.html": [ + "c1d4c4980251c6cc5d1a36052007657003a6acd5", + [ + null, + {} + ] + ], + "navigate-transitionWhile.html": [ + "2fe78e53e99f1cd59a0b2488cd60de00c0ffef17", + [ + null, + {} + ] + ], + "navigate-unload.html": [ + "fbc1fde6e97caed805432c9183260fb738e7b407", + [ + null, + {} + ] + ], + "navigate-unserializable-state.html": [ + "36464ec3c54edfc92048a466c07f94735f725ede", + [ + null, + {} + ] + ], + "navigate.html": [ + "34ff84f0e9a17edce8b72d861176fb85a1d5787e", + [ + null, + {} + ] + ], + "reload-already-detached.html": [ + "9b0780c4a9592c94a9ed101fd27ed8ef6413dd76", + [ + null, + {} + ] + ], + "reload-beforeunload.html": [ + "05338acc5e7879f716b8367c3e0d3bca345c1d27", + [ + null, + {} + ] + ], + "reload-detach.html": [ + "621bb598f64d6898ecde54d2bc5131f6c727617e", + [ + null, + {} + ] + ], + "reload-initial-about-blank.html": [ + "9e717fee48b02c3ad71cd83f3170982e7dc57410", + [ + null, + {} + ] + ], + "reload-preventDefault.html": [ + "747044b60f7baac2d792cbafeec02a18e1d80780", + [ + null, + {} + ] + ], + "reload-rejection-order-beforeunload-unserializablestate.html": [ + "127f05f6d4f74f9353d52bac6a481d85886e1379", + [ + null, + {} + ] + ], + "reload-rejection-order-detached-unserializablestate.html": [ + "0e00510d2ee4e5fa80d009f65e8977d7bebd854f", + [ + null, + {} + ] + ], + "reload-rejection-order-unload-unserializablestate.html": [ + "85f69efcaebe65f5c56062465471a2a655e762dc", + [ + null, + {} + ] + ], + "reload-transitionWhile-rejected.html": [ + "e6ec928a7368593ea2393fc395cc898716cf882c", + [ + null, + {} + ] + ], + "reload-transitionWhile.html": [ + "19cea8afc28069cdc0657e01406bcf1fbda0416e", + [ + null, + {} + ] + ], + "reload-unload.html": [ + "1906659d1db8968ff235e3758a8e14990e9eb825", + [ + null, + {} + ] + ], + "reload-unserializable-state.html": [ + "76fa870558a3f4055317c211ec7caf33406b3f17", + [ + null, + {} + ] + ], + "reload.html": [ + "028d5855701ad83f4ce5c56710fc6b750c79b9c9", + [ + null, + {} + ] + ], + "traverseTo-already-detached.html": [ + "b974393df6e7445d020889398052fad5f3053543", + [ + null, + {} + ] + ], + "traverseTo-beforeunload.html": [ + "3b2722235eecc6be300694bdd97b91a3eafb29ac", + [ + null, + {} + ] + ], + "traverseTo-cross-document-preventDefault.html": [ + "09c91ee647ef7ffa3a9906faa4f1c14e0e830ab7", + [ + null, + {} + ] + ], + "traverseTo-current.html": [ + "212fe992cf774cdcf5565f64ce0f4edf77b33c9f", + [ + null, + {} + ] + ], + "traverseTo-detach-cross-document.html": [ + "8784313b70546e49d37e227ec9c0f809990b77d5", + [ + null, + {} + ] + ], + "traverseTo-detach-same-document.html": [ + "b0308b8df8fe4c3ed975fe16b790c29a0de1891c", + [ + null, + {} + ] + ], + "traverseTo-invalid-key.html": [ + "42be40bfa7679b44b1af1fb935f1925e79942ae3", + [ + null, + {} + ] + ], + "traverseTo-repeated.html": [ + "d1754d6729749316216713cb63c3cc498c8292ad", + [ + null, + {} + ] + ], + "traverseTo-transitionWhile-rejected.html": [ + "613531023fa4bc6455e359d59541d0602b8906d5", + [ + null, + {} + ] + ], + "traverseTo-transitionWhile.html": [ + "430fbe8be79211be28b685e91733aab11a05f9ff", + [ + null, + {} + ] + ], + "traverseTo.html": [ + "8e00f5ba918cddc9d5a7df9336c3eefc05062e32", + [ + null, + {} + ] + ] + }, + "traverseTo-after-adding-iframe.html": [ + "5ab28205510800eccc6fffed97b972929e1c0068", + [ + null, + {} + ] + ], + "traverseTo-after-data-url.html": [ + "0b21a741d3017b71fe26acd586faddbf3c5802b7", + [ + null, + {} + ] + ], + "traverseTo-cross-document.html": [ + "2540639baddd6cf9130e1f8fcfe76dd4d30852ef", + [ + null, + {} + ] + ], + "traverseTo-detach-between-navigate-and-navigatesuccess.html": [ + "9a9529578147b557c83a10f499227645b0ceb746", + [ + null, + {} + ] + ], + "traverseTo-multiple-steps.html": [ + "059eb214a8b8529779b6e0455220faca391a12d8", + [ + null, + {} + ] + ], + "traverseTo-same-document.html": [ + "1a32bce99c98e22ea426f612c26d6368adae4972", + [ + null, + {} + ] + ], + "traverseTo-with-cross-origin-in-history.html": [ + "a6b7745584a6458dca0f9722d1b793367fc94cdb", + [ + null, + {} + ] + ] + }, + "ordering-and-transition": { + "back-same-document-transitionWhile-reject.html": [ + "68cff8085d49fd8f5751d05e81088d828728fff6", + [ + null, + {} + ], + [ + "navigation-api/ordering-and-transition/back-same-document-transitionWhile-reject.html?currententrychange", + {} + ] + ], + "back-same-document-transitionWhile.html": [ + "30d083c9e6dbb80b1f60401cc6ba2ddba92c6366", + [ + null, + {} + ], + [ + "navigation-api/ordering-and-transition/back-same-document-transitionWhile.html?currententrychange", + {} + ] + ], + "back-same-document.html": [ + "cc303754119484bf3338e64fe7af8c3a000e50f1", + [ + null, + {} + ], + [ + "navigation-api/ordering-and-transition/back-same-document.html?currententrychange", + {} + ] + ], + "currententrychange-before-popstate-transitionWhile.html": [ + "f4c36fa0ab21143fd69f4fe5079845d87231ad7f", + [ + null, + {} + ] + ], + "currententrychange-dispose-ordering.html": [ + "396a46ff969b2f3649b39850662bd37186bc0cd8", + [ + null, + {} + ] + ], + "location-href-canceled.html": [ + "f4247413d3aa2f325c920352c643857c0d09ca12", + [ + null, + {} + ] + ], + "location-href-double-transitionWhile.html": [ + "6e7c89502d60844035eea74f35530e81d63402cd", + [ + null, + {} + ], + [ + "navigation-api/ordering-and-transition/location-href-double-transitionWhile.html?currententrychange", + {} + ] + ], + "location-href-transitionWhile-reentrant.html": [ + "36b23554ddb9566c4a7ec894a050944bcae0dea9", + [ + null, + {} + ], + [ + "navigation-api/ordering-and-transition/location-href-transitionWhile-reentrant.html?currententrychange", + {} + ] + ], + "location-href-transitionWhile-reject.html": [ + "e3f65e81d44e0dc1fe53532953f40d4fc767ce6d", + [ + null, + {} + ], + [ + "navigation-api/ordering-and-transition/location-href-transitionWhile-reject.html?currententrychange", + {} + ] + ], + "location-href-transitionWhile.html": [ + "0ae41447213ba7bb6e9ea8baf819715d0328c8e2", + [ + null, + {} + ], + [ + "navigation-api/ordering-and-transition/location-href-transitionWhile.html?currententrychange", + {} + ] + ], + "navigate-canceled.html": [ + "851fa349937c207d97ada62d790d22d6a93f53b4", + [ + null, + {} + ] + ], + "navigate-cross-document-double.html": [ + "353cfa1b4e4b5fbc98a1f5827024ab8e73b98058", + [ + null, + {} + ] + ], + "navigate-cross-document-event-order.html": [ + "34a9b79fb5f01e074538e0bc228bd34a5818b263", + [ + null, + {} + ] + ], + "navigate-double-transitionWhile.html": [ + "4413ca4c35d93a33360d565c9fdaf40fa24fcc4b", + [ + null, + {} + ], + [ + "navigation-api/ordering-and-transition/navigate-double-transitionWhile.html?currententrychange", + {} + ] + ], + "navigate-in-transition-finished.html": [ + "f8ebd6927322e5d360ad648a95995a972ecd9dbe", + [ + null, + {} + ], + [ + "navigation-api/ordering-and-transition/navigate-in-transition-finished.html?currententrychange", + {} + ] + ], + "navigate-same-document-transitionWhile-reentrant.html": [ + "8cbb98e85819e20d742c2b1ac48b2fe33edce6a6", + [ + null, + {} + ], + [ + "navigation-api/ordering-and-transition/navigate-same-document-transitionWhile-reentrant.html?currententrychange", + {} + ] + ], + "navigate-same-document-transitionWhile-reject.html": [ + "45ce700057053b7d7e873f6c21765e5c1ca0cc35", + [ + null, + {} + ], + [ + "navigation-api/ordering-and-transition/navigate-same-document-transitionWhile-reject.html?currententrychange", + {} + ] + ], + "navigate-same-document.html": [ + "07f7bdce5d6ea10acd7801bcbed26deea01dbc98", + [ + null, + {} + ], + [ + "navigation-api/ordering-and-transition/navigate-same-document.html?currententrychange", + {} + ] + ], + "navigate-transitionWhile-stop.html": [ + "9d06ba17969fa4b19db945589cf5a3933c4709e9", + [ + null, + {} + ], + [ + "navigation-api/ordering-and-transition/navigate-transitionWhile-stop.html?currententrychange", + {} + ] + ], + "navigate-transitionWhile.html": [ + "d3125b0fc099877014eddfb401115f1a3833f248", + [ + null, + {} + ], + [ + "navigation-api/ordering-and-transition/navigate-transitionWhile.html?currententrychange", + {} + ] + ], + "reload-canceled.html": [ + "a7ae7913c6107f89e79f9b964d3ae103bf657770", + [ + null, + {} + ] + ], + "reload-transitionWhile-reject.html": [ + "0a70c6deed4fdfe49edbe10d1956fa1d2adecf98", + [ + null, + {} + ], + [ + "navigation-api/ordering-and-transition/reload-transitionWhile-reject.html?currententrychange", + {} + ] + ], + "reload-transitionWhile.html": [ + "8cc237f2dddafa98b4fcf19f9df54f35920f0a87", + [ + null, + {} + ], + [ + "navigation-api/ordering-and-transition/reload-transitionWhile.html?currententrychange", + {} + ] + ], + "transition-cross-document.html": [ + "4a14a1083d4611911f4f03e60209d97643e6af38", + [ + null, + {} + ] + ], + "transition-finished-mark-as-handled.html": [ + "859e07df139701977ccb9fa4fe7d38de2fff4f2f", + [ + null, + {} + ] + ], + "transition-realms-and-identity.html": [ + "16fb8184545e7df127dd581f61ab7e497771c474", + [ + null, + {} + ] + ] + }, + "per-entry-events": { + "dispose-after-bfcache.html": [ + "7d3ef4f81edbcb828ff2cef55d5b9e97403914c3", + [ + null, + {} + ] + ], + "dispose-cross-document.html": [ + "67f54da48d21252db1d08d71db557275fad14b75", + [ + null, + {} + ] + ], + "dispose-same-document-navigate-during.html": [ + "59d9b3cce3977ae255e25a2e96220ef92700c63c", + [ + null, + {} + ] + ], + "dispose-same-document-reload-with-transitionWhile.html": [ + "b55bfb4132923275c49185506ce203fffef4e8cf", + [ + null, + {} + ] + ], + "dispose-same-document-replace-with-transitionWhile.html": [ + "1931cd3ed13eb66a6551d9a7377c6dec3f8a29a5", + [ + null, + {} + ] + ], + "dispose-same-document-replaceState.html": [ + "a6197260a28b8137a142453fd669fbeb82b12680", + [ + null, + {} + ] + ], + "dispose-same-document-transitionWhile.html": [ + "2c0b92e7ad9a80c59863f4dd564581682abd9f8a", + [ + null, + {} + ] + ], + "dispose-same-document.html": [ + "27806ce3c86a672701785be2453788e50b9b7388", + [ + null, + {} + ] + ] + }, + "state": { + "cross-document-away-and-back.html": [ + "25d0c1e79811cea7de5b747aab2066caaceb558e", + [ + null, + {} + ] + ], + "cross-document-location-api.html": [ + "9c869ca1d276e465b29ae719a1e24a735e0e91b8", + [ + null, + {} + ] + ], + "history-pushState.html": [ + "1c8858c0af0c363bb12f74fbc1c76b5914264449", + [ + null, + {} + ] + ], + "history-replaceState.html": [ + "cc37949415eb8b29ac85ebd4efc8c6dd96616b8d", + [ + null, + {} + ] + ], + "location-reload.html": [ + "94d466434638ef5823dee86541a69349a4d5878c", + [ + null, + {} + ] + ], + "same-document-away-and-back-location-api.html": [ + "9cb6215089fdb56e2a241e927a8fb5366de94b62", + [ + null, + {} + ] + ], + "same-document-away-and-back-navigation-api.html": [ + "eed296d583afc722bf14f378e4b0641b64d1c16a", + [ + null, + {} + ] + ] + }, + "updateCurrentEntry-method": { + "basic.html": [ + "b4a49e5bf9ca672756cb972e09ceaf1f9a6c2d36", + [ + null, + {} + ] + ], + "cross-document-away-and-back.html": [ + "a192314050df0a2251a7b89d8eea4569862de7de", + [ + null, + {} + ] + ], + "cross-document-location-api.html": [ + "3b4ec68bae006db8149a323ffb542f7f7fbcbec8", + [ + null, + {} + ] + ], + "exception-order-initial-about-blank-unserializablestate.html": [ + "010632a40fcda3c98ff76965c61453919d6f42ba", + [ + null, + {} + ] + ], + "exception-order-not-fully-active-unserializablestate.html": [ + "1e1c1e2bae48315a5b895b1ed008b49e35c102a7", + [ + null, + {} + ] + ], + "history-pushState.html": [ + "73fb89f2a0f8d4daf76537038b1eb315cd1bb0b0", + [ + null, + {} + ] + ], + "history-replaceState.html": [ + "15472db2e777daf05d107998729b0b3f7f79035a", + [ + null, + {} + ] + ], + "initial-about-blank.html": [ + "c28137c082a3b30fd9f575abd797c107108d0851", + [ + null, + {} + ] + ], + "location-reload.html": [ + "664ff1b23a5c2223e462c1c0feba2a991ba8044d", + [ + null, + {} + ] + ], + "no-args.html": [ + "3fd011e3d37335cacc2c02c3d6649e9a3dc22fd8", + [ + null, + {} + ] + ], + "not-fully-active.html": [ + "fce5e72c8d400e35ce42938dded89d5c837db77e", + [ + null, + {} + ] + ], + "opaque-origin.html": [ + "898ca27e4fab1d34bfe9c148ff53880a8a35d8cd", + [ + null, + {} + ] + ], + "same-document-away-and-back-location-api.html": [ + "a1f54f5b7c21f1a8767c9ed2623bf819c7bad0d8", + [ + null, + {} + ] + ], + "unserializable.html": [ + "596ab16d621f5eb31049a251c8c591d5de504385", + [ + null, + {} + ] + ] + } + }, "navigation-timing": { "buffered-flag.window.js": [ "c6b1e0bc8558a2908d6471fff0e7f5351d4a0022", @@ -509558,6 +509688,15 @@ } ] ], + "opt-out.html": [ + "3bfa00c6dc8921b5888e4c24fbb2f11d0a903080", + [ + null, + { + "timeout": "long" + } + ] + ], "restriction-focus.html": [ "1149b8bd0981e8cf0109f2bca9dd974b9cd9a604", [
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/fedcm-revoke.https.html b/third_party/blink/web_tests/external/wpt/credential-management/fedcm-revoke.https.html index 84a20b0..f0c3e5eb 100644 --- a/third_party/blink/web_tests/external/wpt/credential-management/fedcm-revoke.https.html +++ b/third_party/blink/web_tests/external/wpt/credential-management/fedcm-revoke.https.html
@@ -13,7 +13,6 @@ const provider = { url: provider_url || "https://idp.example/", clientId: "1234", - hint: "foo@bar.com", }; return await navigator.credentials.get({ federated: { @@ -24,17 +23,23 @@ fedcm_test(async (t, mock) => { mock.revokeReturn("kSuccess"); - await (await getCredential()).revoke(); + await (await getCredential()).revoke("foo@bar.com"); }, "Successfully revoking a token should resolve the promise."); fedcm_test(async (t, mock) => { mock.revokeReturn("kError"); - const result = (await getCredential()).revoke(); + const result = (await getCredential()).revoke("foo@bar.com"); return promise_rejects_dom(t, "NetworkError", result); }, "Error should reject the promise."); fedcm_test(async (t, mock) => { - const result = getCredential("https://other-idp.example/").then((c) => c.revoke()); + mock.revokeReturn("kError"); + const result = (await getCredential()).revoke(""); + return promise_rejects_dom(t, "InvalidStateError", result); + }, "Empty hint should reject the promise."); + + fedcm_test(async (t, mock) => { + const result = getCredential("https://other-idp.example/").then((c) => c.revoke("foo@bar.com")); return promise_rejects_dom(t, "NetworkError", result); }, "Provider URL should honor Content-Security-Policy."); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-column-flex-fragmentation-012.html b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-column-flex-fragmentation-012.html new file mode 100644 index 0000000..7552a741 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-column-flex-fragmentation-012.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<title> + Tests that a flexbox expands its intrinsic block-size, due to a + flex item fragmenting. +</title> +<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#pagination"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="width: 100px; height: 100px; columns: 2; column-gap: 0; column-fill: auto; background: red;"> + <div style="display: flex; flex-direction: column; flex-wrap: wrap; background: green;"> + <div style="display: flex; flex-wrap: wrap; flex-direction: column;"> + <div style="line-height: 0;"> + <div style="display: inline-block; width: 50px; height: 50px;"></div> + <div style="display: inline-block; width: 50px; height: 100px;"></div> + </div> + </div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-column-flex-fragmentation-013.html b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-column-flex-fragmentation-013.html new file mode 100644 index 0000000..ed73994 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-column-flex-fragmentation-013.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<title> + Tests that flex-items get pushed down due to a previous flex-item expanding as + a result of fragmentation. +</title> +<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#pagination"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="width: 100px; height: 100px; columns: 2; column-gap: 0; column-fill: auto; background: red;"> + <div style="display: flex; flex-direction: column; flex-wrap: wrap; height: 200px;"> + <div style="line-height: 0; background: green; width: 25px;"> + <div style="display: inline-block; width: 25px; height: 80px;"></div> + <div style="display: inline-block; width: 25px; height: 30px;"></div> + </div> + <div style="background: green; width: 25px; height: 50px;"></div> + <div style="background: green; width: 25px; height: 20px;"></div> + <div style="line-height: 0; background: green; width: 25px;"> + <div style="display: inline-block; width: 25px; height: 30px;"></div> + <div style="display: inline-block; width: 25px; height: 80px;"></div> + </div> + <div style="background: green; width: 25px; height: 10px;"></div> + <div style="background: green; width: 25px; height: 10px;"></div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-column-flex-fragmentation-014.html b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-column-flex-fragmentation-014.html new file mode 100644 index 0000000..bcc32dd --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-column-flex-fragmentation-014.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<title> + Tests that flex-items *don't* get pushed down when there is no expansion. +</title> +<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#pagination"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="width: 100px; height: 100px; columns: 2; column-gap: 0; column-fill: auto; background: red;"> + <div style="display: flex; flex-direction: column; flex-wrap: wrap; height: 200px;"> + <div style="line-height: 0; background: green; height: 110px; width: 25px;"> + <div style="display: inline-block; width: 25px; height: 80px;"></div> + <div style="display: inline-block; width: 25px; height: 30px;"></div> + </div> + <div style="background: green; height: 90px; width: 25px;"></div> + <div style="line-height: 0; background: green; height: 110px; width: 25px;"> + <div style="display: inline-block; width: 25px; height: 30px;"></div> + <div style="display: inline-block; width: 25px; height: 80px;"></div> + </div> + <div style="background: green; height: 90px; width: 25px;"></div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-column-flex-fragmentation-015.html b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-column-flex-fragmentation-015.html new file mode 100644 index 0000000..563f3663 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-column-flex-fragmentation-015.html
@@ -0,0 +1,44 @@ +<!DOCTYPE html> +<title> + Tests that flex-items get pushed down due to a previous flex-item expanding as + a result of fragmentation. +</title> +<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#pagination"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="width: 100px; height: 100px; columns: 5; column-gap: 0; column-fill: auto; background: red;"> + <div style="display: flex; flex-direction: column; flex-wrap: wrap; height: 500px;"> + <div style="background: green; width: 10px;"> + <div style="contain: size; width: 10px; height: 60px;"></div> + <div style="contain: size; width: 25px; height: 50px;"></div> + </div> + <div style="background: green; order: -1; width: 10px;"> + <div style="contain: size; width: 10px; height: 80px;"></div> + <div style="contain: size; width: 10px; height: 30px;"></div> + </div> + <div style="background: green; width: 10px;"> + <div style="contain: size; width: 10px; height: 20px;"></div> + <div style="contain: size; width: 10px; height: 100px; background: white;"></div> + </div> + <div style="background: green; width: 10px;"> + <div style="contain: size; width: 25px; height: 50px;"></div> + <div style="contain: size; width: 10px; height: 60px;"></div> + </div> + <div style="background: green; order: -1; width: 10px;"> + <div style="contain: size; width: 10px; height: 30px;"></div> + <div style="contain: size; width: 10px; height: 100px;"></div> + </div> + <div style="background: green; width: 10px;"> + <div style="contain: size; width: 10px; height: 20px;"></div> + <div style="contain: size; width: 10px; height: 100px;"></div> + </div> + <div style="background: green; width: 10px;"> + <div style="contain: size; width: 10px; height: 40px;"></div> + <div style="contain: size; width: 10px; height: 20px;"></div> + </div> + <div style="background: green; width: 10px;"> + <div style="contain: size; width: 10px; height: 20px;"></div> + <div style="contain: size; width: 10px; height: 100px;"></div> + </div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-column-flex-fragmentation-016.html b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-column-flex-fragmentation-016.html new file mode 100644 index 0000000..e81ad10 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-column-flex-fragmentation-016.html
@@ -0,0 +1,55 @@ +<!DOCTYPE html> +<title> + Tests that flex-items get pushed down due to a previous flex row expanding as + a result of fragmentation with margin-top. +</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-direction: column; + flex-wrap: wrap; + height: 500px; + } + #flex > div { + background: green; + width: 10px; + } +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="width: 100px; height: 100px; columns: 5; column-gap: 0; column-fill: auto; background: red;"> + <div id="flex"> + <div> + <div style="contain: size; width: 10px; height: 80px;"></div> + <div style="contain: size; width: 10px; height: 30px;"></div> + </div> + <div style="position: relative;"> + <div style="contain: size; width: 10px; height: 70px;"></div> + <div style="contain: size; width: 10px; height: 40px;"></div> + <div style="position: absolute; width: 10px; height: 60px; background: green;"></div> + </div> + <div style="margin-top: 10px;"> + <div style="contain: size; width: 10px; height: 80px;"></div> + <div style="contain: size; width: 10px; height: 40px;"></div> + </div> + <div style="height: 100px;"></div> + <div style="height: 60px;"></div> + <div style="margin-top: 10px; position: relative;"> + <div style="position: absolute; top: -10px; width: 10px; height: 10px; background: green;"></div> + <div style="contain: size; width: 10px; height: 30px;"></div> + <div style="contain: size; width: 10px; height: 80px;"></div> + <div style="position: absolute; width: 10px; height: 20px; background: green;"></div> + </div> + <div> + <div style="contain: size; width: 10px; height: 40px;"></div> + <div style="contain: size; width: 10px; height: 70px;"></div> + </div> + <div style="position: relative;"> + <div style="contain: size; width: 10px; height: 30px;"></div> + <div style="contain: size; width: 10px; height: 80px;"></div> + <div style="contain: size; width: 10px; height: 40px;"></div> + <div style="position: absolute; bottom: 0px; left: -10px; width: 20px; height: 40px; background: white;"></div> + </div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-016.html b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-016.html index 7b690f1..fbd557c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-016.html +++ b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/multi-line-row-flex-fragmentation-016.html
@@ -30,7 +30,7 @@ <div style="margin-top: 10px; width: 20px; position: relative;"> <div style="contain: size; width: 20px; height: 80px;"></div> <div style="contain: size; width: 20px; height: 40px;"></div> - <div style="position: absolute; top: -70px; width: 20px; height: 70px; background: green;"></div> + <div style="position: absolute; top: -60px; width: 20px; height: 60px; background: green;"></div> </div> <div style="height: 100px; width: 20px;"></div> <div style="height: 60px; width: 20px;"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-size-fieldset-004-ref.html b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-size-fieldset-004-ref.html index 198e8e1..59f7c7e2 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-size-fieldset-004-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-size-fieldset-004-ref.html
@@ -26,7 +26,6 @@ } legend, .innerContents { width: 0; - height: 0; padding: 0; } </style>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/fieldset-baseline-alignment-ref.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/fieldset-baseline-alignment-ref.html new file mode 100644 index 0000000..d68e033 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/fieldset-baseline-alignment-ref.html
@@ -0,0 +1,4 @@ +<!DOCTYPE html> +<div style="display: block;"> + baseline<fieldset style="display: inline-block;"><legend>legend</legend>content</fieldset> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/fieldset-baseline-alignment.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/fieldset-baseline-alignment.html new file mode 100644 index 0000000..d3fdba3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/fieldset-baseline-alignment.html
@@ -0,0 +1,6 @@ +<!DOCTYPE html> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1305890"> +<link rel="match" href="fieldset-baseline-alignment-ref.html"> +<div style="display: flex; align-items: baseline;"> + baseline<fieldset><legend>legend</legend>content</fieldset> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-baseline-ref.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-baseline-ref.html new file mode 100644 index 0000000..ff58343 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-baseline-ref.html
@@ -0,0 +1,14 @@ +<!DOCTYPE html> +<style> +span { + border: solid 2px; + padding: 10px; + margin: 5px; +} +</style> +<div> + text <span style="display: inline-block;">line1<br>line2</span> +</div> +<div> + text <span style="display: inline-flex;">line1<br>line2</span> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-baseline.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-baseline.html new file mode 100644 index 0000000..23f5ad7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-baseline.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1305890"> +<link rel="match" href="fieldset-baseline-ref.html"> +<style> +fieldset { + border: solid 2px; + padding: 10px; + margin: 5px; +} +</style> +<div> + text <fieldset style="display: inline-block;">line1<br>line2</fieldset> +</div> +<div> + text <fieldset style="display: inline-flex;">line1<br>line2</fieldset> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/lint.ignore b/third_party/blink/web_tests/external/wpt/lint.ignore index 08565dd..bc320dc 100644 --- a/third_party/blink/web_tests/external/wpt/lint.ignore +++ b/third_party/blink/web_tests/external/wpt/lint.ignore
@@ -332,6 +332,7 @@ SET TIMEOUT: scheduler/tentative/current-task-signal-async-abort.any.js SET TIMEOUT: scheduler/tentative/current-task-signal-async-priority.any.js SET TIMEOUT: speculation-rules/prerender/resources/activation-start.html +SET TIMEOUT: speculation-rules/prerender/resources/prerender-response-code.html SET TIMEOUT: speculation-rules/prerender/resources/deferred-promise-utils.js SET TIMEOUT: speculation-rules/prerender/resources/utils.js SET TIMEOUT: html/browsers/browsing-the-web/back-forward-cache/timers.html
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/opt-out.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/opt-out.html new file mode 100644 index 0000000..3bfa00c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/opt-out.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<title>Check that non-successful responses result in discarding the prerender</title> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<script src="/common/dispatcher/dispatcher.js"></script> +<script src="resources/utils.js"></script> +<body> +<script> + +setup(() => assertSpeculationRulesIsSupported()); +function test_prerender_response_code(code, expectation) { + promise_test(async t => { + const {exec, tryToActivate} = await create_prerendered_page(t, {code}); + const result = await tryToActivate(); + assert_equals(result, expectation); + },`Responses with code ${code} should be ${expectation}`); +} + +const expectations = { + activated: [200, 201, 202, 203], + discarded: [204, 205, 402, 404, 500, 503] +}; + +for (const expect in expectations) { + for (const code of expectations[expect]) + test_prerender_response_code(code, expect); +} +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/exec.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/exec.html index 757dba1..80e0c59 100644 --- a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/exec.html +++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/exec.html
@@ -3,6 +3,9 @@ <script src="/common/utils.js"></script> <script src="/common/dispatcher/dispatcher.js"></script> <script> - new Executor(new URLSearchParams(window.location.search).get('uuid')); + const params = new URLSearchParams(window.location.search); + const uuid = params.get('uuid'); + const discard_uuid = params.get('discard_uuid') || uuid; + new Executor(document.prerendering ? uuid : discard_uuid).execute(); </script> </head> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/exec.py b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/exec.py new file mode 100644 index 0000000..835a3f0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/exec.py
@@ -0,0 +1,13 @@ +from wptserve.utils import isomorphic_decode +import os + +def main(request, response): + purpose = request.headers.get(b"purpose") + if (purpose == b'prefetch' and b"code" in request.GET): + code = int(request.GET.first(b"code")) + else: + code = 200 + + with open(os.path.join(os.path.dirname(isomorphic_decode(__file__)), "exec.html"), u"r") as fn: + response.content = fn.read() + response.status = code
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/prerender-response-code.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/prerender-response-code.html new file mode 100644 index 0000000..c3a680bb --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/prerender-response-code.html
@@ -0,0 +1,22 @@ +<head> +<script src="/common/utils.js"></script> +<script src="./utils.js"></script> +<script> + const search = new URLSearchParams(location.search); + const uid = search.get('uid'); + const uid1 = token(); + const uid2 = token(); + const bc = new BroadcastChannel(uid); + + window.onload = async () => { + bc.addEventListener('message', ({data}) => { + if (data === 'close') + window.close(); + else if (data === 'activate') + location.href = url; + }) + + startPrerendering(`/speculation-rules/prerender/resources/dual-exec.html?uid1=${uid1}&uid2=${uid2}`); + }; +</script> +</head> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/utils.js b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/utils.js index bbb9448..6952c3b 100644 --- a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/utils.js +++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/utils.js
@@ -179,13 +179,21 @@ }); } -async function create_prerendered_page(t) { +async function create_prerendered_page(t, opt = {}) { + const baseUrl = '/speculation-rules/prerender/resources/exec.py'; const init_uuid = token(); const prerender_uuid = token(); + const discard_uuid = token(); const init_remote = new RemoteContext(init_uuid); const prerender_remote = new RemoteContext(prerender_uuid); - window.open(`/speculation-rules/prerender/resources/exec.html?uuid=${init_uuid}&init`, '_blank', 'noopener'); - const url = `/speculation-rules/prerender/resources/exec.html?uuid=${prerender_uuid}&prerender`; + const discard_remote = new RemoteContext(discard_uuid); + window.open(`${baseUrl}?uuid=${init_uuid}&init`, '_blank', 'noopener'); + const params = new URLSearchParams(baseUrl.search); + params.set('uuid', prerender_uuid); + params.set('discard_uuid', discard_uuid); + for (const p in opt) + params.set(p, opt[p]); + const url = `${baseUrl}?${params.toString()}`; await init_remote.execute_script(url => { const a = document.createElement('a'); @@ -198,37 +206,48 @@ document.head.appendChild(rules); }, [url]); - await prerender_remote.execute_script(() => { - window.import_script_to_prerendered_page = src => { - const script = document.createElement('script'); - script.src = src; - document.head.appendChild(script); - return new Promise(resolve => script.addEventListener('load', resolve)); - } - }); + await Promise.any([ + prerender_remote.execute_script(() => { + window.import_script_to_prerendered_page = src => { + const script = document.createElement('script'); + script.src = src; + document.head.appendChild(script); + return new Promise(resolve => script.addEventListener('load', resolve)); + } + }), new Promise(r => t.step_timeout(r, 3000)) + ]); t.add_cleanup(() => { init_remote.execute_script(() => window.close()); + discard_remote.execute_script(() => window.close()); prerender_remote.execute_script(() => window.close()); }); - async function activate() { - const prerendering = prerender_remote.execute_script(() => new Promise(resolve => - document.addEventListener('prerenderingchange', () => { - resolve(document.prerendering); - }))); + async function tryToActivate() { + const prerendering = prerender_remote.execute_script(() => new Promise(resolve => { + if (!document.prerendering) + resolve('activated'); + else document.addEventListener('prerenderingchange', () => resolve('activated')); + })); + + const discarded = discard_remote.execute_script(() => Promise.resolve('discarded')); init_remote.execute_script(url => { - location.href = url; + location.href = url; }, [url]); + return Promise.any([prerendering, discarded]); + } - if (await prerendering) + async function activate() { + const prerendering = await tryToActivate(); + if (prerendering !== 'activated') throw new Error('Should not be prerendering at this point') } return { exec: (fn, args) => prerender_remote.execute_script(fn, args), - activate + activate, + tryToActivate }; }
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/styles-3/spectrum-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/styles-3/spectrum-expected.txt index 1bcba848..1c4229f 100644 --- a/third_party/blink/web_tests/http/tests/devtools/elements/styles-3/spectrum-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/elements/styles-3/spectrum-expected.txt
@@ -33,6 +33,14 @@ hsl(1deg 100% 50% / 20%) Testing: hsL(1deg 100% 50% / 20%) hsl(1deg 100% 50% / 20%) +Testing: hwb(1 100% 50%) +hwb(0deg 67% 33%) +Testing: hwb(100grad 100% 50% / 0.2) +hwb(0deg 67% 33% / 20%) +Testing: hwb(1rad 20% 50% / 20%) +hwb(57deg 20% 50% / 20%) +Testing: hwB(1deg 20% 50% / 20%) +hwb(1deg 20% 50% / 20%) --- Testing alpha changes Testing: red #ff000000 @@ -66,6 +74,14 @@ hsl(1deg 100% 50% / 0%) Testing: hsL(1deg 100% 50% / 20%) hsl(1deg 100% 50% / 0%) +Testing: hwb(1 100% 50%) +hwb(0deg 67% 33% / 0%) +Testing: hwb(100grad 100% 50% / 0.2) +hwb(0deg 67% 33% / 0%) +Testing: hwb(1rad 20% 50% / 20%) +hwb(57deg 20% 50% / 0%) +Testing: hwB(1deg 20% 50% / 20%) +hwb(1deg 20% 50% / 0%) --- Testing _formatViewSwitch() Testing: red rgb @@ -84,35 +100,47 @@ hsl Testing: rgb(1, 2, 3) hsl -hex +hwb Testing: rgba(1, 2, 3, 0.2) hsl -hex +hwb Testing: rgb(1, 2, 3, 0.2) hsl -hex +hwb Testing: rgb(1 2 3 / 20%) hsl -hex +hwb Testing: rgbA(1 2 3) hsl -hex +hwb Testing: rgba(1.5 2.6 3.1) hsl -hex +hwb Testing: hsl(1, 100%, 50%) +hwb hex -rgb Testing: hsl(1 100% 50%) +hwb hex -rgb Testing: hsla(1, 100%, 50%, 0.2) +hwb hex -rgb Testing: hsl(1 100% 50% / 20%) +hwb +hex +Testing: hsL(1deg 100% 50% / 20%) +hwb +hex +Testing: hwb(1 100% 50%) hex rgb -Testing: hsL(1deg 100% 50% / 20%) +Testing: hwb(100grad 100% 50% / 0.2) +hex +rgb +Testing: hwb(1rad 20% 50% / 20%) +hex +rgb +Testing: hwB(1deg 20% 50% / 20%) hex rgb
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/styles-3/spectrum.js b/third_party/blink/web_tests/http/tests/devtools/elements/styles-3/spectrum.js index 87a60c1f..02d7995 100644 --- a/third_party/blink/web_tests/http/tests/devtools/elements/styles-3/spectrum.js +++ b/third_party/blink/web_tests/http/tests/devtools/elements/styles-3/spectrum.js
@@ -43,7 +43,9 @@ {string: 'rgb(1 2 3 / 20%)', format: cf.RGB}, {string: 'rgbA(1 2 3)', format: cf.RGB}, {string: 'rgba(1.5 2.6 3.1)', format: cf.RGB}, {string: 'hsl(1, 100%, 50%)', format: cf.HSL}, {string: 'hsl(1 100% 50%)', format: cf.HSL}, {string: 'hsla(1, 100%, 50%, 0.2)', format: cf.HSLA}, - {string: 'hsl(1 100% 50% / 20%)', format: cf.HSL}, {string: 'hsL(1deg 100% 50% / 20%)', format: cf.HSL} + {string: 'hsl(1 100% 50% / 20%)', format: cf.HSL}, {string: 'hsL(1deg 100% 50% / 20%)', format: cf.HSL}, + {string: 'hwb(1 100% 50%)', format: cf.HWB}, {string: 'hwb(100grad 100% 50% / 0.2)', format: cf.HWB}, + {string: 'hwb(1rad 20% 50% / 20%)', format: cf.HWB}, {string: 'hwB(1deg 20% 50% / 20%)', format: cf.HWB} ]; TestRunner.addResult('--- Testing colorString()');
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/styles-4/styles-invalid-color-values-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/styles-4/styles-invalid-color-values-expected.txt index 51bb48f..96931e59 100644 --- a/third_party/blink/web_tests/http/tests/devtools/elements/styles-4/styles-invalid-color-values-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/elements/styles-4/styles-invalid-color-values-expected.txt
@@ -13,6 +13,7 @@ shorthexa: #f00f rgb: rgb(255 0 0) hsl: hsl(0deg 100% 50%) + hwb: hwb(0deg 0% 0%) color: #F00 simple: true @@ -24,6 +25,7 @@ shorthexa: #f00f rgb: rgb(255 0 0) hsl: hsl(0deg 100% 50%) + hwb: hwb(0deg 0% 0%) color: #F00F simple: true @@ -35,6 +37,7 @@ shorthexa: #F00F rgb: rgb(255 0 0) hsl: hsl(0deg 100% 50%) + hwb: hwb(0deg 0% 0%) color: #FF0000 simple: true @@ -46,6 +49,7 @@ shorthexa: #f00f rgb: rgb(255 0 0) hsl: hsl(0deg 100% 50%) + hwb: hwb(0deg 0% 0%) color: #FF0000FF simple: true @@ -57,6 +61,7 @@ shorthexa: #f00f rgb: rgb(255 0 0) hsl: hsl(0deg 100% 50%) + hwb: hwb(0deg 0% 0%) color: rgb(255,0,0) simple: true @@ -68,6 +73,7 @@ shorthexa: #f00f rgb: rgb(255,0,0) hsl: hsl(0deg 100% 50%) + hwb: hwb(0deg 0% 0%) color: rgb(300,0,0) simple: true @@ -79,6 +85,7 @@ shorthexa: #f00f rgb: rgb(255 0 0) hsl: hsl(0deg 100% 50%) + hwb: hwb(0deg 0% 0%) color: rgb(255,-10,0) simple: true @@ -90,6 +97,7 @@ shorthexa: #f00f rgb: rgb(255 0 0) hsl: hsl(0deg 100% 50%) + hwb: hwb(0deg 0% 0%) color: rgb(110%, 0%, 0%) simple: true @@ -101,6 +109,7 @@ shorthexa: #f00f rgb: rgb(255 0 0) hsl: hsl(0deg 100% 50%) + hwb: hwb(0deg 0% 0%) color: rgba(0,0,0,0.5) simple: false @@ -111,6 +120,7 @@ rgba: rgba(0,0,0,0.5) hsl: hsl(0deg 0% 0% / 50%) hsla: hsl(0deg 0% 0% / 50%) + hwb: hwb(0deg 0% 100% / 50%) color: rgb(0,0,0,50%) simple: false @@ -121,6 +131,7 @@ rgba: rgb(0,0,0,50%) hsl: hsl(0deg 0% 0% / 50%) hsla: hsl(0deg 0% 0% / 50%) + hwb: hwb(0deg 0% 100% / 50%) color: rgb( 0 0 0 / 50% ) simple: false @@ -131,6 +142,7 @@ rgba: rgb( 0 0 0 / 50% ) hsl: hsl(0deg 0% 0% / 50%) hsla: hsl(0deg 0% 0% / 50%) + hwb: hwb(0deg 0% 100% / 50%) color: rgb(1 1 1/1) simple: true @@ -140,6 +152,7 @@ shorthexa: null rgb: rgb(1 1 1) hsl: hsl(0deg 0% 0%) + hwb: hwb(0deg 0% 100%) color: rgb(1 1 1/ 1) simple: true @@ -149,6 +162,7 @@ shorthexa: null rgb: rgb(1 1 1) hsl: hsl(0deg 0% 0%) + hwb: hwb(0deg 0% 100%) color: rgba(1.5 1.5 1.5) simple: true @@ -158,6 +172,7 @@ shorthexa: null rgb: rgba(1.5 1.5 1.5) hsl: hsl(0deg 0% 1%) + hwb: hwb(0deg 1% 99%) color: hsl(-120, 100%, 50%) simple: true @@ -169,6 +184,7 @@ shorthexa: #00ff rgb: rgb(0 0 255) hsl: hsl(-120, 100%, 50%) + hwb: hwb(240deg 0% 0%) color: hsl(-120deg, 100%, 50%) simple: true @@ -180,6 +196,7 @@ shorthexa: #00ff rgb: rgb(0 0 255) hsl: hsl(-120deg, 100%, 50%) + hwb: hwb(240deg 0% 0%) color: hsl(-120, 200%, 200%) simple: true @@ -191,6 +208,7 @@ shorthexa: #ffff rgb: rgb(255 255 255) hsl: hsl(-120, 200%, 200%) + hwb: hwb(0deg 100% 0%) color: hsl(-120, -200%, -200%) simple: true @@ -202,6 +220,7 @@ shorthexa: #000f rgb: rgb(0 0 0) hsl: hsl(0deg 0% 0%) + hwb: hwb(0deg 0% 100%) color: hsla(-120, -200%, -200%, -5) simple: false @@ -213,6 +232,7 @@ rgba: rgb(0 0 0 / 0%) hsl: hsl(0deg 0% 0% / 0%) hsla: hsl(0deg 0% 0% / 0%) + hwb: hwb(0deg 0% 100% / 0%) color: hsla(240,100%,50%,0.05) simple: false @@ -223,6 +243,7 @@ rgba: rgb(0 0 255 / 5%) hsl: hsl(240deg 100% 50% / 5%) hsla: hsla(240,100%,50%,0.05) + hwb: hwb(240deg 0% 0% / 5%) color: hsl(200.5,0%,50%) simple: true @@ -233,6 +254,7 @@ shorthexa: null rgb: rgb(128 128 128) hsl: hsl(200.5,0%,50%) + hwb: hwb(0deg 50% 50%) color: hsla(200,1.5%,50%,1) simple: true @@ -242,6 +264,7 @@ shorthexa: null rgb: rgb(126 128 129) hsl: hsl(200deg 1% 50%) + hwb: hwb(200deg 49% 49%) color: rgba(0,0,0,.5) simple: false @@ -252,6 +275,7 @@ rgba: rgba(0,0,0,.5) hsl: hsl(0deg 0% 0% / 50%) hsla: hsl(0deg 0% 0% / 50%) + hwb: hwb(0deg 0% 100% / 50%) color: hsla(.5,.5%,.5%,.5) simple: false @@ -262,6 +286,7 @@ rgba: rgb(1 1 1 / 50%) hsl: hsl(1deg 0% 1% / 50%) hsla: hsla(.5,.5%,.5%,.5) + hwb: hwb(1deg 0% 99% / 50%) color: hsla(100.5,50.5%,50.5%,.5) simple: false @@ -272,6 +297,102 @@ rgba: rgb(106 193 65 / 50%) hsl: hsl(101deg 50% 51% / 50%) hsla: hsla(100.5,50.5%,50.5%,.5) + hwb: hwb(101deg 26% 25% / 50%) + +color: hwb(-120 200% 200%) + simple: true + original: hwb(-120 200% 200%) + nickname: grey + hex: #808080 + hexa: #808080ff + shorthexa: null + rgb: rgb(128 128 128) + hsl: hsl(0deg 0% 50%) + hwb: hwb(-120 200% 200%) + +color: hwb(-120 -200% -200%) + simple: true + original: hwb(-120 -200% -200%) + nickname: blue + hex: #0000ff + shorthex: #00f + hexa: #0000ffff + shorthexa: #00ff + rgb: rgb(0 0 255) + hsl: hsl(240deg 100% 50%) + hwb: hwb(240deg 0% 0%) + +color: hwb(-120 -200% -200% / -5) + simple: false + original: hwb(-120 -200% -200% / -5) + hexa: #0000ff00 + shorthexa: #00f0 + rgb: rgb(0 0 255 / 0%) + rgba: rgb(0 0 255 / 0%) + hsl: hsl(240deg 100% 50% / 0%) + hsla: hsl(240deg 100% 50% / 0%) + hwb: hwb(240deg 0% 0% / 0%) + +color: hwb(240 100% 50% / 0.05) + simple: false + original: hwb(240 100% 50% / 0.05) + hexa: #aaaaaa0d + shorthexa: null + rgb: rgb(170 170 170 / 5%) + rgba: rgb(170 170 170 / 5%) + hsl: hsl(0deg 0% 67% / 5%) + hsla: hsl(0deg 0% 67% / 5%) + hwb: hwb(0deg 67% 33% / 5%) + +color: hwb(200.5 0% 50%) + simple: true + original: hwb(200.5 0% 50%) + hex: #005480 + hexa: #005480ff + shorthexa: null + rgb: rgb(0 84 128) + hsl: hsl(201deg 100% 25%) + hwb: hwb(200.5 0% 50%) + +color: hwb(200 1.5% 50% / 1) + simple: true + original: hwb(200 1.5% 50% / 1) + hex: #045680 + hexa: #045680ff + shorthexa: null + rgb: rgb(4 86 128) + hsl: hsl(200deg 94% 26%) + hwb: hwb(200deg 2% 50%) + +color: hwb(100grad 20% 30%) + simple: true + original: hwb(100grad 20% 30%) + hex: #73b333 + hexa: #73b333ff + shorthexa: null + rgb: rgb(115 179 51) + hsl: hsl(90deg 56% 45%) + hwb: hwb(100grad 20% 30%) + +color: hwb(1rad 5% 15%) + simple: true + original: hwb(1rad 5% 15%) + hex: #d9d00d + hexa: #d9d00dff + shorthexa: null + rgb: rgb(217 208 13) + hsl: hsl(57deg 89% 45%) + hwb: hwb(1rad 5% 15%) + +color: hwb(1turn 25% 15%) + simple: true + original: hwb(1turn 25% 15%) + hex: #d94040 + hexa: #d94040ff + shorthexa: null + rgb: rgb(217 64 64) + hsl: hsl(0deg 67% 55%) + hwb: hwb(1turn 25% 15%) color: rgba(255, 0, 0, -5) simple: false @@ -282,6 +403,7 @@ rgba: rgb(255 0 0 / 0%) hsl: hsl(0deg 100% 50% / 0%) hsla: hsl(0deg 100% 50% / 0%) + hwb: hwb(0deg 0% 0% / 0%) color: rgba(255, 0, 0, 5) simple: true @@ -293,6 +415,7 @@ shorthexa: #f00f rgb: rgb(255 0 0) hsl: hsl(0deg 100% 50%) + hwb: hwb(0deg 0% 0%) Running: testInvalidColors @@ -336,3 +459,17 @@ SUCCESS: parsed invalid color hsla to null +SUCCESS: parsed invalid color hwb(0,0,1) to null + +SUCCESS: parsed invalid color hwb(0 0% 0) to null + +SUCCESS: parsed invalid color hwb(a b c) to null + +SUCCESS: parsed invalid color hwb(0 0 0 / 0) to null + +SUCCESS: parsed invalid color hwb(0 0% 0% 0) to null + +SUCCESS: parsed invalid color hwb(0 turn 0 0 0) to null + +SUCCESS: parsed invalid color hwb to null +
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/styles-4/styles-invalid-color-values.js b/third_party/blink/web_tests/http/tests/devtools/elements/styles-4/styles-invalid-color-values.js index b3b8085..0384ba5 100644 --- a/third_party/blink/web_tests/http/tests/devtools/elements/styles-4/styles-invalid-color-values.js +++ b/third_party/blink/web_tests/http/tests/devtools/elements/styles-4/styles-invalid-color-values.js
@@ -23,7 +23,11 @@ 'hsla(-120, -200%, -200%, -5)', // clipped to hsla(0,0%,0%,0) 'hsla(240,100%,50%,0.05)', 'hsl(200.5,0%,50%)', 'hsla(200,1.5%,50%,1)', 'rgba(0,0,0,.5)', 'hsla(.5,.5%,.5%,.5)', 'hsla(100.5,50.5%,50.5%,.5)', - + 'hwb(-120 200% 200%)', // clipped to hwb(240 100% 100%) = hwb(0 50% 50%) + 'hwb(-120 -200% -200%)', // clipped to hwb(240 100% 100%) + 'hwb(-120 -200% -200% / -5)', // clipped to hwb(0 0% 0% / 0%) + 'hwb(240 100% 50% / 0.05)', 'hwb(200.5 0% 50%)', 'hwb(200 1.5% 50% / 1)', 'hwb(0 0 0 /.5)', 'hwb(.5 .5% .5% .5)', + 'hwb(100grad 20% 30%)', 'hwb(1rad 5% 15%)', 'hwb(1turn 25% 15%)', // Each of these has their alpha clipped [0.0, 1.0]. 'rgba(255, 0, 0, -5)', // clipped to rgba(255,0,0,0) 'rgba(255, 0, 0, 5)', // clipped to rgba(255,0,0,1) @@ -33,7 +37,8 @@ // An invalid color, eg a value for a shorthand like 'border' which can have a color 'none', '#00000', '#ggg', 'rgb(a,b,c)', 'rgb(a,b,c,d)', 'rgba(0 0 0 1%)', 'rgba(0,0,0,)', 'rgba(0 0, 0)', 'rgba(1 1 1 / )', 'rgb(1 1 / 1)', 'rgb(1 1/1)', 'hsl(0,0,0)', 'hsl(0%, 0%, 0%)', - 'hsla(0,,0,1)', 'hsl(0, 0%, 0)', 'hsl(a,b,c)', 'hsla(0,0,0,0)', 'hsla(0 0% 0% 0)', 'hsla(0 turn, 0, 0, 0)', 'hsla' + 'hsla(0,,0,1)', 'hsl(0, 0%, 0)', 'hsl(a,b,c)', 'hsla(0,0,0,0)', 'hsla(0 0% 0% 0)', 'hsla(0 turn, 0, 0, 0)', 'hsla', + 'hwb(0,0,1)', 'hwb(0 0% 0)', 'hwb(a b c)', 'hwb(0 0 0 / 0)', 'hwb(0 0% 0% 0)', 'hwb(0 turn 0 0 0)', 'hwb' ]; TestRunner.runTestSuite([ @@ -74,6 +79,9 @@ // Simple colors do not have RGBA and HSLA representations. if (!color.hasAlpha() && (colorFormat === cf.RGBA || colorFormat === cf.HSLA)) continue; + // Skip alpha representation for HWB - only exists internally + if (colorFormat === cf.HWBA) + continue; // Advanced colors do not have HEX representations. if (color.hasAlpha() && (colorFormat === cf.ShortHEX || colorFormat === cf.HEX)) continue;
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/encrypted-media.https.html b/third_party/blink/web_tests/wpt_internal/prerender/resources/encrypted-media.https.html index 8bee303..332b399 100644 --- a/third_party/blink/web_tests/wpt_internal/prerender/resources/encrypted-media.https.html +++ b/third_party/blink/web_tests/wpt_internal/prerender/resources/encrypted-media.https.html
@@ -1,8 +1,8 @@ <!DOCTYPE html> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="utils.js"></script> -<script src="deferred-promise-utils.js"></script> +<script src="/speculation-rules/prerender/resources/utils.js"></script> +<script src="/speculation-rules/prerender/resources/deferred-promise-utils.js"></script> <script> const params = new URLSearchParams(location.search);
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/media-device-info.https.html b/third_party/blink/web_tests/wpt_internal/prerender/resources/media-device-info.https.html index 90cf9bb..09e85e7 100644 --- a/third_party/blink/web_tests/wpt_internal/prerender/resources/media-device-info.https.html +++ b/third_party/blink/web_tests/wpt_internal/prerender/resources/media-device-info.https.html
@@ -2,8 +2,8 @@ <script src="/common/utils.js"></script> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="utils.js"></script> -<script src="deferred-promise-utils.js"></script> +<script src="/speculation-rules/prerender/resources/utils.js"></script> +<script src="/speculation-rules/prerender/resources/deferred-promise-utils.js"></script> <script> const params = new URLSearchParams(location.search);
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/media-devices-access.https.html b/third_party/blink/web_tests/wpt_internal/prerender/resources/media-devices-access.https.html index c51265f..462ce53e 100644 --- a/third_party/blink/web_tests/wpt_internal/prerender/resources/media-devices-access.https.html +++ b/third_party/blink/web_tests/wpt_internal/prerender/resources/media-devices-access.https.html
@@ -1,8 +1,8 @@ <!DOCTYPE html> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="utils.js"></script> -<script src="deferred-promise-utils.js"></script> +<script src="/speculation-rules/prerender/resources/utils.js"></script> +<script src="/speculation-rules/prerender/resources/deferred-promise-utils.js"></script> <script> const params = new URLSearchParams(location.search);
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/restriction-encrypted-media-unsupported-config.https.html b/third_party/blink/web_tests/wpt_internal/prerender/restriction-encrypted-media-unsupported-config.https.html index 1a5598b..c1cea87 100644 --- a/third_party/blink/web_tests/wpt_internal/prerender/restriction-encrypted-media-unsupported-config.https.html +++ b/third_party/blink/web_tests/wpt_internal/prerender/restriction-encrypted-media-unsupported-config.https.html
@@ -4,12 +4,14 @@ <meta name="timeout" content="long"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="resources/utils.js"></script> +<script src="/common/utils.js"></script> +<script src="/speculation-rules/prerender/resources/utils.js"></script> <body> <script> promise_test(async t => { - const bc = new BroadcastChannel('test-channel'); + const uid = token(); + const bc = new PrerenderChannel('test-channel', uid); t.add_cleanup(_ => bc.close()); const gotMessage = new Promise(resolve => { @@ -19,7 +21,7 @@ once: true }); }); - const url = `resources/encrypted-media.https.html?config=unsupport`; + const url = `resources/encrypted-media.https.html?config=unsupport&uid=${uid}`; window.open(url, '_blank', 'noopener'); const result = await gotMessage; @@ -44,6 +46,9 @@ assert_equals(result[i].prerendering, expected[i].prerendering, `prerendering${i}`); } + + // Send a close signal to PrerenderEventCollector on the prerendered page. + new PrerenderChannel('close', uid).postMessage(''); }, `the access to the Encrypted Media API should be deferred with the unsupported configurations until the prerendered page is activated`);
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/restriction-encrypted-media.https.html b/third_party/blink/web_tests/wpt_internal/prerender/restriction-encrypted-media.https.html index ba825c6..304d625f 100644 --- a/third_party/blink/web_tests/wpt_internal/prerender/restriction-encrypted-media.https.html +++ b/third_party/blink/web_tests/wpt_internal/prerender/restriction-encrypted-media.https.html
@@ -3,12 +3,14 @@ <meta name="timeout" content="long"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="resources/utils.js"></script> +<script src="/common/utils.js"></script> +<script src="/speculation-rules/prerender/resources/utils.js"></script> <body> <script> promise_test(async t => { - const bc = new BroadcastChannel('test-channel'); + const uid = token(); + const bc = new PrerenderChannel('test-channel', uid); t.add_cleanup(_ => bc.close()); const gotMessage = new Promise(resolve => { @@ -18,7 +20,7 @@ once: true }); }); - const url = `resources/encrypted-media.https.html?config=support`; + const url = `resources/encrypted-media.https.html?config=support&uid=${uid}`; window.open(url, '_blank', 'noopener'); const result = await gotMessage; @@ -42,6 +44,9 @@ assert_equals(result[i].prerendering, expected[i].prerendering, `prerendering${i}`); } + + // Send a close signal to PrerenderEventCollector on the prerendered page. + new PrerenderChannel('close', uid).postMessage(''); }, `the access to the Encrypted Media API should be deferred until the prerendered page is activated`);
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/restriction-media-camera.https.html b/third_party/blink/web_tests/wpt_internal/prerender/restriction-media-camera.https.html index d82bc703..dda9eca 100644 --- a/third_party/blink/web_tests/wpt_internal/prerender/restriction-media-camera.https.html +++ b/third_party/blink/web_tests/wpt_internal/prerender/restriction-media-camera.https.html
@@ -1,14 +1,16 @@ <!DOCTYPE html> <title>Access to the Camera of the user media device is deferred</title> <meta name="timeout" content="long"> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> -<script src="resources/utils.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<script src="/speculation-rules/prerender/resources/utils.js"></script> <body> <script> promise_test(async t => { - const bc = new BroadcastChannel('test-channel'); + const uid = token(); + const bc = new PrerenderChannel('test-channel', uid); t.add_cleanup(_ => bc.close()); const gotMessage = new Promise(resolve => { @@ -18,7 +20,7 @@ once: true }); }); - const url = `resources/media-devices-access.https.html?video=true`; + const url = `resources/media-devices-access.https.html?video=true&uid=${uid}`; window.open(url, '_blank', 'noopener'); // According to spec, gUM will resolve only if the window has focus. window.focus(); @@ -44,6 +46,9 @@ assert_equals(result[i].prerendering, expected[i].prerendering, `prerendering${i}`); } + + // Send a close signal to PrerenderEventCollector on the prerendered page. + new PrerenderChannel('close', uid).postMessage(''); }, `the access to the camera of the user media should be deferred until the prerendered page is activated`);
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/restriction-media-device-info.https.html b/third_party/blink/web_tests/wpt_internal/prerender/restriction-media-device-info.https.html index f49f6c37..d50792e3 100644 --- a/third_party/blink/web_tests/wpt_internal/prerender/restriction-media-device-info.https.html +++ b/third_party/blink/web_tests/wpt_internal/prerender/restriction-media-device-info.https.html
@@ -3,12 +3,14 @@ <meta name="timeout" content="long"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="resources/utils.js"></script> +<script src="/common/utils.js"></script> +<script src="/speculation-rules/prerender/resources/utils.js"></script> <body> <script> promise_test(async t => { - const bc = new BroadcastChannel('test-channel'); + const uid = token(); + const bc = new PrerenderChannel('test-channel', uid); const gotMessage = new Promise(resolve => { bc.addEventListener('message', e => { @@ -17,7 +19,7 @@ once: true }); }); - const url = `resources/media-device-info.https.html`; + const url = `resources/media-device-info.https.html?uid=${uid}`; window.open(url, '_blank', 'noopener'); const result = await gotMessage; @@ -42,6 +44,9 @@ `prerendering[${i}]`); } bc.close(); + + // Send a close signal to PrerenderEventCollector on the prerendered page. + new PrerenderChannel('close', uid).postMessage(''); }, `the access to the Media Device Info should be deferred until the prerendered page is activated`);
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/restriction-media-microphone.https.html b/third_party/blink/web_tests/wpt_internal/prerender/restriction-media-microphone.https.html index 5c638042..202840c 100644 --- a/third_party/blink/web_tests/wpt_internal/prerender/restriction-media-microphone.https.html +++ b/third_party/blink/web_tests/wpt_internal/prerender/restriction-media-microphone.https.html
@@ -1,14 +1,16 @@ <!DOCTYPE html> <title>Access to the Microphone of the user media device is deferred</title> <meta name="timeout" content="long"> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> -<script src="resources/utils.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<script src="/speculation-rules/prerender/resources/utils.js"></script> <body> <script> promise_test(async t => { - const bc = new BroadcastChannel('test-channel'); + const uid = token(); + const bc = new PrerenderChannel('test-channel', uid); t.add_cleanup(_ => bc.close()); const gotMessage = new Promise(resolve => { @@ -18,7 +20,7 @@ once: true }); }); - const url = `resources/media-devices-access.https.html?&audio=true`; + const url = `resources/media-devices-access.https.html?&audio=true&uid=${uid}`; window.open(url, '_blank', 'noopener'); // According to spec, gUM will resolve only if the window has focus. window.focus(); @@ -44,6 +46,9 @@ assert_equals(result[i].prerendering, expected[i].prerendering, `prerendering${i}`); } + + // Send a close signal to PrerenderEventCollector on the prerendered page. + new PrerenderChannel('close', uid).postMessage(''); }, `the access to the Microphone of the user media should be deferred until the prerendered page is activated`);
diff --git a/third_party/dav1d/dav1d_generated.gni b/third_party/dav1d/dav1d_generated.gni index 9e48e42..478811d2 100644 --- a/third_party/dav1d/dav1d_generated.gni +++ b/third_party/dav1d/dav1d_generated.gni
@@ -12,6 +12,7 @@ "libdav1d/src/x86/cdef_sse.asm", "libdav1d/src/x86/cpuid.asm", "libdav1d/src/x86/filmgrain16_avx2.asm", + "libdav1d/src/x86/filmgrain16_avx512.asm", "libdav1d/src/x86/filmgrain16_sse.asm", "libdav1d/src/x86/filmgrain_avx2.asm", "libdav1d/src/x86/filmgrain_avx512.asm",
diff --git a/third_party/dav1d/version/vcs_version.h b/third_party/dav1d/version/vcs_version.h index 7f9d753..88548ec 100644 --- a/third_party/dav1d/version/vcs_version.h +++ b/third_party/dav1d/version/vcs_version.h
@@ -1,2 +1,2 @@ /* auto-generated, do not edit */ -#define DAV1D_VERSION "0.9.2-167-g493ffb1" +#define DAV1D_VERSION "0.9.2-172-gb1a5189"
diff --git a/third_party/libdrm/BUILD.gn b/third_party/libdrm/BUILD.gn index 8c1054b..b72d3ef 100644 --- a/third_party/libdrm/BUILD.gn +++ b/third_party/libdrm/BUILD.gn
@@ -3,6 +3,20 @@ # found in the LICENSE file. assert(is_linux || is_chromeos) +generated_static_table_fourcc_file = + "$target_gen_dir/src/generated_static_table_fourcc.h" +fourcc_file = "src/include/drm/drm_fourcc.h" + +action("make_generated_static_table_fourcc") { + script = "src/gen_table_fourcc.py" + args = [ + rebase_path(fourcc_file, root_build_dir), + rebase_path(generated_static_table_fourcc_file), + ] + outputs = [ generated_static_table_fourcc_file ] + inputs = [ fourcc_file ] +} + config("libdrm_config") { # TODO(thomasanderson): Remove this hack once # https://patchwork.kernel.org/patch/10545295/ lands. @@ -29,6 +43,9 @@ # TODO(crbug.com/932060) fix unused result from asprintf in modetest.c. "-Wno-unused-result", + + # modetest.c has an improper conversion in a printf statement. + "-Wno-format", ] } } @@ -41,7 +58,10 @@ "src/xf86drmRandom.c", ] + deps = [ ":make_generated_static_table_fourcc" ] + include_dirs = [ + get_path_info(generated_static_table_fourcc_file, "dir"), "src", "src/include", ] @@ -80,5 +100,7 @@ configs -= [ "//build/config/compiler:chromium_code" ] configs += [ "//build/config/compiler:no_chromium_code" ] + configs += [ ":libdrm_config" ] + deps = [ ":libdrm" ] }
diff --git a/third_party/libdrm/README.chromium b/third_party/libdrm/README.chromium index ea366011..570afa8 100644 --- a/third_party/libdrm/README.chromium +++ b/third_party/libdrm/README.chromium
@@ -1,7 +1,7 @@ Name: libdrm Short Name: libdrm URL: https://chromium.googlesource.com/chromiumos/third_party/libdrm -Version: 2.4.85 +Version: 2.4.110 License: MIT, GPL License File: NOT_SHIPPED Security Critical: yes
diff --git a/tools/make_gtest_filter.py b/tools/make_gtest_filter.py index 26b0273a..c947137 100755 --- a/tools/make_gtest_filter.py +++ b/tools/make_gtest_filter.py
@@ -172,11 +172,13 @@ parser.add_argument('--wildcard-compress', action='store_true') parser.add_argument( '--wildcard-min-depth', + type=int, default=1, help="Minimum number of terms in a case before a wildcard may be " + "used, so that prefixes are not excessively broad.") parser.add_argument( '--wildcard-min-cases', + type=int, default=3, help="Minimum number of cases in a filter before folding into a " + "wildcard, so as to not create wildcards needlessly for small "
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 5f14f0c..cfb6db8 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -8606,6 +8606,9 @@ <int value="266" label="BIBI_BIND_GAMEPAD_HAPTICS_MANAGER_FOR_FENCED_FRAME"/> <int value="267" label="BIBI_BIND_BATTERY_MONITOR_FOR_FENCED_FRAME"/> <int value="268" label="RFH_CREATE_FENCED_FRAME_IN_SANDBOXED_FRAME"/> + <int value="269" label="RFH_UNLOAD_HANDLER_NOT_ALLOWED_IN_FENCED_FRAME"/> + <int value="270" + label="RFH_BEFOREUNLOAD_HANDLER_NOT_ALLOWED_IN_FENCED_FRAME"/> </enum> <enum name="BadMessageReasonExtensions"> @@ -53754,6 +53757,7 @@ <int value="-634122679" label="GoogleBrandedContextMenu:enabled"/> <int value="-634116286" label="OmniboxUIExperimentUnboldSuggestionText:enabled"/> + <int value="-633955136" label="ShowScrollableMVTOnNTPAndroid:disabled"/> <int value="-633274640" label="WebRTCPipeWireCapturer:enabled"/> <int value="-632030508" label="NativeWindowNavButtons:disabled"/> <int value="-631740127" label="inert-visual-viewport"/> @@ -55700,6 +55704,7 @@ <int value="730024226" label="enable-out-of-process-pdf"/> <int value="730750097" label="PermissionsBlacklist:disabled"/> <int value="731318054" label="WebAssemblySimd:enabled"/> + <int value="731593144" label="ReadPrinterCapabilitiesWithXps:enabled"/> <int value="731757746" label="ArcEnableDocumentsProviderInFilesApp:disabled"/> <int value="731775657" label="DownloadsAutoResumptionNative:disabled"/> <int value="731779469" label="BlinkHeapUnifiedGarbageCollection:enabled"/> @@ -55966,6 +55971,7 @@ <int value="921536672" label="OfflinePagesDescriptiveFailStatus:enabled"/> <int value="921561616" label="WebAssemblyTiering:disabled"/> <int value="923923308" label="WifiSyncAllowDeletes:enabled"/> + <int value="923947923" label="ReadPrinterCapabilitiesWithXps:disabled"/> <int value="924769517" label="AppServiceAdaptiveIcon:disabled"/> <int value="925712999" label="V8Orinoco:enabled"/> <int value="926844887" label="QuickDim:disabled"/> @@ -56732,6 +56738,7 @@ <int value="1455881930" label="V8VmFuture:enabled"/> <int value="1455970119" label="MacCoreLocationBackend:disabled"/> <int value="1457465866" label="TouchToFillPasswordSubmission:disabled"/> + <int value="1458041527" label="ShowScrollableMVTOnNTPAndroid:enabled"/> <int value="1458085218" label="MultiDisplayOverviewAndSplitView:disabled"/> <int value="1458255488" label="BlinkGenPropertyTrees:enabled"/> <int value="1458475849" label="D3D11VideoDecoder:disabled"/> @@ -80653,6 +80660,11 @@ <int value="0" label="Success"/> <int value="1" label="ExecutionError"/> <int value="2" label="InvalidMetadata"/> + <int value="3" label="SkippedModelNotReady"/> + <int value="4" label="SkippedHasFreshResults"/> + <int value="5" label="SkippedNotEnoughSignals"/> + <int value="6" label="SkippedResultNotExpired"/> + <int value="7" label="FailedToSaveResultAfterSuccess"/> </enum> <enum name="SegmentationPlatformSegmentationModel"> @@ -80689,9 +80701,12 @@ <int value="3" label="At least one segment's signal collection is not complete"/> <int value="4" label="Segment selection TTL has not expired"/> - <int value="5" label="At least one model failed to execute"/> - <int value="6" label="At least one model needs more signals"/> - <int value="7" label="At least one model has invalid metadata"/> + <int value="5" + label="Deprecated since M101. At least one model failed to execute"/> + <int value="6" + label="Deprecated since M101. At least one model needs more signals"/> + <int value="7" + label="Deprecated since M101. At least one model has invalid metadata"/> <int value="8" label="Failed to write model result to DB"/> <int value="9" label="Invalid selection result found in prefs"/> <int value="10" label="Database initialization failed"/> @@ -94528,6 +94543,18 @@ <int value="3" label="Transferred WebContents"/> </enum> +<enum name="WebDriveOfficeTaskResult"> + <int value="0" label="Available"/> + <int value="1" label="Flag disabled"/> + <int value="2" label="Offline"/> + <int value="3" label="Not on Drive"/> + <int value="4" label="DriveFs interface error"/> + <int value="5" label="File metadata error"/> + <int value="6" label="Not uploaded - Empty or invalid alternate URL"/> + <int value="7" label="Not available for Web Drive editing"/> + <int value="8" label="Unexpected alternate URL"/> +</enum> + <enum name="WebFeedPageInformationRequestReason"> <int value="0" label="User Requested Follow"> The user requested to Follow the current web page.
diff --git a/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS b/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS index 7dffdfa..60456b1 100644 --- a/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS +++ b/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS
@@ -47,7 +47,6 @@ kron@chromium.org lizeb@chromium.org lyf@chromium.org -maxlg@chromium.org manukh@chromium.org mcrouse@chromium.org mhasank@chromium.org
diff --git a/tools/metrics/histograms/metadata/autofill/histograms.xml b/tools/metrics/histograms/metadata/autofill/histograms.xml index 11966b3..e86f8dc 100644 --- a/tools/metrics/histograms/metadata/autofill/histograms.xml +++ b/tools/metrics/histograms/metadata/autofill/histograms.xml
@@ -1601,7 +1601,7 @@ <histogram name="Autofill.IsValueNotAutofilledOverExistingValueSameAsSubmittedValue" - units="bool" expires_after="M105"> + enum="Boolean" expires_after="M105"> <owner>vidhanj@google.com</owner> <owner>koerber@google.com</owner> <owner>chrome-autofill-alerts@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml b/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml index 1db53349..8371060 100644 --- a/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml +++ b/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml
@@ -150,9 +150,9 @@ </histogram> <histogram name="ChromeOS.Settings.LoadCompletedTime" units="ms" - expires_after="2022-04-01"> - <owner>khorimoto@chromium.org</owner> - <owner>cros-system-services@google.com</owner> + expires_after="2023-04-01"> + <owner>xiaohuic@chromium.org</owner> + <owner>assistive-eng@google.com</owner> <summary> The amount of time between the render frame host StartProvisionalLoad event and the render frame DocumentOnLoadCompleted event for the Chrome OS @@ -161,9 +161,9 @@ </histogram> <histogram name="ChromeOS.Settings.LoadDocumentTime" units="ms" - expires_after="2022-04-01"> - <owner>khorimoto@chromium.org</owner> - <owner>cros-system-services@google.com</owner> + expires_after="2023-04-01"> + <owner>xiaohuic@chromium.org</owner> + <owner>assistive-eng@google.com</owner> <summary> The amount of time between the render frame host StartProvisionalLoad and DidFinishDocumentLoad events for the Chrome OS settings page. @@ -239,9 +239,9 @@ </histogram> <histogram name="ChromeOS.Settings.PathVisited" enum="WebUISettingsPathHashes" - expires_after="2022-04-10"> - <owner>khorimoto@chromium.org</owner> - <owner>cros-customization@google.com</owner> + expires_after="2023-04-10"> + <owner>xiaohuic@chromium.org</owner> + <owner>assistive-eng@google.com</owner> <summary> Paths visited within chrome://os-settings. For evaluating popularity and priorities for OS Settings UI. @@ -282,10 +282,9 @@ </histogram> <histogram name="ChromeOS.Settings.SearchRequests" - enum="OsSettingSearchRequestTypes" expires_after="2022-04-17"> - <owner>khorimoto@chromium.org</owner> - <owner>hsuregan@chromium.org</owner> - <owner>cros-customization@google.com</owner> + enum="OsSettingSearchRequestTypes" expires_after="2023-04-17"> + <owner>xiaohuic@chromium.org</owner> + <owner>assistive-eng@google.com</owner> <summary> The number of search requests made to the Settings Search Mojo API. For search requests that succeeded with a response, the number of search @@ -296,10 +295,9 @@ </histogram> <histogram name="ChromeOS.Settings.SearchRequestsPerSession" - units="mojo search requests" expires_after="2022-09-01"> - <owner>khorimoto@chromium.org</owner> - <owner>hsuregan@chromium.org</owner> - <owner>cros-customization@google.com</owner> + units="mojo search requests" expires_after="2023-04-17"> + <owner>xiaohuic@chromium.org</owner> + <owner>assistive-eng@google.com</owner> <summary> The number of search requests made to the Settings Search Mojo API in one session of the settings app. @@ -307,40 +305,36 @@ </histogram> <histogram name="ChromeOS.Settings.SearchResultSectionSelected" - enum="OsSettingsSection" expires_after="2022-04-17"> - <owner>khorimoto@chromium.org</owner> - <owner>hsuregan@chromium.org</owner> - <owner>cros-customization@google.com</owner> + enum="OsSettingsSection" expires_after="2023-04-17"> + <owner>xiaohuic@chromium.org</owner> + <owner>assistive-eng@google.com</owner> <summary> Section search results clicked by user in the OS settings search box. </summary> </histogram> <histogram name="ChromeOS.Settings.SearchResultSettingSelected" - enum="OsSetting" expires_after="2022-09-01"> - <owner>khorimoto@chromium.org</owner> - <owner>hsuregan@chromium.org</owner> - <owner>cros-customization@google.com</owner> + enum="OsSetting" expires_after="2023-04-17"> + <owner>xiaohuic@chromium.org</owner> + <owner>assistive-eng@google.com</owner> <summary> Setting search results clicked by user in the OS settings search box. </summary> </histogram> <histogram name="ChromeOS.Settings.SearchResultSubpageSelected" - enum="OsSettingsSubpage" expires_after="2022-04-24"> - <owner>khorimoto@chromium.org</owner> - <owner>hsuregan@chromium.org</owner> - <owner>cros-customization@google.com</owner> + enum="OsSettingsSubpage" expires_after="2023-04-17"> + <owner>xiaohuic@chromium.org</owner> + <owner>assistive-eng@google.com</owner> <summary> Subpage search results clicked by user in the OS settings search box. </summary> </histogram> <histogram name="ChromeOS.Settings.SearchResultTypeSelected" - enum="OsSettingsSearchResultType" expires_after="2022-04-24"> - <owner>khorimoto@chromium.org</owner> - <owner>hsuregan@chromium.org</owner> - <owner>cros-customization@google.com</owner> + enum="OsSettingsSearchResultType" expires_after="2023-04-17"> + <owner>xiaohuic@google.com</owner> + <owner>assistive-eng@chromium.org</owner> <summary> Type of search results clicked by user in the OS settings search box. </summary>
diff --git a/tools/metrics/histograms/metadata/feature_engagement/histograms.xml b/tools/metrics/histograms/metadata/feature_engagement/histograms.xml index b8a58326..af80158 100644 --- a/tools/metrics/histograms/metadata/feature_engagement/histograms.xml +++ b/tools/metrics/histograms/metadata/feature_engagement/histograms.xml
@@ -398,9 +398,10 @@ <owner>dpenning@chromium.org</owner> <owner>dfried@chromium.org</owner> <summary> - When {TutorialId} is aborted, the step at which the tutorial was aborted. + When {TutorialID} is aborted, the step at which the tutorial was aborted. Only logged on desktop platforms. Logged each time a tutorial is aborted. </summary> + <token key="TutorialID" variants="TutorialID"/> </histogram> <histogram name="Tutorial{TutorialID}.Completion" enum="BooleanSuccess" @@ -408,9 +409,10 @@ <owner>dpenning@chromium.org</owner> <owner>dfried@chromium.org</owner> <summary> - When {TutorialId} is ended, whether the tutorial was completed or aborted. + When {TutorialID} is ended, whether the tutorial was completed or aborted. Only logged on desktop platforms. Logged each time a tutorial is ended. </summary> + <token key="TutorialID" variants="TutorialID"/> </histogram> <histogram name="Tutorial{TutorialID}.IPHLinkClicked" enum="BooleanSuccess" @@ -418,10 +420,11 @@ <owner>dpenning@chromium.org</owner> <owner>dfried@chromium.org</owner> <summary> - When {TutorialId} button is shown from an IPHLink, whether the user clicks + When {TutorialID} button is shown from an IPHLink, whether the user clicks to start the tutorial. Only logged on desktop platforms when the user either clicks or dismisses the FeaturePromo. </summary> + <token key="TutorialID" variants="TutorialID"/> </histogram> </histograms>
diff --git a/tools/metrics/histograms/metadata/file/histograms.xml b/tools/metrics/histograms/metadata/file/histograms.xml index 1114d3f..c0e74c1 100644 --- a/tools/metrics/histograms/metadata/file/histograms.xml +++ b/tools/metrics/histograms/metadata/file/histograms.xml
@@ -550,6 +550,16 @@ </summary> </histogram> +<histogram name="FileBrowser.OfficeFiles.WebDriveOffice" + enum="WebDriveOfficeTaskResult" expires_after="M110"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> + <summary> + Chrome OS File Browser: When a user selects MS Office files, records the + results of trying to enable the Web Drive Office task. + </summary> +</histogram> + <histogram name="FileBrowser.OpenFiles.RootType" enum="FileManagerRootType" expires_after="2022-04-03"> <owner>simmonsjosh@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/input/histograms.xml b/tools/metrics/histograms/metadata/input/histograms.xml index 226a8ee0..02047835 100644 --- a/tools/metrics/histograms/metadata/input/histograms.xml +++ b/tools/metrics/histograms/metadata/input/histograms.xml
@@ -230,6 +230,17 @@ </summary> </histogram> +<histogram name="InputMethod.Assistive.MultiWord.SuggestionLength" + units="chars" expires_after="2022-09-01"> + <owner>curtismcmullan@google.com</owner> + <owner>essential-inputs-team@google.com</owner> + <summary> + This records the length of a multi word suggestion shown to a user in chars. + The metric is recorded once when a suggestion visually appears in front of a + user. + </summary> +</histogram> + <histogram name="InputMethod.Assistive.NotAllowed" enum="IMEAssistiveAction" expires_after="2022-09-30"> <owner>jiwan@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/mobile/histograms.xml b/tools/metrics/histograms/metadata/mobile/histograms.xml index 42d0cb7..87c84caf 100644 --- a/tools/metrics/histograms/metadata/mobile/histograms.xml +++ b/tools/metrics/histograms/metadata/mobile/histograms.xml
@@ -339,12 +339,12 @@ </histogram> <histogram name="Mobile.RecentTabsManager.TotalTabsFromOtherDevicesOpenAll" - units="count" expires_after="2022-04-19"> + units="count" expires_after="2023-04-19"> <owner>sczs@chromium.org</owner> <owner>edchin@chromium.org</owner> <summary> Records the total number of tabs opened when Open all was selected from - other devices in Recent Tabs. + other devices in Recent Tabs, iOS only. </summary> </histogram>
diff --git a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml index 0038676..2594ab2 100644 --- a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml +++ b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
@@ -1471,7 +1471,8 @@ </histogram> <histogram name="NewTabPage.RecipeTasks.RelatedSearchDownloadCount" - units="count" expires_after="2022-03-06"> + units="count" expires_after="2022-07-01"> + <owner>danpeng@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/omnibox/histograms.xml b/tools/metrics/histograms/metadata/omnibox/histograms.xml index 5c1f32b..063814e1 100644 --- a/tools/metrics/histograms/metadata/omnibox/histograms.xml +++ b/tools/metrics/histograms/metadata/omnibox/histograms.xml
@@ -702,6 +702,16 @@ </summary> </histogram> +<histogram name="Omnibox.SearchPrefetch.FetchResult" enum="BooleanSuccess" + expires_after="2022-08-07"> + <owner>ryansturm@chromium.org</owner> + <owner>chrome-omnibox-team@google.com</owner> + <summary> + Whether a prefetch request finished with a success status or a status that + could not be served. Recorded whenever a prefetch request receives headers. + </summary> +</histogram> + <histogram name="Omnibox.SearchPrefetch.PrefetchEligibilityReason" enum="SearchPrefetchEligibilityReason" expires_after="2022-08-07"> <owner>ryansturm@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/payment/OWNERS b/tools/metrics/histograms/metadata/payment/OWNERS index 17f10e9..bec98529d 100644 --- a/tools/metrics/histograms/metadata/payment/OWNERS +++ b/tools/metrics/histograms/metadata/payment/OWNERS
@@ -3,5 +3,4 @@ # Prefer sending CLs to the owners listed below. # Use chromium-metrics-reviews@google.com as a backup. rouslan@chromium.org -maxlg@chromium.org smcgruer@chromium.org
diff --git a/tools/metrics/histograms/metadata/printing/histograms.xml b/tools/metrics/histograms/metadata/printing/histograms.xml index fccee55..f049673 100644 --- a/tools/metrics/histograms/metadata/printing/histograms.xml +++ b/tools/metrics/histograms/metadata/printing/histograms.xml
@@ -84,7 +84,7 @@ <histogram name="Printing.CUPS.AddressResolutionResult" enum="BooleanSuccess" expires_after="2022-08-07"> - <owner>skau@chromium.org</owner> + <owner>bmgordon@chromium.org</owner> <owner>cros-printing-dev@chromium.org</owner> <summary> Records whether resolution of a .local address via mDNS was successful. The @@ -106,7 +106,7 @@ <histogram name="Printing.CUPS.IppAttributesSuccess" enum="BooleanSuccess" expires_after="2022-08-07"> - <owner>skau@chromium.org</owner> + <owner>bmgordon@chromium.org</owner> <owner>cros-printing-dev@chromium.org</owner> <summary> Record if the request for IPP attributes was successful during printer @@ -118,8 +118,8 @@ </histogram> <histogram name="Printing.CUPS.IppDeviceReachable" enum="BooleanSuccess" - expires_after="2022-04-17"> - <owner>skau@chromium.org</owner> + expires_after="2022-10-17"> + <owner>bmgordon@chromium.org</owner> <owner>cros-printing-dev@chromium.org</owner> <summary> Record if the request for IPP attributes was successful in reaching the @@ -128,7 +128,7 @@ </histogram> <histogram name="Printing.CUPS.JobDuration.JobCancelled" units="ms" - expires_after="2022-04-24"> + expires_after="2022-10-24"> <owner>bmgordon@chromium.org</owner> <owner>project-bolton@google.com</owner> <summary> @@ -151,7 +151,7 @@ expires_after="never"> <!-- expires-never: Monitors printing health for Chrome OS. --> - <owner>skau@chromium.org</owner> + <owner>bmgordon@chromium.org</owner> <owner>cros-printing-dev@chromium.org</owner> <summary> The final status of every print job that was succesfully queued. Only used @@ -173,8 +173,8 @@ </histogram> <histogram name="Printing.CUPS.NearbyNetworkPrintersCount" units="printers" - expires_after="2022-04-17"> - <owner>skau@chromium.org</owner> + expires_after="2022-10-17"> + <owner>bmgordon@chromium.org</owner> <owner>project-bolton@google.com</owner> <summary> The number of detected network printers that have not been saved. Recorded @@ -184,7 +184,7 @@ </histogram> <histogram name="Printing.CUPS.PrintDocumentSize" units="KB" - expires_after="2022-04-17"> + expires_after="2022-10-17"> <owner>bmgordon@chromium.org</owner> <owner>project-bolton@google.com</owner> <summary> @@ -194,8 +194,8 @@ </histogram> <histogram name="Printing.CUPS.PrinterAdded" enum="PrinterProtocol" - expires_after="2022-04-17"> - <owner>skau@chromium.org</owner> + expires_after="2022-10-17"> + <owner>bmgordon@chromium.org</owner> <owner>src/chromeos/printing/OWNERS</owner> <summary> The protocol for a printer that was added. Used to track printer churn by @@ -204,8 +204,8 @@ </histogram> <histogram name="Printing.CUPS.PrinterRemoved" enum="PrinterProtocol" - expires_after="2022-04-17"> - <owner>skau@chromium.org</owner> + expires_after="2022-10-17"> + <owner>bmgordon@chromium.org</owner> <owner>src/chromeos/printing/OWNERS</owner> <summary> The protocol for a printer that was removed. Used to track printer churn by @@ -215,7 +215,7 @@ <histogram name="Printing.CUPS.PrintersDiscovered" units="printers" expires_after="2022-08-28"> - <owner>skau@chromium.org</owner> + <owner>bmgordon@chromium.org</owner> <owner>src/chromeos/printing/OWNERS</owner> <summary> The number of printers shown in the discovered printers dialog during @@ -227,7 +227,7 @@ expires_after="never"> <!-- expires-never: Monitors printer setup health for Chrome OS. --> - <owner>skau@chromium.org</owner> + <owner>bmgordon@chromium.org</owner> <owner>src/chromeos/printing/OWNERS</owner> <summary> The success or error code for the setup of a CUPS printer. Recorded when @@ -282,8 +282,8 @@ </histogram> <histogram name="Printing.CUPS.ProtocolUsed" enum="PrinterProtocol" - expires_after="2022-04-17"> - <owner>skau@chromium.org</owner> + expires_after="2022-10-17"> + <owner>bmgordon@chromium.org</owner> <owner>cros-printing-dev@chromium.org</owner> <summary> Records the protocol for a selected printer in Chrome OS. Used to track @@ -295,7 +295,7 @@ <histogram name="Printing.CUPS.TotalNetworkPrintersCount" units="printers" expires_after="2022-08-28"> - <owner>skau@chromium.org</owner> + <owner>bmgordon@chromium.org</owner> <owner>project-bolton@google.com</owner> <summary> The total number of detected network printers. Recorded when the user @@ -369,7 +369,7 @@ <histogram name="Printing.PrintServers.ServersToQuery" units="servers" expires_after="2022-12-31"> <owner>pawliczek@chromium.org</owner> - <owner>skau@chromium.org</owner> + <owner>bmgordon@chromium.org</owner> <summary> Records the number of print servers that must be queried according to policies. Only non-zero values are recorded. The histogram is emitted when
diff --git a/tools/metrics/histograms/metadata/segmentation_platform/histograms.xml b/tools/metrics/histograms/metadata/segmentation_platform/histograms.xml index 6f1a0c7..d163190 100644 --- a/tools/metrics/histograms/metadata/segmentation_platform/histograms.xml +++ b/tools/metrics/histograms/metadata/segmentation_platform/histograms.xml
@@ -30,9 +30,7 @@ <variants name="ModelExecutionStatus"> <variant name="ExecutionError"/> - <variant name="InvalidMetadata"/> <variant name="Success"/> - <variant name="Unknown"/> </variants> <variants name="SegmentationKey"> @@ -352,6 +350,18 @@ segmentation model. Recorded every time a {SegmentationModel} segmentation model is executed. + + Before M100: The ExecutionError could mean either model not available or + execution failed. + + In M100 in addition to ExecutionError, + OptimizationGuide.ModelExecutor.ExecutionStatus will also record + FileNotValid when model is not available. + + M101: SkippedModelNotReady was added which counts execution attempts before + model was ready, and ExecutionError means the model failed after it was + ready. Also other cases when execution was skipped are added to this + histogram ("Skipped*"). </summary> <token key="SegmentationModel" variants="SegmentationModel"/> </histogram> @@ -384,7 +394,7 @@ </histogram> <histogram name="SegmentationPlatform.SelectionFailedReason" - enum="SegmentationSelectionFailureReason" expires_after="2022-07-31"> + enum="SegmentationSelectionFailureReason" expires_after="M101"> <owner>ssid@chromium.org</owner> <owner>chrome-segmentation-platform@google.com</owner> <summary> @@ -394,6 +404,18 @@ </summary> </histogram> +<histogram name="SegmentationPlatform.SelectionFailedReason.{SegmentationKey}" + enum="SegmentationSelectionFailureReason" expires_after="2022-07-31"> + <owner>ssid@chromium.org</owner> + <owner>chrome-segmentation-platform@google.com</owner> + <summary> + Records the reason why the segmentation platform was unable to return a + segment selection for {SegmentationKey}, or if a result was available. + Recorded when failure is hit when trying to compute selection, or when + reading the selected segment. + </summary> +</histogram> + <histogram name="SegmentationPlatform.SignalDatabase.GetSamples.DatabaseEntryCount" units="entries" expires_after="2022-08-28">
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index 78d7126..c440a3fc 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -394,6 +394,8 @@ crbug.com/1297360 [ fuchsia-chrome ] system_health.common_desktop/browse:media:youtube:2019 [ Skip ] crbug.com/1297360 [ fuchsia-chrome ] system_health.common_desktop/browse:tools:sheets:2019 [ Skip ] crbug.com/1297360 [ fuchsia-chrome ] system_health.common_desktop/browse:tools:earth:2020 [ Skip ] +crbug.com/1306274 [ fuchsia-chrome ] system_health.common_desktop/browse:media:imgur [ Skip ] +crbug.com/1306280 [ fuchsia-chrome ] system_health.common_desktop/load:media:google_images:2018 [ Skip ] crbug.com/1302694 [ mac ] system_health.common_desktop/browse:tools:photoshop:2021 [ Skip ] crbug.com/1302694 [ mac ] system_health.common_desktop/browse:tools:photoshop_warm:2021 [ Skip ]
diff --git a/ui/chromeos/file_manager_strings.grdp b/ui/chromeos/file_manager_strings.grdp index 27be0750..51343bec 100644 --- a/ui/chromeos/file_manager_strings.grdp +++ b/ui/chromeos/file_manager_strings.grdp
@@ -1279,6 +1279,15 @@ <message name="IDS_FILE_BROWSER_RAR_ARCHIVE_FILE_TYPE" desc="RAR archive file type"> RAR archive </message> + <message name="IDS_FILE_BROWSER_ISO_ARCHIVE_FILE_TYPE" desc="ISO archive file type"> + ISO image + </message> + <message name="IDS_FILE_BROWSER_7Z_ARCHIVE_FILE_TYPE" desc="7z archive file type"> + 7z archive + </message> + <message name="IDS_FILE_BROWSER_CRX_ARCHIVE_FILE_TYPE" desc="CRX archive file type"> + Chrome extension + </message> <message name="IDS_FILE_BROWSER_TAR_ARCHIVE_FILE_TYPE" desc="Tar archive file type"> Tar archive </message>
diff --git a/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_7Z_ARCHIVE_FILE_TYPE.png.sha1 b/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_7Z_ARCHIVE_FILE_TYPE.png.sha1 new file mode 100644 index 0000000..9c6a2e3 --- /dev/null +++ b/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_7Z_ARCHIVE_FILE_TYPE.png.sha1
@@ -0,0 +1 @@ +4000906aa4c53562a0add25c4057cad140eaa2e1 \ No newline at end of file
diff --git a/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_CRX_ARCHIVE_FILE_TYPE.png.sha1 b/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_CRX_ARCHIVE_FILE_TYPE.png.sha1 new file mode 100644 index 0000000..9c6a2e3 --- /dev/null +++ b/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_CRX_ARCHIVE_FILE_TYPE.png.sha1
@@ -0,0 +1 @@ +4000906aa4c53562a0add25c4057cad140eaa2e1 \ No newline at end of file
diff --git a/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_ISO_ARCHIVE_FILE_TYPE.png.sha1 b/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_ISO_ARCHIVE_FILE_TYPE.png.sha1 new file mode 100644 index 0000000..9c6a2e3 --- /dev/null +++ b/ui/chromeos/file_manager_strings_grdp/IDS_FILE_BROWSER_ISO_ARCHIVE_FILE_TYPE.png.sha1
@@ -0,0 +1 @@ +4000906aa4c53562a0add25c4057cad140eaa2e1 \ No newline at end of file
diff --git a/ui/events/fuchsia/fakes/pointer_event_utility.cc b/ui/events/fuchsia/fakes/pointer_event_utility.cc index db44cb14..59d8bcf 100644 --- a/ui/events/fuchsia/fakes/pointer_event_utility.cc +++ b/ui/events/fuchsia/fakes/pointer_event_utility.cc
@@ -99,13 +99,20 @@ MouseEventBuilder& MouseEventBuilder::AddSample( uint32_t id, std::array<float, 2> position, - std::vector<uint8_t> pressed_buttons) { + std::vector<uint8_t> pressed_buttons, + std::array<int64_t, 2> scroll) { sample_ = absl::make_optional<fup::MousePointerSample>(); sample_->set_device_id(id); if (!pressed_buttons.empty()) { sample_->set_pressed_buttons(pressed_buttons); } sample_->set_position_in_viewport(position); + if (scroll[0] != 0) { + sample_->set_scroll_h(scroll[0]); + } + if (scroll[1] != 0) { + sample_->set_scroll_v(scroll[1]); + } return *this; }
diff --git a/ui/events/fuchsia/fakes/pointer_event_utility.h b/ui/events/fuchsia/fakes/pointer_event_utility.h index d4457e8c..627e2d8 100644 --- a/ui/events/fuchsia/fakes/pointer_event_utility.h +++ b/ui/events/fuchsia/fakes/pointer_event_utility.h
@@ -52,7 +52,8 @@ MouseEventBuilder& AddTime(zx_time_t time); MouseEventBuilder& AddSample(uint32_t id, std::array<float, 2> position, - std::vector<uint8_t> pressed_buttons); + std::vector<uint8_t> pressed_buttons, + std::array<int64_t, 2> scroll); MouseEventBuilder& AddViewParameters( std::array<std::array<float, 2>, 2> view, std::array<std::array<float, 2>, 2> viewport,
diff --git a/ui/events/fuchsia/pointer_events_handler.cc b/ui/events/fuchsia/pointer_events_handler.cc index 43ff891..62751db 100644 --- a/ui/events/fuchsia/pointer_events_handler.cc +++ b/ui/events/fuchsia/pointer_events_handler.cc
@@ -6,6 +6,7 @@ #include <cmath> #include <limits> +#include <memory> #include "base/logging.h" #include "base/notreached.h" @@ -201,12 +202,13 @@ // The gestures expect a gesture to start within the logical view space, and // is not tolerant of floating point drift. This function coerces just the DOWN // event's coordinate to start within the logical view. -MouseEvent CreateMouseEventDraft(const fup::MouseEvent& event, - const EventType event_type, - const int pressed_buttons_flags, - const int changed_buttons_flags, - const fup::ViewParameters& view_parameters, - const fup::MouseDeviceInfo& device_info) { +std::unique_ptr<MouseEvent> CreateMouseEventDraft( + const fup::MouseEvent& event, + const EventType event_type, + const int pressed_buttons_flags, + const int changed_buttons_flags, + const fup::ViewParameters& view_parameters, + const fup::MouseDeviceInfo& device_info) { DCHECK(HasValidMouseSample(event)) << "precondition"; const auto& sample = event.pointer_sample(); @@ -222,13 +224,27 @@ logical = ClampToViewSpace(logical[0], logical[1], view_parameters); } - // TODO(fxbug.dev/88580): Use ui::MouseWheelEvent to signal scroll. + auto location = gfx::PointF(logical[0], logical[1]); + auto root_location = gfx::PointF(sample.position_in_viewport()[0], + sample.position_in_viewport()[1]); - return MouseEvent(event_type, gfx::PointF(logical[0], logical[1]), - gfx::PointF(sample.position_in_viewport()[0], - sample.position_in_viewport()[1]), - timestamp, pressed_buttons_flags, changed_buttons_flags, - pointer_details); + if (event_type == ET_MOUSEWHEEL) { + // TODO(fxbug.dev/92938): Maybe also support ctrl+wheel event here. + + const int offset_x = + sample.has_scroll_h() ? static_cast<int>(sample.scroll_h()) : 0; + const int offset_y = + sample.has_scroll_v() ? static_cast<int>(sample.scroll_v()) : 0; + + // TODO(fxbug.dev/85388): If mouse wheel has by detent(tick) scroll offset, + // we can fill them into |tick_120ths|. + return std::make_unique<MouseWheelEvent>( + gfx::Vector2d(offset_x, offset_y), location, root_location, timestamp, + pressed_buttons_flags, changed_buttons_flags); + } + return std::make_unique<MouseEvent>(event_type, location, root_location, + timestamp, pressed_buttons_flags, + changed_buttons_flags, pointer_details); } } // namespace @@ -360,16 +376,17 @@ // Update mouse_down_ for the next Fuchsia event. mouse_down_[id] = pressed_buttons; - // Handle the default case: moved buttons. - // This is when there are no buttons pressed either previously or - // currently. - if (changed_buttons == 0 && pressed_buttons == 0) { - // Handle the moved case. - auto draft = CreateMouseEventDraft( - event, ET_MOUSE_MOVED, pressed_buttons, changed_buttons, - mouse_view_parameters_.value(), mouse_device_info_[id]); - event_callback_.Run(&draft); - } else { + const bool is_wheel_event = + sample.has_scroll_v() || sample.has_scroll_h(); + // Do not filterout mouse wheel here, because the wheel event may be + // bundled with button down and button up event. Chromium will need to + // split it to 2 events. + const bool is_button_or_drag_event = + (changed_buttons != 0 || pressed_buttons != 0); + // If button is down, use drag event instead of move event. + const bool is_move_event = !is_button_or_drag_event && !is_wheel_event; + + if (is_button_or_drag_event) { // Iterate through possible mouse buttons and potentially emit an event // for each one. for (int button = EF_LEFT_MOUSE_BUTTON; button <= EF_RIGHT_MOUSE_BUTTON; @@ -389,22 +406,45 @@ auto draft = CreateMouseEventDraft( event, event_type, button, changed_buttons, mouse_view_parameters_.value(), mouse_device_info_[id]); - event_callback_.Run(&draft); + event_callback_.Run(draft.get()); } else if (prev_down && curr_down) { + if (is_wheel_event) { + // Skip the drag event when wheel event dispatch. + continue; + } auto event_type = ET_MOUSE_DRAGGED; auto draft = CreateMouseEventDraft( event, event_type, button, changed_buttons, mouse_view_parameters_.value(), mouse_device_info_[id]); - event_callback_.Run(&draft); + event_callback_.Run(draft.get()); } else if (prev_down && !curr_down) { auto event_type = ET_MOUSE_RELEASED; auto draft = CreateMouseEventDraft( event, event_type, button, changed_buttons, mouse_view_parameters_.value(), mouse_device_info_[id]); - event_callback_.Run(&draft); + event_callback_.Run(draft.get()); } } } + + if (is_wheel_event) { + // Handle the mouse scroll. + auto draft = CreateMouseEventDraft( + event, ET_MOUSEWHEEL, pressed_buttons, changed_buttons, + mouse_view_parameters_.value(), mouse_device_info_[id]); + event_callback_.Run(draft.get()); + } + + // Handle the default case: moved pointer. + // This is when there are no buttons pressed either previously or + // currently. + if (is_move_event) { + // Handle the moved case. + auto draft = CreateMouseEventDraft( + event, ET_MOUSE_MOVED, pressed_buttons, changed_buttons, + mouse_view_parameters_.value(), mouse_device_info_[id]); + event_callback_.Run(draft.get()); + } } }
diff --git a/ui/events/fuchsia/pointer_events_handler_unittest.cc b/ui/events/fuchsia/pointer_events_handler_unittest.cc index 7eb929ec..c07ad0b7 100644 --- a/ui/events/fuchsia/pointer_events_handler_unittest.cc +++ b/ui/events/fuchsia/pointer_events_handler_unittest.cc
@@ -20,6 +20,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/events/event.h" +#include "ui/events/event_constants.h" #include "ui/events/fuchsia/fakes/fake_mouse_source.h" #include "ui/events/fuchsia/fakes/fake_touch_source.h" #include "ui/events/fuchsia/fakes/pointer_event_utility.h" @@ -89,7 +90,7 @@ MouseEventBuilder() .AddTime(1111789u) .AddViewParameters(kRect, kRect, kIdentity) - .AddSample(kMouseDeviceId, {10.f, 10.f}, {0}) + .AddSample(kMouseDeviceId, {10.f, 10.f}, {0}, {0, 0}) .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2}) .BuildAsVector(); mouse_source_->ScheduleCallback(std::move(mouse_events)); @@ -138,7 +139,7 @@ MouseEventBuilder() .AddTime(1111789u) .AddViewParameters(kRect, kRect, kIdentity) - .AddSample(kMouseDeviceId, {10.f, 10.f}, {0 /*button id*/}) + .AddSample(kMouseDeviceId, {10.f, 10.f}, {0 /*button id*/}, {0, 0}) .AddMouseDeviceInfo(kMouseDeviceId, {2 /*first button id*/, 0 /*second button id*/, 1 /*third button id*/}) @@ -153,10 +154,11 @@ // Keep Fuchsia button press -> Chrome ET_MOUSE_DRAGGED and // EF_RIGHT_MOUSE_BUTTON - events = MouseEventBuilder() - .AddTime(1111789u) - .AddSample(kMouseDeviceId, {10.f, 10.f}, {0 /*button id*/}) - .BuildAsVector(); + events = + MouseEventBuilder() + .AddTime(1111789u) + .AddSample(kMouseDeviceId, {10.f, 10.f}, {0 /*button id*/}, {0, 0}) + .BuildAsVector(); mouse_source_->ScheduleCallback(std::move(events)); RunLoopUntilIdle(); @@ -168,7 +170,7 @@ // Release Fuchsia button -> Chrome ET_MOUSE_RELEASED events = MouseEventBuilder() .AddTime(1111789u) - .AddSample(kMouseDeviceId, {10.f, 10.f}, {}) + .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, {0, 0}) .BuildAsVector(); mouse_source_->ScheduleCallback(std::move(events)); RunLoopUntilIdle(); @@ -181,7 +183,7 @@ // Release Fuchsia button -> Chrome ET_MOUSE_MOVED events = MouseEventBuilder() .AddTime(1111789u) - .AddSample(kMouseDeviceId, {10.f, 10.f}, {}) + .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, {0, 0}) .BuildAsVector(); mouse_source_->ScheduleCallback(std::move(events)); RunLoopUntilIdle(); @@ -205,7 +207,7 @@ MouseEventBuilder() .AddTime(1111789u) .AddViewParameters(kRect, kRect, kIdentity) - .AddSample(kMouseDeviceId, {10.f, 10.f}, {0}) + .AddSample(kMouseDeviceId, {10.f, 10.f}, {0}, {0, 0}) .AddMouseDeviceInfo(kMouseDeviceId, {2, 0, 1}) .BuildAsVector(); mouse_source_->ScheduleCallback(std::move(events)); @@ -220,7 +222,7 @@ // EF_LEFT_MOUSE_BUTTON events = MouseEventBuilder() .AddTime(1111789u) - .AddSample(kMouseDeviceId, {10.f, 10.f}, {2}) + .AddSample(kMouseDeviceId, {10.f, 10.f}, {2}, {0, 0}) .BuildAsVector(); mouse_source_->ScheduleCallback(std::move(events)); RunLoopUntilIdle(); @@ -247,7 +249,7 @@ MouseEventBuilder() .AddTime(1111789u) .AddViewParameters(kRect, kRect, kIdentity) - .AddSample(kMouseDeviceId, {10.f, 10.f}, {0, 1}) + .AddSample(kMouseDeviceId, {10.f, 10.f}, {0, 1}, {0, 0}) .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2}) .BuildAsVector(); mouse_source_->ScheduleCallback(std::move(events)); @@ -261,6 +263,139 @@ mouse_events.clear(); } +TEST_F(PointerEventsHandlerTest, MouseWheelEvent) { + std::vector<MouseWheelEvent> mouse_events; + pointer_handler_->StartWatching( + base::BindLambdaForTesting([&mouse_events](Event* event) { + ASSERT_EQ(event->type(), ET_MOUSEWHEEL); + mouse_events.push_back(*event->AsMouseWheelEvent()); + })); + RunLoopUntilIdle(); // Server gets watch call. + + // receive a vertical scroll + std::vector<fup::MouseEvent> events = + MouseEventBuilder() + .AddTime(1111789u) + .AddViewParameters(kRect, kRect, kIdentity) + .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, {0, 120}) + .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2}) + .BuildAsVector(); + mouse_source_->ScheduleCallback(std::move(events)); + RunLoopUntilIdle(); + + ASSERT_EQ(mouse_events.size(), 1u); + EXPECT_EQ(mouse_events[0].type(), ET_MOUSEWHEEL); + EXPECT_EQ(mouse_events[0].flags(), EF_NONE); + EXPECT_EQ(mouse_events[0].AsMouseWheelEvent()->x_offset(), 0); + EXPECT_EQ(mouse_events[0].AsMouseWheelEvent()->y_offset(), 120); + mouse_events.clear(); + + // receive a horizontal scroll + events = MouseEventBuilder() + .AddTime(1111789u) + .AddViewParameters(kRect, kRect, kIdentity) + .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, {120, 0}) + .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2}) + .BuildAsVector(); + mouse_source_->ScheduleCallback(std::move(events)); + RunLoopUntilIdle(); + + ASSERT_EQ(mouse_events.size(), 1u); + EXPECT_EQ(mouse_events[0].type(), ET_MOUSEWHEEL); + EXPECT_EQ(mouse_events[0].flags(), EF_NONE); + EXPECT_EQ(mouse_events[0].AsMouseWheelEvent()->x_offset(), 120); + EXPECT_EQ(mouse_events[0].AsMouseWheelEvent()->y_offset(), 0); + mouse_events.clear(); +} + +TEST_F(PointerEventsHandlerTest, MouseWheelEventWithButtonPressed) { + std::vector<std::unique_ptr<Event>> mouse_events; + pointer_handler_->StartWatching( + base::BindLambdaForTesting([&mouse_events](Event* event) { + ASSERT_TRUE(event->IsMouseEvent()); + if (event->IsMouseWheelEvent()) { + auto e = Event::Clone(*event->AsMouseWheelEvent()); + mouse_events.push_back(std::move(e)); + } else if (event->IsMouseEvent()) { + auto e = Event::Clone(*event->AsMouseEvent()); + mouse_events.push_back(std::move(e)); + } else { + NOTREACHED(); + } + })); + RunLoopUntilIdle(); // Server gets watch call. + + // left button down + std::vector<fup::MouseEvent> events = + MouseEventBuilder() + .AddTime(1111000u) + .AddViewParameters(kRect, kRect, kIdentity) + .AddSample(kMouseDeviceId, {10.f, 10.f}, {0}, {0, 0}) + .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2}) + .BuildAsVector(); + + // receive a vertical scroll with pressed button + events.push_back(MouseEventBuilder() + .AddTime(1111789u) + .AddViewParameters(kRect, kRect, kIdentity) + .AddSample(kMouseDeviceId, {10.f, 10.f}, {0}, {0, 120}) + .Build()); + mouse_source_->ScheduleCallback(std::move(events)); + + RunLoopUntilIdle(); + + ASSERT_EQ(mouse_events.size(), 2u); + EXPECT_EQ(mouse_events[0]->type(), ET_MOUSE_PRESSED); + EXPECT_EQ(mouse_events[0]->flags(), EF_LEFT_MOUSE_BUTTON); + EXPECT_EQ(mouse_events[1]->type(), ET_MOUSEWHEEL); + EXPECT_EQ(mouse_events[1]->flags(), EF_LEFT_MOUSE_BUTTON); + EXPECT_EQ(mouse_events[1]->AsMouseWheelEvent()->x_offset(), 0); + EXPECT_EQ(mouse_events[1]->AsMouseWheelEvent()->y_offset(), 120); + + mouse_events.clear(); +} + +TEST_F(PointerEventsHandlerTest, MouseWheelEventWithButtonDownBundled) { + std::vector<std::unique_ptr<Event>> mouse_events; + pointer_handler_->StartWatching( + base::BindLambdaForTesting([&mouse_events](Event* event) { + ASSERT_TRUE(event->IsMouseEvent()); + if (event->IsMouseWheelEvent()) { + auto e = Event::Clone(*event->AsMouseWheelEvent()); + mouse_events.push_back(std::move(e)); + } else if (event->IsMouseEvent()) { + auto e = Event::Clone(*event->AsMouseEvent()); + mouse_events.push_back(std::move(e)); + } else { + NOTREACHED(); + } + })); + RunLoopUntilIdle(); // Server gets watch call. + + // left button down and a vertical scroll bundled. + std::vector<fup::MouseEvent> events = + MouseEventBuilder() + .AddTime(1111000u) + .AddViewParameters(kRect, kRect, kIdentity) + .AddSample(kMouseDeviceId, {10.f, 10.f}, {0}, {0, 120}) + .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2}) + .BuildAsVector(); + + mouse_source_->ScheduleCallback(std::move(events)); + + RunLoopUntilIdle(); + + ASSERT_EQ(mouse_events.size(), 2u); + EXPECT_EQ(mouse_events[0]->type(), ET_MOUSE_PRESSED); + EXPECT_EQ(mouse_events[0]->flags(), EF_LEFT_MOUSE_BUTTON); + EXPECT_EQ(mouse_events[1]->type(), ET_MOUSEWHEEL); + EXPECT_EQ(mouse_events[1]->flags(), EF_LEFT_MOUSE_BUTTON); + EXPECT_EQ(mouse_events[1]->AsMouseWheelEvent()->x_offset(), 0); + EXPECT_EQ(mouse_events[1]->AsMouseWheelEvent()->y_offset(), 120); + + mouse_events.clear(); +} + TEST_F(PointerEventsHandlerTest, Phase_ChromeTouchEventTypesAreSynthesized) { std::vector<TouchEvent> touch_events; pointer_handler_->StartWatching(
diff --git a/ui/file_manager/base/gn/file_types.json5 b/ui/file_manager/base/gn/file_types.json5 index a4c63c1..0f0cc3f 100644 --- a/ui/file_manager/base/gn/file_types.json5 +++ b/ui/file_manager/base/gn/file_types.json5
@@ -309,6 +309,27 @@ }, { "type": "archive", + "translationKey": "ISO_ARCHIVE_FILE_TYPE", + "subtype": "ISO", + "extensions": [".iso"], + "mime": "application/x-iso9660-image" + }, + { + "type": "archive", + "translationKey": "7Z_ARCHIVE_FILE_TYPE", + "subtype": "7Z", + "extensions": [".7z"], + "mime": "application/x-7z-compressed" + }, + { + "type": "archive", + "translationKey": "CRX_ARCHIVE_FILE_TYPE", + "subtype": "CRX", + "extensions": [".crx"], + "mime": "application/x-chrome-extension" + }, + { + "type": "archive", "translationKey": "TAR_ARCHIVE_FILE_TYPE", "subtype": "TAR", "extensions": [".tar"],
diff --git a/ui/file_manager/file_manager/foreground/js/naming_controller.js b/ui/file_manager/file_manager/foreground/js/naming_controller.js index 3a388fc..089bada 100644 --- a/ui/file_manager/file_manager/foreground/js/naming_controller.js +++ b/ui/file_manager/file_manager/foreground/js/naming_controller.js
@@ -285,7 +285,8 @@ try { input.validation_ = true; await validateEntryName( - entry, newName, false, volumeInfo, isRemovableRoot); + entry, newName, this.fileFilter_.isHiddenFilesVisible(), volumeInfo, + isRemovableRoot); } catch (error) { await this.alertDialog_.showAsync(/** @type {string} */ (error.message));
diff --git a/ui/file_manager/integration_tests/file_manager/office.js b/ui/file_manager/integration_tests/file_manager/office.js index ca8405a..9df31d4 100644 --- a/ui/file_manager/integration_tests/file_manager/office.js +++ b/ui/file_manager/integration_tests/file_manager/office.js
@@ -2,13 +2,38 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {ENTRIES, getCaller, pending, repeatUntil, RootPath, sendTestMessage} from '../test_util.js'; +import {ENTRIES, getCaller, getHistogramCount, pending, repeatUntil, RootPath, sendTestMessage} from '../test_util.js'; import {testcase} from '../testcase.js'; import {remoteCall, setupAndWaitUntilReady} from './background.js'; import {FILE_MANAGER_EXTENSIONS_ID, FILE_MANAGER_SWA_APP_ID, FILE_SWA_BASE_URL} from './test_data.js'; /** + * The name of the UMA to track the results of trying to enable Web Drive Office + * for MS Office files. + * @const {string} + */ +const WebDriveOfficeTaskResultHistogramName = + 'FileBrowser.OfficeFiles.WebDriveOffice'; + +/** + * The UMA's enumeration values (must be consistent with + * WebDriveOfficeTaskResult in tools/metrics/histograms/enums.xml). + * @enum {number} + */ +const WebDriveOfficeTaskResultHistogramValues = { + AVAILABLE: 0, + FLAG_DISABLED: 1, + OFFLINE: 2, + NOT_ON_DRIVE: 3, + DRIVE_ERROR: 4, + DRIVE_METADATA_ERROR: 5, + INVALID_ALTERNATE_URL: 6, + DRIVE_ALTERNATE_URL: 7, + UNEXPECTED_ALTERNATE_URL: 8, +}; + +/** * Returns Web Drive Office Word's task descriptor. * * @return {!chrome.fileManagerPrivate.FileTaskDescriptor} @@ -108,6 +133,12 @@ const appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS, [ENTRIES.smallDocx]); + let histogramCount = await getHistogramCount( + WebDriveOfficeTaskResultHistogramName, + WebDriveOfficeTaskResultHistogramValues.NOT_ON_DRIVE); + chrome.test.assertEq( + 0, histogramCount, 'Unexpected UMA metric value for Web Drive Office'); + // Fake chrome.fileManagerPrivate.executeTask to return // chrome.fileManagerPrivate.TaskResult.EMPTY. const fakeData = { @@ -125,6 +156,14 @@ chrome.test.assertFalse( taskDescriptor.actionId == webDriveOfficeWordDescriptor().actionId); + // Assert that a UMA sample has been reported for getting tasks for an Office + // file that is not on Drive. + histogramCount = await getHistogramCount( + WebDriveOfficeTaskResultHistogramName, + WebDriveOfficeTaskResultHistogramValues.NOT_ON_DRIVE); + chrome.test.assertEq( + 1, histogramCount, 'Unexpected UMA metric value for Web Drive Office'); + // Remove fakes. const removedCount = await remoteCall.callRemoteTestUtil( 'removeAllForegroundFakes', appId, []); @@ -135,6 +174,12 @@ const appId = await setupAndWaitUntilReady( RootPath.DRIVE, [], [ENTRIES.smallDocxHosted]); + let histogramCount = await getHistogramCount( + WebDriveOfficeTaskResultHistogramName, + WebDriveOfficeTaskResultHistogramValues.AVAILABLE); + chrome.test.assertEq( + 0, histogramCount, 'Unexpected UMA metric value for Web Drive Office'); + // Fake chrome.fileManagerPrivate.executeTask to return // chrome.fileManagerPrivate.TaskResult.OPENED. const fakeData = { @@ -150,6 +195,14 @@ const taskDescriptor = await getExecutedTask(appId); chrome.test.assertEq(webDriveOfficeWordDescriptor(), taskDescriptor); + // Assert that a UMA sample has been reported for selecting an Office file on + // Drive. + histogramCount = await getHistogramCount( + WebDriveOfficeTaskResultHistogramName, + WebDriveOfficeTaskResultHistogramValues.AVAILABLE); + chrome.test.assertEq( + 1, histogramCount, 'Unexpected UMA metric value for Web Drive Office'); + // Remove fakes. const removedCount = await remoteCall.callRemoteTestUtil( 'removeAllForegroundFakes', appId, []); @@ -160,6 +213,12 @@ const appId = await setupAndWaitUntilReady( RootPath.DRIVE, [], [ENTRIES.smallXlsxPinned]); + let histogramCount = await getHistogramCount( + WebDriveOfficeTaskResultHistogramName, + WebDriveOfficeTaskResultHistogramValues.AVAILABLE); + chrome.test.assertEq( + 0, histogramCount, 'Unexpected UMA metric value for Web Drive Office'); + // Fake chrome.fileManagerPrivate.executeTask to return // chrome.fileManagerPrivate.TaskResult.OPENED. const fakeData = { @@ -175,6 +234,14 @@ const taskDescriptor = await getExecutedTask(appId); chrome.test.assertEq(webDriveOfficeExcelDescriptor(), taskDescriptor); + // Assert that a UMA sample has been reported for selecting an Office file on + // Drive. + histogramCount = await getHistogramCount( + WebDriveOfficeTaskResultHistogramName, + WebDriveOfficeTaskResultHistogramValues.AVAILABLE); + chrome.test.assertEq( + 1, histogramCount, 'Unexpected UMA metric value for Web Drive Office'); + // Remove fakes. const removedCount = await remoteCall.callRemoteTestUtil( 'removeAllForegroundFakes', appId, []); @@ -185,6 +252,12 @@ const appId = await setupAndWaitUntilReady( RootPath.DRIVE, [], [ENTRIES.smallPptxPinned]); + let histogramCount = await getHistogramCount( + WebDriveOfficeTaskResultHistogramName, + WebDriveOfficeTaskResultHistogramValues.AVAILABLE); + chrome.test.assertEq( + 0, histogramCount, 'Unexpected UMA metric value for Web Drive Office'); + // Fake chrome.fileManagerPrivate.executeTask to return // chrome.fileManagerPrivate.TaskResult.OPENED. const fakeData = { @@ -200,6 +273,14 @@ const taskDescriptor = await getExecutedTask(appId); chrome.test.assertEq(webDriveOfficePowerPointDescriptor(), taskDescriptor); + // Assert that a UMA sample has been reported for selecting an Office file on + // Drive. + histogramCount = await getHistogramCount( + WebDriveOfficeTaskResultHistogramName, + WebDriveOfficeTaskResultHistogramValues.AVAILABLE); + chrome.test.assertEq( + 1, histogramCount, 'Unexpected UMA metric value for Web Drive Office'); + // Remove fakes. const removedCount = await remoteCall.callRemoteTestUtil( 'removeAllForegroundFakes', appId, []); @@ -260,6 +341,19 @@ taskDescriptor.actionId == webDriveOfficeWordDescriptor().actionId); } + // Assert that a UMA sample has been reported for selecting an Office file on + // Drive that doesn't have a Web Drive editing alternate URL yet. + let histogramCount = await getHistogramCount( + WebDriveOfficeTaskResultHistogramName, + WebDriveOfficeTaskResultHistogramValues.DRIVE_ALTERNATE_URL); + chrome.test.assertEq( + 1, histogramCount, 'Unexpected UMA metric value for Web Drive Office'); + histogramCount = await getHistogramCount( + WebDriveOfficeTaskResultHistogramName, + WebDriveOfficeTaskResultHistogramValues.AVAILABLE); + chrome.test.assertEq( + 0, histogramCount, 'Unexpected UMA metric value for Web Drive Office'); + // Unselect the file that doesn't have an alternate URL. await remoteCall.waitAndClickElement( appId, `#file-list [file-name="${ENTRIES.smallDocx.nameText}"]`, @@ -277,6 +371,14 @@ taskDescriptor = await getExecutedTask(appId, expectedExecuteTaskCount); chrome.test.assertEq(webDriveOfficeWordDescriptor(), taskDescriptor); + // Assert that a UMA sample has been reported for selecting synchronized + // Office files on Drive. + histogramCount = await getHistogramCount( + WebDriveOfficeTaskResultHistogramName, + WebDriveOfficeTaskResultHistogramValues.AVAILABLE); + chrome.test.assertEq( + 1, histogramCount, 'Unexpected UMA metric value for Web Drive Office'); + // Remove fakes. const removedCount = await remoteCall.callRemoteTestUtil( 'removeAllForegroundFakes', appId, []); @@ -287,6 +389,12 @@ const appId = await setupAndWaitUntilReady(RootPath.DRIVE, [], [ENTRIES.smallDocx]); + let histogramCount = await getHistogramCount( + WebDriveOfficeTaskResultHistogramName, + WebDriveOfficeTaskResultHistogramValues.DRIVE_ALTERNATE_URL); + chrome.test.assertEq( + 0, histogramCount, 'Unexpected UMA metric value for Web Drive Office'); + // Fake chrome.fileManagerPrivate.executeTask to return // chrome.fileManagerPrivate.TaskResult.OPENED. const fakeData = { @@ -306,6 +414,14 @@ chrome.test.assertFalse( taskDescriptor.actionId == webDriveOfficeWordDescriptor().actionId); + // Assert that a UMA sample has been reported for selecting an Office file on + // Drive that doesn't have a Web Drive editing alternate URL. + histogramCount = await getHistogramCount( + WebDriveOfficeTaskResultHistogramName, + WebDriveOfficeTaskResultHistogramValues.DRIVE_ALTERNATE_URL); + chrome.test.assertEq( + 1, histogramCount, 'Unexpected UMA metric value for Web Drive Office'); + // Remove fakes. const removedCount = await remoteCall.callRemoteTestUtil( 'removeAllForegroundFakes', appId, []); @@ -316,6 +432,12 @@ const appId = await setupAndWaitUntilReady( RootPath.DRIVE, [], [ENTRIES.smallDocxPinned]); + let histogramCount = await getHistogramCount( + WebDriveOfficeTaskResultHistogramName, + WebDriveOfficeTaskResultHistogramValues.OFFLINE); + chrome.test.assertEq( + 0, histogramCount, 'Unexpected UMA metric value for Web Drive Office'); + // Fake chrome.fileManagerPrivate.executeTask to return // chrome.fileManagerPrivate.TaskResult.OPENED. const fakeData = { @@ -334,6 +456,14 @@ chrome.test.assertFalse( taskDescriptor.actionId == webDriveOfficeWordDescriptor().actionId); + // Assert that a UMA sample has been reported for selecting an Office file on + // Drive while offline. + histogramCount = await getHistogramCount( + WebDriveOfficeTaskResultHistogramName, + WebDriveOfficeTaskResultHistogramValues.OFFLINE); + chrome.test.assertEq( + 1, histogramCount, 'Unexpected UMA metric value for Web Drive Office'); + // Remove fakes. const removedCount = await remoteCall.callRemoteTestUtil( 'removeAllForegroundFakes', appId, []);
diff --git a/ui/file_manager/integration_tests/test_util.js b/ui/file_manager/integration_tests/test_util.js index 36a6fb5..df36c87 100644 --- a/ui/file_manager/integration_tests/test_util.js +++ b/ui/file_manager/integration_tests/test_util.js
@@ -826,6 +826,8 @@ nameText: 'text.docx', sizeText: '8.7 KB', typeText: 'Office document', + alternateUrl: 'https://drive.google.com/open?id=smalldocxid&\ +usp=drive_fs', }), smallDocxHosted: new TestEntryInfo({
diff --git a/ui/gfx/buffer_format_util.cc b/ui/gfx/buffer_format_util.cc index 72b7ea78..9d526f5 100644 --- a/ui/gfx/buffer_format_util.cc +++ b/ui/gfx/buffer_format_util.cc
@@ -105,14 +105,14 @@ case BufferFormat::RGBA_F16: return 1; case BufferFormat::YVU_420: { - static size_t factor[] = {1, 2, 2}; - DCHECK_LT(static_cast<size_t>(plane), std::size(factor)); + constexpr size_t factor[] = {1, 2, 2}; + DCHECK_LT(plane, std::size(factor)); return factor[plane]; } case BufferFormat::YUV_420_BIPLANAR: case BufferFormat::P010: { - static size_t factor[] = {1, 2}; - DCHECK_LT(static_cast<size_t>(plane), std::size(factor)); + constexpr size_t factor[] = {1, 2}; + DCHECK_LT(plane, std::size(factor)); return factor[plane]; } } @@ -120,6 +120,77 @@ return 0; } +size_t PlaneWidthForBufferFormat(size_t width, + BufferFormat format, + size_t plane) { + const size_t subsample = SubsamplingFactorForBufferFormat(format, plane); + return (width + subsample - 1) / subsample; +} + +size_t PlaneHeightForBufferFormat(size_t height, + BufferFormat format, + size_t plane) { + const size_t subsample = SubsamplingFactorForBufferFormat(format, plane); + return (height + subsample - 1) / subsample; +} + +size_t BytesPerPixelForBufferFormat(BufferFormat format, size_t plane) { + switch (format) { + case BufferFormat::R_8: + return 1; + case BufferFormat::R_16: + case BufferFormat::RG_88: + case BufferFormat::BGR_565: + case BufferFormat::RGBA_4444: + return 2; + case BufferFormat::RG_1616: + case BufferFormat::BGRX_8888: + case BufferFormat::BGRA_1010102: + case BufferFormat::RGBA_1010102: + case BufferFormat::RGBX_8888: + case BufferFormat::RGBA_8888: + case BufferFormat::BGRA_8888: + return 4; + case BufferFormat::RGBA_F16: + return 8; + case BufferFormat::YVU_420: + return 1; + case BufferFormat::YUV_420_BIPLANAR: + return SubsamplingFactorForBufferFormat(format, plane); + case BufferFormat::P010: + return 2 * SubsamplingFactorForBufferFormat(format, plane); + } + NOTREACHED(); + return 0; +} + +size_t RowByteAlignmentForBufferFormat(BufferFormat format, size_t plane) { + switch (format) { + case BufferFormat::R_8: + case BufferFormat::R_16: + case BufferFormat::RG_88: + case BufferFormat::BGR_565: + case BufferFormat::RGBA_4444: + case BufferFormat::RG_1616: + case BufferFormat::BGRX_8888: + case BufferFormat::BGRA_1010102: + case BufferFormat::RGBA_1010102: + case BufferFormat::RGBX_8888: + case BufferFormat::RGBA_8888: + case BufferFormat::BGRA_8888: + return 4; + case BufferFormat::RGBA_F16: + return 8; + case BufferFormat::YVU_420: + return 1; + case BufferFormat::YUV_420_BIPLANAR: + case BufferFormat::P010: + return BytesPerPixelForBufferFormat(format, plane); + } + NOTREACHED(); + return 0; +} + size_t RowSizeForBufferFormat(size_t width, BufferFormat format, size_t plane) { size_t row_size = 0; bool valid = RowSizeForBufferFormatChecked(width, format, plane, &row_size); @@ -131,57 +202,43 @@ BufferFormat format, size_t plane, size_t* size_in_bytes) { - base::CheckedNumeric<size_t> checked_size = width; - switch (format) { - case BufferFormat::R_8: - checked_size += 3; - if (!checked_size.IsValid()) - return false; - *size_in_bytes = (checked_size & ~0x3).ValueOrDie(); - return true; - case BufferFormat::R_16: - case BufferFormat::RG_88: - case BufferFormat::BGR_565: - case BufferFormat::RGBA_4444: - checked_size *= 2; - checked_size += 3; - if (!checked_size.IsValid()) - return false; - *size_in_bytes = (checked_size & ~0x3).ValueOrDie(); - return true; - case BufferFormat::RG_1616: - case BufferFormat::BGRX_8888: - case BufferFormat::BGRA_1010102: - case BufferFormat::RGBA_1010102: - case BufferFormat::RGBX_8888: - case BufferFormat::RGBA_8888: - case BufferFormat::BGRA_8888: - checked_size *= 4; - if (!checked_size.IsValid()) - return false; - *size_in_bytes = checked_size.ValueOrDie(); - return true; - case BufferFormat::RGBA_F16: - checked_size *= 8; - if (!checked_size.IsValid()) - return false; - *size_in_bytes = checked_size.ValueOrDie(); - return true; - case BufferFormat::YVU_420: - DCHECK_EQ(width % 2, 0u); - *size_in_bytes = width / SubsamplingFactorForBufferFormat(format, plane); - return true; - case BufferFormat::YUV_420_BIPLANAR: - DCHECK_EQ(width % 2, 0u); - *size_in_bytes = width; - return true; - case BufferFormat::P010: - DCHECK_EQ(width % 2, 0u); - *size_in_bytes = 2 * width; - return true; - } - NOTREACHED(); - return false; + base::CheckedNumeric<size_t> checked_size = + PlaneWidthForBufferFormat(width, format, plane); + checked_size *= BytesPerPixelForBufferFormat(format, plane); + const size_t alignment = RowByteAlignmentForBufferFormat(format, plane); + checked_size = (checked_size + alignment - 1) & ~(alignment - 1); + if (!checked_size.IsValid()) + return false; + + *size_in_bytes = checked_size.ValueOrDie(); + return true; +} + +size_t PlaneSizeForBufferFormat(const Size& size, + BufferFormat format, + size_t plane) { + size_t plane_size = 0; + bool valid = + PlaneSizeForBufferFormatChecked(size, format, plane, &plane_size); + DCHECK(valid); + return plane_size; +} + +bool PlaneSizeForBufferFormatChecked(const Size& size, + BufferFormat format, + size_t plane, + size_t* size_in_bytes) { + size_t row_size = 0; + if (!RowSizeForBufferFormatChecked(size.width(), format, plane, &row_size)) + return false; + base::CheckedNumeric<size_t> checked_plane_size = row_size; + checked_plane_size *= + PlaneHeightForBufferFormat(size.height(), format, plane); + if (!checked_plane_size.IsValid()) + return false; + + *size_in_bytes = checked_plane_size.ValueOrDie(); + return true; } size_t BufferSizeForBufferFormat(const Size& size, BufferFormat format) { @@ -197,18 +254,14 @@ base::CheckedNumeric<size_t> checked_size = 0; size_t num_planes = NumberOfPlanesForLinearBufferFormat(format); for (size_t i = 0; i < num_planes; ++i) { - size_t row_size = 0; - if (!RowSizeForBufferFormatChecked(size.width(), format, i, &row_size)) + size_t plane_size = 0; + if (!PlaneSizeForBufferFormatChecked(size, format, i, &plane_size)) return false; - base::CheckedNumeric<size_t> checked_plane_size = row_size; - checked_plane_size *= size.height() / - SubsamplingFactorForBufferFormat(format, i); - if (!checked_plane_size.IsValid()) - return false; - checked_size += checked_plane_size.ValueOrDie(); + checked_size += plane_size; if (!checked_size.IsValid()) return false; } + *size_in_bytes = checked_size.ValueOrDie(); return true; } @@ -217,6 +270,7 @@ BufferFormat format, size_t plane) { DCHECK_LT(plane, gfx::NumberOfPlanesForLinearBufferFormat(format)); + switch (format) { case BufferFormat::R_8: case BufferFormat::R_16: @@ -232,23 +286,14 @@ case BufferFormat::BGRA_8888: case BufferFormat::RGBA_F16: return 0; - case BufferFormat::YVU_420: { - static size_t offset_in_2x2_sub_sampling_sizes[] = {0, 4, 5}; - DCHECK_LT(plane, std::size(offset_in_2x2_sub_sampling_sizes)); - return offset_in_2x2_sub_sampling_sizes[plane] * (size.width() / 2) * - (size.height() / 2); - } - case gfx::BufferFormat::YUV_420_BIPLANAR: { - static size_t offset_in_2x2_sub_sampling_sizes[] = {0, 4}; - DCHECK_LT(plane, std::size(offset_in_2x2_sub_sampling_sizes)); - return offset_in_2x2_sub_sampling_sizes[plane] * (size.width() / 2) * - (size.height() / 2); - } + case BufferFormat::YVU_420: + case BufferFormat::YUV_420_BIPLANAR: case BufferFormat::P010: { - static size_t offset_in_2x2_sub_sampling_sizes[] = {0, 4}; - DCHECK_LT(plane, std::size(offset_in_2x2_sub_sampling_sizes)); - return 2 * offset_in_2x2_sub_sampling_sizes[plane] * - (size.width() / 2 + size.height() / 2); + size_t offset = 0; + for (size_t i = 0; i < plane; i++) { + offset += PlaneSizeForBufferFormat(size, format, i); + } + return offset; } } NOTREACHED(); @@ -315,8 +360,12 @@ return "Invalid Plane"; } -bool AllowOddHeightMultiPlanarBuffers() { +bool IsOddHeightMultiPlanarBuffersAllowed() { return base::FeatureList::IsEnabled(features::kOddHeightMultiPlanarBuffers); } +bool IsOddWidthMultiPlanarBuffersAllowed() { + return base::FeatureList::IsEnabled(features::kOddWidthMultiPlanarBuffers); +} + } // namespace gfx
diff --git a/ui/gfx/buffer_format_util.h b/ui/gfx/buffer_format_util.h index 702ef5b..3951ea05 100644 --- a/ui/gfx/buffer_format_util.h +++ b/ui/gfx/buffer_format_util.h
@@ -40,9 +40,20 @@ size_t plane, size_t* size_in_bytes); +// Returns the number of bytes used to the plane of a given |format|. +GFX_EXPORT size_t PlaneSizeForBufferFormat(const Size& size, + BufferFormat format, + size_t plane); +[[nodiscard]] GFX_EXPORT bool PlaneSizeForBufferFormatChecked( + const Size& size, + BufferFormat format, + size_t plane, + size_t* size_in_bytes); + // Returns the number of bytes used to store all the planes of a given |format|. GFX_EXPORT size_t BufferSizeForBufferFormat(const Size& size, BufferFormat format); + [[nodiscard]] GFX_EXPORT bool BufferSizeForBufferFormatChecked( const Size& size, BufferFormat format, @@ -62,8 +73,9 @@ // tricky when the size of the primary plane is odd, because the subsampled // planes will have a size that is not a divisor of the primary plane's size. // This indicates that odd height multiplanar formats are supported. -GFX_EXPORT bool AllowOddHeightMultiPlanarBuffers(); +GFX_EXPORT bool IsOddHeightMultiPlanarBuffersAllowed(); +GFX_EXPORT bool IsOddWidthMultiPlanarBuffersAllowed(); } // namespace gfx #endif // UI_GFX_BUFFER_FORMAT_UTIL_H_
diff --git a/ui/gfx/switches.cc b/ui/gfx/switches.cc index be932ac..67a798b 100644 --- a/ui/gfx/switches.cc +++ b/ui/gfx/switches.cc
@@ -37,7 +37,6 @@ } // namespace switches namespace features { - const base::Feature kOddHeightMultiPlanarBuffers { "OddHeightMultiPlanarBuffers", #if BUILDFLAG(IS_MAC) @@ -47,4 +46,7 @@ #endif }; +const base::Feature kOddWidthMultiPlanarBuffers{ + "OddWidthMultiPlanarBuffers", base::FEATURE_DISABLED_BY_DEFAULT}; + } // namespace features
diff --git a/ui/gfx/switches.h b/ui/gfx/switches.h index 442809de..e8e5d44 100644 --- a/ui/gfx/switches.h +++ b/ui/gfx/switches.h
@@ -26,6 +26,7 @@ namespace features { GFX_SWITCHES_EXPORT extern const base::Feature kOddHeightMultiPlanarBuffers; +GFX_SWITCHES_EXPORT extern const base::Feature kOddWidthMultiPlanarBuffers; } // namespace features #endif // UI_GFX_SWITCHES_H_
diff --git a/ui/ozone/platform/drm/BUILD.gn b/ui/ozone/platform/drm/BUILD.gn index b6c498e8..a35a83a 100644 --- a/ui/ozone/platform/drm/BUILD.gn +++ b/ui/ozone/platform/drm/BUILD.gn
@@ -202,9 +202,13 @@ deps = [ ":gbm", "//base/test:test_support", - "//build/config/linux/libdrm", "//skia", "//testing/gtest", + + # We're using this instead of the config to ensure that our tests built for + # linux have a controllable dependency instead of relying on whatever is on + # the system. + "//third_party/libdrm", "//ui/base/ime", "//ui/gfx", "//ui/gfx/linux:drm",
diff --git a/ui/ozone/platform/drm/gpu/mock_drm_device.cc b/ui/ozone/platform/drm/gpu/mock_drm_device.cc index 1ef0fe9..6501e9a 100644 --- a/ui/ozone/platform/drm/gpu/mock_drm_device.cc +++ b/ui/ozone/platform/drm/gpu/mock_drm_device.cc
@@ -4,6 +4,7 @@ #include "ui/ozone/platform/drm/gpu/mock_drm_device.h" +#include <stdint.h> #include <xf86drm.h> #include <memory> #include <utility> @@ -24,6 +25,7 @@ uint32_t object_id; uint32_t property_id; uint64_t value; + uint32_t cursor; }; typedef drmModeAtomicReqItem* drmModeAtomicReqItemPtr;
diff --git a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc index a82227d..32c9079 100644 --- a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc +++ b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc
@@ -70,20 +70,15 @@ auto* surface = static_cast<XDGSurfaceWrapperImpl*>(data); DCHECK(surface); - surface->OnConfigure(serial); -} - -void XDGSurfaceWrapperImpl::OnConfigure(uint32_t serial) { // Calls to HandleSurfaceConfigure() might end up hiding the enclosing // toplevel window, and deleting this object. - auto alive = weak_ptr_factory_.GetWeakPtr(); - - wayland_window_->HandleSurfaceConfigure(serial); - - if (!alive) + auto weak_window = surface->wayland_window_->AsWeakPtr(); + weak_window->HandleSurfaceConfigure(serial); + + if (!weak_window) return; - - wayland_window_->OnSurfaceConfigureEvent(); + + weak_window->OnSurfaceConfigureEvent(); } xdg_surface* XDGSurfaceWrapperImpl::xdg_surface() const {
diff --git a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h index d90d2fd..a44a5d8 100644 --- a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h +++ b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h
@@ -9,7 +9,6 @@ #include <cstdint> -#include "base/memory/weak_ptr.h" #include "ui/ozone/platform/wayland/common/wayland_object.h" namespace gfx { @@ -44,8 +43,6 @@ struct xdg_surface* xdg_surface, uint32_t serial); - void OnConfigure(uint32_t serial); - // Non-owing WaylandWindow that uses this surface wrapper. WaylandWindow* const wayland_window_; WaylandConnection* const connection_; @@ -53,8 +50,6 @@ bool is_configured_ = false; wl::Object<struct xdg_surface> xdg_surface_; - - base::WeakPtrFactory<XDGSurfaceWrapperImpl> weak_ptr_factory_{this}; }; } // namespace ui
diff --git a/ui/views/controls/animated_image_view.cc b/ui/views/controls/animated_image_view.cc index deb2a250..0029a27 100644 --- a/ui/views/controls/animated_image_view.cc +++ b/ui/views/controls/animated_image_view.cc
@@ -11,7 +11,6 @@ #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/compositor/compositor.h" #include "ui/gfx/canvas.h" -#include "ui/lottie/animation.h" #include "ui/views/widget/widget.h" namespace views { @@ -49,7 +48,14 @@ SchedulePaint(); } -void AnimatedImageView::Play() { +void AnimatedImageView::Play(lottie::Animation::Style style) { + DCHECK(animated_image_); + Play(base::TimeDelta(), animated_image_->GetAnimationDuration(), style); +} + +void AnimatedImageView::Play(base::TimeDelta start_offset, + base::TimeDelta duration, + lottie::Animation::Style style) { DCHECK(animated_image_); if (state_ == State::kPlaying) return; @@ -58,7 +64,7 @@ SetCompositorFromWidget(); - animated_image_->Start(); + animated_image_->StartSubsection(start_offset, duration, style); } void AnimatedImageView::Stop() {
diff --git a/ui/views/controls/animated_image_view.h b/ui/views/controls/animated_image_view.h index 1281e48c..04d6dea 100644 --- a/ui/views/controls/animated_image_view.h +++ b/ui/views/controls/animated_image_view.h
@@ -9,9 +9,11 @@ #include <utility> #include "base/memory/raw_ptr.h" +#include "base/time/time.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/compositor/compositor_animation_observer.h" #include "ui/gfx/geometry/vector2d.h" +#include "ui/lottie/animation.h" #include "ui/views/controls/image_view_base.h" #include "ui/views/metadata/view_factory.h" #include "ui/views/views_export.h" @@ -61,7 +63,11 @@ // Plays the animation in loop and must only be called when this view has // access to a widget. - void Play(); + void Play(lottie::Animation::Style style = lottie::Animation::Style::kLoop); + // Version of the above that mirrors lottie::Animation::StartSubsection(). + void Play(base::TimeDelta start_offset, + base::TimeDelta duration, + lottie::Animation::Style style = lottie::Animation::Style::kLoop); // Stops any animation and resets it to the start frame. void Stop();
diff --git a/ui/webui/resources/cr_components/app_management/browser_proxy.ts b/ui/webui/resources/cr_components/app_management/browser_proxy.ts index c2e143e..5843343 100644 --- a/ui/webui/resources/cr_components/app_management/browser_proxy.ts +++ b/ui/webui/resources/cr_components/app_management/browser_proxy.ts
@@ -19,10 +19,6 @@ (this.handler as PageHandlerRemote).$.bindNewPipeAndPassReceiver()); } - recordEnumerationValue(metricName: string, value: number, enumSize: number) { - chrome.metricsPrivate.recordEnumerationValue(metricName, value, enumSize); - } - static getInstance(): BrowserProxy { return instance || (instance = new BrowserProxy()); }
diff --git a/ui/webui/resources/cr_components/app_management/util.ts b/ui/webui/resources/cr_components/app_management/util.ts index 6734317..4f572466 100644 --- a/ui/webui/resources/cr_components/app_management/util.ts +++ b/ui/webui/resources/cr_components/app_management/util.ts
@@ -5,7 +5,6 @@ import {assert, assertNotReached} from 'chrome://resources/js/assert.m.js'; import {App} from './app_management.mojom-webui.js'; -import {BrowserProxy} from './browser_proxy.js'; import {AppManagementUserAction, AppType, OptionalBool} from './constants.js'; import {PermissionType, PermissionTypeIndex} from './permission_constants.js'; import {isPermissionEnabled} from './permission_util.js'; @@ -121,6 +120,6 @@ appType: AppType, userAction: AppManagementUserAction) { const histogram = getUserActionHistogramNameForAppType_(appType); const enumLength = Object.keys(AppManagementUserAction).length; - BrowserProxy.getInstance().recordEnumerationValue( + chrome.metricsPrivate.recordEnumerationValue( histogram, userAction, enumLength); }
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_config.js b/ui/webui/resources/cr_components/chromeos/network/network_config.js index b997c60..35afad4 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_config.js +++ b/ui/webui/resources/cr_components/chromeos/network/network_config.js
@@ -2137,6 +2137,7 @@ assert(vpn.ipSec); assert(vpn.l2tp); + vpn.ipSec.authenticationType = this.ipsecAuthType_; if (vpn.ipSec.authenticationType === IpsecAuthType.CERT) { vpn.ipSec.clientCertType = 'PKCS11Id'; vpn.ipSec.clientCertPkcs11Id = this.getUserCertPkcs11Id_(); @@ -2145,6 +2146,11 @@ vpn.ipSec.ikeVersion = 1; vpn.ipSec.saveCredentials = this.vpnSaveCredentials_; vpn.l2tp.saveCredentials = this.vpnSaveCredentials_; + + // Clear IPsec fields which are only for IKEv2. + delete vpn.ipSec.eap; + delete vpn.ipSec.localIdentity; + delete vpn.ipSec.remoteIdentity; }, /**