diff --git a/.clang-tidy b/.clang-tidy index 3f644c5..4381dda6 100644 --- a/.clang-tidy +++ b/.clang-tidy
@@ -4,17 +4,28 @@ google-build-explicit-make-pair, google-explicit-constructor, google-readability-casting, + modernize-avoid-bind, modernize-loop-convert, modernize-make-shared, + modernize-make-unique, modernize-redundant-void-arg, modernize-replace-random-shuffle, modernize-shrink-to-fit, modernize-use-bool-literals, + modernize-use-default-member-init, + modernize-use-emplace, modernize-use-equals-default, modernize-use-equals-delete, + modernize-use-noexcept, modernize-use-nullptr, modernize-use-override, modernize-use-transparent-functors, readability-redundant-member-init' + CheckOptions: + # This relaxes modernize-use-emplace in some cases; we might want to make it + # more aggressive in the future. See discussion on + # https://groups.google.com/a/chromium.org/g/cxx/c/noMMTNYiM0w . + - key: modernize-use-emplace.IgnoreImplicitConstructors + value: 1 ...
diff --git a/DEPS b/DEPS index bbe59ce..fec83f251 100644 --- a/DEPS +++ b/DEPS
@@ -178,11 +178,11 @@ # 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': 'd077e6a3d013e02c1f3bf0d3735b64ced28f31f5', + 'skia_revision': '1b63b4ac6933ccddb15bcf650cd5747d5eba44d0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': 'efeaf3d82f81d47b3bf40c9c50055493f48ce544', + 'v8_revision': 'b072390cd31323aec324401a835bc319b94878d4', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -190,7 +190,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '0b5f3df1f97e4a1cb51f0d100ef27305afd83849', + 'angle_revision': 'cdfc69c7f0f833e99b435715b3c012a2b61e55b1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -225,7 +225,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling NaCl # and whatever else without interference from each other. - 'nacl_revision': 'f45e60c61cc1ae967e6f5fefc8f3e560e3b3c501', + 'nacl_revision': '7e802793566c7bafd2c0846595d22bf5f805284e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -249,7 +249,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '9e4db33a563ef629331e4b24415c653929e5a45f', + 'devtools_frontend_revision': '501473c8d1a3463327d1cdabb2708e5bf5d3cc07', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -301,11 +301,11 @@ # 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': '9b54466be408f6a07856da33e531111408edbe33', + 'dawn_revision': '8d6b021a2a134068bc46a7773ae553f8d957b937', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'quiche_revision': '281f7a98285d4e1543863c36f08d5e9266970fb1', + 'quiche_revision': '9d0a88542030288b1e02646485b929abb1f0f481', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ios_webkit # and whatever else without interference from each other. @@ -524,7 +524,7 @@ }, 'src/ios/third_party/material_components_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'e479b366e735e55056b93559b6dc5eb29e4af47a', + 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '9c26a7e67aa298a57e5a78e22d7fbe5abc6fe34f', 'condition': 'checkout_ios', }, @@ -851,7 +851,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'e4ad8580e0f59bc1762a6e959009dfa9e843758d', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '9adfd61269a07e71c6a52e8ca5e86811213512fe', 'condition': 'checkout_linux', }, @@ -1115,7 +1115,7 @@ }, 'src/third_party/libunwindstack': { - 'url': Var('chromium_git') + '/chromium/src/third_party/libunwindstack.git' + '@' + 'acf93761dc00ac67bd7534c4040699abed4f8d94', + 'url': Var('chromium_git') + '/chromium/src/third_party/libunwindstack.git' + '@' + 'dfd3f3d84cfc222af93bc86b276414fc690977da', 'condition': 'checkout_android', }, @@ -1453,7 +1453,7 @@ }, 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '48b82798132248dfa1aaf0ed3dcac57a44a6855f', + Var('webrtc_git') + '/src.git' + '@' + '71e9acb97c7701bf5c9c77e4fc7a525678d65edc', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1525,7 +1525,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@612fae5937affc683a8ed5142935a7a7631246be', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@e0d8925a3c32232ce0cdf0396522ef096730d2ee', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index 5d31c91f..990b82e 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -480,6 +480,7 @@ ":common_variations_java", ":resources", "//android_webview/nonembedded:system_webview_manifest", + "//android_webview/proto:metrics_bridge_records_proto_java", "//base:base_java", "//base:jni_java", "//components/autofill/android:autofill_java", @@ -506,6 +507,7 @@ "//net/android:net_java", "//services/network/public/mojom:mojom_java", "//third_party/android_deps:androidx_annotation_annotation_java", + "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", "//third_party/blink/public:blink_headers_java", "//ui/android:ui_java", "//url:gurl_java",
diff --git a/android_webview/browser/gfx/aw_draw_fn_impl.cc b/android_webview/browser/gfx/aw_draw_fn_impl.cc index beb6789d..5544605 100644 --- a/android_webview/browser/gfx/aw_draw_fn_impl.cc +++ b/android_webview/browser/gfx/aw_draw_fn_impl.cc
@@ -553,9 +553,12 @@ // Flush so that we know the image's transition has been submitted and that // the |post_draw_semaphore| is pending. + GrFlushInfo flushInfo; + flushInfo.fNumSemaphores = 1; + flushInfo.fSignalSemaphores = &gr_post_draw_semaphore; GrSemaphoresSubmitted submitted = - vulkan_context_provider_->gr_context()->flushAndSignalSemaphores( - 1, &gr_post_draw_semaphore); + vulkan_context_provider_->gr_context()->flush(flushInfo); + vulkan_context_provider_->gr_context()->submit(); if (submitted != GrSemaphoresSubmitted::kYes) { LOG(ERROR) << "Skia could not submit GrSemaphore."; return;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java index e408038..c4cf1718 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java
@@ -301,7 +301,7 @@ gcAndCheckAllAwContentsDestroyed(); } finally { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { Reference.reachabilityFence(heldObject); } }
diff --git a/android_webview/nonembedded/BUILD.gn b/android_webview/nonembedded/BUILD.gn index 3c88eaa..a87c01a 100644 --- a/android_webview/nonembedded/BUILD.gn +++ b/android_webview/nonembedded/BUILD.gn
@@ -23,6 +23,7 @@ ":services_java", "//android_webview:android_webview_product_config_java", "//android_webview:common_java", + "//android_webview:common_metrics_java", "//base:base_java", "//base:jni_java", "//components/about_ui/android:aboutui_java", @@ -85,11 +86,13 @@ "//android_webview:common_metrics_java", "//android_webview:common_platform_services_java", "//android_webview:common_variations_java", + "//android_webview/proto:metrics_bridge_records_proto_java", "//base:base_java", "//components/background_task_scheduler:background_task_scheduler_task_ids_java", "//components/minidump_uploader:minidump_uploader_java", "//components/variations/android:variations_java", "//components/version_info/android:version_constants_java", + "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", ] }
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/MainActivity.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/MainActivity.java index 7d693b01..b608373 100644 --- a/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/MainActivity.java +++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/MainActivity.java
@@ -74,9 +74,34 @@ int COUNT = 3; } - private static void logFragmentNavigation(@FragmentNavigation int selectedFragment) { - RecordHistogram.recordEnumeratedHistogram("Android.WebView.DevUi.FragmentNavigation", - selectedFragment, FragmentNavigation.COUNT); + /** + * Logs a navigation to a fragment. Requires a suffix from histograms.xml ("AnyMethod", + * "FromIntent", or "NavBar") to determine which histogram to log. + * + * @param histogramSuffix one of the suffixes listed in histograms.xml + * @param selectedFragmentId one of FRAGMENT_ID_HOME, FRAGMENT_ID_CRASHES, or FRAGMENT_ID_FLAGS + */ + private static void logFragmentNavigation(String histogramSuffix, int selectedFragmentId) { + // Map FRAGMENT_ID_* to FragmentNavigation value (so FRAGMENT_ID_* values are permitted to + // change in the future without messing up logs). + @FragmentNavigation + int sample; + switch (selectedFragmentId) { + default: + // Fall through. + case FRAGMENT_ID_HOME: + sample = FragmentNavigation.HOME_FRAGMENT; + break; + case FRAGMENT_ID_CRASHES: + sample = FragmentNavigation.CRASHES_LIST_FRAGMENT; + break; + case FRAGMENT_ID_FLAGS: + sample = FragmentNavigation.FLAGS_FRAGMENT; + break; + } + RecordHistogram.recordEnumeratedHistogram( + "Android.WebView.DevUi.FragmentNavigation." + histogramSuffix, sample, + FragmentNavigation.COUNT); } @Override @@ -100,6 +125,7 @@ assert mFragmentIdMap.containsKey(view.getId()) : "Unexpected view ID: " + view.getId(); int fragmentId = mFragmentIdMap.get(view.getId()); switchFragment(fragmentId); + logFragmentNavigation("NavBar", fragmentId); }; final int childCount = bottomNavBar.getChildCount(); for (int i = 0; i < childCount; ++i) { @@ -132,19 +158,17 @@ chosenFragmentId = FRAGMENT_ID_HOME; // Fall through. case FRAGMENT_ID_HOME: - logFragmentNavigation(FragmentNavigation.HOME_FRAGMENT); fragment = new HomeFragment(); break; case FRAGMENT_ID_CRASHES: - logFragmentNavigation(FragmentNavigation.CRASHES_LIST_FRAGMENT); fragment = new CrashesListFragment(); break; case FRAGMENT_ID_FLAGS: - logFragmentNavigation(FragmentNavigation.FLAGS_FRAGMENT); fragment = new FlagsFragment(); break; } assert fragment != null; + logFragmentNavigation("AnyMethod", chosenFragmentId); // Switch fragments FragmentManager fm = getSupportFragmentManager(); @@ -212,6 +236,7 @@ fragmentId = extras.getInt(FRAGMENT_ID_INTENT_EXTRA, fragmentId); } switchFragment(fragmentId); + logFragmentNavigation("FromIntent", fragmentId); } @Override
diff --git a/android_webview/test/BUILD.gn b/android_webview/test/BUILD.gn index 3abf0ad..8d183b62 100644 --- a/android_webview/test/BUILD.gn +++ b/android_webview/test/BUILD.gn
@@ -159,17 +159,29 @@ deps = [ ":webview_instrumentation_test_utils_java", "//android_webview:android_webview_java", + "//android_webview:common_aidl_java", + "//android_webview:common_crash_java", + "//android_webview:common_metrics_java", + "//android_webview:common_platform_services_java", + "//android_webview:common_variations_java", + "//android_webview/nonembedded:devui_java", + "//android_webview/nonembedded:services_java", + "//android_webview/proto:aw_variations_seed_proto_java", + "//android_webview/proto:metrics_bridge_records_proto_java", "//android_webview/test/embedded_test_server:aw_net_java_test_support", "//base:base_java", "//base:base_java_test_support", "//components/autofill/android:provider_java", + "//components/content_capture/android:java", "//components/embedder_support/android:web_contents_delegate_java", + "//components/heap_profiling/multi_process:heap_profiling_java_test_support", "//components/metrics:metrics_java", "//components/minidump_uploader:minidump_uploader_java", "//components/minidump_uploader:minidump_uploader_javatests", "//components/policy/android:policy_java", "//components/policy/android:policy_java_test_support", "//components/safe_browsing/android:safe_browsing_java", + "//components/variations/android:variations_java", "//content/public/android:content_java", "//content/public/test/android:content_java_test_support", "//mojo/public/java:bindings_java", @@ -179,9 +191,11 @@ "//services/device/public/java:geolocation_java", "//services/device/public/java:geolocation_java_test_support", "//third_party/android_deps:com_google_guava_failureaccess_java", + "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", "//third_party/espresso:espresso_all_java", + "//third_party/guava:guava_android_java", "//third_party/hamcrest:hamcrest_java", "//third_party/junit", "//third_party/metrics_proto:metrics_proto_java", @@ -463,9 +477,14 @@ deps = [ "//android_webview:android_webview_java", + "//android_webview:common_metrics_java", + "//android_webview/nonembedded:services_java", + "//android_webview/proto:metrics_bridge_records_proto_java", + "//base:base_java", "//base:base_java_test_support", "//base:base_junit_test_support", "//content/public/test/android:content_java_test_support", + "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", "//third_party/android_support_test_runner:runner_java", ]
diff --git a/android_webview/tools/system_webview_shell/BUILD.gn b/android_webview/tools/system_webview_shell/BUILD.gn index 454403c..bb54081 100644 --- a/android_webview/tools/system_webview_shell/BUILD.gn +++ b/android_webview/tools/system_webview_shell/BUILD.gn
@@ -116,6 +116,7 @@ "//base:base_java", "//base:base_java_test_support", "//testing/android/reporter:reporter_java", + "//third_party/android_sdk:android_test_base_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", "//third_party/junit",
diff --git a/ash/assistant/assistant_interaction_controller_impl.cc b/ash/assistant/assistant_interaction_controller_impl.cc index caa226c..94b71ec5 100644 --- a/ash/assistant/assistant_interaction_controller_impl.cc +++ b/ash/assistant/assistant_interaction_controller_impl.cc
@@ -894,9 +894,6 @@ bool AssistantInteractionControllerImpl::ShouldAttemptWarmerWelcome( AssistantEntryPoint entry_point) const { - if (!chromeos::assistant::features::IsWarmerWelcomeEnabled()) - return false; - if (number_of_times_shown_ > 1) return false;
diff --git a/ash/quick_answers/quick_answers_controller_impl.cc b/ash/quick_answers/quick_answers_controller_impl.cc index 8831efb..bd08aae 100644 --- a/ash/quick_answers/quick_answers_controller_impl.cc +++ b/ash/quick_answers/quick_answers_controller_impl.cc
@@ -85,6 +85,9 @@ } void QuickAnswersControllerImpl::DismissQuickAnswers(bool is_active) { + if (!is_eligible_) + return; + MaybeDismissQuickAnswersConsent(); quick_answers_ui_controller_->CloseQuickAnswersView(); quick_answers_client_->OnQuickAnswersDismissed(
diff --git a/ash/system/message_center/unified_message_center_view_unittest.cc b/ash/system/message_center/unified_message_center_view_unittest.cc index b04e4292..a4778b6b 100644 --- a/ash/system/message_center/unified_message_center_view_unittest.cc +++ b/ash/system/message_center/unified_message_center_view_unittest.cc
@@ -106,15 +106,21 @@ return id; } - void CreateMessageCenterView(int max_height = kDefaultMaxHeight) { - message_center_view_ = + std::unique_ptr<TestUnifiedMessageCenterView> CreateMessageCenterViewImpl( + int max_height) { + auto message_center_view = std::make_unique<TestUnifiedMessageCenterView>(model_.get()); - message_center_view_->AddObserver(this); - message_center_view_->SetMaxHeight(max_height); - message_center_view_->SetAvailableHeight(max_height); - message_center_view_->set_owned_by_client(); - OnViewPreferredSizeChanged(message_center_view_.get()); + message_center_view->AddObserver(this); + message_center_view->SetMaxHeight(max_height); + message_center_view->SetAvailableHeight(max_height); + OnViewPreferredSizeChanged(message_center_view.get()); size_changed_count_ = 0; + + return message_center_view; + } + + virtual void CreateMessageCenterView(int max_height = kDefaultMaxHeight) { + message_center_view_ = CreateMessageCenterViewImpl(max_height); } void AnimateMessageListToValue(float value) { @@ -201,7 +207,7 @@ return focused_message_view; } - TestUnifiedMessageCenterView* message_center_view() { + virtual TestUnifiedMessageCenterView* message_center_view() { return message_center_view_.get(); } @@ -219,6 +225,40 @@ DISALLOW_COPY_AND_ASSIGN(UnifiedMessageCenterViewTest); }; +class UnifiedMessageCenterViewInWidgetTest + : public UnifiedMessageCenterViewTest { + public: + UnifiedMessageCenterViewInWidgetTest() = default; + UnifiedMessageCenterViewInWidgetTest( + const UnifiedMessageCenterViewInWidgetTest&) = delete; + UnifiedMessageCenterViewInWidgetTest& operator=( + const UnifiedMessageCenterViewInWidgetTest&) = delete; + ~UnifiedMessageCenterViewInWidgetTest() override = default; + + void TearDown() override { + widget_.reset(); + + UnifiedMessageCenterViewTest::TearDown(); + } + + protected: + void CreateMessageCenterView(int max_height = kDefaultMaxHeight) override { + widget_ = CreateTestWidget(); + message_center_ = widget_->GetRootView()->AddChildView( + CreateMessageCenterViewImpl(max_height)); + } + + TestUnifiedMessageCenterView* message_center_view() override { + return message_center_; + } + + views::Widget* widget() { return widget_.get(); } + + private: + std::unique_ptr<views::Widget> widget_; + TestUnifiedMessageCenterView* message_center_ = nullptr; +}; + TEST_F(UnifiedMessageCenterViewTest, AddAndRemoveNotification) { CreateMessageCenterView(); EXPECT_FALSE(message_center_view()->GetVisible()); @@ -687,13 +727,12 @@ EXPECT_EQ(0, message_center_view()->rect_below_scroll().height()); } -TEST_F(UnifiedMessageCenterViewTest, FocusClearedAfterNotificationRemoval) { +// We need a widget to initialize a FocusManager. +TEST_F(UnifiedMessageCenterViewInWidgetTest, + FocusClearedAfterNotificationRemoval) { CreateMessageCenterView(); - // We need to create a widget in order to initialize a FocusManager. - auto widget = CreateTestWidget(); - widget->GetRootView()->AddChildView(message_center_view()); - widget->Show(); + widget()->Show(); // Add notifications and focus on a child view in the last notification. AddNotification(); @@ -709,8 +748,6 @@ MessageCenter::Get()->RemoveNotification(id1, true /* by_user */); AnimateMessageListToEnd(); EXPECT_FALSE(message_center_view()->GetFocusManager()->GetFocusedView()); - - widget->GetRootView()->RemoveChildView(message_center_view()); } TEST_F(UnifiedMessageCenterViewTest, CollapseAndExpand_NonAnimated) {
diff --git a/base/memory/checked_ptr.h b/base/memory/checked_ptr.h index fe430c1..cebea3f3 100644 --- a/base/memory/checked_ptr.h +++ b/base/memory/checked_ptr.h
@@ -123,6 +123,11 @@ return *this; } + ALWAYS_INLINE CheckedPtr& operator=(std::nullptr_t) noexcept { + wrapped_ptr_ = Impl::GetWrappedNullPtr(); + return *this; + } + ~CheckedPtr() = default; // Avoid using. The goal of CheckedPtr is to be as close to raw pointer as
diff --git a/base/memory/checked_ptr_unittest.cc b/base/memory/checked_ptr_unittest.cc index 5e6c091..2656087 100644 --- a/base/memory/checked_ptr_unittest.cc +++ b/base/memory/checked_ptr_unittest.cc
@@ -50,12 +50,14 @@ namespace { +static int g_wrap_raw_ptr_cnt = INT_MIN; static int g_get_for_dereference_cnt = INT_MIN; static int g_get_for_extraction_cnt = INT_MIN; static int g_get_for_comparison_cnt = INT_MIN; static int g_checked_ptr_swap_cnt = INT_MIN; static void ClearCounters() { + g_wrap_raw_ptr_cnt = 0; g_get_for_dereference_cnt = 0; g_get_for_extraction_cnt = 0; g_get_for_comparison_cnt = 0; @@ -65,6 +67,11 @@ struct CheckedPtrCountingNoOpImpl : base::internal::CheckedPtrNoOpImpl { using Super = base::internal::CheckedPtrNoOpImpl; + static ALWAYS_INLINE uintptr_t WrapRawPtr(const void* const_ptr) { + ++g_wrap_raw_ptr_cnt; + return Super::WrapRawPtr(const_ptr); + } + static ALWAYS_INLINE void* SafelyUnwrapPtrForDereference( uintptr_t wrapped_ptr) { ++g_get_for_dereference_cnt; @@ -455,4 +462,16 @@ } } +TEST(CheckedPtr, AssignmentFromNullptr) { + CountingCheckedPtr<int> checked_ptr; + + ClearCounters(); + checked_ptr = nullptr; + + EXPECT_EQ(g_wrap_raw_ptr_cnt, 0); + EXPECT_EQ(g_get_for_comparison_cnt, 0); + EXPECT_EQ(g_get_for_extraction_cnt, 0); + EXPECT_EQ(g_get_for_dereference_cnt, 0); +} + } // namespace
diff --git a/base/strings/string_util.cc b/base/strings/string_util.cc index 2e07ea77..ebd0767 100644 --- a/base/strings/string_util.cc +++ b/base/strings/string_util.cc
@@ -120,19 +120,19 @@ } // namespace std::string ToLowerASCII(StringPiece str) { - return ToLowerASCIIImpl<std::string>(str); + return ToLowerASCIIImpl(str); } string16 ToLowerASCII(StringPiece16 str) { - return ToLowerASCIIImpl<string16>(str); + return ToLowerASCIIImpl(str); } std::string ToUpperASCII(StringPiece str) { - return ToUpperASCIIImpl<std::string>(str); + return ToUpperASCIIImpl(str); } string16 ToUpperASCII(StringPiece16 str) { - return ToUpperASCIIImpl<string16>(str); + return ToUpperASCIIImpl(str); } template<class StringType> @@ -163,23 +163,19 @@ } int CompareCaseInsensitiveASCII(StringPiece a, StringPiece b) { - return CompareCaseInsensitiveASCIIT<std::string>(a, b); + return CompareCaseInsensitiveASCIIT(a, b); } int CompareCaseInsensitiveASCII(StringPiece16 a, StringPiece16 b) { - return CompareCaseInsensitiveASCIIT<string16>(a, b); + return CompareCaseInsensitiveASCIIT(a, b); } bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece b) { - if (a.length() != b.length()) - return false; - return CompareCaseInsensitiveASCIIT<std::string>(a, b) == 0; + return a.size() == b.size() && CompareCaseInsensitiveASCIIT(a, b) == 0; } bool EqualsCaseInsensitiveASCII(StringPiece16 a, StringPiece16 b) { - if (a.length() != b.length()) - return false; - return CompareCaseInsensitiveASCIIT<string16>(a, b) == 0; + return a.size() == b.size() && CompareCaseInsensitiveASCIIT(a, b) == 0; } const std::string& EmptyString() { @@ -193,32 +189,32 @@ } template <class StringType> -bool ReplaceCharsT(const StringType& input, +bool ReplaceCharsT(BasicStringPiece<StringType> input, BasicStringPiece<StringType> find_any_of_these, BasicStringPiece<StringType> replace_with, StringType* output); -bool ReplaceChars(const string16& input, +bool ReplaceChars(StringPiece16 input, StringPiece16 replace_chars, StringPiece16 replace_with, string16* output) { return ReplaceCharsT(input, replace_chars, replace_with, output); } -bool ReplaceChars(const std::string& input, +bool ReplaceChars(StringPiece input, StringPiece replace_chars, StringPiece replace_with, std::string* output) { return ReplaceCharsT(input, replace_chars, replace_with, output); } -bool RemoveChars(const string16& input, +bool RemoveChars(StringPiece16 input, StringPiece16 remove_chars, string16* output) { return ReplaceCharsT(input, remove_chars, StringPiece16(), output); } -bool RemoveChars(const std::string& input, +bool RemoveChars(StringPiece input, StringPiece remove_chars, std::string* output) { return ReplaceCharsT(input, remove_chars, StringPiece(), output); @@ -353,8 +349,8 @@ return TrimStringPieceT(input, StringPiece(kWhitespaceASCII), positions); } -template<typename STR> -STR CollapseWhitespaceT(const STR& text, +template <typename STR> +STR CollapseWhitespaceT(BasicStringPiece<STR> text, bool trim_sequences_with_line_breaks) { STR result; result.resize(text.size()); @@ -365,15 +361,15 @@ bool already_trimmed = true; int chars_written = 0; - for (typename STR::const_iterator i(text.begin()); i != text.end(); ++i) { - if (IsUnicodeWhitespace(*i)) { + for (auto c : text) { + if (IsUnicodeWhitespace(c)) { if (!in_whitespace) { // Reduce all whitespace sequences to a single space. in_whitespace = true; result[chars_written++] = L' '; } if (trim_sequences_with_line_breaks && !already_trimmed && - ((*i == '\n') || (*i == '\r'))) { + ((c == '\n') || (c == '\r'))) { // Whitespace sequences containing CR or LF are eliminated entirely. already_trimmed = true; --chars_written; @@ -382,7 +378,7 @@ // Non-whitespace chracters are copied straight across. in_whitespace = false; already_trimmed = false; - result[chars_written++] = *i; + result[chars_written++] = c; } } @@ -395,12 +391,12 @@ return result; } -string16 CollapseWhitespace(const string16& text, +string16 CollapseWhitespace(StringPiece16 text, bool trim_sequences_with_line_breaks) { return CollapseWhitespaceT(text, trim_sequences_with_line_breaks); } -std::string CollapseWhitespaceASCII(const std::string& text, +std::string CollapseWhitespaceASCII(StringPiece text, bool trim_sequences_with_line_breaks) { return CollapseWhitespaceT(text, trim_sequences_with_line_breaks); } @@ -531,9 +527,7 @@ } bool EqualsASCII(StringPiece16 str, StringPiece ascii) { - if (str.length() != ascii.length()) - return false; - return std::equal(ascii.begin(), ascii.end(), str.begin()); + return std::equal(ascii.begin(), ascii.end(), str.begin(), str.end()); } template<typename Str> @@ -836,13 +830,14 @@ } template <class StringType> -bool ReplaceCharsT(const StringType& input, +bool ReplaceCharsT(BasicStringPiece<StringType> input, BasicStringPiece<StringType> find_any_of_these, BasicStringPiece<StringType> replace_with, StringType* output) { // Commonly, this is called with output and input being the same string; in - // that case, this assignment is inexpensive. - *output = input; + // that case, skip the copy. + if (input.data() != output->data() || input.size() != output->size()) + output->assign(input.data(), input.size()); return DoReplaceMatchesAfterOffset( output, 0, CharacterMatcher<StringType>{find_any_of_these}, replace_with, @@ -903,11 +898,11 @@ } // Generic version for all JoinString overloads. |list_type| must be a sequence -// (std::vector or std::initializer_list) of strings/StringPieces (std::string, +// (base::span or std::initializer_list) of strings/StringPieces (std::string, // string16, StringPiece or StringPiece16). |string_type| is either std::string // or string16. template <typename list_type, typename string_type> -static string_type JoinStringT(const list_type& parts, +static string_type JoinStringT(list_type parts, BasicStringPiece<string_type> sep) { if (base::empty(parts)) return string_type(); @@ -936,23 +931,19 @@ return result; } -std::string JoinString(const std::vector<std::string>& parts, - StringPiece separator) { +std::string JoinString(span<const std::string> parts, StringPiece separator) { return JoinStringT(parts, separator); } -string16 JoinString(const std::vector<string16>& parts, - StringPiece16 separator) { +string16 JoinString(span<const string16> parts, StringPiece16 separator) { return JoinStringT(parts, separator); } -std::string JoinString(const std::vector<StringPiece>& parts, - StringPiece separator) { +std::string JoinString(span<const StringPiece> parts, StringPiece separator) { return JoinStringT(parts, separator); } -string16 JoinString(const std::vector<StringPiece16>& parts, - StringPiece16 separator) { +string16 JoinString(span<const StringPiece16> parts, StringPiece16 separator) { return JoinStringT(parts, separator); } @@ -966,10 +957,10 @@ return JoinStringT(parts, separator); } -template<class FormatStringType, class OutStringType> -OutStringType DoReplaceStringPlaceholders( - const FormatStringType& format_string, - const std::vector<OutStringType>& subst, +template <class StringType> +StringType DoReplaceStringPlaceholders( + BasicStringPiece<StringType> format_string, + const std::vector<StringType>& subst, std::vector<size_t>* offsets) { size_t substitutions = subst.size(); DCHECK_LT(substitutions, 10U); @@ -978,7 +969,7 @@ for (const auto& cur : subst) sub_length += cur.length(); - OutStringType formatted; + StringType formatted; formatted.reserve(format_string.length() + sub_length); std::vector<ReplacementOffset> r_offsets; @@ -1021,7 +1012,7 @@ return formatted; } -string16 ReplaceStringPlaceholders(const string16& format_string, +string16 ReplaceStringPlaceholders(StringPiece16 format_string, const std::vector<string16>& subst, std::vector<size_t>* offsets) { return DoReplaceStringPlaceholders(format_string, subst, offsets); @@ -1037,9 +1028,7 @@ const string16& a, size_t* offset) { std::vector<size_t> offsets; - std::vector<string16> subst; - subst.push_back(a); - string16 result = ReplaceStringPlaceholders(format_string, subst, &offsets); + string16 result = ReplaceStringPlaceholders(format_string, {a}, &offsets); DCHECK_EQ(1U, offsets.size()); if (offset) @@ -1048,19 +1037,33 @@ } #if defined(OS_WIN) && defined(BASE_STRING16_IS_STD_U16STRING) - -TrimPositions TrimWhitespace(WStringPiece input, - TrimPositions positions, - std::wstring* output) { - return TrimStringT(input, WStringPiece(kWhitespaceWide), positions, output); +std::wstring ToLowerASCII(WStringPiece str) { + return ToLowerASCIIImpl(str); } -WStringPiece TrimWhitespace(WStringPiece input, TrimPositions positions) { - return TrimStringPieceT(input, WStringPiece(kWhitespaceWide), positions); +std::wstring ToUpperASCII(WStringPiece str) { + return ToUpperASCIIImpl(str); } -bool LowerCaseEqualsASCII(WStringPiece str, StringPiece lowercase_ascii) { - return DoLowerCaseEqualsASCII(str, lowercase_ascii); +int CompareCaseInsensitiveASCII(WStringPiece a, WStringPiece b) { + return CompareCaseInsensitiveASCIIT(a, b); +} + +bool EqualsCaseInsensitiveASCII(WStringPiece a, WStringPiece b) { + return a.size() == b.size() && CompareCaseInsensitiveASCIIT(a, b) == 0; +} + +bool RemoveChars(WStringPiece input, + WStringPiece remove_chars, + std::wstring* output) { + return ReplaceCharsT(input, remove_chars, WStringPiece(), output); +} + +bool ReplaceChars(WStringPiece input, + WStringPiece replace_chars, + WStringPiece replace_with, + std::wstring* output) { + return ReplaceCharsT(input, replace_chars, replace_with, output); } bool TrimString(WStringPiece input, @@ -1075,16 +1078,88 @@ return TrimStringPieceT(input, trim_chars, positions); } +TrimPositions TrimWhitespace(WStringPiece input, + TrimPositions positions, + std::wstring* output) { + return TrimStringT(input, WStringPiece(kWhitespaceWide), positions, output); +} + +WStringPiece TrimWhitespace(WStringPiece input, TrimPositions positions) { + return TrimStringPieceT(input, WStringPiece(kWhitespaceWide), positions); +} + +std::wstring CollapseWhitespace(WStringPiece text, + bool trim_sequences_with_line_breaks) { + return CollapseWhitespaceT(text, trim_sequences_with_line_breaks); +} + +bool ContainsOnlyChars(WStringPiece input, WStringPiece characters) { + return input.find_first_not_of(characters) == StringPiece::npos; +} + +bool LowerCaseEqualsASCII(WStringPiece str, StringPiece lowercase_ascii) { + return DoLowerCaseEqualsASCII(str, lowercase_ascii); +} + +bool EqualsASCII(WStringPiece str, StringPiece ascii) { + return std::equal(ascii.begin(), ascii.end(), str.begin(), str.end()); +} + bool StartsWith(WStringPiece str, WStringPiece search_for, CompareCase case_sensitivity) { return StartsWithT(str, search_for, case_sensitivity); } +bool EndsWith(WStringPiece str, + WStringPiece search_for, + CompareCase case_sensitivity) { + return EndsWithT(str, search_for, case_sensitivity); +} + +void ReplaceFirstSubstringAfterOffset(std::wstring* str, + size_t start_offset, + WStringPiece find_this, + WStringPiece replace_with) { + DoReplaceMatchesAfterOffset(str, start_offset, + SubstringMatcher<std::wstring>{find_this}, + replace_with, ReplaceType::REPLACE_FIRST); +} + +void ReplaceSubstringsAfterOffset(std::wstring* str, + size_t start_offset, + WStringPiece find_this, + WStringPiece replace_with) { + DoReplaceMatchesAfterOffset(str, start_offset, + SubstringMatcher<std::wstring>{find_this}, + replace_with, ReplaceType::REPLACE_ALL); +} + wchar_t* WriteInto(std::wstring* str, size_t length_with_null) { return WriteIntoT(str, length_with_null); } +std::wstring JoinString(span<const std::wstring> parts, + WStringPiece separator) { + return JoinStringT(parts, separator); +} + +std::wstring JoinString(span<const WStringPiece> parts, + WStringPiece separator) { + return JoinStringT(parts, separator); +} + +std::wstring JoinString(std::initializer_list<WStringPiece> parts, + WStringPiece separator) { + return JoinStringT(parts, separator); +} + +std::wstring ReplaceStringPlaceholders(WStringPiece format_string, + const std::vector<std::wstring>& subst, + std::vector<size_t>* offsets) { + return DoReplaceStringPlaceholders(format_string, subst, offsets); +} + #endif // The following code is compatible with the OpenBSD lcpy interface. See:
diff --git a/base/strings/string_util.h b/base/strings/string_util.h index b9eee733..b132fa4 100644 --- a/base/strings/string_util.h +++ b/base/strings/string_util.h
@@ -19,6 +19,7 @@ #include "base/base_export.h" #include "base/compiler_specific.h" +#include "base/containers/span.h" #include "base/stl_util.h" #include "base/strings/string16.h" #include "base/strings/string_piece.h" // For implicit conversions. @@ -169,10 +170,10 @@ // Removes characters in |remove_chars| from anywhere in |input|. Returns true // if any characters were removed. |remove_chars| must be null-terminated. // NOTE: Safe to use the same variable for both |input| and |output|. -BASE_EXPORT bool RemoveChars(const string16& input, +BASE_EXPORT bool RemoveChars(StringPiece16 input, StringPiece16 remove_chars, string16* output); -BASE_EXPORT bool RemoveChars(const std::string& input, +BASE_EXPORT bool RemoveChars(StringPiece input, StringPiece remove_chars, std::string* output); @@ -181,11 +182,11 @@ // the |replace_with| string. Returns true if any characters were replaced. // |replace_chars| must be null-terminated. // NOTE: Safe to use the same variable for both |input| and |output|. -BASE_EXPORT bool ReplaceChars(const string16& input, +BASE_EXPORT bool ReplaceChars(StringPiece16 input, StringPiece16 replace_chars, StringPiece16 replace_with, string16* output); -BASE_EXPORT bool ReplaceChars(const std::string& input, +BASE_EXPORT bool ReplaceChars(StringPiece input, StringPiece replace_chars, StringPiece replace_with, std::string* output); @@ -314,11 +315,10 @@ // (2) If |trim_sequences_with_line_breaks| is true, any other whitespace // sequences containing a CR or LF are trimmed. // (3) All other whitespace sequences are converted to single spaces. -BASE_EXPORT string16 CollapseWhitespace( - const string16& text, - bool trim_sequences_with_line_breaks); +BASE_EXPORT string16 CollapseWhitespace(StringPiece16 text, + bool trim_sequences_with_line_breaks); BASE_EXPORT std::string CollapseWhitespaceASCII( - const std::string& text, + StringPiece text, bool trim_sequences_with_line_breaks); // Returns true if |input| is empty or contains only characters found in @@ -488,8 +488,8 @@ BASE_EXPORT char* WriteInto(std::string* str, size_t length_with_null); BASE_EXPORT char16* WriteInto(string16* str, size_t length_with_null); -// Joins a vector or list of strings into a single string, inserting |separator| -// (which may be empty) in between all elements. +// Joins a list of strings into a single string, inserting |separator| (which +// may be empty) in between all elements. // // Note this is inverse of SplitString()/SplitStringPiece() defined in // string_split.h. @@ -501,13 +501,13 @@ // copies of those strings are created until the final join operation. // // Use StrCat (in base/strings/strcat.h) if you don't need a separator. -BASE_EXPORT std::string JoinString(const std::vector<std::string>& parts, +BASE_EXPORT std::string JoinString(span<const std::string> parts, StringPiece separator); -BASE_EXPORT string16 JoinString(const std::vector<string16>& parts, +BASE_EXPORT string16 JoinString(span<const string16> parts, StringPiece16 separator); -BASE_EXPORT std::string JoinString(const std::vector<StringPiece>& parts, +BASE_EXPORT std::string JoinString(span<const StringPiece> parts, StringPiece separator); -BASE_EXPORT string16 JoinString(const std::vector<StringPiece16>& parts, +BASE_EXPORT string16 JoinString(span<const StringPiece16> parts, StringPiece16 separator); // Explicit initializer_list overloads are required to break ambiguity when used // with a literal initializer list (otherwise the compiler would not be able to @@ -521,10 +521,10 @@ // Additionally, any number of consecutive '$' characters is replaced by that // number less one. Eg $$->$, $$$->$$, etc. The offsets parameter here can be // NULL. This only allows you to use up to nine replacements. -BASE_EXPORT string16 ReplaceStringPlaceholders( - const string16& format_string, - const std::vector<string16>& subst, - std::vector<size_t>* offsets); +BASE_EXPORT string16 +ReplaceStringPlaceholders(StringPiece16 format_string, + const std::vector<string16>& subst, + std::vector<size_t>* offsets); BASE_EXPORT std::string ReplaceStringPlaceholders( StringPiece format_string, @@ -536,7 +536,36 @@ const string16& a, size_t* offset); +// The following section contains overloads of the previously defined APIs for +// std::wstring and base::WStringPiece. In order to discourage using +// std::wstring in cross-platform code, these overloads are only enabled on +// Windows, and only if std::wstring is a different type than base::string16. #if defined(OS_WIN) && defined(BASE_STRING16_IS_STD_U16STRING) +BASE_EXPORT std::wstring ToLowerASCII(WStringPiece str); + +BASE_EXPORT std::wstring ToUpperASCII(WStringPiece str); + +BASE_EXPORT int CompareCaseInsensitiveASCII(WStringPiece a, WStringPiece b); + +BASE_EXPORT bool EqualsCaseInsensitiveASCII(WStringPiece a, WStringPiece b); + +BASE_EXPORT bool RemoveChars(WStringPiece input, + WStringPiece remove_chars, + std::wstring* output); + +BASE_EXPORT bool ReplaceChars(WStringPiece input, + WStringPiece replace_chars, + WStringPiece replace_with, + std::wstring* output); + +BASE_EXPORT bool TrimString(WStringPiece input, + WStringPiece trim_chars, + std::string* output); + +BASE_EXPORT WStringPiece TrimString(WStringPiece input, + WStringPiece trim_chars, + TrimPositions positions); + BASE_EXPORT TrimPositions TrimWhitespace(WStringPiece input, TrimPositions positions, std::wstring* output); @@ -544,22 +573,50 @@ BASE_EXPORT WStringPiece TrimWhitespace(WStringPiece input, TrimPositions positions); +BASE_EXPORT std::wstring CollapseWhitespace( + WStringPiece text, + bool trim_sequences_with_line_breaks); + +BASE_EXPORT bool ContainsOnlyChars(WStringPiece input, WStringPiece characters); + BASE_EXPORT bool LowerCaseEqualsASCII(WStringPiece str, StringPiece lowecase_ascii); -BASE_EXPORT bool TrimString(WStringPiece input, - WStringPiece trim_chars, - std::wstring* output); - -BASE_EXPORT WStringPiece TrimString(WStringPiece input, - WStringPiece trim_chars, - TrimPositions positions); +BASE_EXPORT bool EqualsASCII(StringPiece16 str, StringPiece ascii); BASE_EXPORT bool StartsWith(WStringPiece str, WStringPiece search_for, CompareCase case_sensitivity); +BASE_EXPORT bool EndsWith(WStringPiece str, + WStringPiece search_for, + CompareCase case_sensitivity); + +BASE_EXPORT void ReplaceFirstSubstringAfterOffset(std::wstring* str, + size_t start_offset, + WStringPiece find_this, + WStringPiece replace_with); + +BASE_EXPORT void ReplaceSubstringsAfterOffset(std::wstring* str, + size_t start_offset, + WStringPiece find_this, + WStringPiece replace_with); + BASE_EXPORT wchar_t* WriteInto(std::wstring* str, size_t length_with_null); + +BASE_EXPORT std::wstring JoinString(span<const std::wstring> parts, + WStringPiece separator); + +BASE_EXPORT std::wstring JoinString(span<const WStringPiece> parts, + WStringPiece separator); + +BASE_EXPORT std::wstring JoinString(std::initializer_list<WStringPiece> parts, + WStringPiece separator); + +BASE_EXPORT std::wstring ReplaceStringPlaceholders( + WStringPiece format_string, + const std::vector<string16>& subst, + std::vector<size_t>* offsets); #endif } // namespace base
diff --git a/build/android/gyp/compile_resources.py b/build/android/gyp/compile_resources.py index 2ca4ec7..eece2eb3 100755 --- a/build/android/gyp/compile_resources.py +++ b/build/android/gyp/compile_resources.py
@@ -18,7 +18,6 @@ import filecmp import hashlib import logging -import multiprocessing.dummy import os import re import shutil @@ -26,7 +25,6 @@ import sys import tempfile import textwrap -import time import zipfile from xml.etree import ElementTree @@ -34,9 +32,11 @@ from util import diff_utils from util import manifest_utils from util import md5_check +from util import parallel from util import protoresources from util import resource_utils + # Pngs that we shouldn't convert to webp. Please add rationale when updating. _PNG_WEBP_EXCLUSION_PATTERN = re.compile('|'.join([ # Crashes on Galaxy S5 running L (https://crbug.com/807059). @@ -546,68 +546,64 @@ build_utils.MatchesGlob(path, resource_exclusion_exceptions)) -def _ConvertToWebP(webp_binary, png_paths, path_info, webp_cache_dir): - pool = multiprocessing.dummy.Pool(10) +def _ComputeSha1(path): + with open(path, 'rb') as f: + data = f.read() + return hashlib.sha1(data).hexdigest() + + +def _ConvertToWebPSingle(png_path, cwebp_binary, cwebp_version, webp_cache_dir): + sha1_hash = _ComputeSha1(png_path) + + # The set of arguments that will appear in the cache key. + quality_args = ['-m', '6', '-q', '100', '-lossless'] + + webp_cache_path = os.path.join( + webp_cache_dir, '{}-{}-{}'.format(sha1_hash, cwebp_version, + ''.join(quality_args))) + # No need to add .webp. Android can load images fine without them. + webp_path = os.path.splitext(png_path)[0] + + cache_hit = os.path.exists(webp_cache_path) + if cache_hit: + os.link(webp_cache_path, webp_path) + else: + # We place the generated webp image to webp_path, instead of in the + # webp_cache_dir to avoid concurrency issues. + args = [cwebp_binary, png_path, '-o', webp_path, '-quiet'] + quality_args + subprocess.check_call(args) + + try: + os.link(webp_path, webp_cache_path) + except OSError: + # Because of concurrent run, a webp image may already exists in + # webp_cache_path. + pass + + os.remove(png_path) + original_dir = os.path.dirname(os.path.dirname(png_path)) + rename_tuple = (os.path.relpath(png_path, original_dir), + os.path.relpath(webp_path, original_dir)) + return rename_tuple, cache_hit + + +def _ConvertToWebP(cwebp_binary, png_paths, path_info, webp_cache_dir): + cwebp_version = subprocess.check_output([cwebp_binary, '-version']).rstrip() + shard_args = [(f, ) for f in png_paths + if not _PNG_WEBP_EXCLUSION_PATTERN.match(f)] build_utils.MakeDirectory(webp_cache_dir) + results = parallel.BulkForkAndCall(_ConvertToWebPSingle, + shard_args, + cwebp_binary=cwebp_binary, + cwebp_version=cwebp_version, + webp_cache_dir=webp_cache_dir) + total_cache_hits = 0 + for rename_tuple, cache_hit in results: + path_info.RegisterRename(*rename_tuple) + total_cache_hits += int(cache_hit) - cwebp_version = subprocess.check_output([webp_binary, '-version']).rstrip() - cwebp_arguments = ['-mt', '-quiet', '-m', '6', '-q', '100', '-lossless'] - - sha1_time = [0] - cwebp_time = [0] - cache_hits = [0] - - def cal_sha1(png_path): - start = time.time() - with open(png_path, 'rb') as f: - png_content = f.read() - - sha1_hex = hashlib.sha1(png_content).hexdigest() - sha1_time[0] += time.time() - start - return sha1_hex - - def get_converted_image(png_path): - sha1_hash = cal_sha1(png_path) - - webp_cache_path = os.path.join( - webp_cache_dir, '{}-{}-{}'.format(sha1_hash, cwebp_version, - ''.join(cwebp_arguments))) - # No need to add an extension, android can load images fine without them. - webp_path = os.path.splitext(png_path)[0] - - if os.path.exists(webp_cache_path): - cache_hits[0] += 1 - os.link(webp_cache_path, webp_path) - else: - # We place the generated webp image to webp_path, instead of in the - # webp_cache_dir to avoid concurrency issues. - start = time.time() - args = [webp_binary, png_path] + cwebp_arguments + ['-o', webp_path] - subprocess.check_call(args) - cwebp_time[0] += time.time() - start - - try: - os.link(webp_path, webp_cache_path) - except OSError: - # Because of concurrent run, a webp image may already exists in - # webp_cache_path. - pass - - os.remove(png_path) - original_dir = os.path.dirname(os.path.dirname(png_path)) - path_info.RegisterRename( - os.path.relpath(png_path, original_dir), - os.path.relpath(webp_path, original_dir)) - - png_paths = [f for f in png_paths if not _PNG_WEBP_EXCLUSION_PATTERN.match(f)] - try: - pool.map(get_converted_image, png_paths) - finally: - pool.close() - pool.join() - logging.debug('png->webp: cache: %d/%d sha1 time: %.1fms cwebp time: %.1fms', - cache_hits[0], len(png_paths), sha1_time[0], cwebp_time[0]) + logging.debug('png->webp cache: %d/%d', total_cache_hits, len(shard_args)) def _RemoveImageExtensions(directory, path_info): @@ -627,10 +623,9 @@ os.path.relpath(path_no_extension, directory)) -def _CompileSingleDep(args): - index, dep_path, aapt2_path, partials_dir, exclusion_rules = args - basename = os.path.basename(dep_path) - unique_name = '{}_{}'.format(index, basename) +def _CompileSingleDep(index, dep_subdir, keep_predicate, aapt2_path, + partials_dir): + unique_name = '{}_{}'.format(index, os.path.basename(dep_subdir)) partial_path = os.path.join(partials_dir, '{}.zip'.format(unique_name)) compile_command = [ @@ -639,7 +634,7 @@ # TODO(wnwen): Turn this on once aapt2 forces 9-patch to be crunched. # '--no-crunch', '--dir', - dep_path, + dep_subdir, '-o', partial_path ] @@ -654,33 +649,16 @@ # Filtering these files is expensive, so only apply filters to the partials # that have been explicitly targeted. - keep_predicate = _CreateValuesKeepPredicate(exclusion_rules, dep_path) if keep_predicate: - logging.debug('Applying .arsc filtering to %s', dep_path) + logging.debug('Applying .arsc filtering to %s', dep_subdir) protoresources.StripUnwantedResources(partial_path, keep_predicate) return partial_path -def _CompileDeps(aapt2_path, dep_subdirs, temp_dir, exclusion_rules): - partials_dir = os.path.join(temp_dir, 'partials') - build_utils.MakeDirectory(partials_dir) - - def iter_params(): - for i, dep_path in enumerate(dep_subdirs): - yield i, dep_path, aapt2_path, partials_dir, exclusion_rules - - pool = multiprocessing.dummy.Pool(10) - try: - return pool.map(_CompileSingleDep, iter_params()) - finally: - pool.close() - pool.join() - - -def _CreateValuesKeepPredicate(exclusion_rules, dep_path): +def _CreateValuesKeepPredicate(exclusion_rules, dep_subdir): patterns = [ x[1] for x in exclusion_rules - if build_utils.MatchesGlob(dep_path, [x[0]]) + if build_utils.MatchesGlob(dep_subdir, [x[0]]) ] if not patterns: return None @@ -689,6 +667,23 @@ return lambda x: not any(r.search(x) for r in regexes) +def _CompileDeps(aapt2_path, dep_subdirs, temp_dir, exclusion_rules): + partials_dir = os.path.join(temp_dir, 'partials') + build_utils.MakeDirectory(partials_dir) + + job_params = [(i, dep_subdir, + _CreateValuesKeepPredicate(exclusion_rules, dep_subdir)) + for i, dep_subdir in enumerate(dep_subdirs)] + + # Filtering is slow, so ensure jobs with keep_predicate are started first. + job_params.sort(key=lambda x: not x[2]) + return list( + parallel.BulkForkAndCall(_CompileSingleDep, + job_params, + aapt2_path=aapt2_path, + partials_dir=partials_dir)) + + def _CreateResourceInfoFile(path_info, info_path, dependencies_res_zips): for zip_file in dependencies_res_zips: zip_info_file_path = zip_file + '.info'
diff --git a/build/android/gyp/compile_resources.pydeps b/build/android/gyp/compile_resources.pydeps index f34926c1..4e5ce72 100644 --- a/build/android/gyp/compile_resources.pydeps +++ b/build/android/gyp/compile_resources.pydeps
@@ -55,5 +55,6 @@ util/diff_utils.py util/manifest_utils.py util/md5_check.py +util/parallel.py util/protoresources.py util/resource_utils.py
diff --git a/build/android/gyp/util/parallel.py b/build/android/gyp/util/parallel.py new file mode 100644 index 0000000..082ad972 --- /dev/null +++ b/build/android/gyp/util/parallel.py
@@ -0,0 +1,214 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +"""Helpers related to multiprocessing. + +Based on: //tools/binary_size/libsupersize/parallel.py +""" + +import atexit +import logging +import multiprocessing +import os +import sys +import threading +import traceback + +DISABLE_ASYNC = os.environ.get('DISABLE_ASYNC') == '1' +if DISABLE_ASYNC: + logging.warning('Running in synchronous mode.') + +_all_pools = None +_is_child_process = False +_silence_exceptions = False + +# Used to pass parameters to forked processes without pickling. +_fork_params = None +_fork_kwargs = None + + +class _ImmediateResult(object): + def __init__(self, value): + self._value = value + + def get(self): + return self._value + + def wait(self): + pass + + def ready(self): + return True + + def successful(self): + return True + + +class _ExceptionWrapper(object): + """Used to marshal exception messages back to main process.""" + + def __init__(self, msg, exception_type=None): + self.msg = msg + self.exception_type = exception_type + + def MaybeThrow(self): + if self.exception_type: + raise getattr(__builtins__, + self.exception_type)('Originally caused by: ' + self.msg) + + +class _FuncWrapper(object): + """Runs on the fork()'ed side to catch exceptions and spread *args.""" + + def __init__(self, func): + global _is_child_process + _is_child_process = True + self._func = func + + def __call__(self, index, _=None): + try: + return self._func(*_fork_params[index], **_fork_kwargs) + except Exception as e: + # Only keep the exception type for builtin exception types or else risk + # further marshalling exceptions. + exception_type = None + if hasattr(__builtins__, type(e).__name__): + exception_type = type(e).__name__ + # multiprocessing is supposed to catch and return exceptions automatically + # but it doesn't seem to work properly :(. + return _ExceptionWrapper(traceback.format_exc(), exception_type) + except: # pylint: disable=bare-except + return _ExceptionWrapper(traceback.format_exc()) + + +class _WrappedResult(object): + """Allows for host-side logic to be run after child process has terminated. + + * Unregisters associated pool _all_pools. + * Raises exception caught by _FuncWrapper. + """ + + def __init__(self, result, pool=None): + self._result = result + self._pool = pool + + def get(self): + self.wait() + value = self._result.get() + _CheckForException(value) + return value + + def wait(self): + self._result.wait() + if self._pool: + _all_pools.remove(self._pool) + self._pool = None + + def ready(self): + return self._result.ready() + + def successful(self): + return self._result.successful() + + +def _TerminatePools(): + """Calls .terminate() on all active process pools. + + Not supposed to be necessary according to the docs, but seems to be required + when child process throws an exception or Ctrl-C is hit. + """ + global _silence_exceptions + _silence_exceptions = True + # Child processes cannot have pools, but atexit runs this function because + # it was registered before fork()ing. + if _is_child_process: + return + + def close_pool(pool): + try: + pool.terminate() + except: # pylint: disable=bare-except + pass + + for i, pool in enumerate(_all_pools): + # Without calling terminate() on a separate thread, the call can block + # forever. + thread = threading.Thread(name='Pool-Terminate-{}'.format(i), + target=close_pool, + args=(pool, )) + thread.daemon = True + thread.start() + + +def _CheckForException(value): + if isinstance(value, _ExceptionWrapper): + global _silence_exceptions + if not _silence_exceptions: + value.MaybeThrow() + _silence_exceptions = True + logging.error('Subprocess raised an exception:\n%s', value.msg) + sys.exit(1) + + +def _MakeProcessPool(job_params, **job_kwargs): + global _all_pools + global _fork_params + global _fork_kwargs + assert _fork_params is None + assert _fork_kwargs is None + pool_size = min(len(job_params), multiprocessing.cpu_count()) + _fork_params = job_params + _fork_kwargs = job_kwargs + ret = multiprocessing.Pool(pool_size) + _fork_params = None + _fork_kwargs = None + if _all_pools is None: + _all_pools = [] + atexit.register(_TerminatePools) + _all_pools.append(ret) + return ret + + +def ForkAndCall(func, args): + """Runs |func| in a fork'ed process. + + Returns: + A Result object (call .get() to get the return value) + """ + if DISABLE_ASYNC: + pool = None + result = _ImmediateResult(func(*args)) + else: + pool = _MakeProcessPool([args]) # Omit |kwargs|. + result = pool.apply_async(_FuncWrapper(func), (0, )) + pool.close() + return _WrappedResult(result, pool=pool) + + +def BulkForkAndCall(func, arg_tuples, **kwargs): + """Calls |func| in a fork'ed process for each set of args within |arg_tuples|. + + Args: + kwargs: Common keyword arguments to be passed to |func|. + + Yields the return values in order. + """ + arg_tuples = list(arg_tuples) + if not arg_tuples: + return + + if DISABLE_ASYNC: + for args in arg_tuples: + yield func(*args, **kwargs) + return + + pool = _MakeProcessPool(arg_tuples, **kwargs) + wrapped_func = _FuncWrapper(func) + try: + for result in pool.imap(wrapped_func, xrange(len(arg_tuples))): + _CheckForException(result) + yield result + finally: + pool.close() + pool.join() + _all_pools.remove(pool)
diff --git a/build/android/lint/suppressions.xml b/build/android/lint/suppressions.xml index bf7ad48b..fa78146 100644 --- a/build/android/lint/suppressions.xml +++ b/build/android/lint/suppressions.xml
@@ -275,8 +275,6 @@ <ignore regexp="Field requires API level .*`android.app.TaskInfo"/> <!-- 1: This is for testonly target android_support_chromium_java in android_sdk. --> <ignore regexp="third_party/android_sdk/public/extras/chromium/support/src/org/chromium/android/support/PackageManagerWrapper.java"/> - <!-- 1: TODO(crbug.com/1081242): Fix --> - <ignore regexp="chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiWindowUtils.java"/> <!-- 1: TODO(crbug.com/1081243): Fix --> <ignore regexp="chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerVideoPlayer.java"/> <!-- 1: TODO(crbug.com/1082222): Fix -->
diff --git a/build/android/pylib/symbols/deobfuscator.py b/build/android/pylib/symbols/deobfuscator.py index 42084dd..ffc23b8 100644 --- a/build/android/pylib/symbols/deobfuscator.py +++ b/build/android/pylib/symbols/deobfuscator.py
@@ -150,7 +150,7 @@ # De-obfuscation is broken. if self._num_restarts == _MAX_RESTARTS: - return lines + raise Exception('Deobfuscation seems broken.') # Restart any closed Deobfuscators. for i, d in enumerate(self._pool):
diff --git a/build/config/ios/ios_sdk.gni b/build/config/ios/ios_sdk.gni index f3aaf810..822db3ae 100644 --- a/build/config/ios/ios_sdk.gni +++ b/build/config/ios/ios_sdk.gni
@@ -27,12 +27,18 @@ # not work (see build/BUILDCONFIG.gn for pattern that would cause issue). ios_sdk_developer_dir = "" - # The iOS Code signing identity to use - # TODO(GYP), TODO(sdfresne): Consider having a separate - # ios_enable_code_signing_flag=<bool> flag to make the invocation clearer. + # Control whether codesiging is enabled (ignored for simulator builds). ios_enable_code_signing = true + + # Explicitly select the identity to use for codesigning. If defined, must + # be set to a non-empty string that will be passed to codesigning. Can be + # left unspecified if ios_code_signing_identity_description is used instead. ios_code_signing_identity = "" - ios_code_signing_identity_description = "iPhone Developer" + + # Pattern used to select the identity to use for codesigning. If defined, + # must be a substring of the description of exactly one of the identities by + # `security find-identity -v -p codesigning`. + ios_code_signing_identity_description = "" # Prefix for CFBundleIdentifier property of iOS bundles (correspond to the # "Organization Identifier" in Xcode). Code signing will fail if no mobile @@ -68,6 +74,18 @@ use_ios_simulator = current_cpu == "x86" || current_cpu == "x64" +# If codesigning is enabled, use must configure either a codesigning identity +# or a filter to automatically select the codesigning identity. +if (!use_ios_simulator && ios_enable_code_signing) { + assert(ios_code_signing_identity == "" || + ios_code_signing_identity_description == "", + "You should either specify the precise identity to use with " + + "ios_code_signing_identity or let the code select an identity " + + "automatically (via find_signing_identity.py which use the " + + "variable ios_code_signing_identity_description to set the " + + "pattern to match the identity to use).") +} + # Initialize additional_toolchains from additional_target_cpus. Assert here # that the list does not contains $target_cpu nor duplicates as this would # cause weird errors during the build. @@ -135,12 +153,15 @@ # Automatically select a codesigning identity if no identity is configured. # This only applies to device build as simulator builds are not signed. if (ios_code_signing_identity == "") { - ios_code_signing_identity = - exec_script("find_signing_identity.py", - [ - "--matching-pattern", - ios_code_signing_identity_description, - ], - "string") + find_signing_identity_args = [] + if (ios_code_signing_identity_description != "") { + find_signing_identity_args = [ + "--matching-pattern", + ios_code_signing_identity_description, + ] + } + ios_code_signing_identity = exec_script("find_signing_identity.py", + find_signing_identity_args, + "trim string") } }
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index a0a05ca..e18892a 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20200519.0.1 +0.20200519.1.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index a0a05ca..e18892a 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -0.20200519.0.1 +0.20200519.1.1
diff --git a/build/fuchsia/qemu_image.py b/build/fuchsia/qemu_image.py index 5126074..ab5e040a 100644 --- a/build/fuchsia/qemu_image.py +++ b/build/fuchsia/qemu_image.py
@@ -18,6 +18,7 @@ import logging import subprocess +import tempfile import time @@ -33,7 +34,9 @@ """ logging.info('qemu-img starting') - p = subprocess.Popen(command) + command_output_file = tempfile.NamedTemporaryFile('w') + p = subprocess.Popen(command, stdout=command_output_file, + stderr=subprocess.STDOUT) start_sec = time.time() while p.poll() is None and time.time() - start_sec < QEMU_IMG_TIMEOUT_SEC: time.sleep(1) @@ -41,10 +44,17 @@ logging.info('qemu-img duration: %f' % float(stop_sec - start_sec)) if p.poll() is None: + returncode = None p.kill() - return None + p.wait() + else: + returncode = p.returncode - return p.returncode + log_level = logging.WARN if returncode else logging.DEBUG + for line in open(command_output_file.name, 'r'): + logging.log(log_level, 'qemu-img stdout: ' + line.strip()) + + return returncode def ExecQemuImgWithRetry(command):
diff --git a/build/fuchsia/runner_exceptions.py b/build/fuchsia/runner_exceptions.py index 88196e3..03f872e 100644 --- a/build/fuchsia/runner_exceptions.py +++ b/build/fuchsia/runner_exceptions.py
@@ -67,9 +67,12 @@ return 73 return 72 elif type is subprocess.CalledProcessError: - if value.cmd[0] == 'scp': + if os.path.basename(value.cmd[0]) == 'scp': print('Error: scp operation failed - %s' % str(value)) return 81 + if os.path.basename(value.cmd[0]) == 'qemu-img': + print('Error: qemu-img fuchsia image generation failed.') + return 82 return 80 else: return 1
diff --git a/cc/paint/image_transfer_cache_entry_unittest.cc b/cc/paint/image_transfer_cache_entry_unittest.cc index 24a334ee..0da5db2 100644 --- a/cc/paint/image_transfer_cache_entry_unittest.cc +++ b/cc/paint/image_transfer_cache_entry_unittest.cc
@@ -144,7 +144,7 @@ if (texture.isValid()) gr_context_->deleteBackendTexture(texture); } - gr_context_->flush(); + gr_context_->flushAndSubmit(); textures_to_free_.clear(); }
diff --git a/cc/paint/oop_pixeltest.cc b/cc/paint/oop_pixeltest.cc index 6c9f1c1..7533b17 100644 --- a/cc/paint/oop_pixeltest.cc +++ b/cc/paint/oop_pixeltest.cc
@@ -332,7 +332,7 @@ raster_source->PlaybackToCanvas( canvas, options.content_size, options.full_raster_rect, options.playback_rect, raster_transform, settings); - surface->flush(); + surface->flushAndSubmit(); EXPECT_EQ(gles2_context_provider_->ContextGL()->GetError(), static_cast<unsigned>(GL_NO_ERROR));
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc index 4a2d658..b745256 100644 --- a/cc/tiles/gpu_image_decode_cache.cc +++ b/cc/tiles/gpu_image_decode_cache.cc
@@ -2526,7 +2526,7 @@ CheckContextLockAcquiredIfNecessary(); lock_.AssertAcquired(); for (auto& image : *yuv_images) { - image->flush(context_->GrContext()); + image->flushAndSubmit(context_->GrContext()); } yuv_images->clear(); }
diff --git a/cc/tiles/gpu_image_decode_cache_perftest.cc b/cc/tiles/gpu_image_decode_cache_perftest.cc index 7a90390..416cd82 100644 --- a/cc/tiles/gpu_image_decode_cache_perftest.cc +++ b/cc/tiles/gpu_image_decode_cache_perftest.cc
@@ -157,7 +157,7 @@ surface->getCanvas()->drawImageRect(decoded_image.image().get(), SkRect::MakeWH(1024, 2048), SkRect::MakeWH(614, 1229), &paint); - surface->flush(); + surface->flushAndSubmit(); } cache_->DrawWithImageFinished(image, decoded_image);
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index d76f602e..4fc24ad 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -431,6 +431,7 @@ "//third_party/android_data_chart:android_data_chart_java", "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:androidx_annotation_annotation_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", "//third_party/android_deps:androidx_collection_collection_java", "//third_party/android_deps:androidx_coordinatorlayout_coordinatorlayout_java", "//third_party/android_deps:androidx_core_core_java", @@ -725,56 +726,99 @@ "//base:base_java", "//base:base_java_test_support", "//base:base_junit_test_support", + "//base:jni_java", + "//chrome/android:update_proto_java", + "//chrome/android:usage_stats_proto_java", "//chrome/android/features/keyboard_accessory:internal_java", + "//chrome/android/features/start_surface/internal:java", "//chrome/android/features/tab_ui:java", "//chrome/android/webapk/libs/client:client_java", "//chrome/android/webapk/libs/common:common_java", + "//chrome/android/webapk/libs/common:splash_java", "//chrome/android/webapk/test:junit_test_support", + "//chrome/browser/android/lifecycle:java", + "//chrome/browser/download/android:java", "//chrome/browser/flags:flags_junit_tests", + "//chrome/browser/flags:java", "//chrome/browser/image_fetcher:java", "//chrome/browser/optimization_guide/android:junit_tests", + "//chrome/browser/performance_hints/android:java", + "//chrome/browser/preferences:java", "//chrome/browser/preferences:preferences_junit_tests", + "//chrome/browser/profiles/android:java", + "//chrome/browser/tab:java", "//chrome/browser/thumbnail:java", "//chrome/browser/ui/android/appmenu/internal:junit", + "//chrome/browser/ui/android/favicon:java", + "//chrome/browser/ui/android/native_page:java", + "//chrome/browser/ui/messages/android:java", "//chrome/browser/ui/messages/android:junit", + "//chrome/browser/util:java", + "//chrome/browser/xsurface:java", "//chrome/test/android:chrome_java_test_support", "//components/background_task_scheduler:background_task_scheduler_java", "//components/bookmarks/common/android:bookmarks_java", + "//components/browser_ui/android/bottomsheet:java", + "//components/browser_ui/notifications/android:java", + "//components/browser_ui/site_settings/android:java", + "//components/browser_ui/util/android:java", "//components/browser_ui/util/android:junit", "//components/browser_ui/webshare/android:junit", + "//components/browser_ui/widget/android:java", "//components/browser_ui/widget/android:junit", + "//components/dom_distiller/core/android:dom_distiller_core_java", + "//components/embedder_support/android:browser_context_java", + "//components/embedder_support/android:content_view_java", + "//components/embedder_support/android:context_menu_java", "//components/embedder_support/android:junit_test_support", + "//components/embedder_support/android:util_java", + "//components/feature_engagement/public:public_java", + "//components/feed/core/proto:proto_java", + "//components/feed/core/proto:proto_java_v2", "//components/minidump_uploader:minidump_uploader_java", "//components/module_installer/android:module_installer_java", "//components/offline_items_collection/core:core_java", + "//components/omnibox/browser:browser_java", "//components/page_info/android:java", "//components/payments/content/android:java", "//components/payments/mojom:mojom_java", "//components/schema_org/common:mojom_java", + "//components/search_engines/android:java", + "//components/security_state/content/android:java", "//components/signin/core/browser/android:java", "//components/signin/core/browser/android:signin_java_test_support", + "//components/signin/public/android:java", "//components/sync:sync_java_test_support", "//components/sync/android:sync_java", "//components/url_formatter/android:url_formatter_java", "//components/variations/android:variations_java", "//content/public/android:content_java", + "//content/public/test/android:content_java_test_support", "//mojo/public/java:bindings_java", "//mojo/public/java:system_java", "//net/android:net_java", "//services/media_session/public/cpp/android:media_session_java", "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:androidx_annotation_annotation_java", + "//third_party/android_deps:androidx_collection_collection_java", "//third_party/android_deps:androidx_lifecycle_lifecycle_common_java", "//third_party/android_deps:androidx_mediarouter_mediarouter_java", "//third_party/android_deps:androidx_recyclerview_recyclerview_java", + "//third_party/android_deps:androidx_swiperefreshlayout_swiperefreshlayout_java", + "//third_party/android_deps:androidx_test_core_java", + "//third_party/android_deps:com_google_dagger_dagger_java", + "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", "//third_party/android_deps:com_googlecode_java_diff_utils_diffutils_java", "//third_party/android_sdk/androidx_browser:androidx_browser_java", "//third_party/blink/public:blink_headers_java", "//third_party/blink/public/mojom:android_mojo_bindings_java", "//third_party/cacheinvalidation:cacheinvalidation_javalib", + "//third_party/gif_player:gif_player_java", "//third_party/google-truth:google_truth_java", + "//third_party/guava:guava_android_java", "//third_party/hamcrest:hamcrest_java", "//ui/android:ui_java", + "//url:gurl_java", "//url/mojom:url_mojom_gurl_java", ] @@ -859,12 +903,14 @@ "//chrome/browser/download/android:java", "//chrome/browser/enterprise/util:java", "//chrome/browser/flags:java", + "//chrome/browser/offline_pages/android:java", "//chrome/browser/password_manager/android_test_helpers:test_support_java", "//chrome/browser/performance_hints/android:java", "//chrome/browser/preferences:java", "//chrome/browser/profiles/android:java", "//chrome/browser/settings:java", "//chrome/browser/settings:javatests", + "//chrome/browser/settings:test_support_java", "//chrome/browser/tab:java", "//chrome/browser/thumbnail:java", "//chrome/browser/thumbnail:javatests", @@ -884,14 +930,19 @@ "//components/browser_ui/android/bottomsheet:java", "//components/browser_ui/modaldialog/android:java", "//components/browser_ui/modaldialog/android:javatests", + "//components/browser_ui/notifications/android:java", + "//components/browser_ui/notifications/android:test_support_java", "//components/browser_ui/settings/android:java", "//components/browser_ui/share/android:javatests", + "//components/browser_ui/site_settings/android:java", "//components/browser_ui/site_settings/android:javatests", "//components/browser_ui/styles/android:java", "//components/browser_ui/util/android:java", "//components/browser_ui/widget/android:java", "//components/browser_ui/widget/android:javatests", "//components/browser_ui/widget/android:test_support_java", + "//components/content_settings/android:content_settings_enums_java", + "//components/content_settings/android:java", "//components/crash/android:java", "//components/dom_distiller/core/android:dom_distiller_core_java", "//components/dom_distiller/core/mojom:mojom_java", @@ -921,12 +972,14 @@ "//components/offline_pages/core/prefetch:offline_prefetch_proto_java", "//components/omnibox/browser:browser_java", "//components/page_info/android:java", + "//components/page_info/android:page_info_action_enum_java", "//components/paint_preview/player/android:javatests", "//components/payments/content/android:java", "//components/payments/mojom:mojom_java", "//components/permissions/android:java", "//components/policy/android:policy_java", "//components/policy/android:policy_java_test_support", + "//components/query_tiles:public_java", "//components/safe_browsing/android:safe_browsing_java", "//components/schema_org/common:mojom_java", "//components/search_engines/android:java", @@ -959,10 +1012,13 @@ "//third_party/android_data_chart:android_data_chart_java", "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:androidx_annotation_annotation_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", "//third_party/android_deps:androidx_collection_collection_java", "//third_party/android_deps:androidx_lifecycle_lifecycle_common_java", "//third_party/android_deps:androidx_preference_preference_java", "//third_party/android_deps:androidx_recyclerview_recyclerview_java", + "//third_party/android_deps:androidx_viewpager_viewpager_java", + "//url:origin_java", # TODO (bjoyce): Remove recyclerview_v7 when espresso tests are migrated # to androidx. @@ -1162,14 +1218,20 @@ "javatests/src/org/chromium/chrome/browser/vr/util/VrTransitionUtils.java", ] - deps = chrome_test_xr_java_deps + [ - ":chrome_test_util_java", - "//chrome/android:chrome_test_xr_java", - "//components/module_installer/android:module_installer_java", - "//third_party/gvr-android-sdk:controller_test_api_java", - "//third_party/gvr-android-sdk:gvr_common_java", - "//ui/android:ui_java_test_support", - ] + deps = + chrome_test_xr_java_deps + [ + ":chrome_test_util_java", + "//chrome/android:chrome_test_xr_java", + "//components/module_installer/android:module_installer_java", + "//components/browser_ui/site_settings/android:java", + "//chrome/browser/settings:java", + "//components/content_settings/android:content_settings_enums_java", + "//chrome/browser/profiles/android:java", + + "//third_party/gvr-android-sdk:controller_test_api_java", + "//third_party/gvr-android-sdk:gvr_common_java", + "//ui/android:ui_java_test_support", + ] data = [ "//chrome/android/shared_preference_files/test/", @@ -3035,20 +3097,24 @@ "//chrome/android:chrome_java", "//chrome/browser/flags:java", "//chrome/browser/image_fetcher:java", + "//chrome/browser/preferences:java", "//chrome/browser/profiles/android:java", "//chrome/browser/tab:java", + "//chrome/browser/ui/android/favicon:java", "//chrome/browser/util:java", "//chrome/test/android:chrome_java_test_support", "//components/embedder_support/android:context_menu_java", "//components/embedder_support/android:util_java", "//components/omnibox/browser:browser_java", "//components/payments/content/android:java", + "//components/payments/mojom:mojom_java", "//components/search_engines/android:java", "//components/security_state/content/android:java", "//components/security_state/core:security_state_enums_java", "//content/public/android:content_java", "//content/public/test/android:android_test_message_pump_support_java", "//content/public/test/android:content_java_test_support", + "//third_party/android_deps:androidx_collection_collection_java", "//third_party/android_deps:com_google_code_findbugs_jsr305_java", "//third_party/blink/public:blink_headers_java", "//third_party/blink/public/mojom:android_mojo_bindings_java",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index e7d42204..c312c53 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -895,7 +895,6 @@ "java/src/org/chromium/chrome/browser/media/PictureInPictureActivity.java", "java/src/org/chromium/chrome/browser/media/PictureInPictureController.java", "java/src/org/chromium/chrome/browser/media/remote/RecordCastAction.java", - "java/src/org/chromium/chrome/browser/media/ui/MediaButtonReceiver.java", "java/src/org/chromium/chrome/browser/media/ui/MediaImageCallback.java", "java/src/org/chromium/chrome/browser/media/ui/MediaImageManager.java", "java/src/org/chromium/chrome/browser/media/ui/MediaNotificationInfo.java",
diff --git a/chrome/android/features/autofill_assistant/BUILD.gn b/chrome/android/features/autofill_assistant/BUILD.gn index 7e20e80..2458468 100644 --- a/chrome/android/features/autofill_assistant/BUILD.gn +++ b/chrome/android/features/autofill_assistant/BUILD.gn
@@ -16,6 +16,7 @@ "//base:base_java", "//chrome/android:chrome_java", "//third_party/android_deps:android_support_v7_appcompat_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", ] sources = [ "java/src/org/chromium/chrome/browser/" + @@ -51,6 +52,7 @@ "//mojo/public/java:bindings_java", "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:androidx_annotation_annotation_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", "//third_party/android_deps:androidx_collection_collection_java", "//third_party/android_deps:androidx_coordinatorlayout_coordinatorlayout_java", "//third_party/android_deps:androidx_core_core_java", @@ -273,6 +275,8 @@ "//chrome/browser/image_fetcher:java", "//chrome/browser/password_manager/android_test_helpers:test_support_java", "//chrome/browser/preferences:java", + "//chrome/browser/tab:java", + "//chrome/browser/util:java", "//chrome/test/android:chrome_java_test_support", "//components/autofill_assistant/browser:proto_java", "//components/browser_ui/android/bottomsheet:java", @@ -290,6 +294,7 @@ "//third_party/junit", "//third_party/mockito:mockito_java", "//ui/android:ui_full_java", + "//url:gurl_java", ] data = [ "//components/test/data/autofill_assistant/" ]
diff --git a/chrome/android/features/autofill_assistant/java/DEPS b/chrome/android/features/autofill_assistant/java/DEPS index 37154db7..2f948de 100644 --- a/chrome/android/features/autofill_assistant/java/DEPS +++ b/chrome/android/features/autofill_assistant/java/DEPS
@@ -1,5 +1,6 @@ include_rules = [ "+chrome/browser/image_fetcher", + "+chrome/browser/profiles/android/java", "+chrome/browser/ui/messages/android/java", "+components/autofill/android", "+components/browser_ui/widget/android",
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataBinder.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataBinder.java index 94de1a87..ef148346 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataBinder.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataBinder.java
@@ -23,6 +23,7 @@ import org.chromium.chrome.browser.payments.BasicCardUtils; import org.chromium.chrome.browser.payments.CardEditor; import org.chromium.chrome.browser.payments.ContactEditor; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.components.payments.MethodStrings; import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; @@ -647,6 +648,7 @@ return true; } + Profile profile = Profile.fromWebContents(webContents); if (shouldShowContactDetails(model)) { ContactEditor contactEditor = new ContactEditor(model.get(AssistantCollectUserDataModel.REQUEST_NAME), @@ -654,14 +656,14 @@ model.get(AssistantCollectUserDataModel.REQUEST_EMAIL), !webContents.isIncognito()); contactEditor.setEditorDialog(new EditorDialog(view.mActivity, - /*deleteRunnable =*/null)); + /*deleteRunnable =*/null, profile)); view.mContactDetailsSection.setEditor(contactEditor); } AddressEditor addressEditor = new AddressEditor(AddressEditor.Purpose.PAYMENT_REQUEST, /* saveToDisk= */ !webContents.isIncognito()); addressEditor.setEditorDialog(new EditorDialog(view.mActivity, - /*deleteRunnable =*/null)); + /*deleteRunnable =*/null, profile)); CardEditor cardEditor = new CardEditor(webContents, addressEditor, /* includeOrgLabel= */ false, /* observerForTest= */ null); @@ -673,7 +675,7 @@ } EditorDialog cardEditorDialog = new EditorDialog(view.mActivity, - /*deleteRunnable =*/null); + /*deleteRunnable =*/null, profile); if (ChromeVersionInfo.isBetaBuild() || ChromeVersionInfo.isStableBuild()) { cardEditorDialog.disableScreenshots(); }
diff --git a/chrome/android/features/keyboard_accessory/BUILD.gn b/chrome/android/features/keyboard_accessory/BUILD.gn index 235b10d..fee568c 100644 --- a/chrome/android/features/keyboard_accessory/BUILD.gn +++ b/chrome/android/features/keyboard_accessory/BUILD.gn
@@ -100,11 +100,26 @@ deps = [ ":internal_java", + "//base:base_java", "//base:base_java_test_support", "//base:base_junit_test_support", + "//chrome/android:chrome_java", "//chrome/android:chrome_test_util_java", + "//chrome/android/features/keyboard_accessory/public:public_java", + "//chrome/browser/flags:java", + "//chrome/browser/tab:java", + "//chrome/test/android:chrome_java_test_support", + "//components/autofill/android:autofill_java", + "//components/embedder_support/android:content_view_java", "//components/module_installer/android:module_installer_java", + "//content/public/android:content_java", + "//third_party/android_deps:androidx_recyclerview_recyclerview_java", + "//third_party/android_deps:com_google_android_material_material_java", + "//third_party/hamcrest:hamcrest_java", "//third_party/junit", "//third_party/mockito:mockito_java", + "//ui/android:ui_full_java", + "//ui/android:ui_java_test_support", + "//ui/android:ui_utils_java", ] }
diff --git a/chrome/android/features/keyboard_accessory/internal/BUILD.gn b/chrome/android/features/keyboard_accessory/internal/BUILD.gn index 5bef9e6..827b821 100644 --- a/chrome/android/features/keyboard_accessory/internal/BUILD.gn +++ b/chrome/android/features/keyboard_accessory/internal/BUILD.gn
@@ -26,6 +26,7 @@ "//components/feature_engagement/public:public_java", "//content/public/android:content_java", "//third_party/android_deps:android_support_v7_appcompat_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", "//third_party/android_deps:androidx_recyclerview_recyclerview_java", "//third_party/android_deps:androidx_viewpager_viewpager_java", "//third_party/android_deps:com_google_android_material_material_java",
diff --git a/chrome/android/features/media_router/BUILD.gn b/chrome/android/features/media_router/BUILD.gn index 8b99219..4721796 100644 --- a/chrome/android/features/media_router/BUILD.gn +++ b/chrome/android/features/media_router/BUILD.gn
@@ -122,8 +122,13 @@ deps = [ ":java", + "$google_play_services_package:google_play_services_basement_java", + "$google_play_services_package:google_play_services_cast_framework_java", + "$google_play_services_package:google_play_services_cast_java", + "//base:base_java", "//base:base_java_test_support", "//base:base_junit_test_support", + "//third_party/android_deps:androidx_mediarouter_mediarouter_java", ] }
diff --git a/chrome/android/features/tab_ui/BUILD.gn b/chrome/android/features/tab_ui/BUILD.gn index 89dcb33..8da48ff 100644 --- a/chrome/android/features/tab_ui/BUILD.gn +++ b/chrome/android/features/tab_ui/BUILD.gn
@@ -199,6 +199,7 @@ "//content/public/android:content_java_resources", "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:androidx_annotation_annotation_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", "//third_party/android_deps:androidx_core_core_java", "//third_party/android_deps:androidx_legacy_legacy_support_v13_java", "//third_party/android_deps:androidx_lifecycle_lifecycle_common_java",
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurface.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurface.java index c872d7d..e911a57 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurface.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurface.java
@@ -337,6 +337,8 @@ // TODO(jianli): Call this function at the appropriate time. void reportStreamScrolled( long nativeFeedStreamSurface, FeedStreamSurface caller, int distanceDp); + // TODO(jianli): Call this function at the appropriate time. + void reportStreamScrollStart(long nativeFeedStreamSurface, FeedStreamSurface caller); void loadMore(long nativeFeedStreamSurface, FeedStreamSurface caller); void processThereAndBackAgain( long nativeFeedStreamSurface, FeedStreamSurface caller, byte[] data);
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index 472536e..8cb812cd 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -1173,24 +1173,6 @@ </intent-filter> </service> - - <receiver android:name="org.chromium.chrome.browser.media.ui.MediaNotificationManager$PlaybackMediaButtonReceiver"> - <intent-filter> - <action android:name="android.intent.action.MEDIA_BUTTON" /> - </intent-filter> - </receiver> - <receiver android:name="org.chromium.chrome.browser.media.ui.MediaNotificationManager$PresentationMediaButtonReceiver"> - <intent-filter> - <action android:name="android.intent.action.MEDIA_BUTTON" /> - </intent-filter> - </receiver> - <receiver android:name="org.chromium.chrome.browser.media.ui.MediaNotificationManager$CastMediaButtonReceiver"> - <intent-filter> - <action android:name="android.intent.action.MEDIA_BUTTON" /> - </intent-filter> - </receiver> - - <service android:name="org.chromium.chrome.browser.tracing.TracingNotificationService" android:exported="false"/>
diff --git a/chrome/android/java/monochrome_public_bundle__base_bundle_module.AndroidManifest.expected b/chrome/android/java/monochrome_public_bundle__base_bundle_module.AndroidManifest.expected index 5b34e69..6472f9a 100644 --- a/chrome/android/java/monochrome_public_bundle__base_bundle_module.AndroidManifest.expected +++ b/chrome/android/java/monochrome_public_bundle__base_bundle_module.AndroidManifest.expected
@@ -968,24 +968,6 @@ android:name="android.appwidget.provider" android:resource="@xml/search_widget_info"/> </receiver> - <receiver - android:name="org.chromium.chrome.browser.media.ui.MediaNotificationManager$CastMediaButtonReceiver"> - <intent-filter> - <action android:name="android.intent.action.MEDIA_BUTTON"/> - </intent-filter> - </receiver> - <receiver - android:name="org.chromium.chrome.browser.media.ui.MediaNotificationManager$PlaybackMediaButtonReceiver"> - <intent-filter> - <action android:name="android.intent.action.MEDIA_BUTTON"/> - </intent-filter> - </receiver> - <receiver - android:name="org.chromium.chrome.browser.media.ui.MediaNotificationManager$PresentationMediaButtonReceiver"> - <intent-filter> - <action android:name="android.intent.action.MEDIA_BUTTON"/> - </intent-filter> - </receiver> <receiver android:name="org.chromium.chrome.browser.services.AccountsChangedReceiver"> <intent-filter> <action android:name="android.accounts.LOGIN_ACCOUNTS_CHANGED"/>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java b/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java index b024ff3..aaa2c835 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java
@@ -276,9 +276,12 @@ } } + boolean isIntentSenderChrome = IntentHandler.wasIntentSenderChrome(intent); + // Use a custom tab with a unique theme for payment handlers. if (intent.getIntExtra(CustomTabIntentDataProvider.EXTRA_UI_TYPE, CustomTabsUiType.DEFAULT) - == CustomTabsUiType.PAYMENT_REQUEST) { + == CustomTabsUiType.PAYMENT_REQUEST + && isIntentSenderChrome) { newIntent.setClassName(context, PaymentHandlerActivity.class.getName()); } @@ -314,7 +317,7 @@ // If the previous caller was not Chrome, but added EXTRA_IS_OPENED_BY_CHROME // for malicious purpose, remove it. The new intent will be sent by Chrome, but was not // sent by Chrome initially. - if (!IntentHandler.wasIntentSenderChrome(intent)) { + if (!isIntentSenderChrome) { IntentUtils.safeRemoveExtra( newIntent, CustomTabIntentDataProvider.EXTRA_IS_OPENED_BY_CHROME); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskBridge.java index 5eb8a1ce..d0448916 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskBridge.java
@@ -25,10 +25,9 @@ public CardUnmaskBridge(long nativeCardUnmaskPromptViewAndroid, String title, String instructions, String confirmButtonLabel, int iconId, - boolean shouldRequestExpirationDate, boolean canStoreLocally, - boolean defaultToStoringLocally, boolean shouldOfferWebauthn, - boolean defaultUseScreenlockChecked, long successMessageDurationMilliseconds, - WindowAndroid windowAndroid) { + boolean shouldRequestExpirationDate, boolean defaultToStoringLocally, + boolean shouldOfferWebauthn, boolean defaultUseScreenlockChecked, + long successMessageDurationMilliseconds, WindowAndroid windowAndroid) { mNativeCardUnmaskPromptViewAndroid = nativeCardUnmaskPromptViewAndroid; Activity activity = windowAndroid.getActivity().get(); if (activity == null) { @@ -38,7 +37,7 @@ new Handler().post(() -> dismissed()); } else { mCardUnmaskPrompt = new CardUnmaskPrompt(activity, this, title, instructions, - confirmButtonLabel, iconId, shouldRequestExpirationDate, canStoreLocally, + confirmButtonLabel, iconId, shouldRequestExpirationDate, defaultToStoringLocally, shouldOfferWebauthn, defaultUseScreenlockChecked, successMessageDurationMilliseconds); } @@ -47,14 +46,12 @@ @CalledByNative private static CardUnmaskBridge create(long nativeUnmaskPrompt, String title, String instructions, String confirmButtonLabel, int iconId, - boolean shouldRequestExpirationDate, boolean canStoreLocally, - boolean defaultToStoringLocally, boolean shouldOfferWebauthn, - boolean defaultUseScreenlockChecked, long successMessageDurationMilliseconds, - WindowAndroid windowAndroid) { + boolean shouldRequestExpirationDate, boolean defaultToStoringLocally, + boolean shouldOfferWebauthn, boolean defaultUseScreenlockChecked, + long successMessageDurationMilliseconds, WindowAndroid windowAndroid) { return new CardUnmaskBridge(nativeUnmaskPrompt, title, instructions, confirmButtonLabel, - iconId, shouldRequestExpirationDate, canStoreLocally, defaultToStoringLocally, - shouldOfferWebauthn, defaultUseScreenlockChecked, - successMessageDurationMilliseconds, windowAndroid); + iconId, shouldRequestExpirationDate, defaultToStoringLocally, shouldOfferWebauthn, + defaultUseScreenlockChecked, successMessageDurationMilliseconds, windowAndroid); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java index da7ae9ae..9c5f5ce2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java
@@ -145,9 +145,9 @@ public CardUnmaskPrompt(Context context, CardUnmaskPromptDelegate delegate, String title, String instructions, String confirmButtonLabel, int drawableId, - boolean shouldRequestExpirationDate, boolean canStoreLocally, - boolean defaultToStoringLocally, boolean shouldOfferWebauthn, - boolean defaultUseScreenlockChecked, long successMessageDurationMilliseconds) { + boolean shouldRequestExpirationDate, boolean defaultToStoringLocally, + boolean shouldOfferWebauthn, boolean defaultUseScreenlockChecked, + long successMessageDurationMilliseconds) { mDelegate = delegate; LayoutInflater inflater = LayoutInflater.from(context); @@ -165,16 +165,15 @@ mNewCardLink.setOnClickListener(this); mErrorMessage = (TextView) v.findViewById(R.id.error_message); mStoreLocallyCheckbox = (CheckBox) v.findViewById(R.id.store_locally_checkbox); - mStoreLocallyCheckbox.setChecked(canStoreLocally && defaultToStoringLocally); mUseScreenlockCheckbox = (CheckBox) v.findViewById(R.id.use_screenlock_checkbox); mUseScreenlockCheckbox.setChecked(defaultUseScreenlockChecked); - if (canStoreLocally || !shouldOfferWebauthn) { + if (!shouldOfferWebauthn) { mUseScreenlockCheckbox.setVisibility(View.GONE); mUseScreenlockCheckbox.setChecked(false); } mStoreLocallyTooltipIcon = (ImageView) v.findViewById(R.id.store_locally_tooltip_icon); mStoreLocallyTooltipIcon.setOnClickListener(this); - if (!canStoreLocally) v.findViewById(R.id.store_locally_container).setVisibility(View.GONE); + v.findViewById(R.id.store_locally_container).setVisibility(View.GONE); mControlsContainer = (ViewGroup) v.findViewById(R.id.controls_container); mVerificationOverlay = v.findViewById(R.id.verification_overlay); mVerificationProgressBar = (ProgressBar) v.findViewById(R.id.verification_progress_bar);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/prefeditor/EditorDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/prefeditor/EditorDialog.java index 0373fdf..2bff411 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/prefeditor/EditorDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/prefeditor/EditorDialog.java
@@ -104,13 +104,15 @@ @Nullable private Runnable mDeleteRunnable; private boolean mIsDismissed; + private Profile mProfile; /** * Builds the editor dialog. * * @param activity The activity on top of which the UI should be displayed. * @param deleteRunnable The runnable that when called will delete the profile. + * @param profile The current profile that creates EditorDialog. */ - public EditorDialog(Activity activity, Runnable deleteRunnable) { + public EditorDialog(Activity activity, Runnable deleteRunnable, Profile profile) { super(activity, R.style.Theme_Chromium_Fullscreen); // Sets transparent background for animating content view. getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); @@ -163,6 +165,7 @@ mCardNumberFormatter = new CreditCardNumberFormattingTextWatcher(); mDeleteRunnable = deleteRunnable; + mProfile = profile; } /** Prevents screenshots of this editor. */ @@ -172,14 +175,10 @@ getWindow().setAttributes(attributes); } - /** Launches the Autofill help page on top of the current Context. */ - public static void launchAutofillHelpPage(Context context) { - // TODO(https://crbug.com/1041781): Use the current profile (i.e., regular profile or - // incognito profile) instead of always using regular profile. It is wrong and need to be - // fixed not to cause data leakage from incognito to regular profile. + /** Launches the Autofill help page on top of the current Context and current Profile. */ + public static void launchAutofillHelpPage(Context context, Profile profile) { HelpAndFeedback.getInstance().show((Activity) context, - context.getString(R.string.help_context_autofill), - Profile.getLastUsedRegularProfile(), null); + context.getString(R.string.help_context_autofill), profile, null); } /** @@ -206,7 +205,7 @@ mDeleteRunnable.run(); animateOutDialog(); } else if (item.getItemId() == R.id.help_menu_id) { - launchAutofillHelpPage(mContext); + launchAutofillHelpPage(mContext, mProfile); } return true; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillEditorBase.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillEditorBase.java index 60f5f909..3a39dc4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillEditorBase.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillEditorBase.java
@@ -28,6 +28,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.prefeditor.EditorDialog; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.components.browser_ui.settings.SettingsUtils; import org.chromium.components.browser_ui.widget.FadingEdgeScrollView; @@ -93,7 +94,7 @@ getActivity().finish(); return true; } else if (item.getItemId() == R.id.help_menu_id) { - EditorDialog.launchAutofillHelpPage(getActivity()); + EditorDialog.launchAutofillHelpPage(getActivity(), Profile.getLastUsedRegularProfile()); return true; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillProfilesFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillProfilesFragment.java index 9c39293d..3a13b0a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillProfilesFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillProfilesFragment.java
@@ -24,6 +24,7 @@ import org.chromium.chrome.browser.payments.AddressEditor; import org.chromium.chrome.browser.payments.AutofillAddress; import org.chromium.chrome.browser.payments.SettingsAutofillAndPaymentsObserver; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.settings.ChromeManagedPreferenceDelegate; import org.chromium.components.browser_ui.settings.ChromeSwitchPreference; @@ -177,7 +178,7 @@ } }; - return new EditorDialog(getActivity(), runnable); + return new EditorDialog(getActivity(), runnable, Profile.getLastUsedRegularProfile()); } private void editAddress(EditorDialog dialog, AutofillAddress autofillAddress) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaButtonReceiver.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaButtonReceiver.java deleted file mode 100644 index 437468f..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaButtonReceiver.java +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.media.ui; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.view.KeyEvent; - -import org.chromium.base.Log; -import org.chromium.chrome.browser.notifications.ForegroundServiceUtils; - -/** - * MediaButtonReceiver is a basic BroadcastReceiver class that receives - * ACTION_MEDIA_BUTTON from a MediaSessionCompat. It then forward these intents - * to the service listening to them. - * This is there for backward compatibility with JB_MR0 and JB_MR1. - */ -public abstract class MediaButtonReceiver extends BroadcastReceiver { - public abstract Class<?> getServiceClass(); - - private static final String TAG = "MediaButtonReceiver"; - - @Override - public void onReceive(Context context, Intent intent) { - if (intent == null || !Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction()) - || !intent.hasExtra(Intent.EXTRA_KEY_EVENT)) { - return; - } - - Log.i(TAG, "Receive broadcast message, starting foreground service"); - - KeyEvent event = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); - if (event == null) { - Log.i(TAG, "no event"); - } else { - Log.i(TAG, "action: " + event.getAction() + ", keycode: " + event.getKeyCode()); - } - - intent.setClass(context, getServiceClass()); - ForegroundServiceUtils.getInstance().startForegroundService(intent); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java index dca8b19..4e9720a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
@@ -7,7 +7,6 @@ import android.app.PendingIntent; import android.app.Service; import android.content.BroadcastReceiver; -import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -27,7 +26,6 @@ import android.support.v4.media.session.PlaybackStateCompat; import android.text.TextUtils; import android.util.SparseArray; -import android.view.KeyEvent; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -102,15 +100,13 @@ sMapNotificationIdToOptions.put(PlaybackListenerService.NOTIFICATION_ID, new NotificationOptions(PlaybackListenerService.class, - PlaybackMediaButtonReceiver.class, NotificationConstants.GROUP_MEDIA_PLAYBACK)); sMapNotificationIdToOptions.put(PresentationListenerService.NOTIFICATION_ID, new NotificationOptions(PresentationListenerService.class, - PresentationMediaButtonReceiver.class, NotificationConstants.GROUP_MEDIA_PRESENTATION)); sMapNotificationIdToOptions.put(CastListenerService.NOTIFICATION_ID, - new NotificationOptions(CastListenerService.class, CastMediaButtonReceiver.class, - NotificationConstants.GROUP_MEDIA_REMOTE)); + new NotificationOptions( + CastListenerService.class, NotificationConstants.GROUP_MEDIA_REMOTE)); } private final NotificationUmaTracker mNotificationUmaTracker; @@ -275,13 +271,10 @@ @VisibleForTesting static class NotificationOptions { public Class<?> serviceClass; - public Class<?> receiverClass; public String groupName; - public NotificationOptions( - Class<?> serviceClass, Class<?> receiverClass, String groupName) { + public NotificationOptions(Class<?> serviceClass, String groupName) { this.serviceClass = serviceClass; - this.receiverClass = receiverClass; this.groupName = groupName; } } @@ -397,47 +390,7 @@ void processAction(Intent intent, MediaNotificationManager manager) { String action = intent.getAction(); - // Before Android L, instead of using the MediaSession callback, the system will fire - // ACTION_MEDIA_BUTTON intents which stores the information about the key event. - if (Intent.ACTION_MEDIA_BUTTON.equals(action)) { - KeyEvent event = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); - if (event == null) return; - if (event.getAction() != KeyEvent.ACTION_DOWN) return; - switch (event.getKeyCode()) { - case KeyEvent.KEYCODE_MEDIA_PLAY: - manager.onPlay( - MediaNotificationListener.ACTION_SOURCE_MEDIA_SESSION); - break; - case KeyEvent.KEYCODE_MEDIA_PAUSE: - manager.onPause( - MediaNotificationListener.ACTION_SOURCE_MEDIA_SESSION); - break; - case KeyEvent.KEYCODE_HEADSETHOOK: - case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: - if (manager.mMediaNotificationInfo.isPaused) { - manager.onPlay(MediaNotificationListener.ACTION_SOURCE_MEDIA_SESSION); - } else { - manager.onPause( - MediaNotificationListener.ACTION_SOURCE_MEDIA_SESSION); - } - break; - case KeyEvent.KEYCODE_MEDIA_PREVIOUS: - manager.onMediaSessionAction(MediaSessionAction.PREVIOUS_TRACK); - break; - case KeyEvent.KEYCODE_MEDIA_NEXT: - manager.onMediaSessionAction(MediaSessionAction.NEXT_TRACK); - break; - case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: - manager.onMediaSessionAction(MediaSessionAction.SEEK_FORWARD); - break; - case KeyEvent.KEYCODE_MEDIA_REWIND: - manager.onMediaSessionAction(MediaSessionAction.SEEK_BACKWARD); - break; - default: - break; - } - } else if (ACTION_STOP.equals(action) - || ACTION_SWIPE.equals(action) + if (ACTION_STOP.equals(action) || ACTION_SWIPE.equals(action) || ACTION_CANCEL.equals(action)) { manager.onStop( MediaNotificationListener.ACTION_SOURCE_MEDIA_NOTIFICATION); @@ -522,38 +475,6 @@ } } - // Three classes to specify the right notification id in the intent. - - /** - * This class is used internally but have to be public to be able to launch the service. - */ - public static final class PlaybackMediaButtonReceiver extends MediaButtonReceiver { - @Override - public Class<?> getServiceClass() { - return PlaybackListenerService.class; - } - } - - /** - * This class is used internally but have to be public to be able to launch the service. - */ - public static final class PresentationMediaButtonReceiver extends MediaButtonReceiver { - @Override - public Class<?> getServiceClass() { - return PresentationListenerService.class; - } - } - - /** - * This class is used internally but have to be public to be able to launch the service. - */ - public static final class CastMediaButtonReceiver extends MediaButtonReceiver { - @Override - public Class<?> getServiceClass() { - return CastListenerService.class; - } - } - @VisibleForTesting Intent createIntent() { Class<?> serviceClass = sMapNotificationIdToOptions.get(mNotificationId).serviceClass; @@ -566,13 +487,6 @@ return PendingIntent.getService(getContext(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); } - private Class<?> getButtonReceiverClass() { - Class<?> receiverClass = sMapNotificationIdToOptions.get(mNotificationId).receiverClass; - - assert receiverClass != null; - return receiverClass; - } - // Returns the notification group name used to prevent automatic grouping. private String getNotificationGroupName() { String groupName = sMapNotificationIdToOptions.get(mNotificationId).groupName; @@ -880,7 +794,6 @@ manager.cancel(mMediaNotificationInfo.id); if (mMediaSession != null) { - mMediaSession.setMediaButtonReceiver(null); mMediaSession.setCallback(null); mMediaSession.setActive(false); mMediaSession.release(); @@ -1091,25 +1004,9 @@ private MediaSessionCompat createMediaSession() { Context context = getContext(); MediaSessionCompat mediaSession = - new MediaSessionCompat(context, context.getString(R.string.app_name), - new ComponentName(context, getButtonReceiverClass()), null); - mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS - | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); + new MediaSessionCompat(context, context.getString(R.string.app_name)); mediaSession.setCallback(mMediaSessionCallback); - - // TODO(mlamouri): the following code is to work around a bug that hopefully - // MediaSessionCompat will handle directly. see b/24051980. - try { - mediaSession.setActive(true); - } catch (NullPointerException e) { - // Some versions of KitKat do not support AudioManager.registerMediaButtonIntent - // with a PendingIntent. They will throw a NullPointerException, in which case - // they should be able to activate a MediaSessionCompat with only transport - // controls. - mediaSession.setActive(false); - mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); - mediaSession.setActive(true); - } + mediaSession.setActive(true); return mediaSession; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiWindowUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiWindowUtils.java index 8ac9c8d..b11fa123 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiWindowUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiWindowUtils.java
@@ -228,7 +228,10 @@ * Determines the name of an activity from its {@link AppTask}. * @param task The AppTask to get the name of. */ + @TargetApi(Build.VERSION_CODES.M) public static String getActivityNameFromTask(AppTask task) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return ""; + if (task.getTaskInfo() == null || task.getTaskInfo().baseActivity == null) return ""; String baseActivity = task.getTaskInfo().baseActivity.getClassName();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentAppFactoryParams.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentAppFactoryParams.java index 2764b8a..0968afe 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentAppFactoryParams.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentAppFactoryParams.java
@@ -6,7 +6,7 @@ import androidx.annotation.Nullable; -import org.chromium.components.payments.PaymentApp.PaymentRequestUpdateEventListener; +import org.chromium.components.payments.PaymentRequestUpdateEventListener; import org.chromium.content_public.browser.RenderFrameHost; import org.chromium.content_public.browser.WebContents; import org.chromium.payments.mojom.PaymentDetailsModifier;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java index b848449..f73ee27e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
@@ -48,9 +48,6 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; import org.chromium.chrome.browser.ui.favicon.FaviconHelper; -import org.chromium.chrome.browser.widget.ScrimView; -import org.chromium.chrome.browser.widget.ScrimView.EmptyScrimObserver; -import org.chromium.chrome.browser.widget.ScrimView.ScrimParams; import org.chromium.components.autofill.Completable; import org.chromium.components.autofill.EditableOption; import org.chromium.components.embedder_support.util.UrlConstants; @@ -64,7 +61,7 @@ import org.chromium.components.payments.PaymentApp; import org.chromium.components.payments.PaymentDetailsConverter; import org.chromium.components.payments.PaymentHandlerHost; -import org.chromium.components.payments.PaymentHandlerHost.PaymentHandlerHostDelegate; +import org.chromium.components.payments.PaymentRequestUpdateEventListener; import org.chromium.components.payments.PaymentValidator; import org.chromium.components.payments.UrlUtil; import org.chromium.components.security_state.SecurityStateModel; @@ -115,12 +112,11 @@ */ public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Client, PaymentAppFactoryDelegate, - PaymentAppFactoryParams, PaymentApp.PaymentRequestUpdateEventListener, + PaymentAppFactoryParams, PaymentRequestUpdateEventListener, PaymentApp.AbortCallback, PaymentApp.InstrumentDetailsCallback, PaymentResponseHelper.PaymentResponseRequesterDelegate, FocusChangedObserver, NormalizedAddressRequestDelegate, SettingsAutofillAndPaymentsObserver.Observer, - PaymentHandlerHostDelegate, PaymentDetailsConverter.MethodChecker, - PaymentHandlerUiObserver { + PaymentDetailsConverter.MethodChecker, PaymentHandlerUiObserver { /** * A delegate to ask questions about the system, that allows tests to inject behaviour without * having to modify the entire system. This partially mirrors a similar C++ @@ -897,14 +893,12 @@ mUI = new PaymentRequestUI(activity, this, mMerchantSupportsAutofillCards, !PaymentPreferencesUtil.isPaymentCompleteOnce(), mMerchantName, mTopLevelOrigin, SecurityStateModel.getSecurityLevelForWebContents(mWebContents), - new ShippingStrings(mShippingType), mPaymentUisShowStateReconciler); + new ShippingStrings(mShippingType), mPaymentUisShowStateReconciler, + Profile.fromWebContents(mWebContents)); activity.getLifecycleDispatcher().register(mUI); - // TODO(https://crbug.com/1048632): Use the current profile (i.e., regular profile or - // incognito profile) instead of always using regular profile. It works correctly now, but - // it is not safe. final FaviconHelper faviconHelper = new FaviconHelper(); - faviconHelper.getLocalFaviconImageForURL(Profile.getLastUsedRegularProfile(), + faviconHelper.getLocalFaviconImageForURL(Profile.fromWebContents(mWebContents), mWebContents.getLastCommittedUrl(), activity.getResources().getDimensionPixelSize(R.dimen.payments_favicon_size), (bitmap, iconUrl) -> { @@ -1187,7 +1181,8 @@ @Override public boolean changePaymentMethodFromInvokedApp(String methodName, String stringifiedDetails) { if (TextUtils.isEmpty(methodName) || stringifiedDetails == null || mClient == null - || mInvokedPaymentApp == null) { + || mInvokedPaymentApp == null + || mInvokedPaymentApp.isWaitingForPaymentDetailsUpdate()) { return false; } @@ -1201,7 +1196,8 @@ @Override public boolean changeShippingOptionFromInvokedApp(String shippingOptionId) { if (TextUtils.isEmpty(shippingOptionId) || mClient == null || mInvokedPaymentApp == null - || !mRequestShipping || mRawShippingOptions == null) { + || mInvokedPaymentApp.isWaitingForPaymentDetailsUpdate() || !mRequestShipping + || mRawShippingOptions == null) { return false; } @@ -1225,7 +1221,7 @@ @Override public boolean changeShippingAddressFromInvokedApp(PaymentAddress shippingAddress) { if (shippingAddress == null || mClient == null || mInvokedPaymentApp == null - || !mRequestShipping) { + || mInvokedPaymentApp.isWaitingForPaymentDetailsUpdate() || !mRequestShipping) { return false; } @@ -1235,46 +1231,6 @@ } /** - * Called by the web-based payment handler to get updated total based on the billing address, - * for example. - */ - @Override - public boolean changePaymentMethodFromPaymentHandler( - String methodName, String stringifiedData) { - if (mPaymentHandlerHost == null || mPaymentHandlerHost.isWaitingForPaymentDetailsUpdate()) { - return false; - } - - return changePaymentMethodFromInvokedApp(methodName, stringifiedData); - } - - /** - * Called by the web-based payment handler to get updated payment details based on the shipping - * option. - */ - @Override - public boolean changeShippingOptionFromPaymentHandler(String shippingOptionId) { - if (mPaymentHandlerHost == null || mPaymentHandlerHost.isWaitingForPaymentDetailsUpdate()) { - return false; - } - - return changeShippingOptionFromInvokedApp(shippingOptionId); - } - - /** - * Called by the web-based payment handler to get updated payment details based on the shipping - * address. - */ - @Override - public boolean changeShippingAddressFromPaymentHandler(PaymentAddress shippingAddress) { - if (mPaymentHandlerHost == null || mPaymentHandlerHost.isWaitingForPaymentDetailsUpdate()) { - return false; - } - - return changeShippingAddressFromInvokedApp(shippingAddress); - } - - /** * Get the WebContents of the Expandable Payment Handler for testing purpose; return null if * nonexistent. * @@ -1395,21 +1351,12 @@ public void onPaymentHandlerUiClosed() { mPaymentUisShowStateReconciler.onBottomSheetClosed(); mPaymentHandlerUi = null; - ChromeActivity activity = ChromeActivity.fromWebContents(mWebContents); - if (activity != null) activity.getScrim().hideScrim(true); } @Override public void onPaymentHandlerUiShown() { assert mPaymentHandlerUi != null; mPaymentUisShowStateReconciler.onBottomSheetShown(); - // Using an empty scrim observer is to avoid the dismissal of the bottom-sheet on tapping. - ScrimParams params = ChromeActivity.fromWebContents(mWebContents) - .getBottomSheetController() - .createScrimParams(new EmptyScrimObserver()); - ScrimView scrim = ChromeActivity.fromWebContents(mWebContents).getScrim(); - scrim.showScrim(params); - scrim.setViewAlpha(0); } @Override @@ -2612,7 +2559,7 @@ // PaymentAppFactoryParams implementation. @Override - public PaymentApp.PaymentRequestUpdateEventListener getPaymentRequestUpdateEventListener() { + public PaymentRequestUpdateEventListener getPaymentRequestUpdateEventListener() { return this; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerCoordinator.java index 55e17f2..b9653e4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerCoordinator.java
@@ -113,13 +113,13 @@ changeProcessor.destroy(); bottomSheetController.removeObserver(mediator); bottomSheetController.hideContent(/*content=*/view, /*animate=*/true); - mWebContents.destroy(); uiObserver.onPaymentHandlerUiClosed(); assert activity.getWindow() != null; assert activity.getWindow().getDecorView() != null; activity.getWindow().getDecorView().removeOnLayoutChangeListener(mediator); - thinWebView.destroy(); mediator.destroy(); + thinWebView.destroy(); + mWebContents.destroy(); }; return bottomSheetController.requestShowContent(view, /*animate=*/true); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerMediator.java index 63fc3a3e..32297346 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerMediator.java
@@ -7,11 +7,14 @@ import android.os.Handler; import android.view.View; +import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChangeReason; import org.chromium.chrome.browser.payments.ServiceWorkerPaymentAppBridge; import org.chromium.chrome.browser.payments.SslValidityChecker; import org.chromium.chrome.browser.payments.handler.PaymentHandlerCoordinator.PaymentHandlerUiObserver; import org.chromium.chrome.browser.payments.handler.toolbar.PaymentHandlerToolbarCoordinator.PaymentHandlerToolbarObserver; +import org.chromium.chrome.browser.ui.TabObscuringHandler; +import org.chromium.chrome.browser.widget.ScrimView; import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController; import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController.SheetState; import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetObserver; @@ -21,6 +24,7 @@ import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContentsObserver; import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.util.TokenHolder; /** * PaymentHandler mediator, which is responsible for receiving events from the view and notifies the @@ -49,6 +53,9 @@ private final int mToolbarViewHeightPx; private final int mContainerTopPaddingPx; + /** A token held while the payment sheet is obscuring all visible tabs. */ + private int mTabObscuringToken; + /** * Build a new mediator that handle events from outside the payment handler component. * @param model The {@link PaymentHandlerProperties} that holds all the view state for the @@ -74,15 +81,11 @@ mPaymentHandlerUiObserver = observer; mContainerTopPaddingPx = containerTopPaddingPx; mModel.set(PaymentHandlerProperties.CONTENT_VISIBLE_HEIGHT_PX, contentVisibleHeight()); + + mTabObscuringToken = TokenHolder.INVALID_TOKEN; } - @Override - public void destroy() { - super.destroy(); // Stops observing the web contents and cleans up associated references. - mHandler.removeCallbacksAndMessages(null); - } - - // View.OnLayoutChangeListener: + // Implement View.OnLayoutChangeListener: // This is the Tab View's layout change listener, invoked in response to phone rotation. // TODO(crbug.com/1057825): It should listen to the BottomSheet container's layout change // instead of the Tab View layout change for better encapsulation. @@ -92,7 +95,7 @@ mModel.set(PaymentHandlerProperties.CONTENT_VISIBLE_HEIGHT_PX, contentVisibleHeight()); } - // BottomSheetObserver: + // Implement BottomSheetObserver: @Override public void onSheetStateChanged(@SheetState int newState) { switch (newState) { @@ -112,9 +115,41 @@ @Override public void onSheetOffsetChanged(float heightFraction, float offsetPx) {} + /** + * Set whether PaymentHandler UI is obscuring all tabs. + * @param activity The ChromeActivity of the tab. + * @param isObscuring Whether PaymentHandler UI is considered to be obscuring. + */ + private void setIsObscuringAllTabs(ChromeActivity activity, boolean isObscuring) { + TabObscuringHandler obscuringHandler = activity.getTabObscuringHandler(); + if (obscuringHandler == null) return; + if (isObscuring) { + assert mTabObscuringToken == TokenHolder.INVALID_TOKEN; + mTabObscuringToken = obscuringHandler.obscureAllTabs(); + } else { + obscuringHandler.unobscureAllTabs(mTabObscuringToken); + mTabObscuringToken = TokenHolder.INVALID_TOKEN; + } + } + + private void showScrim() { + // Using an empty scrim observer is to avoid the dismissal of the bottom-sheet on tapping. + ChromeActivity activity = ChromeActivity.fromWebContents(mWebContentsRef); + assert activity != null; + + ScrimView.ScrimParams params = activity.getBottomSheetController().createScrimParams( + new ScrimView.EmptyScrimObserver()); + ScrimView scrim = activity.getScrim(); + scrim.showScrim(params); + scrim.setViewAlpha(0); + + setIsObscuringAllTabs(activity, true); + } + @Override public void onSheetOpened(@StateChangeReason int reason) { mPaymentHandlerUiObserver.onPaymentHandlerUiShown(); + showScrim(); } @Override @@ -129,7 +164,22 @@ @Override public void onSheetContentChanged(BottomSheetContent newContent) {} - // WebContentsObserver: + // Implement WebContentsObserver: + @Override + public void destroy() { + super.destroy(); // Stops observing the web contents and cleans up associated references. + mHandler.removeCallbacksAndMessages(null); + hideScrim(); + } + + private void hideScrim() { + ChromeActivity activity = ChromeActivity.fromWebContents(mWebContentsRef); + assert activity != null; + + activity.getScrim().hideScrim(true); + setIsObscuringAllTabs(activity, false); + } + @Override public void didFinishNavigation(NavigationHandle navigationHandle) { if (navigationHandle.isSameDocument()) return; @@ -164,7 +214,7 @@ }); } - // PaymentHandlerToolbarObserver: + // Implement PaymentHandlerToolbarObserver: @Override public void onToolbarCloseButtonClicked() { ServiceWorkerPaymentAppBridge.onClosingPaymentAppWindow(mWebContentsRef);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java index 1d2071ca..da87e995 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java
@@ -46,6 +46,7 @@ import org.chromium.chrome.browser.payments.ui.PaymentRequestSection.LineItemBreakdownSection; import org.chromium.chrome.browser.payments.ui.PaymentRequestSection.OptionSection; import org.chromium.chrome.browser.payments.ui.PaymentRequestSection.SectionSeparator; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.signin.IdentityServicesProvider; import org.chromium.components.autofill.EditableOption; import org.chromium.components.browser_ui.widget.FadingEdgeScrollView; @@ -352,11 +353,12 @@ * https://www.chromium.org/Home/chromium-security/enamel#TOC-Eliding-Origin-Names-And-Hostnames * @param securityLevel The security level of the page that invoked PaymentRequest. * @param shippingStrings The string resource identifiers to use in the shipping sections. + * @param profile The current profile that creates the PaymentRequestUI. */ public PaymentRequestUI(Activity activity, Client client, boolean canAddCards, boolean showDataSource, String title, String origin, int securityLevel, ShippingStrings shippingStrings, - PaymentUisShowStateReconciler paymentUisShowStateReconciler) { + PaymentUisShowStateReconciler paymentUisShowStateReconciler, Profile profile) { mContext = activity; mClient = client; mShowDataSource = showDataSource; @@ -405,10 +407,10 @@ (ViewGroup) LayoutInflater.from(mContext).inflate(R.layout.payment_request, null); prepareRequestView(mContext, title, origin, securityLevel, canAddCards); - mEditorDialog = new EditorDialog(activity, /*deleteRunnable =*/null); + mEditorDialog = new EditorDialog(activity, /*deleteRunnable =*/null, profile); DimmingDialog.setVisibleStatusBarIconColor(mEditorDialog.getWindow()); - mCardEditorDialog = new EditorDialog(activity, /*deleteRunnable =*/null); + mCardEditorDialog = new EditorDialog(activity, /*deleteRunnable =*/null, profile); DimmingDialog.setVisibleStatusBarIconColor(mCardEditorDialog.getWindow()); // Allow screenshots of the credit card number in Canary, Dev, and developer builds.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/policy/EnterpriseInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/policy/EnterpriseInfo.java index 9099807..4822fb3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/policy/EnterpriseInfo.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/policy/EnterpriseInfo.java
@@ -10,6 +10,7 @@ import android.content.pm.PackageManager; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; +import android.os.SystemClock; import org.chromium.base.ContextUtils; import org.chromium.base.metrics.RecordHistogram; @@ -31,6 +32,8 @@ private Boolean calculateIsRunningOnManagedProfile(Context context) { if (VERSION.SDK_INT < VERSION_CODES.M) return null; + long startTime = SystemClock.elapsedRealtime(); + boolean hasProfileOwnerApp = false; PackageManager packageManager = context.getPackageManager(); DevicePolicyManager devicePolicyManager = context.getSystemService(DevicePolicyManager.class); @@ -38,11 +41,17 @@ for (PackageInfo pkg : packageManager.getInstalledPackages(/* flags= */ 0)) { assert devicePolicyManager != null; if (devicePolicyManager.isProfileOwnerApp(pkg.packageName)) { - return true; + hasProfileOwnerApp = true; + break; } } - return false; + long endTime = SystemClock.elapsedRealtime(); + RecordHistogram.recordTimesHistogram( + "EnterpriseCheck.IsRunningOnManagedProfileDuration", + endTime - startTime); + + return hasProfileOwnerApp; } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProvider.java index 79d3c88..5dd69de 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProvider.java
@@ -11,10 +11,8 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.net.Uri; import android.os.Bundle; -import android.os.StrictMode; import android.text.TextUtils; import android.view.View; import android.widget.RemoteViews; @@ -33,6 +31,8 @@ import org.chromium.chrome.browser.firstrun.FirstRunFlowSequencer; import org.chromium.chrome.browser.locale.LocaleManager; import org.chromium.chrome.browser.omnibox.UrlBarData; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; +import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory; import org.chromium.components.search_engines.TemplateUrl; import org.chromium.components.search_engines.TemplateUrlService; @@ -69,9 +69,9 @@ return mContext; } - /** See {@link ContextUtils#getAppSharedPreferences}. */ - protected SharedPreferences getSharedPreferences() { - return ContextUtils.getAppSharedPreferences(); + /** Returns the {@link SharedPreferencesManager} to store prefs. */ + protected SharedPreferencesManager getSharedPreferencesManager() { + return SharedPreferencesManager.getInstance(); } /** Returns IDs for all search widgets that exist. */ @@ -117,13 +117,6 @@ public static final String EXTRA_START_VOICE_SEARCH = "org.chromium.chrome.browser.searchwidget.START_VOICE_SEARCH"; - private static final String PREF_IS_VOICE_SEARCH_AVAILABLE = - "org.chromium.chrome.browser.searchwidget.IS_VOICE_SEARCH_AVAILABLE"; - private static final String PREF_NUM_CONSECUTIVE_CRASHES = - "org.chromium.chrome.browser.searchwidget.NUM_CONSECUTIVE_CRASHES"; - static final String PREF_SEARCH_ENGINE_SHORTNAME = - "org.chromium.chrome.browser.searchwidget.SEARCH_ENGINE_SHORTNAME"; - /** Number of consecutive crashes this widget will absorb before giving up. */ private static final int CRASH_LIMIT = 3; @@ -163,10 +156,9 @@ /** Nukes all cached information and forces all widgets to start with a blank slate. */ public static void reset() { - SharedPreferences.Editor editor = getDelegate().getSharedPreferences().edit(); - editor.remove(PREF_IS_VOICE_SEARCH_AVAILABLE); - editor.remove(PREF_SEARCH_ENGINE_SHORTNAME); - editor.apply(); + SharedPreferencesManager prefs = getDelegate().getSharedPreferencesManager(); + prefs.removeKey(ChromePreferenceKeys.SEARCH_WIDGET_IS_VOICE_SEARCH_AVAILABLE); + prefs.removeKey(ChromePreferenceKeys.SEARCH_WIDGET_SEARCH_ENGINE_SHORTNAME); performUpdate(null); } @@ -240,7 +232,7 @@ if (ids == null) ids = delegate.getAllSearchWidgetIds(); if (ids.length == 0) return; - SharedPreferences prefs = delegate.getSharedPreferences(); + SharedPreferencesManager prefs = delegate.getSharedPreferencesManager(); boolean isVoiceSearchAvailable = getCachedVoiceSearchAvailability(prefs); String engineName = getCachedEngineName(prefs); @@ -293,9 +285,10 @@ /** Caches whether or not a voice search is possible. */ static void updateCachedVoiceSearchAvailability(boolean isVoiceSearchAvailable) { - SharedPreferences prefs = getDelegate().getSharedPreferences(); + SharedPreferencesManager prefs = getDelegate().getSharedPreferencesManager(); if (getCachedVoiceSearchAvailability(prefs) != isVoiceSearchAvailable) { - prefs.edit().putBoolean(PREF_IS_VOICE_SEARCH_AVAILABLE, isVoiceSearchAvailable).apply(); + prefs.writeBoolean(ChromePreferenceKeys.SEARCH_WIDGET_IS_VOICE_SEARCH_AVAILABLE, + isVoiceSearchAvailable); performUpdate(null); } } @@ -333,12 +326,13 @@ * TemplateUrlService whenever the widget is updated. */ static void updateCachedEngineName(String engineName) { - SharedPreferences prefs = getDelegate().getSharedPreferences(); + SharedPreferencesManager prefs = getDelegate().getSharedPreferencesManager(); if (!shouldShowFullString()) engineName = null; if (!TextUtils.equals(getCachedEngineName(prefs), engineName)) { - prefs.edit().putString(PREF_SEARCH_ENGINE_SHORTNAME, engineName).apply(); + prefs.writeString( + ChromePreferenceKeys.SEARCH_WIDGET_SEARCH_ENGINE_SHORTNAME, engineName); performUpdate(null); } } @@ -346,36 +340,25 @@ /** Updates the number of consecutive crashes this widget has absorbed. */ @SuppressLint({"ApplySharedPref", "CommitPrefEdits"}) static void updateNumConsecutiveCrashes(int newValue) { - SharedPreferences prefs = getDelegate().getSharedPreferences(); + SharedPreferencesManager prefs = getDelegate().getSharedPreferencesManager(); if (getNumConsecutiveCrashes(prefs) == newValue) return; - SharedPreferences.Editor editor = prefs.edit(); - if (newValue == 0) { - editor.remove(PREF_NUM_CONSECUTIVE_CRASHES); - } else { - editor.putInt(PREF_NUM_CONSECUTIVE_CRASHES, newValue); - } - // This metric is committed synchronously because it relates to crashes. - StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); - try { - editor.commit(); - } finally { - StrictMode.setThreadPolicy(oldPolicy); - } + prefs.writeIntSync(ChromePreferenceKeys.SEARCH_WIDGET_NUM_CONSECUTIVE_CRASHES, newValue); } - private static boolean getCachedVoiceSearchAvailability(SharedPreferences prefs) { - return prefs.getBoolean(PREF_IS_VOICE_SEARCH_AVAILABLE, true); + private static boolean getCachedVoiceSearchAvailability(SharedPreferencesManager prefs) { + return prefs.readBoolean( + ChromePreferenceKeys.SEARCH_WIDGET_IS_VOICE_SEARCH_AVAILABLE, true); } - private static String getCachedEngineName(SharedPreferences prefs) { - return prefs.getString(PREF_SEARCH_ENGINE_SHORTNAME, null); + private static String getCachedEngineName(SharedPreferencesManager prefs) { + return prefs.readString(ChromePreferenceKeys.SEARCH_WIDGET_SEARCH_ENGINE_SHORTNAME, null); } @VisibleForTesting - static int getNumConsecutiveCrashes(SharedPreferences prefs) { - return prefs.getInt(PREF_NUM_CONSECUTIVE_CRASHES, 0); + static int getNumConsecutiveCrashes(SharedPreferencesManager prefs) { + return prefs.readInt(ChromePreferenceKeys.SEARCH_WIDGET_NUM_CONSECUTIVE_CRASHES); } private static SearchWidgetProviderDelegate getDelegate() { @@ -391,7 +374,8 @@ runnable.run(); updateNumConsecutiveCrashes(0); } catch (Exception e) { - int numCrashes = getNumConsecutiveCrashes(getDelegate().getSharedPreferences()) + 1; + int numCrashes = + getNumConsecutiveCrashes(getDelegate().getSharedPreferencesManager()) + 1; updateNumConsecutiveCrashes(numCrashes); if (numCrashes < CRASH_LIMIT) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr/ArCoreInstallUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/vr/ArCoreInstallUtils.java index 4c4e533..1c90e11 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr/ArCoreInstallUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr/ArCoreInstallUtils.java
@@ -70,6 +70,7 @@ try { return getArCoreShimInstance().checkAvailability(ContextUtils.getApplicationContext()); } catch (RuntimeException e) { + Log.w(TAG, "ARCore availability check failed with error: %s", e.toString()); return ArCoreShim.Availability.UNSUPPORTED_DEVICE_NOT_CAPABLE; } } @@ -112,6 +113,13 @@ break; } + if (infobarText == null || buttonText == null) { + // The action was something other than "install" or "update", log this + // and exit early to avoid showing an empty infobar. + Log.w(TAG, "ARCore unavailable, status code %d", arCoreAvailability); + return; + } + SimpleConfirmInfoBarBuilder.Listener listener = new SimpleConfirmInfoBarBuilder.Listener() { @Override public void onInfoBarDismissed() {
diff --git a/chrome/android/java/trichrome_chrome_bundle__base_bundle_module.AndroidManifest.expected b/chrome/android/java/trichrome_chrome_bundle__base_bundle_module.AndroidManifest.expected index 6ad395c0..4303d9a 100644 --- a/chrome/android/java/trichrome_chrome_bundle__base_bundle_module.AndroidManifest.expected +++ b/chrome/android/java/trichrome_chrome_bundle__base_bundle_module.AndroidManifest.expected
@@ -911,24 +911,6 @@ android:name="android.appwidget.provider" android:resource="@xml/search_widget_info"/> </receiver> - <receiver - android:name="org.chromium.chrome.browser.media.ui.MediaNotificationManager$CastMediaButtonReceiver"> - <intent-filter> - <action android:name="android.intent.action.MEDIA_BUTTON"/> - </intent-filter> - </receiver> - <receiver - android:name="org.chromium.chrome.browser.media.ui.MediaNotificationManager$PlaybackMediaButtonReceiver"> - <intent-filter> - <action android:name="android.intent.action.MEDIA_BUTTON"/> - </intent-filter> - </receiver> - <receiver - android:name="org.chromium.chrome.browser.media.ui.MediaNotificationManager$PresentationMediaButtonReceiver"> - <intent-filter> - <action android:name="android.intent.action.MEDIA_BUTTON"/> - </intent-filter> - </receiver> <receiver android:name="org.chromium.chrome.browser.services.AccountsChangedReceiver"> <intent-filter> <action android:name="android.accounts.LOGIN_ACCOUNTS_CHANGED"/>
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java index 8cff3f8a..8d073c4 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.customtabs; +import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.support.test.InstrumentationRegistry; @@ -23,6 +24,7 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; import org.chromium.chrome.R; +import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.LaunchIntentDispatcher; import org.chromium.chrome.browser.customtabs.CustomTabDelegateFactory.CustomTabNavigationDelegate; import org.chromium.chrome.browser.flags.ChromeSwitches; @@ -30,14 +32,17 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabDelegateFactory; import org.chromium.chrome.browser.tab.TabTestUtils; +import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResult; import org.chromium.components.external_intents.InterceptNavigationDelegateImpl; import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.CriteriaHelper; +import org.chromium.content_public.browser.test.util.DOMUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.net.test.EmbeddedTestServerRule; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicReference; /** @@ -50,6 +55,9 @@ public CustomTabActivityTestRule mActivityRule = new CustomTabActivityTestRule(); @Rule + public ChromeActivityTestRule mChromeActivityTestRule = + new ChromeActivityTestRule(ChromeTabbedActivity.class); + public EmbeddedTestServerRule mServerRule = new EmbeddedTestServerRule(); private Intent getCustomTabFromChromeIntent(final String url, final boolean markFromChrome) { @@ -169,4 +177,43 @@ Assert.assertFalse(menu.findItem(R.id.add_to_homescreen_id).isVisible()); Assert.assertFalse(menu.findItem(R.id.open_webapk_id).isVisible()); } + + /** + * This test verifies that untrusted intents are not launched by PaymentHandlerActivity. + * The source of untrusted intent for our test is IntentURI. + */ + @Test + @LargeTest + public void testCCTOpenedFromIntentUriWithPaymentsUI() throws Exception { + final String initialUrl = + mServerRule.getServer().getURL("/chrome/test/data/android/url_overriding/" + + "navigation_to_cct_via_intent_uri_spoofing.html"); + + mChromeActivityTestRule.startMainActivityOnBlankPage(); + mChromeActivityTestRule.loadUrlInNewTab(initialUrl); + + mChromeActivityTestRule.getActivity().onUserInteraction(); + // Simulate the click on the link that fires the IntentURI for external navigations. + try { + DOMUtils.clickNode(mChromeActivityTestRule.getWebContents(), "link"); + } catch (TimeoutException e) { + Assert.fail("Failed to click on the target node."); + return; + } + + // We poll to check that a CustomTabActivity is fired because of our IntentURI. + // We also check that this CustomTabActivity should not be of PaymentHandlerActivity + // type as it lacks the trusted extras which can only be added by Chrome. + CriteriaHelper.pollUiThread(() -> { + boolean isCCTLaunched = false; + for (Activity runningActivity : ApplicationStatus.getRunningActivities()) { + if (runningActivity instanceof CustomTabActivity) { + isCCTLaunched = true; + CustomTabActivity cta = (CustomTabActivity) runningActivity; + if (PaymentHandlerActivity.class == cta.getClass()) return false; + } + } + return isCCTLaunched; + }); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/PermissionTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/PermissionTestRule.java index 6d968db..3979014 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/PermissionTestRule.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/PermissionTestRule.java
@@ -27,6 +27,7 @@ import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.browser.test.util.TouchCommon; import org.chromium.net.test.EmbeddedTestServer; +import org.chromium.net.test.ServerCertificate; import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogType; @@ -53,6 +54,7 @@ public class PermissionTestRule extends ChromeActivityTestRule<ChromeActivity> { private InfoBarTestAnimationListener mListener; private EmbeddedTestServer mTestServer; + private boolean mUseHttpsServer; /** * Waits till a JavaScript callback which updates the page title is called the specified number @@ -80,6 +82,11 @@ public void waitForNumUpdates(int numUpdates) throws Exception { mExpectedCount = numUpdates; + + // Update might have already happened, check before waiting for title udpdates. + String expectedTitle = mPrefix + mExpectedCount; + if (mActivity.getActivityTab().getTitle().equals(expectedTitle)) return; + mCallbackHelper.waitForCallback(0); } } @@ -132,12 +139,20 @@ } public PermissionTestRule() { + this(false); + } + + public PermissionTestRule(boolean useHttpsServer) { super(ChromeActivity.class); + mUseHttpsServer = useHttpsServer; } private void ruleSetUp() { // TODO(https://crbug.com/867446): Refactor to use EmbeddedTestServerRule. - mTestServer = EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext()); + mTestServer = mUseHttpsServer + ? EmbeddedTestServer.createAndStartHTTPSServer( + InstrumentationRegistry.getContext(), ServerCertificate.CERT_OK) + : EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext()); } /** @@ -153,7 +168,7 @@ mTestServer.stopAndDestroyServer(); } - protected void setUpUrl(final String url) { + public void setUpUrl(final String url) { loadUrl(getURL(url)); } @@ -165,6 +180,10 @@ return mTestServer.getURL("/"); } + public String getURLWithHostName(String hostName, String url) { + return mTestServer.getURLWithHostName(hostName, url); + } + /** * Runs a permission prompt test that grants the permission and expects the page title to be * updated in response. @@ -190,8 +209,8 @@ } /** - * Runs a permission prompt test that grants the permission and expects the page title to be - * updated in response. + * Runs a permission prompt test that does not grant the permission and expects the page title + * to be updated in response. * @param updateWaiter The update waiter to wait for callbacks. Should be added as an observer * to the current tab prior to calling this method. * @param javascript The JS function to run in the current tab to execute the test and update @@ -213,20 +232,53 @@ replyToPromptAndWaitForUpdates(updateWaiter, false, nUpdates, isDialog); } + /** + * Runs a permission prompt test that expects no prompt to be displayed because the permission + * is already granted/blocked and expects the page title to be updated. + * @param updateWaiter The update waiter to wait for callbacks. Should be added as an observer + * to the current tab prior to calling this method. + * @param javascript The JS function to run in the current tab to execute the test and update + * the page title. + * @param nUpdates How many updates of the page title to wait for. + * @param withGesture True if we require a user gesture. + * @param isDialog True if we are testing a permission dialog, false for an infobar. + * @throws Exception + */ + public void runNoPromptTest(PermissionUpdateWaiter updateWaiter, final String url, + String javascript, int nUpdates, boolean withGesture, boolean isDialog) + throws Exception { + setUpUrl(url); + if (withGesture) { + runJavaScriptCodeInCurrentTabWithGesture(javascript); + } else { + runJavaScriptCodeInCurrentTab(javascript); + } + waitForUpdatesAndAssertNoPrompt(updateWaiter, nUpdates, isDialog); + } + private void replyToPromptAndWaitForUpdates(PermissionUpdateWaiter updateWaiter, boolean allow, int nUpdates, boolean isDialog) throws Exception { if (isDialog) { - ModalDialogManager dialogManager = TestThreadUtils.runOnUiThreadBlockingNoException( - getActivity()::getModalDialogManager); - DialogShownCriteria criteria = - new DialogShownCriteria(dialogManager, "Dialog not shown", true); - CriteriaHelper.pollUiThread(criteria); + waitForDialog(getActivity()); replyToDialogAndWaitForUpdates(updateWaiter, nUpdates, allow); } else { replyToInfoBarAndWaitForUpdates(updateWaiter, nUpdates, allow); } } + private void waitForUpdatesAndAssertNoPrompt( + PermissionUpdateWaiter updateWaiter, int nUpdates, boolean isDialog) throws Exception { + updateWaiter.waitForNumUpdates(nUpdates); + + if (isDialog) { + Assert.assertFalse("Modal permission prompt shown when none expected", + PermissionDialogController.getInstance().isDialogShownForTest()); + } else { + Assert.assertEquals( + "Permission infobar shown when none expected", getInfoBars().size(), 0); + } + } + private void runJavaScriptCodeInCurrentTabWithGesture(String javascript) throws java.util.concurrent.TimeoutException { runJavaScriptCodeInCurrentTab("functionToRun = '" + javascript + "'"); @@ -258,13 +310,27 @@ */ private void replyToDialogAndWaitForUpdates( PermissionUpdateWaiter updateWaiter, int nUpdates, boolean allow) throws Exception { + replyToDialog(allow, getActivity()); + updateWaiter.waitForNumUpdates(nUpdates); + } + + /** + * Utility functions to support permissions testing in other contexts. + */ + public static void replyToDialog(boolean allow, ChromeActivity activity) { TestThreadUtils.runOnUiThreadBlocking(() -> { - TabModalPresenter presenter = (TabModalPresenter) getActivity() - .getModalDialogManager() + TabModalPresenter presenter = (TabModalPresenter) activity.getModalDialogManager() .getCurrentPresenterForTest(); TouchCommon.singleClickView(presenter.getDialogContainerForTest().findViewById( allow ? R.id.positive_button : R.id.negative_button)); }); - updateWaiter.waitForNumUpdates(nUpdates); + } + + public static void waitForDialog(ChromeActivity activity) { + ModalDialogManager dialogManager = + TestThreadUtils.runOnUiThreadBlockingNoException(activity::getModalDialogManager); + DialogShownCriteria criteria = + new DialogShownCriteria(dialogManager, "Dialog not shown", true); + CriteriaHelper.pollUiThread(criteria); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/QuotaTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/QuotaTest.java index b32d890..bb9c089f8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/QuotaTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/QuotaTest.java
@@ -12,7 +12,6 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.RetryOnFailure; import org.chromium.chrome.browser.flags.ChromeSwitches; @@ -57,8 +56,7 @@ @Test @MediumTest @Feature({"QuotaPermissions"}) - @DisabledTest(message = "Modals are now enabled and test needs to be reworked crbug.com/935900") - public void testQuotaShowsInfobar() throws Exception { - testQuotaPermissionsPlumbing("initiate_requestQuota(1024)", 1, false, false); + public void testQuotaPermissionRequestShowsModal() throws Exception { + testQuotaPermissionsPlumbing("initiate_requestQuota(1024)", 1, false, true); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/push_messaging/PushMessagingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/push_messaging/PushMessagingTest.java index ff64643..867d03cf 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/push_messaging/PushMessagingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/push_messaging/PushMessagingTest.java
@@ -27,23 +27,20 @@ import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; import org.chromium.chrome.browser.notifications.NotificationTestRule; +import org.chromium.chrome.browser.permissions.PermissionTestRule; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.ui.messages.infobar.InfoBar; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; -import org.chromium.chrome.test.util.InfoBarUtil; import org.chromium.chrome.test.util.browser.TabTitleObserver; import org.chromium.components.browser_ui.notifications.MockNotificationManagerProxy.NotificationEntry; import org.chromium.components.content_settings.ContentSettingValues; import org.chromium.components.gcm_driver.GCMDriver; import org.chromium.components.gcm_driver.GCMMessage; import org.chromium.components.gcm_driver.instance_id.FakeInstanceIDWithSubtype; -import org.chromium.content_public.browser.test.util.Criteria; -import org.chromium.content_public.browser.test.util.CriteriaHelper; +import org.chromium.components.permissions.PermissionDialogController; import org.chromium.content_public.browser.test.util.JavaScriptUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.net.test.EmbeddedTestServerRule; -import java.util.List; import java.util.concurrent.TimeoutException; /** @@ -112,10 +109,11 @@ // Reload page to ensure the block is persisted. mNotificationTestRule.loadUrl(mPushTestPage); - // PushManager.subscribePush() should fail immediately without showing an infobar. + // PushManager.subscribePush() should fail immediately without showing a prompt. runScriptAndWaitForTitle("subscribePush()", "subscribe fail: NotAllowedError: Registration failed - permission denied"); - Assert.assertEquals(0, mNotificationTestRule.getInfoBars().size()); + Assert.assertFalse("Permission prompt should not be shown", + PermissionDialogController.getInstance().isDialogShownForTest()); // Notifications permission should still be denied. Assert.assertEquals("\"denied\"", runScriptBlocking("Notification.permission")); @@ -124,39 +122,37 @@ /** * Verifies that PushManager.subscribe() fails if permission is dismissed or blocked. */ - //@MediumTest - //@Feature({"Browser", "PushMessaging"}) - //@CommandLineFlags.Add("disable-features=ModalPermissionPrompts") @Test - @DisabledTest + @MediumTest + @Feature({"Browser", "PushMessaging"}) public void testPushPermissionDenied() throws TimeoutException { // Notifications permission should initially be prompt. Assert.assertEquals("\"default\"", runScriptBlocking("Notification.permission")); - // PushManager.subscribePush() should show the notifications infobar. - Assert.assertEquals(0, mNotificationTestRule.getInfoBars().size()); + // PushManager.subscribePush() should show the notifications permission prompt. + Assert.assertFalse("Permission prompt should not be shown", + PermissionDialogController.getInstance().isDialogShownForTest()); runScript("subscribePush()"); - InfoBar infoBar = getInfobarBlocking(); - // Dismissing the infobar should cause subscribe() to fail. - Assert.assertTrue(InfoBarUtil.clickCloseButton(infoBar)); - waitForInfobarToClose(); + // Dismissing the prompt should cause subscribe() to fail. + PermissionTestRule.waitForDialog(mNotificationTestRule.getActivity()); + TestThreadUtils.runOnUiThreadBlocking( + () -> { mNotificationTestRule.getActivity().onBackPressed(); }); + waitForTitle(mNotificationTestRule.getActivity().getActivityTab(), "subscribe fail: NotAllowedError: Registration failed - permission denied"); // Notifications permission should still be prompt. Assert.assertEquals("\"default\"", runScriptBlocking("Notification.permission")); - runScriptAndWaitForTitle("sendToTest('reset title')", - "clearCachedVerificationsForTesting title"); + runScriptAndWaitForTitle("sendToTest('reset title')", "reset title"); - // PushManager.subscribePush() should show the notifications infobar again. + // PushManager.subscribePush() should show the notifications permission prompt again. runScript("subscribePush()"); - infoBar = getInfobarBlocking(); - // Denying the infobar should cause subscribe() to fail. - Assert.assertTrue(InfoBarUtil.clickSecondaryButton(infoBar)); - waitForInfobarToClose(); + // Denying the prompt should cause subscribe() to fail. + PermissionTestRule.waitForDialog(mNotificationTestRule.getActivity()); + PermissionTestRule.replyToDialog(false, mNotificationTestRule.getActivity()); waitForTitle(mNotificationTestRule.getActivity().getActivityTab(), "subscribe fail: NotAllowedError: Registration failed - permission denied"); @@ -166,10 +162,12 @@ // Reload page to ensure the block is persisted. mNotificationTestRule.loadUrl(mPushTestPage); - // PushManager.subscribePush() should now fail immediately without showing an infobar. + // PushManager.subscribePush() should now fail immediately without showing a permission + // prompt. runScriptAndWaitForTitle("subscribePush()", "subscribe fail: NotAllowedError: Registration failed - permission denied"); - Assert.assertEquals(0, mNotificationTestRule.getInfoBars().size()); + Assert.assertFalse("Permission prompt should not be shown", + PermissionDialogController.getInstance().isDialogShownForTest()); // Notifications permission should still be denied. Assert.assertEquals("\"denied\"", runScriptBlocking("Notification.permission")); @@ -181,19 +179,18 @@ @Test @MediumTest @Feature({"Browser", "PushMessaging"}) - @DisabledTest(message = "Modals are now enabled and test needs to be reworked crbug.com/935900") public void testPushPermissionGranted() throws TimeoutException { // Notifications permission should initially be prompt. Assert.assertEquals("\"default\"", runScriptBlocking("Notification.permission")); - // PushManager.subscribePush() should show the notifications infobar. - Assert.assertEquals(0, mNotificationTestRule.getInfoBars().size()); + // PushManager.subscribePush() should show the notifications permission prompt. + Assert.assertFalse("Permission prompt should not be shown", + PermissionDialogController.getInstance().isDialogShownForTest()); runScript("subscribePush()"); - InfoBar infoBar = getInfobarBlocking(); - // Accepting the infobar should cause subscribe() to succeed. - Assert.assertTrue(InfoBarUtil.clickPrimaryButton(infoBar)); - waitForInfobarToClose(); + // Accepting the prompt should cause subscribe() to succeed. + PermissionTestRule.waitForDialog(mNotificationTestRule.getActivity()); + PermissionTestRule.replyToDialog(true, mNotificationTestRule.getActivity()); waitForTitle(mNotificationTestRule.getActivity().getActivityTab(), "subscribe ok"); // This should have caused notifications permission to become granted. @@ -330,26 +327,4 @@ Assert.assertEquals(expectedTitle, tab.getTitle()); } } - - private InfoBar getInfobarBlocking() { - CriteriaHelper.pollUiThread(new Criteria() { - @Override - public boolean isSatisfied() { - return !mNotificationTestRule.getInfoBars().isEmpty(); - } - }); - List<InfoBar> infoBars = mNotificationTestRule.getInfoBars(); - Assert.assertEquals(1, infoBars.size()); - return infoBars.get(0); - } - - private void waitForInfobarToClose() { - CriteriaHelper.pollUiThread(new Criteria() { - @Override - public boolean isSatisfied() { - return mNotificationTestRule.getInfoBars().isEmpty(); - } - }); - Assert.assertEquals(0, mNotificationTestRule.getInfoBars().size()); - } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProviderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProviderTest.java index 5051241..6394053 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProviderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProviderTest.java
@@ -9,7 +9,6 @@ import android.app.Instrumentation.ActivityMonitor; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.util.Pair; @@ -27,11 +26,12 @@ import org.chromium.base.IntentUtils; import org.chromium.base.test.util.AdvancedMockContext; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.InMemorySharedPreferences; import org.chromium.chrome.R; import org.chromium.chrome.browser.firstrun.FirstRunActivity; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.locale.LocaleManager; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; +import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.searchwidget.SearchActivity.SearchActivityDelegate; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.util.ApplicationTestUtils; @@ -62,12 +62,10 @@ public final List<Pair<Integer, RemoteViews>> mViews = new ArrayList<>(); private Context mContext; - private SharedPreferences mPreferences; private TestDelegate(Context context) { super(context); mContext = context; - mPreferences = new InMemorySharedPreferences(); } @Override @@ -76,11 +74,6 @@ } @Override - protected SharedPreferences getSharedPreferences() { - return mPreferences; - } - - @Override protected int[] getAllSearchWidgetIds() { return ALL_IDS; } @@ -198,10 +191,8 @@ // SearchWidgetProvider should now believe that its widgets are displaying branding when it // isn't allowed to, then update them. mDelegate.mViews.clear(); - mDelegate.getSharedPreferences() - .edit() - .putString(SearchWidgetProvider.PREF_SEARCH_ENGINE_SHORTNAME, TEXT_SEARCH_ENGINE) - .apply(); + mDelegate.getSharedPreferencesManager().writeString( + ChromePreferenceKeys.SEARCH_WIDGET_SEARCH_ENGINE_SHORTNAME, TEXT_SEARCH_ENGINE); TestThreadUtils.runOnUiThreadBlocking( () -> SearchWidgetProvider.updateCachedEngineName(TEXT_SEARCH_ENGINE)); checkWidgetStates(TEXT_GENERIC, View.VISIBLE); @@ -307,7 +298,7 @@ } }; - SharedPreferences prefs = mDelegate.getSharedPreferences(); + SharedPreferencesManager prefs = mDelegate.getSharedPreferencesManager(); Assert.assertEquals(0, SearchWidgetProvider.getNumConsecutiveCrashes(prefs)); // The first few crashes should be silently absorbed.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java index 1d1c0c7e..a6fe0dfb 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java
@@ -27,20 +27,19 @@ import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.RetryOnFailure; -import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.flags.ChromeSwitches; -import org.chromium.chrome.browser.infobar.InfoBarContainer; import org.chromium.chrome.browser.notifications.channels.ChromeChannelDefinitions; import org.chromium.chrome.browser.notifications.channels.SiteChannelsManager; +import org.chromium.chrome.browser.permissions.PermissionTestRule; +import org.chromium.chrome.browser.permissions.PermissionTestRule.PermissionUpdateWaiter; import org.chromium.chrome.browser.preferences.Pref; import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.settings.SettingsActivity; import org.chromium.chrome.browser.settings.SettingsLauncher; import org.chromium.chrome.browser.settings.SettingsLauncherImpl; -import org.chromium.chrome.test.ChromeActivityTestRule; +import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; -import org.chromium.chrome.test.util.InfoBarTestAnimationListener; import org.chromium.chrome.test.util.browser.Features.DisableFeatures; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.chrome.test.util.browser.LocationSettingsTestUtil; @@ -63,14 +62,13 @@ import org.chromium.components.permissions.nfc.NfcSystemLevelSetting; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.common.ContentSwitches; -import org.chromium.net.test.EmbeddedTestServer; -import org.chromium.net.test.ServerCertificate; +import org.chromium.device.geolocation.LocationProviderOverrider; +import org.chromium.device.geolocation.MockLocationProvider; import org.chromium.policy.test.annotations.Policies; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.concurrent.Callable; /** * Tests for everything under Settings > Site Settings. @@ -82,21 +80,28 @@ @EnableFeatures(ContentSettingsFeatureList.IMPROVED_COOKIE_CONTROLS) public class SiteSettingsTest { @Rule - public ChromeActivityTestRule<ChromeActivity> mActivityTestRule = - new ChromeActivityTestRule<>(ChromeActivity.class); + public PermissionTestRule mPermissionRule = new PermissionTestRule(true); - private EmbeddedTestServer mTestServer; + private PermissionUpdateWaiter mPermissionUpdateWaiter = null; @Before public void setUp() throws Exception { - mActivityTestRule.startMainActivityOnBlankPage(); - mTestServer = EmbeddedTestServer.createAndStartHTTPSServer( - InstrumentationRegistry.getContext(), ServerCertificate.CERT_OK); + mPermissionRule.startMainActivityOnBlankPage(); } @After public void tearDown() { - mTestServer.stopAndDestroyServer(); + if (mPermissionUpdateWaiter != null) { + mPermissionRule.getActivity().getActivityTab().removeObserver(mPermissionUpdateWaiter); + } + } + + private void initializeUpdateWaiter(final boolean expectGranted) { + Tab tab = mPermissionRule.getActivity().getActivityTab(); + + mPermissionUpdateWaiter = new PermissionUpdateWaiter( + expectGranted ? "Granted:" : "Denied:", mPermissionRule.getActivity()); + tab.addObserver(mPermissionUpdateWaiter); } private BrowserContextHandle getBrowserContextHandle() { @@ -105,6 +110,7 @@ private void setAllowLocation(final boolean enabled) { LocationSettingsTestUtil.setSystemLocationSettingEnabled(true); + LocationProviderOverrider.setLocationProviderImpl(new MockLocationProvider()); final SettingsActivity settingsActivity = SiteSettingsTestUtils.startSiteSettingsCategory( SiteSettingsCategory.Type.DEVICE_LOCATION); @@ -123,58 +129,35 @@ }); } - private InfoBarTestAnimationListener setInfoBarAnimationListener() { - return TestThreadUtils.runOnUiThreadBlockingNoException( - new Callable<InfoBarTestAnimationListener>() { - @Override - public InfoBarTestAnimationListener call() { - InfoBarContainer container = mActivityTestRule.getInfoBarContainer(); - InfoBarTestAnimationListener listener = new InfoBarTestAnimationListener(); - container.addAnimationListener(listener); - return listener; - } - }); - } - /** * Sets Allow Location Enabled to be true and make sure it is set correctly. - * - * TODO(timloh): Update this test once modals are enabled everywhere. */ @Test @SmallTest @Feature({"Preferences"}) - @DisabledTest(message = "Modals are now enabled and test needs to be reworked crbug.com/935900") public void testSetAllowLocationEnabled() throws Exception { setAllowLocation(true); - InfoBarTestAnimationListener listener = setInfoBarAnimationListener(); - // Launch a page that uses geolocation and make sure an infobar shows up. - mActivityTestRule.loadUrl( - mTestServer.getURL("/chrome/test/data/geolocation/geolocation_on_load.html")); - listener.addInfoBarAnimationFinished("InfoBar not added."); + initializeUpdateWaiter(true /* expectGranted */); - Assert.assertEquals("Wrong infobar count", 1, mActivityTestRule.getInfoBars().size()); + // Launch a page that uses geolocation and make sure a permission prompt shows up. + mPermissionRule.runAllowTest(mPermissionUpdateWaiter, + "/chrome/test/data/geolocation/geolocation_on_load.html", "", 1, false, true); } /** * Sets Allow Location Enabled to be false and make sure it is set correctly. - * - * TODO(timloh): Update this test once modals are enabled everywhere. */ @Test @SmallTest @Feature({"Preferences"}) - @DisabledTest(message = "Modals are now enabled and test needs to be reworked crbug.com/935900") - public void testSetAllowLocationNotEnabled() { + public void testSetAllowLocationNotEnabled() throws Exception { setAllowLocation(false); - // Launch a page that uses geolocation. - mActivityTestRule.loadUrl( - mTestServer.getURL("/chrome/test/data/geolocation/geolocation_on_load.html")); - - // No infobars are expected. - Assert.assertTrue(mActivityTestRule.getInfoBars().isEmpty()); + // Launch a page that uses geolocation. No permission prompt is expected. + initializeUpdateWaiter(false /* expectGranted */); + mPermissionRule.runNoPromptTest(mPermissionUpdateWaiter, + "/chrome/test/data/geolocation/geolocation_on_load.html", "", 1, false, true); } private void setCookiesEnabled(final SettingsActivity settingsActivity, final boolean enabled) { @@ -441,19 +424,19 @@ setCookiesEnabled(settingsActivity, true); settingsActivity.finish(); - final String url = mTestServer.getURL("/chrome/test/data/android/cookie.html"); + final String url = mPermissionRule.getURL("/chrome/test/data/android/cookie.html"); // Load the page and clear any set cookies. - mActivityTestRule.loadUrl(url + "#clear"); - Assert.assertEquals("\"\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()")); - mActivityTestRule.runJavaScriptCodeInCurrentTab("setCookie()"); + mPermissionRule.loadUrl(url + "#clear"); + Assert.assertEquals("\"\"", mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); + mPermissionRule.runJavaScriptCodeInCurrentTab("setCookie()"); Assert.assertEquals( - "\"Foo=Bar\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()")); + "\"Foo=Bar\"", mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); // Load the page again and ensure the cookie still is set. - mActivityTestRule.loadUrl(url); + mPermissionRule.loadUrl(url); Assert.assertEquals( - "\"Foo=Bar\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()")); + "\"Foo=Bar\"", mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); } /** @@ -468,17 +451,17 @@ setCookiesEnabled(settingsActivity, false); settingsActivity.finish(); - final String url = mTestServer.getURL("/chrome/test/data/android/cookie.html"); + final String url = mPermissionRule.getURL("/chrome/test/data/android/cookie.html"); // Load the page and clear any set cookies. - mActivityTestRule.loadUrl(url + "#clear"); - Assert.assertEquals("\"\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()")); - mActivityTestRule.runJavaScriptCodeInCurrentTab("setCookie()"); - Assert.assertEquals("\"\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()")); + mPermissionRule.loadUrl(url + "#clear"); + Assert.assertEquals("\"\"", mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); + mPermissionRule.runJavaScriptCodeInCurrentTab("setCookie()"); + Assert.assertEquals("\"\"", mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); // Load the page again and ensure the cookie remains unset. - mActivityTestRule.loadUrl(url); - Assert.assertEquals("\"\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()")); + mPermissionRule.loadUrl(url); + Assert.assertEquals("\"\"", mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); } /** @@ -496,29 +479,30 @@ setCookiesEnabled(settingsActivity, true); settingsActivity.finish(); - final String url = mTestServer.getURL("/chrome/test/data/android/cookie.html"); + final String url = mPermissionRule.getURL("/chrome/test/data/android/cookie.html"); // Load the page and clear any set cookies. - mActivityTestRule.loadUrl(url + "#clear"); - Assert.assertEquals("\"\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()")); + mPermissionRule.loadUrl(url + "#clear"); + Assert.assertEquals("\"\"", mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); // Check cookies can be set for this website when there is no rule. - mActivityTestRule.runJavaScriptCodeInCurrentTab("setCookie()"); + mPermissionRule.runJavaScriptCodeInCurrentTab("setCookie()"); Assert.assertEquals( - "\"Foo=Bar\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()")); + "\"Foo=Bar\"", mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); // Set specific rule to block site and ensure it cannot set cookies. - mActivityTestRule.loadUrl(url + "#clear"); + mPermissionRule.loadUrl(url + "#clear"); settingsActivity = SiteSettingsTestUtils.startSiteSettingsCategory(SiteSettingsCategory.Type.COOKIES); setBlockCookiesSiteException(settingsActivity, url, false); - settingsActivity.finish(); - mActivityTestRule.runJavaScriptCodeInCurrentTab("setCookie()"); - Assert.assertEquals("\"\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()")); + mPermissionRule.runJavaScriptCodeInCurrentTab("setCookie()"); + Assert.assertEquals("\"\"", mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); // Load the page again and ensure the cookie remains unset. - mActivityTestRule.loadUrl(url); - Assert.assertEquals("\"\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()")); + mPermissionRule.loadUrl(url); + Assert.assertEquals("\"\"", mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); + + settingsActivity.finish(); } /** @@ -528,19 +512,19 @@ @SmallTest @Feature({"Preferences"}) public void testClearCookies() throws Exception { - final String url = mTestServer.getURL("/chrome/test/data/android/cookie.html"); + final String url = mPermissionRule.getURL("/chrome/test/data/android/cookie.html"); - mActivityTestRule.loadUrl(url); - Assert.assertEquals("\"\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()")); - mActivityTestRule.runJavaScriptCodeInCurrentTab("setCookie()"); + mPermissionRule.loadUrl(url); + Assert.assertEquals("\"\"", mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); + mPermissionRule.runJavaScriptCodeInCurrentTab("setCookie()"); Assert.assertEquals( - "\"Foo=Bar\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()")); + "\"Foo=Bar\"", mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); resetSite(WebsiteAddress.create(url)); // Load the page again and ensure the cookie is gone. - mActivityTestRule.loadUrl(url); - Assert.assertEquals("\"\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()")); + mPermissionRule.loadUrl(url); + Assert.assertEquals("\"\"", mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); } /** @@ -550,21 +534,21 @@ @SmallTest @Feature({"Preferences"}) public void testClearDomainCookies() throws Exception { - final String url = mTestServer.getURLWithHostName( + final String url = mPermissionRule.getURLWithHostName( "test.example.com", "/chrome/test/data/android/cookie.html"); - mActivityTestRule.loadUrl(url); - Assert.assertEquals("\"\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()")); - mActivityTestRule.runJavaScriptCodeInCurrentTab("setCookie(\".example.com\")"); - mActivityTestRule.runJavaScriptCodeInCurrentTab("setCookie(\".test.example.com\")"); + mPermissionRule.loadUrl(url); + Assert.assertEquals("\"\"", mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); + mPermissionRule.runJavaScriptCodeInCurrentTab("setCookie(\".example.com\")"); + mPermissionRule.runJavaScriptCodeInCurrentTab("setCookie(\".test.example.com\")"); Assert.assertEquals("\"Foo=Bar; Foo=Bar\"", - mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()")); + mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); resetSite(WebsiteAddress.create("test.example.com")); // Load the page again and ensure the cookie is gone. - mActivityTestRule.loadUrl(url); - Assert.assertEquals("\"\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()")); + mPermissionRule.loadUrl(url); + Assert.assertEquals("\"\"", mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); } /** @@ -741,7 +725,7 @@ setEnablePopups(false); // Test that the popup doesn't open. - mActivityTestRule.loadUrl(mTestServer.getURL("/chrome/test/data/android/popup.html")); + mPermissionRule.setUpUrl("/chrome/test/data/android/popup.html"); InstrumentationRegistry.getInstrumentation().waitForIdleSync(); Assert.assertEquals(1, getTabCount()); @@ -757,7 +741,7 @@ setEnablePopups(true); // Test that a popup opens. - mActivityTestRule.loadUrl(mTestServer.getURL("/chrome/test/data/android/popup.html")); + mPermissionRule.setUpUrl("/chrome/test/data/android/popup.html"); InstrumentationRegistry.getInstrumentation().waitForIdleSync(); Assert.assertEquals(2, getTabCount()); @@ -939,26 +923,21 @@ setEnableCamera(false); // Test that the camera permission doesn't get requested. - mActivityTestRule.loadUrl(mTestServer.getURL("/content/test/data/media/getusermedia.html")); - mActivityTestRule.runJavaScriptCodeInCurrentTab( - "getUserMediaAndStop({video: true, audio: false});"); - - // No infobars are expected. - Assert.assertTrue(mActivityTestRule.getInfoBars().isEmpty()); + initializeUpdateWaiter(false /* expectGranted */); + mPermissionRule.runNoPromptTest(mPermissionUpdateWaiter, + "/content/test/data/media/getusermedia.html", + "getUserMediaAndStop({video: true, audio: false});", 1, false, true); } /** * Sets Allow Mic Enabled to be false and make sure it is set correctly. * - * TODO(timloh): Update this test once modals are enabled everywhere. - * * @throws Exception */ @Test @SmallTest @Feature({"Preferences"}) @CommandLineFlags.Add({ContentSwitches.USE_FAKE_DEVICE_FOR_MEDIA_STREAM}) - @DisabledTest(message = "Modals are now enabled and test needs to be reworked crbug.com/935900") public void testMicBlocked() throws Exception { setGlobalToggleForCategory(SiteSettingsCategory.Type.MICROPHONE, false); @@ -969,64 +948,47 @@ }); // Test that the microphone permission doesn't get requested. - mActivityTestRule.loadUrl(mTestServer.getURL("/content/test/data/media/getusermedia.html")); - mActivityTestRule.runJavaScriptCodeInCurrentTab( - "getUserMediaAndStop({video: false, audio: true});"); - - // No infobars are expected. - Assert.assertTrue(mActivityTestRule.getInfoBars().isEmpty()); + initializeUpdateWaiter(false /* expectGranted */); + mPermissionRule.runNoPromptTest(mPermissionUpdateWaiter, + "/content/test/data/media/getusermedia.html", + "getUserMediaAndStop({video: false, audio: true});", 1, true, true); } /** * Sets Allow Camera Enabled to be true and make sure it is set correctly. * - * TODO(timloh): Update this test once modals are enabled everywhere. - * * @throws Exception */ @Test @SmallTest @Feature({"Preferences"}) @CommandLineFlags.Add({ContentSwitches.USE_FAKE_DEVICE_FOR_MEDIA_STREAM}) - @DisabledTest(message = "Modals are now enabled and test needs to be reworked crbug.com/935900") public void testCameraNotBlocked() throws Exception { setEnableCamera(true); - InfoBarTestAnimationListener listener = setInfoBarAnimationListener(); - - // Launch a page that uses camera and make sure an infobar shows up. - mActivityTestRule.loadUrl(mTestServer.getURL("/content/test/data/media/getusermedia.html")); - mActivityTestRule.runJavaScriptCodeInCurrentTab( - "getUserMediaAndStop({video: true, audio: false});"); - - listener.addInfoBarAnimationFinished("InfoBar not added."); - Assert.assertEquals("Wrong infobar count", 1, mActivityTestRule.getInfoBars().size()); + initializeUpdateWaiter(true /* expectGranted */); + mPermissionRule.runAllowTest(mPermissionUpdateWaiter, + "/content/test/data/media/getusermedia.html", + "getUserMediaAndStop({video: true, audio: false});", 1, false, true); } /** * Sets Allow Mic Enabled to be true and make sure it is set correctly. * - * TODO(timloh): Update this test once modals are enabled everywhere. - * * @throws Exception */ @Test @SmallTest @Feature({"Preferences"}) @CommandLineFlags.Add({ContentSwitches.USE_FAKE_DEVICE_FOR_MEDIA_STREAM}) - @DisabledTest(message = "Modals are now enabled and test needs to be reworked crbug.com/935900") public void testMicNotBlocked() throws Exception { setEnableCamera(true); - InfoBarTestAnimationListener listener = setInfoBarAnimationListener(); - - // Launch a page that uses the microphone and make sure an infobar shows up. - mActivityTestRule.loadUrl(mTestServer.getURL("/content/test/data/media/getusermedia.html")); - mActivityTestRule.runJavaScriptCodeInCurrentTab( - "getUserMediaAndStop({video: false, audio: true});"); - - listener.addInfoBarAnimationFinished("InfoBar not added."); - Assert.assertEquals("Wrong infobar count", 1, mActivityTestRule.getInfoBars().size()); + // Launch a page that uses the microphone and make sure a permission prompt shows up. + initializeUpdateWaiter(true /* expectGranted */); + mPermissionRule.runAllowTest(mPermissionUpdateWaiter, + "/content/test/data/media/getusermedia.html", + "getUserMediaAndStop({video: false, audio: true});", 1, true, true); } /** @@ -1234,7 +1196,7 @@ private int getTabCount() { return TestThreadUtils.runOnUiThreadBlockingNoException( - () -> mActivityTestRule.getActivity().getTabModelSelector().getTotalTabCount()); + () -> mPermissionRule.getActivity().getTabModelSelector().getTotalTabCount()); } @Test @@ -1242,14 +1204,14 @@ @Feature({"Preferences"}) public void testEmbargoedNotificationSiteSettings() throws Exception { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return; - final String url = mTestServer.getURLWithHostName( + final String url = mPermissionRule.getURLWithHostName( "example.com", "/chrome/test/data/notifications/notification_tester.html"); // Ignore notification request 4 times to enter embargo. 5th one ensures that notifications // are blocked by actually causing a deny-by-embargo. for (int i = 0; i < 5; i++) { - mActivityTestRule.loadUrl(url); - mActivityTestRule.runJavaScriptCodeInCurrentTab("requestPermissionAndRespond()"); + mPermissionRule.loadUrl(url); + mPermissionRule.runJavaScriptCodeInCurrentTab("requestPermissionAndRespond()"); } SettingsLauncher settingsLauncher = new SettingsLauncherImpl();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerServiceActionsTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerServiceActionsTest.java index 6619dbf..95aa2e97 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerServiceActionsTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerServiceActionsTest.java
@@ -6,14 +6,11 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.any; -import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; import android.content.Intent; import android.media.AudioManager; -import android.view.KeyEvent; import org.junit.Test; import org.junit.runner.RunWith; @@ -24,7 +21,7 @@ import org.chromium.media_session.mojom.MediaSessionAction; /** - * JUnit tests for checking {@link MediaNotificationManager.ListenerService} handles intent actionss + * JUnit tests for checking {@link MediaNotificationManager.ListenerService} handles intent actions * correctly. */ @RunWith(BaseRobolectricTestRunner.class) @@ -49,110 +46,6 @@ } @Test - public void testProcessMediaButton_Play() { - setUpService(); - - mService.processAction( - createMediaButtonActionIntent(KeyEvent.KEYCODE_MEDIA_PLAY), getManager()); - verify(getManager()).onPlay(MediaNotificationListener.ACTION_SOURCE_MEDIA_SESSION); - } - - @Test - public void testProcessMediaButton_Pause() { - setUpService(); - - mService.processAction( - createMediaButtonActionIntent(KeyEvent.KEYCODE_MEDIA_PAUSE), getManager()); - verify(getManager()).onPause(MediaNotificationListener.ACTION_SOURCE_MEDIA_SESSION); - } - - @Test - public void testProcessMediaButton_HeadsetHook() { - setUpService(); - - mMediaNotificationInfoBuilder.setPaused(false); - getManager().mMediaNotificationInfo = mMediaNotificationInfoBuilder.build(); - - mService.processAction( - createMediaButtonActionIntent(KeyEvent.KEYCODE_HEADSETHOOK), getManager()); - verify(getManager()).onPause(MediaNotificationListener.ACTION_SOURCE_MEDIA_SESSION); - } - - @Test - public void testProcessMediaButton_PlayPause() { - setUpService(); - - mService.processAction( - createMediaButtonActionIntent(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE), getManager()); - verify(getManager()).onPause(MediaNotificationListener.ACTION_SOURCE_MEDIA_SESSION); - } - - @Test - public void testProcessMediaButton_Previous() { - setUpService(); - - mService.processAction( - createMediaButtonActionIntent(KeyEvent.KEYCODE_MEDIA_PREVIOUS), getManager()); - verify(getManager()).onMediaSessionAction(MediaSessionAction.PREVIOUS_TRACK); - } - - @Test - public void testProcessMediaButton_Next() { - setUpService(); - - mService.processAction( - createMediaButtonActionIntent(KeyEvent.KEYCODE_MEDIA_NEXT), getManager()); - verify(getManager()).onMediaSessionAction(MediaSessionAction.NEXT_TRACK); - } - - @Test - public void testProcessMediaButton_Rewind() { - setUpService(); - - mService.processAction( - createMediaButtonActionIntent(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD), getManager()); - verify(getManager()).onMediaSessionAction(MediaSessionAction.SEEK_FORWARD); - } - - @Test - public void testProcessMediaButton_Backward() { - setUpService(); - - mService.processAction( - createMediaButtonActionIntent(KeyEvent.KEYCODE_MEDIA_REWIND), getManager()); - verify(getManager()).onMediaSessionAction(MediaSessionAction.SEEK_BACKWARD); - } - - @Test - public void testProcessMediaButtonActionWithNoKeyEvent() { - setUpService(); - - clearInvocations(getManager()); - mService.processAction(new Intent(Intent.ACTION_MEDIA_BUTTON), getManager()); - - verifyZeroInteractions(getManager()); - } - - @Test - public void testProcessMediaButtonActionWithWrongTypeKeyEvent() { - setUpService(); - - clearInvocations(getManager()); - mService.processAction( - new Intent(Intent.ACTION_MEDIA_BUTTON) - .putExtra(Intent.EXTRA_KEY_EVENT, - new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PLAY)), - getManager()); - mService.processAction(new Intent(Intent.ACTION_MEDIA_BUTTON) - .putExtra(Intent.EXTRA_KEY_EVENT, - new KeyEvent(KeyEvent.ACTION_MULTIPLE, - KeyEvent.KEYCODE_MEDIA_PLAY)), - getManager()); - - verifyZeroInteractions(getManager()); - } - - @Test public void testProcessNotificationButtonAction_Stop() { setUpService();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerTestBase.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerTestBase.java index c2c9f925..d5e62f3f 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerTestBase.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerTestBase.java
@@ -21,7 +21,6 @@ import android.graphics.drawable.Icon; import android.os.Build; import android.support.v4.media.session.MediaSessionCompat; -import android.view.KeyEvent; import org.junit.After; import org.junit.Before; @@ -83,13 +82,6 @@ } } - static class MockMediaButtonReceiver extends MediaButtonReceiver { - @Override - public Class<?> getServiceClass() { - return MockListenerService.class; - } - } - @Before public void setUp() { // For checking the notification presented to NotificationManager. @@ -103,8 +95,8 @@ mListener = mock(MediaNotificationListener.class); MediaNotificationManager.sMapNotificationIdToOptions.put(getNotificationId(), - new MediaNotificationManager.NotificationOptions(MockListenerService.class, - MockMediaButtonReceiver.class, NOTIFICATION_GROUP_NAME)); + new MediaNotificationManager.NotificationOptions( + MockListenerService.class, NOTIFICATION_GROUP_NAME)); mMockUmaTracker = mock(NotificationUmaTracker.class); MediaNotificationManager.setManagerForTesting(getNotificationId(), @@ -197,14 +189,6 @@ .stopListenerService(); } - Intent createMediaButtonActionIntent(int keyCode) { - Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON); - KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode); - intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent); - - return intent; - } - Bitmap iconToBitmap(Icon icon) { if (icon == null) return null;
diff --git a/chrome/android/webapk/libs/client/BUILD.gn b/chrome/android/webapk/libs/client/BUILD.gn index 84eac576..2d537d0 100644 --- a/chrome/android/webapk/libs/client/BUILD.gn +++ b/chrome/android/webapk/libs/client/BUILD.gn
@@ -43,6 +43,7 @@ data = [ "//chrome/test/data/webapks/" ] deps = [ ":client_java", + "//base:base_java", "//base:base_junit_test_support", "//chrome/android/webapk/libs/common:common_java", "//chrome/android/webapk/libs/runtime_library:webapk_service_aidl_java",
diff --git a/chrome/android/webapk/shell_apk/BUILD.gn b/chrome/android/webapk/shell_apk/BUILD.gn index 04a3ce9..1466558 100644 --- a/chrome/android/webapk/shell_apk/BUILD.gn +++ b/chrome/android/webapk/shell_apk/BUILD.gn
@@ -359,6 +359,8 @@ "junit/src/org/chromium/webapk/shell_apk/WebApkUtilsTest.java", ] deps = [ + ":compiled_in_runtime_library_java", + ":webapk_generated_webapk_java", ":webapk_generated_webapk_with_service_java", "//chrome/android/webapk/libs/common:common_java", "//chrome/android/webapk/libs/runtime_library:runtime_library_for_tests_java", @@ -375,6 +377,7 @@ ] deps = [ ":${h2o_junit_manifest_target_name}", + ":h2o_j_unit_webapk_generated_webapk_java", ":h2o_j_unit_webapk_generated_webapk_with_service_java", "//chrome/android/webapk/libs/common:common_java", "//chrome/android/webapk/test:junit_test_support",
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 679132be..d979979 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -1963,41 +1963,6 @@ No language </message> - <!-- OOBE supervised user Change picture UI --> - <message name="IDS_OPTIONS_CHANGE_PICTURE_TAKE_PHOTO" desc="The text on the button to take photo of the current user."> - Take photo - </message> - <message name="IDS_OPTIONS_CHANGE_PICTURE_CAPTURE_VIDEO" desc="The text on the button to capture video of the current user."> - Capture video - </message> - <message name="IDS_OPTIONS_CHANGE_PICTURE_PHOTO_FROM_CAMERA" desc="The accessible text on the icon in the user image grid for a camera photo, when a photo has been captured."> - Photo from internal camera - </message> - <message name="IDS_OPTIONS_CHANGE_PICTURE_DISCARD_PHOTO" desc="The text on the button to discard the captured photo or video of the current user."> - Discard photo or video - </message> - <message name="IDS_OPTIONS_PHOTO_CAPTURE_ACCESSIBLE_TEXT" desc="The accessible message to speak to announce that a photo was captured."> - Photo was captured - </message> - <message name="IDS_OPTIONS_PHOTO_DISCARD_ACCESSIBLE_TEXT" desc="The accessible message to speak to announce that a photo was discarded."> - Photo was discarded - </message> - <message name="IDS_OPTIONS_CHANGE_PICTURE_SWITCH_MODE_TO_CAMERA" desc="The text on the button to switch the mode of the camera to photo."> - Switch to camera mode - </message> - <message name="IDS_OPTIONS_CHANGE_PICTURE_SWITCH_MODE_TO_VIDEO" desc="The text on the button to switch the mode of the camera to video."> - Switch to video recorder - </message> - <message name="IDS_IMAGE_SCREEN_PROFILE_PHOTO" desc="The title of the Google profile photo of the user on image selection screen. Please keep in sync with IDS_OPTIONS_CHANGE_PICTURE_PROFILE_PHOTO."> - Google Profile photo - </message> - <message name="IDS_IMAGE_SCREEN_PROFILE_LOADING_PHOTO" desc="The title of the loading stub for Google profile image on image selection screen. Please keep in sync with IDS_OPTIONS_CHANGE_PICTURE_PROFILE_LOADING_PHOTO."> - Google Profile photo (loading) - </message> - <message name="IDS_IMAGE_SCREEN_SYNCING_PREFERENCES" desc="The message displayed on the image screen of the GAIA flow while user preferences are syncing."> - Syncing your preferences... - </message> - <!-- Slow UI --> <message name="IDS_SLOW_DISABLE" desc="The text of the button that disables performance collection for feedback reports"> Disable performance data collection
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 3bb47f4..61dfad01 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -4621,6 +4621,12 @@ <message name="IDS_EXTENSION_NTP_OVERRIDDEN_DIALOG_BODY_GENERIC" desc="The body of the dialog informing the user that the new tab page has been overridden by an extension, indicating which extension now controls it."> This page was changed by the <ph name="EXTENSION_NAME">$1<ex>Google Arts and Culture</ex></ph> extension </message> + <message name="IDS_EXTENSION_SEARCH_OVERRIDDEN_DIALOG_TITLE_GENERIC" desc="The title of the dialog informing the user that the new tab page has been overridden by an extension."> + Did you mean to change your search provider? + </message> + <message name="IDS_EXTENSION_SEARCH_OVERRIDDEN_DIALOG_BODY_GENERIC" desc="The body of the dialog informing the user that the new tab page has been overridden by an extension, indicating which extension now controls it."> + The <ph name="EXTENSION_NAME">$2<ex>Some New Search</ex></ph> extension changed search to use <ph name="SEARCH_PROVIDER_DOMAIN">$1<ex>google.com</ex></ph> + </message> <!-- End Extension Settings Overridden Dialog strings. --> <!-- Extensions Menu bubble -->
diff --git a/chrome/app/generated_resources_grd/IDS_EXTENSION_SEARCH_OVERRIDDEN_DIALOG_BODY_GENERIC.png.sha1 b/chrome/app/generated_resources_grd/IDS_EXTENSION_SEARCH_OVERRIDDEN_DIALOG_BODY_GENERIC.png.sha1 new file mode 100644 index 0000000..f116e3a --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_EXTENSION_SEARCH_OVERRIDDEN_DIALOG_BODY_GENERIC.png.sha1
@@ -0,0 +1 @@ +8a6343ef70fa82abb74d059084f03dee82bb8dc6 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_EXTENSION_SEARCH_OVERRIDDEN_DIALOG_TITLE_GENERIC.png.sha1 b/chrome/app/generated_resources_grd/IDS_EXTENSION_SEARCH_OVERRIDDEN_DIALOG_TITLE_GENERIC.png.sha1 new file mode 100644 index 0000000..f116e3a --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_EXTENSION_SEARCH_OVERRIDDEN_DIALOG_TITLE_GENERIC.png.sha1
@@ -0,0 +1 @@ +8a6343ef70fa82abb74d059084f03dee82bb8dc6 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index 8626eb2..18d2725b 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -793,11 +793,12 @@ Manage your signed-in accounts. Websites, apps, and extensions in Chrome and Google Play may use these accounts to customize your experience, depending on permissions. <ph name="LINK_BEGIN"><a></ph>Learn more<ph name="LINK_END"></a></ph> </message> <message name="IDS_SETTINGS_ACCOUNT_MANAGER_CHILD_DESCRIPTION" desc="Description of the Account Manager Settings page for child users. Shown just below the title of the page."> - Add a school account or manage child accounts here. <ph name="LINK_BEGIN"><a></ph>Learn more<ph name="LINK_END"></a></ph> + Manage your accounts here. <ph name="LINK_BEGIN"><a></ph>Learn more<ph name="LINK_END"></a></ph> </message> - <message name="IDS_SETTINGS_ACCOUNT_MANAGER_CHILD_DESCRIPTION_2" desc="Description of the Account Manager Settings page for child users. Shown just below the title of the page."> - Manage your accounts here. <ph name="LINK_BEGIN"><a></ph>Learn more<ph name="LINK_END"></a></ph><br><br> - Bookmarks, passwords, and other browser data are synced with the primary account.<br><br> + <message name="IDS_SETTINGS_ACCOUNT_MANAGER_CHILD_FIRST_MESSAGE" desc="Description of the Account Manager Settings page for child users. Shown just below the link to learn more about account management."> + Bookmarks, passwords, and other browser data are synced with the primary account. + </message> + <message name="IDS_SETTINGS_ACCOUNT_MANAGER_CHILD_SECOND_MESSAGE" desc="Description of the Account Manager Settings page for child users. Shown just below the link to learn more about account management."> Adding a school account enables easy sign-in to websites and extensions as a student while still operating under parental controls. </message> <message name="IDS_SETTINGS_ACCOUNT_MANAGER_LIST_HEADER" desc="List header for Account List in Account Manager Settings page."> @@ -1100,10 +1101,10 @@ Ports </message> <message name="IDS_SETTINGS_CROSTINI_MIC_TITLE" desc="Title for sharing mic with Crostini."> - Allow Linux apps to access the microphone + Allow Linux to access your microphone </message> <message name="IDS_SETTINGS_CROSTINI_MIC_DIALOG_LABEL" desc="Dialog label for sharing mic with Crostini."> - The change made to the microphone access requires Linux to restart. Shut down Linux to proceed. + The change in microphone setting requires Linux to shut down. Shut down Linux to proceed. </message> <message name="IDS_SETTINGS_CROSTINI_MIC_DIALOG_SHUTDOWN_BUTTON" desc="Label for the shutdown button in the Crostini mic sharing dialog."> Shut down
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CROSTINI_MIC_DIALOG_LABEL.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CROSTINI_MIC_DIALOG_LABEL.png.sha1 index b911b03c..56aea6c 100644 --- a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CROSTINI_MIC_DIALOG_LABEL.png.sha1 +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CROSTINI_MIC_DIALOG_LABEL.png.sha1
@@ -1 +1 @@ -2256ba32a9633ed3aea27de9637f0fdcda261de0 \ No newline at end of file +6c6941186b10a819f5e133f5a8fdc3991786f24a \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CROSTINI_MIC_TITLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CROSTINI_MIC_TITLE.png.sha1 index 9185bcb..b431b89b 100644 --- a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CROSTINI_MIC_TITLE.png.sha1 +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CROSTINI_MIC_TITLE.png.sha1
@@ -1 +1 @@ -43cc7d849d3cc002110273bb5cc133ee0f18416c \ No newline at end of file +9de1f7b23f79a3608c60869725a7ea0558b7b52c \ No newline at end of file
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index ab686ee..b321c9a 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -455,6 +455,14 @@ Password deleted </message> <!-- TODO(crbug.com/1062344): Make it translateable and add translation screenshots once final mocks are available. --> + <message translateable="false" name="IDS_SETTINGS_PASSWORD_STORED_ON_DEVICE" desc="Message displayed in the edit dialog for a password stored on the device."> + Your password is stored <b>on this device</b>. + </message> + <!-- TODO(crbug.com/1062344): Make it translateable and add translation screenshots once final mocks are available. --> + <message translateable="false" name="IDS_SETTINGS_PASSWORD_STORED_IN_ACCOUNT" desc="Message displayed in the edit dialog for a password stored in the account."> + Your password is stored <b>in your Google Account</b>. + </message> + <!-- TODO(crbug.com/1062344): Make it translateable and add translation screenshots once final mocks are available. --> <message translateable="false" name="IDS_SETTINGS_PASSWORD_DELETED_PASSWORD_FROM_ACCOUNT" desc="Label for an undo tooltip following deletion of a password from the account."> Password deleted from your Google Account </message>
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index 6e1f0e4..573a0fe 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd
@@ -250,6 +250,8 @@ </if> <if expr="chromeos"> <structure type="chrome_scaled_image" name="IDR_RESET_WARNING" file="cros/reset_warning.png" /> + <structure type="chrome_scaled_image" name="IDR_ENABLE_DEBUGGING_FAILURE" file="cros/enable_debugging_failure.png" /> + <structure type="chrome_scaled_image" name="IDR_ENABLE_DEBUGGING_SUCCESS" file="cros/enable_debugging_success.png" /> </if> <structure type="chrome_scaled_image" name="IDR_RESTORE_BUTTON_MASK" file="common/restore_button_mask.png" /> <if expr="not is_android">
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 3c8efd5f..a1acd043 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -3205,14 +3205,6 @@ kOsAll, FEATURE_VALUE_TYPE( autofill::features::kAutofillCreditCardAblationExperiment)}, - {"enable-autofill-credit-card-upload-editable-expiration-date", - flag_descriptions:: - kEnableAutofillCreditCardUploadEditableExpirationDateName, - flag_descriptions:: - kEnableAutofillCreditCardUploadEditableExpirationDateDescription, - kOsAll, - FEATURE_VALUE_TYPE( - autofill::features::kAutofillUpstreamEditableExpirationDate)}, #if defined(OS_ANDROID) {"enable-autofill-manual-fallback", @@ -4629,12 +4621,6 @@ flag_descriptions::kStrictOriginIsolationDescription, kOsAll, FEATURE_VALUE_TYPE(features::kStrictOriginIsolation)}, - {"autofill-no-local-save-on-unmask-success", - flag_descriptions::kAutofillNoLocalSaveOnUnmaskSuccessName, - flag_descriptions::kAutofillNoLocalSaveOnUnmaskSuccessDescription, kOsAll, - FEATURE_VALUE_TYPE( - autofill::features::kAutofillNoLocalSaveOnUnmaskSuccess)}, - #if defined(OS_ANDROID) {"enable-logging-js-console-messages", flag_descriptions::kLogJsConsoleMessagesName,
diff --git a/chrome/browser/android/explore_sites/explore_sites_fetcher.cc b/chrome/browser/android/explore_sites/explore_sites_fetcher.cc index ced913b..90176e4 100644 --- a/chrome/browser/android/explore_sites/explore_sites_fetcher.cc +++ b/chrome/browser/android/explore_sites/explore_sites_fetcher.cc
@@ -89,7 +89,7 @@ -1, // Don't discard entry even if unused. false // Don't use initial delay unless the last was an error. }; -const int ExploreSitesFetcher::kMaxFailureCountForBackgroundFetch = 7; +const int ExploreSitesFetcher::kMaxFailureCountForBackgroundFetch = 2; // static std::unique_ptr<ExploreSitesFetcher> ExploreSitesFetcher::CreateForGetCatalog(
diff --git a/chrome/browser/android/explore_sites/explore_sites_fetcher_unittest.cc b/chrome/browser/android/explore_sites/explore_sites_fetcher_unittest.cc index b93b5c3..cd857a3 100644 --- a/chrome/browser/android/explore_sites/explore_sites_fetcher_unittest.cc +++ b/chrome/browser/android/explore_sites/explore_sites_fetcher_unittest.cc
@@ -436,30 +436,6 @@ EXPECT_EQ(kTestData, data); } -TEST_F(ExploreSitesFetcherTest, TwoBackoffsForBackgroundFetch) { - std::string data; - int initial_delay_ms = - ExploreSitesFetcher::kBackgroundFetchBackoffPolicy.initial_delay_ms; - std::vector<base::TimeDelta> backoff_delays = { - base::TimeDelta::FromMilliseconds(initial_delay_ms), - base::TimeDelta::FromMilliseconds(initial_delay_ms * 2)}; - std::vector<base::OnceCallback<void(void)>> respond_callbacks; - respond_callbacks.push_back( - base::BindOnce(&ExploreSitesFetcherTest::RespondWithNetError, - base::Unretained(this), net::ERR_INTERNET_DISCONNECTED)); - respond_callbacks.push_back( - base::BindOnce(&ExploreSitesFetcherTest::RespondWithHttpError, - base::Unretained(this), net::HTTP_INTERNAL_SERVER_ERROR)); - respond_callbacks.push_back( - base::BindOnce(&ExploreSitesFetcherTest::RespondWithData, - base::Unretained(this), kTestData)); - EXPECT_EQ( - ExploreSitesRequestStatus::kSuccess, - RunFetcherWithBackoffs(false /*is_immediate_fetch*/, 2u, backoff_delays, - std::move(respond_callbacks), &data)); - EXPECT_EQ(kTestData, data); -} - TEST_F(ExploreSitesFetcherTest, ExceedMaxBackoffsForImmediateFetch) { std::string data; int delay_ms =
diff --git a/chrome/browser/android/feed/v2/feed_stream_surface.cc b/chrome/browser/android/feed/v2/feed_stream_surface.cc index 482f6363..a5b5e15 100644 --- a/chrome/browser/android/feed/v2/feed_stream_surface.cc +++ b/chrome/browser/android/feed/v2/feed_stream_surface.cc
@@ -190,4 +190,10 @@ feed_stream_api_->ReportStreamScrolled(distance_dp); } +void FeedStreamSurface::ReportStreamScrollStart( + JNIEnv* env, + const JavaParamRef<jobject>& obj) { + feed_stream_api_->ReportStreamScrollStart(); +} + } // namespace feed
diff --git a/chrome/browser/android/feed/v2/feed_stream_surface.h b/chrome/browser/android/feed/v2/feed_stream_surface.h index abb8dfa..70dda94 100644 --- a/chrome/browser/android/feed/v2/feed_stream_surface.h +++ b/chrome/browser/android/feed/v2/feed_stream_surface.h
@@ -99,6 +99,8 @@ void ReportStreamScrolled(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, int distance_dp); + void ReportStreamScrollStart(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); private: base::android::ScopedJavaGlobalRef<jobject> java_ref_;
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 056df0e..9a47490c 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -224,7 +224,6 @@ <include name="IDR_EDU_LOGIN_EDU_LOGIN_BUTTON_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\edu_login\edu_login_button.js" use_base_dir="false" type="BINDATA" compress="gzip" /> <include name="IDR_EDU_LOGIN_EDU_LOGIN_TEMPLATE_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\edu_login\edu_login_template.js" use_base_dir="false" type="BINDATA" compress="gzip" /> <include name="IDR_EDU_LOGIN_EDU_LOGIN_CSS_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\edu_login\edu_login_css.js" use_base_dir="false" type ="BINDATA" /> - <include name="IDR_EDU_LOGIN_EDU_LOGIN_WELCOME_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\edu_login\edu_login_welcome.js" use_base_dir="false" type ="BINDATA" compress="gzip" preprocess="true" /> <include name="IDR_EDU_LOGIN_EDU_LOGIN_PARENTS_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\edu_login\edu_login_parents.js" use_base_dir="false" type ="BINDATA" compress="gzip" preprocess="true" /> <include name="IDR_EDU_LOGIN_EDU_LOGIN_PARENT_SIGNIN_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\edu_login\edu_login_parent_signin.js" use_base_dir="false" type ="BINDATA" compress="gzip" preprocess="true" /> <include name="IDR_EDU_LOGIN_EDU_LOGIN_PARENT_INFO_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\edu_login\edu_login_parent_info.js" use_base_dir="false" type ="BINDATA" compress="gzip" preprocess="true" />
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index af01f3e..f7ecc02 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -2230,10 +2230,6 @@ command_line->AppendSwitch(switches::kAllowSyncXHRInPageDismissal); } - if (prefs->HasPrefPath(prefs::kUseLegacyFormControls) && - prefs->GetBoolean(prefs::kUseLegacyFormControls)) { - command_line->AppendSwitch(switches::kUseLegacyFormControls); - } if (prefs->HasPrefPath(prefs::kScrollToTextFragmentEnabled) && !prefs->GetBoolean(prefs::kScrollToTextFragmentEnabled)) {
diff --git a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler_user_service.h b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler_user_service.h index 4d0be0d..6370ead 100644 --- a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler_user_service.h +++ b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler_user_service.h
@@ -19,6 +19,8 @@ explicit CertProvisioningSchedulerUserService(Profile* profile); ~CertProvisioningSchedulerUserService() override; + CertProvisioningScheduler* scheduler() { return scheduler_.get(); } + private: std::unique_ptr<CertProvisioningScheduler> scheduler_; };
diff --git a/chrome/browser/chromeos/extensions/printing/printing_apitest.cc b/chrome/browser/chromeos/extensions/printing/printing_apitest.cc index 04dcee1b..f6efa49a 100644 --- a/chrome/browser/chromeos/extensions/printing/printing_apitest.cc +++ b/chrome/browser/chromeos/extensions/printing/printing_apitest.cc
@@ -18,6 +18,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/test/base/ui_test_utils.h" #include "chromeos/printing/printer_configuration.h" +#include "content/public/test/browser_test.h" #include "extensions/test/result_catcher.h" #include "printing/backend/print_backend.h" #include "printing/backend/test_print_backend.h"
diff --git a/chrome/browser/chromeos/login/screens/welcome_screen.h b/chrome/browser/chromeos/login/screens/welcome_screen.h index d970c19..18cf413f 100644 --- a/chrome/browser/chromeos/login/screens/welcome_screen.h +++ b/chrome/browser/chromeos/login/screens/welcome_screen.h
@@ -70,6 +70,8 @@ void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); + base::Value* GetConfigurationForTesting() { return GetConfiguration(); } + protected: // Exposes exit callback to test overrides. base::RepeatingClosure* exit_callback() { return &exit_callback_; }
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc index 2fd3632..dff19885 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.cc +++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -2314,8 +2314,10 @@ if (!release_notes_notification_) { release_notes_notification_ = std::make_unique<ReleaseNotesNotification>(profile); - if (chrome::GetChannel() == version_info::Channel::STABLE) + if (chrome::GetChannel() == version_info::Channel::STABLE || + chrome::GetChannel() == version_info::Channel::BETA) { release_notes_notification_->MaybeShowReleaseNotes(); + } } }
diff --git a/chrome/browser/chromeos/login/test/oobe_base_test.cc b/chrome/browser/chromeos/login/test/oobe_base_test.cc index 1475ee8..d948534 100644 --- a/chrome/browser/chromeos/login/test/oobe_base_test.cc +++ b/chrome/browser/chromeos/login/test/oobe_base_test.cc
@@ -113,13 +113,16 @@ } void OobeBaseTest::WaitForOobeUI() { + // Wait for notification first. Otherwise LoginDisplayHost might not be + // created yet. + MaybeWaitForLoginScreenLoad(); + // Wait for OobeUI to finish loading. base::RunLoop run_loop; if (!LoginDisplayHost::default_host()->GetOobeUI()->IsJSReady( run_loop.QuitClosure())) { run_loop.Run(); } - MaybeWaitForLoginScreenLoad(); } void OobeBaseTest::WaitForGaiaPageLoad() {
diff --git a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc index be52725..47d6a88e 100644 --- a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc +++ b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
@@ -169,11 +169,6 @@ ~PrefStoreStub() override {} }; -// Matches on non-empty DictionaryValue* object. -MATCHER(NonEmptyConfiguration, "") { - return arg && !arg->DictEmpty(); -} - // Used to set up a |FakeAutoEnrollmentClientFactory| for the duration of a // test. class ScopedFakeAutoEnrollmentClientFactory { @@ -373,19 +368,6 @@ return host->GetOobeWebContents(); } - void WaitUntilJSIsReady() { - LoginDisplayHost* host = LoginDisplayHost::default_host(); - if (!host) - return; - chromeos::OobeUI* oobe_ui = host->GetOobeUI(); - if (!oobe_ui) - return; - base::RunLoop run_loop; - const bool oobe_ui_ready = oobe_ui->IsJSReady(run_loop.QuitClosure()); - if (!oobe_ui_ready) - run_loop.Run(); - } - bool JSExecute(const std::string& script) { return content::ExecuteScript(GetWebContents(), script); } @@ -693,8 +675,6 @@ void TestControlFlowMain() { CheckCurrentScreen(WelcomeView::kScreenId); - WaitUntilJSIsReady(); - test_url_loader_factory_.SetInterceptor(base::BindLambdaForTesting( [&](const network::ResourceRequest& request) { if (base::StartsWith( @@ -1345,7 +1325,6 @@ EXPECT_EQ(AutoEnrollmentCheckScreenView::kScreenId.AsId(), GetErrorScreen()->GetParentScreen()); - WaitUntilJSIsReady(); constexpr char guest_session_link_display[] = "window.getComputedStyle($('error-guest-signin-fix-network')).display"; if (IsFREExplicitlyRequired()) { @@ -1448,7 +1427,6 @@ EXPECT_EQ(AutoEnrollmentCheckScreenView::kScreenId.AsId(), GetErrorScreen()->GetParentScreen()); - WaitUntilJSIsReady(); constexpr char guest_session_link_display[] = "window.getComputedStyle($('error-guest-signin-fix-network'))." "display"; @@ -1663,7 +1641,6 @@ EXPECT_EQ(AutoEnrollmentCheckScreenView::kScreenId.AsId(), GetErrorScreen()->GetParentScreen()); - WaitUntilJSIsReady(); constexpr char guest_session_link_display[] = "window.getComputedStyle($('error-guest-signin-fix-network'))." "display"; @@ -2110,7 +2087,6 @@ ASSERT_EQ(NetworkError::UI_STATE_LOCAL_STATE_ERROR, GetErrorScreen()->GetUIState()); - WaitUntilJSIsReady(); OobeScreenWaiter(ErrorScreenView::kScreenId).Wait(); // Checks visibility of the error message and powerwash button. @@ -2305,7 +2281,6 @@ IN_PROC_BROWSER_TEST_F(WizardControllerEnableAdbSideloadingTest, ShowAndEnableSideloading) { CheckCurrentScreen(WelcomeView::kScreenId); - WaitUntilJSIsReady(); EXPECT_CALL(*mock_welcome_screen_, HideImpl()).Times(1); EXPECT_CALL(*mock_welcome_screen_, SetConfiguration(IsNull())).Times(1); @@ -2334,7 +2309,6 @@ IN_PROC_BROWSER_TEST_F(WizardControllerEnableAdbSideloadingTest, ShowAndDoNotEnableSideloading) { CheckCurrentScreen(WelcomeView::kScreenId); - WaitUntilJSIsReady(); EXPECT_CALL(*mock_welcome_screen_, HideImpl()).Times(1); EXPECT_CALL(*mock_welcome_screen_, SetConfiguration(IsNull())).Times(1); @@ -2377,7 +2351,6 @@ IN_PROC_BROWSER_TEST_F(WizardControllerEnableDebuggingTest, ShowAndCancelEnableDebugging) { CheckCurrentScreen(WelcomeView::kScreenId); - WaitUntilJSIsReady(); EXPECT_CALL(*mock_welcome_screen_, HideImpl()).Times(1); EXPECT_CALL(*mock_welcome_screen_, SetConfiguration(IsNull())).Times(1); @@ -2430,7 +2403,6 @@ OnlineDemoSetupFlowFinished) { CheckCurrentScreen(WelcomeView::kScreenId); EXPECT_FALSE(DemoSetupController::IsOobeDemoSetupFlowInProgress()); - WaitUntilJSIsReady(); EXPECT_CALL(*mock_welcome_screen_, HideImpl()).Times(1); EXPECT_CALL(*mock_welcome_screen_, SetConfiguration(IsNull())).Times(1); @@ -2505,7 +2477,6 @@ OfflineDemoSetupFlowFinished) { CheckCurrentScreen(WelcomeView::kScreenId); EXPECT_FALSE(DemoSetupController::IsOobeDemoSetupFlowInProgress()); - WaitUntilJSIsReady(); EXPECT_CALL(*mock_welcome_screen_, HideImpl()).Times(1); EXPECT_CALL(*mock_welcome_screen_, SetConfiguration(IsNull())).Times(1); @@ -2563,7 +2534,6 @@ IN_PROC_BROWSER_TEST_F(WizardControllerDemoSetupTest, DemoSetupCanceled) { CheckCurrentScreen(WelcomeView::kScreenId); EXPECT_FALSE(DemoSetupController::IsOobeDemoSetupFlowInProgress()); - WaitUntilJSIsReady(); EXPECT_CALL(*mock_welcome_screen_, HideImpl()).Times(1); EXPECT_CALL(*mock_welcome_screen_, SetConfiguration(IsNull())).Times(1); @@ -2641,7 +2611,6 @@ IN_PROC_BROWSER_TEST_F(WizardControllerDemoSetupTest, DemoPreferencesCanceled) { CheckCurrentScreen(WelcomeView::kScreenId); EXPECT_FALSE(DemoSetupController::IsOobeDemoSetupFlowInProgress()); - WaitUntilJSIsReady(); SkipToScreen(DemoPreferencesScreenView::kScreenId, mock_demo_preferences_screen_); @@ -2661,7 +2630,6 @@ IN_PROC_BROWSER_TEST_F(WizardControllerDemoSetupTest, NetworkBackPressed) { CheckCurrentScreen(WelcomeView::kScreenId); EXPECT_FALSE(DemoSetupController::IsOobeDemoSetupFlowInProgress()); - WaitUntilJSIsReady(); SkipToScreen(NetworkScreenView::kScreenId, mock_network_screen_); CheckCurrentScreen(NetworkScreenView::kScreenId); @@ -2679,7 +2647,6 @@ IN_PROC_BROWSER_TEST_F(WizardControllerDemoSetupTest, EulaBackPressed) { CheckCurrentScreen(WelcomeView::kScreenId); EXPECT_FALSE(DemoSetupController::IsOobeDemoSetupFlowInProgress()); - WaitUntilJSIsReady(); SkipToScreen(EulaView::kScreenId, mock_eula_screen_); CheckCurrentScreen(EulaView::kScreenId); @@ -2697,7 +2664,6 @@ IN_PROC_BROWSER_TEST_F(WizardControllerDemoSetupTest, ArcTosBackPressed) { CheckCurrentScreen(WelcomeView::kScreenId); EXPECT_FALSE(DemoSetupController::IsOobeDemoSetupFlowInProgress()); - WaitUntilJSIsReady(); // User cannot go to ARC ToS screen without accepting eula - simulate that. StartupUtils::MarkEulaAccepted(); @@ -2737,7 +2703,6 @@ OnlineDemoSetup) { CheckCurrentScreen(WelcomeView::kScreenId); EXPECT_FALSE(DemoSetupController::IsOobeDemoSetupFlowInProgress()); - WaitUntilJSIsReady(); EXPECT_CALL(*mock_welcome_screen_, HideImpl()).Times(1); EXPECT_CALL(*mock_welcome_screen_, SetConfiguration(IsNull())).Times(1); @@ -2924,7 +2889,7 @@ // WizardControllerTest: void SetUpCommandLine(base::CommandLine* command_line) override { - WizardControllerTest ::SetUpCommandLine(command_line); + WizardControllerTest::SetUpCommandLine(command_line); base::FilePath configuration_file; ASSERT_TRUE(chromeos::test_utils::GetTestDataPath( @@ -2937,49 +2902,22 @@ // WizardControllerTest: void SetUpOnMainThread() override { WizardControllerTest::SetUpOnMainThread(); - - // Make sure that OOBE is run as an "official" build. - branded_build_override_ = WizardController::ForceBrandedBuildForTesting(); - // Clear portal list (as it is by default in OOBE). NetworkHandler::Get()->network_state_handler()->SetCheckPortalList(""); - - mock_welcome_view_ = std::make_unique<MockWelcomeView>(); - mock_welcome_screen_ = - MockScreenExpectLifecycle(std::make_unique<MockWelcomeScreen>( - mock_welcome_view_.get(), - base::BindRepeating( - &WizardController::OnWelcomeScreenExit, - base::Unretained(WizardController::default_controller())))); } - void WaitForConfigurationLoaded() { - base::RunLoop run_loop; - OOBEConfigurationWaiter waiter; - const bool ready = waiter.IsConfigurationLoaded(run_loop.QuitClosure()); - if (!ready) - run_loop.Run(); - } - - protected: - std::unique_ptr<MockWelcomeView> mock_welcome_view_; - MockWelcomeScreen* mock_welcome_screen_ = nullptr; - std::unique_ptr<base::AutoReset<bool>> branded_build_override_; - private: DISALLOW_COPY_AND_ASSIGN(WizardControllerOobeConfigurationTest); }; -// TODO: fix, test is flaky. https://crbug.com/904841. IN_PROC_BROWSER_TEST_F(WizardControllerOobeConfigurationTest, - DISABLED_ConfigurationIsLoaded) { - WaitForConfigurationLoaded(); - EXPECT_CALL(*mock_welcome_screen_, ShowImpl()).Times(1); - EXPECT_CALL(*mock_welcome_screen_, SetConfiguration(NonEmptyConfiguration())) - .Times(1); - WizardController::default_controller()->AdvanceToScreen( - WelcomeView::kScreenId); - CheckCurrentScreen(WelcomeView::kScreenId); + ConfigurationIsLoaded) { + OobeScreenWaiter(WelcomeView::kScreenId).Wait(); + WelcomeScreen* screen = WelcomeScreen::Get( + WizardController::default_controller()->screen_manager()); + base::Value* configuration = screen->GetConfigurationForTesting(); + ASSERT_NE(configuration, nullptr); + EXPECT_FALSE(configuration->DictEmpty()); } // TODO(dzhioev): Add test emulating device with wrong HWID.
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h index 6cf773f..f9c1cff 100644 --- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h +++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h
@@ -179,6 +179,13 @@ return hostname_handler_.get(); } + // Return a pointer to the device-wide client certificate provisioning + // scheduler. The callers do not take ownership of that pointer. + chromeos::cert_provisioning::CertProvisioningScheduler* + GetDeviceCertProvisioningScheduler() { + return device_cert_provisioning_scheduler_.get(); + } + // Returns device's market segment. MarketSegment GetEnterpriseMarketSegment() const;
diff --git a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc index 99c9d73..60f275f 100644 --- a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc +++ b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
@@ -1566,17 +1566,6 @@ } } - if (policy.has_device_login_screen_isolate_origins()) { - const em::DeviceLoginScreenIsolateOriginsProto& container( - policy.device_login_screen_isolate_origins()); - if (container.has_isolate_origins()) { - policies->Set( - key::kDeviceLoginScreenIsolateOrigins, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, - std::make_unique<base::Value>(container.isolate_origins()), nullptr); - } - } - if (policy.has_virtual_machines_allowed()) { const em::VirtualMachinesAllowedProto& container( policy.virtual_machines_allowed());
diff --git a/chrome/browser/download/android/BUILD.gn b/chrome/browser/download/android/BUILD.gn index 38b102b..263c21f 100644 --- a/chrome/browser/download/android/BUILD.gn +++ b/chrome/browser/download/android/BUILD.gn
@@ -55,6 +55,8 @@ "//components/offline_items_collection/core:core_java", "//content/public/android:content_java", "//third_party/android_deps:androidx_core_core_java", + "//third_party/android_deps:androidx_fragment_fragment_java", + "//third_party/android_deps:androidx_preference_preference_java", "//third_party/android_deps:com_google_android_material_material_java", "//ui/android:ui_java", ] @@ -94,6 +96,7 @@ "//base:base_java", "//base:base_java_test_support", "//chrome/test/android:chrome_java_test_support", + "//components/browser_ui/util/android:java", "//components/offline_items_collection/core:core_java", "//third_party/android_support_test_runner:runner_java", "//third_party/junit",
diff --git a/chrome/browser/extensions/settings_api_bubble_delegate.cc b/chrome/browser/extensions/settings_api_bubble_delegate.cc index 93f18705..265cdce 100644 --- a/chrome/browser/extensions/settings_api_bubble_delegate.cc +++ b/chrome/browser/extensions/settings_api_bubble_delegate.cc
@@ -25,10 +25,6 @@ namespace { -// Whether the user has been notified about extension taking over some aspect of -// the user's settings (homepage, startup pages, or search engine). -const char kSettingsBubbleAcknowledged[] = "ack_settings_bubble"; - using ProfileSetMap = std::map<std::string, std::set<Profile*>>; base::LazyInstance<ProfileSetMap>::Leaky g_settings_api_shown = LAZY_INSTANCE_INITIALIZER; @@ -41,9 +37,12 @@ : ExtensionMessageBubbleController::Delegate(profile), type_(type), profile_(profile) { - set_acknowledged_flag_pref_name(kSettingsBubbleAcknowledged); + set_acknowledged_flag_pref_name(kAcknowledgedPreference); } +const char SettingsApiBubbleDelegate::kAcknowledgedPreference[] = + "ack_settings_bubble"; + SettingsApiBubbleDelegate::~SettingsApiBubbleDelegate() {} bool SettingsApiBubbleDelegate::ShouldIncludeExtension(
diff --git a/chrome/browser/extensions/settings_api_bubble_delegate.h b/chrome/browser/extensions/settings_api_bubble_delegate.h index e6749179..6b3da095 100644 --- a/chrome/browser/extensions/settings_api_bubble_delegate.h +++ b/chrome/browser/extensions/settings_api_bubble_delegate.h
@@ -21,6 +21,13 @@ SettingsApiBubbleDelegate(Profile* profile, SettingsApiOverrideType type); ~SettingsApiBubbleDelegate() override; + // The preference used to indicate if the user has acknowledged the extension + // taking over some aspect of the user's settings (homepage, startup pages, + // or search engine). + // TODO(devlin): We currently use one preference for all of these, but that's + // probably not desirable. + static const char kAcknowledgedPreference[]; + // ExtensionMessageBubbleController::Delegate methods. bool ShouldIncludeExtension(const Extension* extension) override; void AcknowledgeExtension(
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index c74190f..f9a2d297 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -2209,7 +2209,7 @@ { "name": "enable-touch-drag-drop", "owners": [ "nzolghadr", "input-dev" ], - "expiry_milestone": 82 + "expiry_milestone": 88 }, { "name": "enable-touchscreen-calibration", @@ -3746,7 +3746,7 @@ { "name": "safety-tips", "owners": [ "jdeblasio", "estark", "meacer" ], - "expiry_milestone": 84 + "expiry_milestone": 87 }, { "name": "same-site-by-default-cookies",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 0d18ab5a..e84c17db 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -248,12 +248,6 @@ "When enabled, autofill will generally require a form to have at least 3 " "fillable fields before uploading field-type votes for that form."; -const char kAutofillNoLocalSaveOnUnmaskSuccessName[] = - "Remove the option to save local copies of unmasked server cards"; -const char kAutofillNoLocalSaveOnUnmaskSuccessDescription[] = - "When enabled, the server card unmask prompt will not include the checkbox " - "to also save the card locally on the current device upon success."; - const char kAutofillOffNoServerDataName[] = "Autofill Off No Server Data"; const char kAutofillOffNoServerDataDescription[] = "Disables Autofill for fields with autocomplete off that have no " @@ -518,13 +512,6 @@ "authenticator (if available) to verify card ownership when retrieving " "credit cards from Google Payments."; -const char kEnableAutofillCreditCardUploadEditableExpirationDateName[] = - "Make expiration date editable in dialog during credit card upload"; -const char kEnableAutofillCreditCardUploadEditableExpirationDateDescription[] = - "If enabled, if a credit card's expiration date was not detected when " - "offering card upload to Google Payments, the offer-to-save dialog " - "displays an expiration date selector."; - const char kEnableAutofillCreditCardUploadFeedbackName[] = "Enable feedback for credit card upload flow"; const char kEnableAutofillCreditCardUploadFeedbackDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 004ea83c..a0fb8a8 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -150,9 +150,6 @@ extern const char kAutofillEnforceMinRequiredFieldsForUploadName[]; extern const char kAutofillEnforceMinRequiredFieldsForUploadDescription[]; -extern const char kAutofillNoLocalSaveOnUnmaskSuccessName[]; -extern const char kAutofillNoLocalSaveOnUnmaskSuccessDescription[]; - extern const char kAutofillOffNoServerDataName[]; extern const char kAutofillOffNoServerDataDescription[]; @@ -319,10 +316,6 @@ extern const char kEnableAutofillCreditCardAuthenticationName[]; extern const char kEnableAutofillCreditCardAuthenticationDescription[]; -extern const char kEnableAutofillCreditCardUploadEditableExpirationDateName[]; -extern const char - kEnableAutofillCreditCardUploadEditableExpirationDateDescription[]; - extern const char kEnableAutofillCreditCardUploadFeedbackName[]; extern const char kEnableAutofillCreditCardUploadFeedbackDescription[];
diff --git a/chrome/browser/flags/BUILD.gn b/chrome/browser/flags/BUILD.gn index a8481265..d26786b7 100644 --- a/chrome/browser/flags/BUILD.gn +++ b/chrome/browser/flags/BUILD.gn
@@ -64,6 +64,7 @@ "//base:base_junit_test_support", "//base/test:test_support_java", "//chrome/test/android:chrome_java_test_support", + "//third_party/junit", ] }
diff --git a/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc b/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc index fedd73b..43d5111 100644 --- a/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc +++ b/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/stl_util.h" -#include "base/strings/strcat.h" #include "base/task/post_task.h" #include "chrome/browser/media/router/providers/cast/cast_activity_manager.h" #include "chrome/browser/media/router/providers/cast/cast_internal_message_util.h" @@ -23,6 +22,25 @@ namespace media_router { +namespace { + +// Returns a list of origins that are valid for |source_id|. An empty list +// means all origins are valid. +std::vector<url::Origin> GetOrigins(const MediaSource::Id& source_id) { + // Use of the mirroring app as a Cast URL is permitted for Slides as a + // temporary workaround only. The eventual goal is to support their usecase + // using generic Presentation API. + // See also cast_media_source.cc. + static const char kMirroringAppPrefix[] = "cast:0F5096E8"; + return base::StartsWith(source_id, kMirroringAppPrefix, + base::CompareCase::SENSITIVE) + ? std::vector<url::Origin>( + {url::Origin::Create(GURL("https://docs.google.com"))}) + : std::vector<url::Origin>(); +} + +} // namespace + CastMediaRouteProvider::CastMediaRouteProvider( mojo::PendingReceiver<mojom::MediaRouteProvider> receiver, mojo::PendingRemote<mojom::MediaRouter> media_router, @@ -94,23 +112,16 @@ return; } - const auto cast_source = CastMediaSource::FromMediaSourceId(source_id); + std::unique_ptr<CastMediaSource> cast_source = + CastMediaSource::FromMediaSourceId(source_id); if (!cast_source) { DVLOG(2) << "CreateRoute: invalid source"; std::move(callback).Run( - base::nullopt, nullptr, base::StrCat({"Invalid source ", source_id}), + base::nullopt, nullptr, std::string("Invalid source"), RouteRequestResult::ResultCode::NO_SUPPORTED_PROVIDER); return; } - if (!cast_source->IsAllowedOrigin(origin)) { - std::move(callback).Run( - base::nullopt, nullptr, - base::StrCat({"Invalid origin ", origin.Serialize()}), - RouteRequestResult::ResultCode::INVALID_ORIGIN); - return; - } - activity_manager_->LaunchSession(*cast_source, *sink, presentation_id, origin, tab_id, incognito, std::move(callback)); } @@ -122,10 +133,11 @@ base::TimeDelta timeout, bool incognito, JoinRouteCallback callback) { - const auto cast_source = CastMediaSource::FromMediaSourceId(media_source); + std::unique_ptr<CastMediaSource> cast_source = + CastMediaSource::FromMediaSourceId(media_source); if (!cast_source) { std::move(callback).Run( - base::nullopt, nullptr, base::StrCat({"Invalid source ", media_source}), + base::nullopt, nullptr, std::string("Invalid source"), RouteRequestResult::ResultCode::NO_SUPPORTED_PROVIDER); return; } @@ -175,7 +187,8 @@ if (base::Contains(sink_queries_, media_source)) return; - const auto cast_source = CastMediaSource::FromMediaSourceId(media_source); + std::unique_ptr<CastMediaSource> cast_source = + CastMediaSource::FromMediaSourceId(media_source); if (!cast_source) return; @@ -278,11 +291,8 @@ const std::vector<MediaSinkInternal>& sinks) { DVLOG(1) << __func__ << ", source_id: " << source_id << ", #sinks: " << sinks.size(); - const auto cast_source = CastMediaSource::FromMediaSourceId(source_id); - if (cast_source) { - media_router_->OnSinksReceived(MediaRouteProviderId::CAST, source_id, sinks, - cast_source->GetAllowedOrigins()); - } + media_router_->OnSinksReceived(MediaRouteProviderId::CAST, source_id, sinks, + GetOrigins(source_id)); } void CastMediaRouteProvider::BroadcastMessageToSinks(
diff --git a/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc b/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc index c22d340c..cc3985d6 100644 --- a/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc +++ b/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc
@@ -6,7 +6,6 @@ #include "base/bind.h" #include "base/run_loop.h" -#include "base/strings/strcat.h" #include "base/test/test_simple_task_runner.h" #include "base/threading/sequenced_task_runner_handle.h" #include "chrome/browser/media/router/providers/cast/cast_session_tracker.h" @@ -90,17 +89,6 @@ route_ = std::make_unique<MediaRoute>(*route); } - void ExpectCreateRouteSuccessWithoutConnections( - const base::Optional<MediaRoute>& route, - mojom::RoutePresentationConnectionPtr presentation_connections, - const base::Optional<std::string>& error, - RouteRequestResult::ResultCode result) { - EXPECT_TRUE(route); - EXPECT_FALSE(presentation_connections); - EXPECT_FALSE(error); - EXPECT_EQ(RouteRequestResult::ResultCode::OK, result); - } - void ExpectCreateRouteFailure( RouteRequestResult::ResultCode expected_result, const base::Optional<MediaRoute>& route, @@ -195,66 +183,6 @@ RouteRequestResult::ResultCode::NO_SUPPORTED_PROVIDER)); } -TEST_F(CastMediaRouteProviderTest, CreateRouteForStreamingFailsInvalidOrigin) { - MediaSinkInternal sink = CreateCastSink(1); - media_sink_service_.AddOrUpdateSink(sink); - - const auto streaming_source = CastMediaSource::FromAppId(kCastStreamingAppId); - - // origin_ == https://www.youtube.com is not allowed to launch streaming apps. - provider_->CreateRoute( - streaming_source->source_id(), sink.sink().id(), kPresentationId, origin_, - kTabId, kRouteTimeout, /* incognito */ false, - base::BindOnce(&CastMediaRouteProviderTest::ExpectCreateRouteFailure, - base::Unretained(this), - RouteRequestResult::ResultCode::INVALID_ORIGIN)); -} - -TEST_F(CastMediaRouteProviderTest, - CreateRouteForStreamingSucceedsForWhitelistedOrigin) { - MediaSinkInternal sink = CreateCastSink(1); - media_sink_service_.AddOrUpdateSink(sink); - - const auto streaming_source = CastMediaSource::FromMediaSourceId( - base::StrCat({"cast:", kCastStreamingAppId, "?clientId=12345"})); - - EXPECT_CALL(message_handler_, LaunchSession(sink.cast_data().cast_channel_id, - kCastStreamingAppId, - kDefaultLaunchTimeout, _, _, _)); - // Whitelisted origins are allowed to launch streaming apps. - provider_->CreateRoute( - streaming_source->source_id(), sink.sink().id(), kPresentationId, - url::Origin::Create(GURL("https://meet.google.com")), kTabId, - kRouteTimeout, /* incognito */ false, - base::BindOnce( - &CastMediaRouteProviderTest::ExpectCreateRouteSuccessAndSetRoute, - base::Unretained(this))); -} - -TEST_F(CastMediaRouteProviderTest, - CreateRouteForTabMirroringSucceedsForEmptyOrigin) { - MediaSinkInternal sink = CreateCastSink(1); - media_sink_service_.AddOrUpdateSink(sink); - - const auto tab_mirroring_source = - CastMediaSource::FromMediaSource(MediaSource::ForTab(kTabId)); - - EXPECT_CALL(message_handler_, LaunchSession(sink.cast_data().cast_channel_id, - kCastStreamingAppId, - kDefaultLaunchTimeout, _, _, _)); - - // Empty origins, passed by the browser UI, are allowed to initiate tab - // mirroring. - // TODO(crbug.com/1047834): Check a specific origin for browser requested - // mirroring. - provider_->CreateRoute( - tab_mirroring_source->source_id(), sink.sink().id(), kPresentationId, - url::Origin::Create(GURL()), kTabId, kRouteTimeout, /* incognito */ false, - base::BindOnce(&CastMediaRouteProviderTest:: - ExpectCreateRouteSuccessWithoutConnections, - base::Unretained(this))); -} - TEST_F(CastMediaRouteProviderTest, CreateRoute) { MediaSinkInternal sink = CreateCastSink(1); media_sink_service_.AddOrUpdateSink(sink);
diff --git a/chrome/browser/net/chrome_mojo_proxy_resolver_factory.cc b/chrome/browser/net/chrome_mojo_proxy_resolver_factory.cc index 1347508..99dfc41 100644 --- a/chrome/browser/net/chrome_mojo_proxy_resolver_factory.cc +++ b/chrome/browser/net/chrome_mojo_proxy_resolver_factory.cc
@@ -12,6 +12,7 @@ #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" +#include "chrome/browser/service_sandbox_type.h" #include "content/public/common/child_process_host.h" #include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" @@ -24,10 +25,6 @@ #include "services/strings/grit/services_strings.h" #endif -#if defined(OS_WIN) -#include "services/service_manager/sandbox/sandbox_type.h" -#endif - namespace { proxy_resolver::mojom::ProxyResolverFactory* GetProxyResolverFactory() { @@ -47,9 +44,6 @@ remote->BindNewPipeAndPassReceiver(), content::ServiceProcessHost::Options() .WithDisplayName(IDS_PROXY_RESOLVER_DISPLAY_NAME) -#if defined(OS_WIN) - .WithSandboxType(service_manager::SandboxType::kProxyResolver) -#endif .Pass()); // The service will report itself idle once there are no more bound
diff --git a/chrome/browser/offline_pages/android/BUILD.gn b/chrome/browser/offline_pages/android/BUILD.gn index a5b1a67f..f455eb6 100644 --- a/chrome/browser/offline_pages/android/BUILD.gn +++ b/chrome/browser/offline_pages/android/BUILD.gn
@@ -8,6 +8,7 @@ sources = [ "java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchConfiguration.java" ] deps = [ + "//base:jni_java", "//chrome/browser/flags:java", "//chrome/browser/profiles/android:java", ]
diff --git a/chrome/browser/optimization_guide/android/BUILD.gn b/chrome/browser/optimization_guide/android/BUILD.gn index 2fecfe28..ff706ea 100644 --- a/chrome/browser/optimization_guide/android/BUILD.gn +++ b/chrome/browser/optimization_guide/android/BUILD.gn
@@ -60,6 +60,8 @@ "//base:base_java_test_support", "//base:base_junit_test_support", "//chrome/android:chrome_test_util_java", + "//components/optimization_guide/proto:optimization_guide_proto_java", + "//content/public/android:content_java", "//third_party/junit", "//third_party/mockito:mockito_java", ]
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index 906653c..55dea91 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -345,9 +345,6 @@ { key::kSendFilesForMalwareCheck, prefs::kSafeBrowsingSendFilesForMalwareCheck, base::Value::Type::INTEGER }, - { key::kUseLegacyFormControls, - prefs::kUseLegacyFormControls, - base::Value::Type::BOOLEAN }, { key::kAmbientAuthenticationInPrivateModesEnabled, prefs::kAmbientAuthenticationInPrivateModesEnabled, base::Value::Type::INTEGER },
diff --git a/chrome/browser/preferences/BUILD.gn b/chrome/browser/preferences/BUILD.gn index 5491897..1a48601 100644 --- a/chrome/browser/preferences/BUILD.gn +++ b/chrome/browser/preferences/BUILD.gn
@@ -51,5 +51,7 @@ "//base:base_java_test_support", "//base:base_junit_test_support", "//base/test:test_support_java", + "//third_party/junit:junit", + "//third_party/mockito:mockito_java", ] }
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java index 92b6afd7..7096280 100644 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
@@ -529,6 +529,13 @@ public static final String SEARCH_ENGINE_CHOICE_REQUESTED_TIMESTAMP = "search_engine_choice_requested_timestamp"; + public static final String SEARCH_WIDGET_IS_VOICE_SEARCH_AVAILABLE = + "org.chromium.chrome.browser.searchwidget.IS_VOICE_SEARCH_AVAILABLE"; + public static final String SEARCH_WIDGET_NUM_CONSECUTIVE_CRASHES = + "org.chromium.chrome.browser.searchwidget.NUM_CONSECUTIVE_CRASHES"; + public static final String SEARCH_WIDGET_SEARCH_ENGINE_SHORTNAME = + "org.chromium.chrome.browser.searchwidget.SEARCH_ENGINE_SHORTNAME"; + // Tracks which GUIDs there is an active notification for. public static final String SEND_TAB_TO_SELF_ACTIVE_NOTIFICATIONS = "send_tab_to_self.notification.active";
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/GrandfatheredChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/GrandfatheredChromePreferenceKeys.java index ca5196f6..8c7d547f 100644 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/GrandfatheredChromePreferenceKeys.java +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/GrandfatheredChromePreferenceKeys.java
@@ -145,6 +145,9 @@ ChromePreferenceKeys.SEARCH_ENGINE_CHOICE_DEFAULT_TYPE_BEFORE, ChromePreferenceKeys.SEARCH_ENGINE_CHOICE_PRESENTED_VERSION, ChromePreferenceKeys.SEARCH_ENGINE_CHOICE_REQUESTED_TIMESTAMP, + ChromePreferenceKeys.SEARCH_WIDGET_IS_VOICE_SEARCH_AVAILABLE, + ChromePreferenceKeys.SEARCH_WIDGET_NUM_CONSECUTIVE_CRASHES, + ChromePreferenceKeys.SEARCH_WIDGET_SEARCH_ENGINE_SHORTNAME, ChromePreferenceKeys.SEND_TAB_TO_SELF_ACTIVE_NOTIFICATIONS, ChromePreferenceKeys.SEND_TAB_TO_SELF_NEXT_NOTIFICATION_ID, ChromePreferenceKeys.SETTINGS_DEVELOPER_ENABLED,
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index bf68b12..95485d7 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -89,7 +89,6 @@ #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/browser/webauthn/chrome_authenticator_request_delegate.h" #include "chrome/common/buildflags.h" -#include "chrome/common/chrome_ui_features_prefs.h" #include "chrome/common/pref_names.h" #include "chrome/common/secure_origin_whitelist.h" #include "components/autofill/core/common/autofill_prefs.h" @@ -840,7 +839,6 @@ chrome_browser_net::NetErrorTabHelper::RegisterProfilePrefs(registry); chrome_browser_net::RegisterPredictionOptionsProfilePrefs(registry); chrome_prefs::RegisterProfilePrefs(registry); - chrome_ui_features_prefs::RegisterProfilePrefs(registry); DocumentProvider::RegisterProfilePrefs(registry); dom_distiller::DistilledPagePrefs::RegisterProfilePrefs(registry); dom_distiller::RegisterProfilePrefs(registry);
diff --git a/chrome/browser/printing/print_preview_message_handler.cc b/chrome/browser/printing/print_preview_message_handler.cc index a32714a..c38a1cf 100644 --- a/chrome/browser/printing/print_preview_message_handler.cc +++ b/chrome/browser/printing/print_preview_message_handler.cc
@@ -23,6 +23,7 @@ #include "chrome/browser/printing/printer_query.h" #include "chrome/browser/ui/webui/print_preview/print_preview_ui.h" #include "components/printing/browser/print_composite_client.h" +#include "components/printing/common/print.mojom.h" #include "components/printing/common/print_messages.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -104,7 +105,7 @@ } void PrintPreviewMessageHandler::OnDidStartPreview( - const PrintHostMsg_DidStartPreview_Params& params, + const mojom::DidStartPreviewParams& params, const PrintHostMsg_PreviewIds& ids) { if (params.page_count <= 0 || params.pages_to_render.empty()) { NOTREACHED();
diff --git a/chrome/browser/printing/print_preview_message_handler.h b/chrome/browser/printing/print_preview_message_handler.h index 6d8b0a3..3e8629e 100644 --- a/chrome/browser/printing/print_preview_message_handler.h +++ b/chrome/browser/printing/print_preview_message_handler.h
@@ -9,13 +9,13 @@ #include "base/memory/read_only_shared_memory_region.h" #include "base/memory/weak_ptr.h" #include "chrome/services/printing/public/mojom/pdf_nup_converter.mojom.h" +#include "components/printing/common/print.mojom-forward.h" #include "components/services/print_compositor/public/mojom/print_compositor.mojom.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" struct PrintHostMsg_DidPreviewDocument_Params; struct PrintHostMsg_DidPreviewPage_Params; -struct PrintHostMsg_DidStartPreview_Params; struct PrintHostMsg_PreviewIds; struct PrintHostMsg_RequestPrintPreview_Params; @@ -69,7 +69,7 @@ const gfx::Rect& printable_area_in_points, bool has_custom_page_size_style, const PrintHostMsg_PreviewIds& ids); - void OnDidStartPreview(const PrintHostMsg_DidStartPreview_Params& params, + void OnDidStartPreview(const mojom::DidStartPreviewParams& params, const PrintHostMsg_PreviewIds& ids); void OnDidPreviewPage(content::RenderFrameHost* render_frame_host, const PrintHostMsg_DidPreviewPage_Params& params,
diff --git a/chrome/browser/printing/print_preview_pdf_generated_browsertest.cc b/chrome/browser/printing/print_preview_pdf_generated_browsertest.cc index 84ff527..a5ac123 100644 --- a/chrome/browser/printing/print_preview_pdf_generated_browsertest.cc +++ b/chrome/browser/printing/print_preview_pdf_generated_browsertest.cc
@@ -39,6 +39,7 @@ #include "chrome/common/chrome_paths.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/printing/common/print.mojom.h" #include "components/printing/common/print_messages.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui_message_handler.h" @@ -269,7 +270,7 @@ // Called when the observer gets the IPC message with the preview document's // properties. - void OnDidStartPreview(const PrintHostMsg_DidStartPreview_Params& params, + void OnDidStartPreview(const mojom::DidStartPreviewParams& params, const PrintHostMsg_PreviewIds& ids) { WebContents* web_contents = GetDialog(); ASSERT_TRUE(web_contents);
diff --git a/chrome/browser/printing/printing_service.cc b/chrome/browser/printing/printing_service.cc index 1c9e085..2b73b110 100644 --- a/chrome/browser/printing/printing_service.cc +++ b/chrome/browser/printing/printing_service.cc
@@ -5,7 +5,7 @@ #include "chrome/browser/printing/printing_service.h" #include "base/no_destructor.h" -#include "build/build_config.h" +#include "chrome/browser/service_sandbox_type.h" #include "chrome/grit/generated_resources.h" #include "content/public/browser/service_process_host.h" @@ -17,9 +17,6 @@ remote->BindNewPipeAndPassReceiver(), content::ServiceProcessHost::Options() .WithDisplayName(IDS_UTILITY_PROCESS_PRINTING_SERVICE_NAME) -#if defined(OS_WIN) - .WithSandboxType(service_manager::SandboxType::kPdfConversion) -#endif .Pass()); // Ensure that if the interface is ever disconnected (e.g. the service
diff --git a/chrome/browser/renderer_context_menu/quick_answers_menu_observer.cc b/chrome/browser/renderer_context_menu/quick_answers_menu_observer.cc index c34333ab2..90a657c 100644 --- a/chrome/browser/renderer_context_menu/quick_answers_menu_observer.cc +++ b/chrome/browser/renderer_context_menu/quick_answers_menu_observer.cc
@@ -133,7 +133,7 @@ if (!IsRichUiEnabled()) return; - if (!is_eligible_ || !quick_answers_controller_) + if (!quick_answers_controller_) return; if (params.input_field_type == @@ -157,7 +157,7 @@ if (!IsRichUiEnabled()) return; - if (!is_eligible_ || !quick_answers_controller_) + if (!quick_answers_controller_) return; quick_answers_controller_->DismissQuickAnswers(!is_other_command_executed_);
diff --git a/chrome/browser/resources/chromeos/edu_login/BUILD.gn b/chrome/browser/resources/chromeos/edu_login/BUILD.gn index 7f88acd..1370a3a 100644 --- a/chrome/browser/resources/chromeos/edu_login/BUILD.gn +++ b/chrome/browser/resources/chromeos/edu_login/BUILD.gn
@@ -22,7 +22,6 @@ ":edu_login_signin", ":edu_login_template", ":edu_login_util", - ":edu_login_welcome", ] } @@ -33,7 +32,6 @@ ":edu_login_parents", ":edu_login_signin", ":edu_login_util", - ":edu_login_welcome", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements/cr_view_manager:cr_view_manager.m", "//ui/webui/resources/js:assert.m", @@ -145,12 +143,6 @@ html_type = "v3-ready" } -polymer_modulizer("edu_login_welcome") { - js_file = "edu_login_welcome.js" - html_file = "edu_login_welcome.html" - html_type = "v3-ready" -} - polymer_modulizer("edu_login_parents") { js_file = "edu_login_parents.js" html_file = "edu_login_parents.html" @@ -185,7 +177,6 @@ ":edu_login_parents_module", ":edu_login_signin_module", ":edu_login_template_module", - ":edu_login_welcome_module", ":icons_module", ] }
diff --git a/chrome/browser/resources/chromeos/edu_login/app.html b/chrome/browser/resources/chromeos/edu_login/app.html index b55c819..1a7547d 100644 --- a/chrome/browser/resources/chromeos/edu_login/app.html +++ b/chrome/browser/resources/chromeos/edu_login/app.html
@@ -1,6 +1,4 @@ <cr-view-manager id="viewManager"> - <edu-login-welcome id="[[Steps.WELCOME]]" slot="view"> - </edu-login-welcome> <edu-login-parents id="[[Steps.PARENTS]]" slot="view" selected-parent="{{selectedParent_}}"> </edu-login-parents>
diff --git a/chrome/browser/resources/chromeos/edu_login/app.js b/chrome/browser/resources/chromeos/edu_login/app.js index 7be7137..9955dc74 100644 --- a/chrome/browser/resources/chromeos/edu_login/app.js +++ b/chrome/browser/resources/chromeos/edu_login/app.js
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import './edu_login_welcome.js'; import './edu_login_parents.js'; import './edu_login_parent_signin.js'; import './edu_login_parent_info.js'; @@ -15,7 +14,6 @@ /** @enum {string} */ const Steps = { - WELCOME: 'welcome', PARENTS: 'parents', PARENT_SIGNIN: 'parent-signin', PARENT_INFO: 'parent-info',
diff --git a/chrome/browser/resources/chromeos/edu_login/edu_login_parents.html b/chrome/browser/resources/chromeos/edu_login/edu_login_parents.html index 718f869f..1a573a4 100644 --- a/chrome/browser/resources/chromeos/edu_login/edu_login_parents.html +++ b/chrome/browser/resources/chromeos/edu_login/edu_login_parents.html
@@ -7,6 +7,10 @@ transition: background 200ms; } + .main-padding { + margin-bottom: 16px; + } + .main-padding.account-list-item { padding-bottom: 0; padding-top: 0; @@ -31,20 +35,20 @@ width: var(--profile-icon-size); } - #parentsListBody { - margin-bottom: 16px; - } </style> <edu-login-template> <span slot="main"> <div class="main-padding"> <if expr="_google_chrome"> - <img class="google-full-logo" - src="chrome://theme/IDR_LOGO_GOOGLE_COLOR_90" alt=""> + <img class="google-logo" + src="chrome://chrome-signin/googleg.svg" alt=""> </if> - <h1>$i18n{parentsListTitle}</h1> - <p id="parentsListBody" class="secondary">$i18n{parentsListBody}</p> + <h1>[[getTitle_()]]</h1> + <p id="reauth-message" hidden="[[!reauthFlow_]]"> + [[getReauthMessage_()]] + </p> + <p>[[getBody_()]]</p> </div> <div> <template is="dom-repeat" items="[[parents_]]"> @@ -66,7 +70,6 @@ </div> </span> <span slot="buttons"> - <edu-login-button button-type="back"></edu-login-button> <edu-login-button button-type="next" disabled="[[isNextDisabled_(selectedParent)]]"> </edu-login-button>
diff --git a/chrome/browser/resources/chromeos/edu_login/edu_login_parents.js b/chrome/browser/resources/chromeos/edu_login/edu_login_parents.js index 7bc049a..2d07e85 100644 --- a/chrome/browser/resources/chromeos/edu_login/edu_login_parents.js +++ b/chrome/browser/resources/chromeos/edu_login/edu_login_parents.js
@@ -6,6 +6,7 @@ import './edu_login_template.js'; import './edu_login_button.js'; +import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; import {getImage} from 'chrome://resources/js/icon.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -17,6 +18,8 @@ _template: html`{__html_template__}`, + behaviors: [I18nBehavior], + properties: { /** * Selected parent account for approving EDU login flow. @@ -38,6 +41,27 @@ return []; }, }, + + /** + * Whether current flow is a reauthentication. + * @private {boolean} + */ + reauthFlow_: { + type: Boolean, + value: false, + }, + }, + + /** @override */ + created() { + // For the reauth flow the email is appended to query params in + // InlineLoginHandlerDialogChromeOS. It's used later in auth extension to + // pass the email value to Gaia. + let currentQueryParameters = new URLSearchParams(window.location.search); + if (currentQueryParameters.get('email')) { + this.reauthFlow_ = true; + } + document.title = this.getTitle_(); }, /** @override */ @@ -95,4 +119,28 @@ this.selectedParent = e.model.item; this.fire('go-next'); }, + + /** + * @return {string} + * @private + */ + getTitle_() { + return this.i18n('parentsListTitle'); + }, + + /** + * @return {string} + * @private + */ + getBody_() { + return this.i18n('parentsListBody'); + }, + + /** + * @return {string} + * @private + */ + getReauthMessage_() { + return this.i18n('reauthBody'); + } });
diff --git a/chrome/browser/resources/chromeos/edu_login/edu_login_welcome.html b/chrome/browser/resources/chromeos/edu_login/edu_login_welcome.html deleted file mode 100644 index f6a36e0..0000000 --- a/chrome/browser/resources/chromeos/edu_login/edu_login_welcome.html +++ /dev/null
@@ -1,39 +0,0 @@ -<style include="edu-login-css"> - .main-padding { - display: flex; - flex-direction: column; - height: calc(100% - 90px); - } - - .image-container { - align-items: center; - display: flex; - flex-grow: 1; - justify-content: center; - width: 100%; - } - - .welcome-image { - height: 256px; - width: 256px; - } -</style> -<edu-login-template> - <span slot="main"> - <div class="main-padding"> - <if expr="_google_chrome"> - <img class="google-logo" - src="chrome://chrome-signin/googleg.svg" alt=""> - </if> - <h1>[[getTitle_()]]</h1> - <p>[[getBody_()]]</p> - <div class="image-container"> - <img class="welcome-image" src="family_link_logo.svg" alt=""> - </div> - </div> - </span> - <span slot="buttons"> - <edu-login-button button-type="ok"> - </edu-login-button> - </span> -</edu-login-template>
diff --git a/chrome/browser/resources/chromeos/edu_login/edu_login_welcome.js b/chrome/browser/resources/chromeos/edu_login/edu_login_welcome.js deleted file mode 100644 index ab4b295f..0000000 --- a/chrome/browser/resources/chromeos/edu_login/edu_login_welcome.js +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import './edu_login_css.js'; -import './edu_login_template.js'; -import './edu_login_button.js'; - -import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; -import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; - -Polymer({ - is: 'edu-login-welcome', - - _template: html`{__html_template__}`, - - behaviors: [I18nBehavior], - - /** - * Whether current flow is a reauthentication. - * @private {boolean} - */ - reauthFlow_: false, - - /** @override */ - created() { - // For the reauth flow the email is appended to query params in - // InlineLoginHandlerDialogChromeOS. It's used later in auth extension to - // pass the email value to Gaia. - let currentQueryParameters = new URLSearchParams(window.location.search); - if (currentQueryParameters.get('email')) { - this.reauthFlow_ = true; - } - document.title = this.getTitle_(); - }, - - /** - * @return {string} - * @private - */ - getTitle_() { - return this.reauthFlow_ ? this.i18n('welcomeReauthTitle') : - this.i18n('welcomeTitle'); - }, - - /** - * @return {string} - * @private - */ - getBody_() { - return this.reauthFlow_ ? this.i18n('welcomeReauthBody') : - this.i18n('welcomeBody'); - }, -});
diff --git a/chrome/browser/resources/chromeos/login/arc_terms_of_service.css b/chrome/browser/resources/chromeos/login/arc_terms_of_service.css index 16f92fc..59378b07 100644 --- a/chrome/browser/resources/chromeos/login/arc_terms_of_service.css +++ b/chrome/browser/resources/chromeos/login/arc_terms_of_service.css
@@ -14,6 +14,10 @@ padding: 0; } +cr-checkbox { + --cr-checkbox-label-padding-start: 16px; +} + .arc-tos-loaded .arc-tos-loading, .arc-tos-loaded .arc-tos-error, .arc-tos-loaded #arcTosRetryButton,
diff --git a/chrome/browser/resources/chromeos/login/arc_terms_of_service.html b/chrome/browser/resources/chromeos/login/arc_terms_of_service.html index 1dd60dbb..39011805 100644 --- a/chrome/browser/resources/chromeos/login/arc_terms_of_service.html +++ b/chrome/browser/resources/chromeos/login/arc_terms_of_service.html
@@ -45,6 +45,7 @@ disabled="[[backupRestoreManaged]]" hidden="[[demoMode]]"> <cr-checkbox id="arcEnableBackupRestore" + class="layout start" checked="{{backupRestore}}" disabled="[[backupRestoreManaged]]"> <p> @@ -62,6 +63,7 @@ disabled="[[locationServiceManaged]]" hidden="[[demoMode]]"> <cr-checkbox id="arcEnableLocationService" + class="layout start" checked="{{locationService}}" disabled="[[locationServiceManaged]]"> <p> @@ -90,6 +92,7 @@ class="parameter-section arc-tos-content" hidden="[[demoMode]]"> <cr-checkbox id="arcReviewSettingsCheckbox" + class="layout start" checked="{{reviewSettings}}"> <p>[[i18nDynamic(locale, 'arcTextReviewSettings')]]</p> </cr-checkbox>
diff --git a/chrome/browser/resources/chromeos/login/oobe_eula.css b/chrome/browser/resources/chromeos/login/oobe_eula.css index c52e0dc..b00432f 100644 --- a/chrome/browser/resources/chromeos/login/oobe_eula.css +++ b/chrome/browser/resources/chromeos/login/oobe_eula.css
@@ -37,14 +37,13 @@ color: rgba(0, 0, 0, 0.54); } -cr-toggle { - align-self: center; +cr-checkbox { + --cr-checkbox-label-padding-start: 16px; } #usageStatsLabelContainer { color: var(--google-grey-refresh-700); /* #5F6368 */ line-height: 20px; - margin-inline-start: 16px; } #usageStatsLabel {
diff --git a/chrome/browser/resources/chromeos/login/oobe_eula.html b/chrome/browser/resources/chromeos/login/oobe_eula.html index 4b929d44..3bfe19f 100644 --- a/chrome/browser/resources/chromeos/login/oobe_eula.html +++ b/chrome/browser/resources/chromeos/login/oobe_eula.html
@@ -4,7 +4,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_checkbox/cr_checkbox.html"> <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> <dom-module id="oobe-eula-md"> @@ -46,18 +46,20 @@ [[i18nDynamic(locale, 'eulaSystemInstallationSettings')]] </a> <div id="logging" class="layout horizontal"> - <cr-toggle id="usageStats" checked="{{usageStatsChecked}}" - on-change="onUsageChanged_" aria-labelledby="usageStatsLabel"> - </cr-toggle> - <div id="usageStatsLabelContainer"> - <span id="usageStatsLabel" on-tap="usageStatsLabelClicked_"> - [[i18nDynamic(locale, 'checkboxLogging')]] - </span> - <a id="learn-more" href="#" on-tap="onUsageStatsHelpLinkClicked_" - class="oobe-local-link"> - [[i18nDynamic(locale, 'learnMore')]] - </a> - </div> + <cr-checkbox id="usageStats" class="layout start self-center" + checked="{{usageStatsChecked}}" on-change="onUsageChanged_" + aria-labelledby="usageStatsLabel"> + <div id="usageStatsLabelContainer"> + <span id="usageStatsLabel" on-tap="usageStatsLabelClicked_"> + [[i18nDynamic(locale, 'checkboxLogging')]] + </span> + <a id="learn-more" href="#" + on-tap="onUsageStatsHelpLinkClicked_" + class="oobe-local-link"> + [[i18nDynamic(locale, 'learnMore')]] + </a> + </div> + </cr-checkbox> </div> </div> </div>
diff --git a/chrome/browser/resources/new_tab_page/app.js b/chrome/browser/resources/new_tab_page/app.js index 74dbea61..d1086c2c 100644 --- a/chrome/browser/resources/new_tab_page/app.js +++ b/chrome/browser/resources/new_tab_page/app.js
@@ -608,10 +608,11 @@ overlayRects.forEach(({x, y, width, height}) => { const rectElement = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); - rectElement.setAttribute('x', x); - rectElement.setAttribute('y', y); - rectElement.setAttribute('width', width); - rectElement.setAttribute('height', height); + // Add 8px around every rect to ensure shadows are not cutoff. + rectElement.setAttribute('x', x - 8); + rectElement.setAttribute('y', y - 8); + rectElement.setAttribute('width', width + 16); + rectElement.setAttribute('height', height + 16); this.$.oneGoogleBarClipPath.appendChild(rectElement); }); }
diff --git a/chrome/browser/resources/print_preview/ui/link_container.html b/chrome/browser/resources/print_preview/ui/link_container.html index 6ada90e..9c483864 100644 --- a/chrome/browser/resources/print_preview/ui/link_container.html +++ b/chrome/browser/resources/print_preview/ui/link_container.html
@@ -42,7 +42,7 @@ } .link:not([actionable]) .label { - @apply --print-preview-disabled-label; + opacity: var(--cr-disabled-opacity); } </style> <div class="link" id="systemDialogLink"
diff --git a/chrome/browser/resources/print_preview/ui/more_settings.html b/chrome/browser/resources/print_preview/ui/more_settings.html index d63ce664..13c6d2c 100644 --- a/chrome/browser/resources/print_preview/ui/more_settings.html +++ b/chrome/browser/resources/print_preview/ui/more_settings.html
@@ -33,7 +33,7 @@ } :host([disabled]) #label { - @apply --print-preview-disabled-label; + opacity: var(--cr-disabled-opacity); } </style> <div on-click="toggleExpandButton_" actionable>
diff --git a/chrome/browser/resources/print_preview/ui/print_preview_vars_css.html b/chrome/browser/resources/print_preview/ui/print_preview_vars_css.html index d476823e..2208774 100644 --- a/chrome/browser/resources/print_preview/ui/print_preview_vars_css.html +++ b/chrome/browser/resources/print_preview/ui/print_preview_vars_css.html
@@ -8,10 +8,6 @@ --print-preview-settings-border: 1px solid var(--google-grey-200); --print-preview-dialog-margin: 34px; - --print-preview-disabled-label: { - color: var(--paper-grey-600); - opacity: .65; - } --cr-form-field-label-height: initial; --cr-form-field-label-line-height: .75rem; --destination-item-height: 32px;
diff --git a/chrome/browser/resources/settings/autofill_page/password_edit_dialog.html b/chrome/browser/resources/settings/autofill_page/password_edit_dialog.html index 0e06b580..ada16c2a 100644 --- a/chrome/browser/resources/settings/autofill_page/password_edit_dialog.html +++ b/chrome/browser/resources/settings/autofill_page/password_edit_dialog.html
@@ -20,6 +20,11 @@ justify-content: initial; } + #storageDetails { + margin-inline-start: 2px; + margin-bottom: 16px; + } + cr-icon-button { --cr-icon-button-icon-size: 24px; margin-inline-start: 2px; @@ -28,6 +33,8 @@ <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">$i18n{passwordDetailsTitle}</div> <div slot="body"> + <div hidden="[[!shouldShowStorageDetails]]" id="storageDetails" + inner-h-t-m-l="[[getStorageDetailsMessage_()]]"></div> <cr-input id="websiteInput" label="$i18n{editPasswordWebsiteLabel}" value="[[item.entry.urls.link]]" on-blur="onInputBlur_" readonly> </cr-input>
diff --git a/chrome/browser/resources/settings/autofill_page/password_edit_dialog.js b/chrome/browser/resources/settings/autofill_page/password_edit_dialog.js index e41e1e9..e636d9c7 100644 --- a/chrome/browser/resources/settings/autofill_page/password_edit_dialog.js +++ b/chrome/browser/resources/settings/autofill_page/password_edit_dialog.js
@@ -17,6 +17,7 @@ import '../settings_shared_css.m.js'; import '../settings_vars_css.m.js'; import './passwords_shared_css.js'; +import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -28,7 +29,11 @@ _template: html`{__html_template__}`, - behaviors: [ShowPasswordBehavior], + behaviors: [ShowPasswordBehavior, I18nBehavior], + + properties: { + shouldShowStorageDetails: {type: Boolean, value: false}, + }, /** @override */ attached() { @@ -52,4 +57,16 @@ onInputBlur_() { this.shadowRoot.getSelection().removeAllRanges(); }, + + /** + * Gets the HTML-formatted message to indicate in which locations the password + * is stored. + */ + getStorageDetailsMessage_() { + // TODO(crbug.com/1049141): Add support and tests for the multi-store case + // when dedup is being done. + return this.item.entry.isPresentInAccount() ? + this.i18nAdvanced('passwordStoredInAccount', {tags: ['b']}) : + this.i18nAdvanced('passwordStoredOnDevice', {tags: ['b']}); + } });
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_section.html b/chrome/browser/resources/settings/autofill_page/passwords_section.html index 8c16900..a23be0e 100644 --- a/chrome/browser/resources/settings/autofill_page/passwords_section.html +++ b/chrome/browser/resources/settings/autofill_page/passwords_section.html
@@ -217,10 +217,13 @@ </template> <template is="dom-if" if="[[showPasswordEditDialog_]]" restamp> <password-edit-dialog on-close="onPasswordEditDialogClosed_" + id="passwordEditDialog" <if expr="chromeos"> token-request-manager="[[tokenRequestManager_]]" </if> - item="[[activePassword.item]]"> + item="[[activePassword.item]]" + should-show-storage-details= + "[[shouldShowStorageDetailsInEditDialog_]]"> </password-edit-dialog> </template> <if expr="chromeos">
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_section.js b/chrome/browser/resources/settings/autofill_page/passwords_section.js index 0c9721b0..d607a889 100644 --- a/chrome/browser/resources/settings/autofill_page/passwords_section.js +++ b/chrome/browser/resources/settings/autofill_page/passwords_section.js
@@ -186,6 +186,13 @@ 'signedIn_, hasNeverCheckedPasswords_, hasStoredPasswords_)', }, + shouldShowStorageDetailsInEditDialog_: { + type: Boolean, + value: false, + computed: 'computeShouldShowStorageDetailsInEditDialog_('+ + 'eligibleForAccountStorage_, isOptedInForAccountStorage_)', + }, + /** @private */ hasLeakedCredentials_: { type: Boolean, @@ -501,6 +508,14 @@ * @return {boolean} * @private */ + computeShouldShowStorageDetailsInEditDialog_() { + return this.eligibleForAccountStorage_ && this.isOptedInForAccountStorage_; + }, + + /** + * @return {boolean} + * @private + */ computeHidePasswordsLink_() { return !!this.syncStatus_ && !!this.syncStatus_.signedIn && !!this.syncPrefs_ && !!this.syncPrefs_.encryptAllData;
diff --git a/chrome/browser/resources/settings/chromeos/localized_link/localized_link.js b/chrome/browser/resources/settings/chromeos/localized_link/localized_link.js index 2c8967c..1ae4452 100644 --- a/chrome/browser/resources/settings/chromeos/localized_link/localized_link.js +++ b/chrome/browser/resources/settings/chromeos/localized_link/localized_link.js
@@ -73,6 +73,7 @@ ariaLabelledByIds.push(node.id); return; } + // Only text and <a> nodes are allowed. assertNotReached('settings-localized-link has invalid node types'); });
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html b/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html index 2c3ef2f2..58f176e 100644 --- a/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html +++ b/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html
@@ -54,6 +54,15 @@ align-items: flex-end; } + #account-description { + align-items: flex-start; + flex-direction: column; + } + + #account-description > p { + margin-bottom: 0; + } + #account-list-header > h2 { padding-bottom: 12px; padding-top: 12px; @@ -111,12 +120,16 @@ } </style> - <div class="settings-box first"> + <div id="account-description" class="settings-box first"> <settings-localized-link class="account-manager-description" localized-string="[[getAccountManagerDescription_()]]" link-url="$i18nRaw{accountManagerLearnMoreUrl}"> </settings-localized-link> + <template is="dom-if" if="[[isChildUser_]]"> + <p>$i18n{accountManagerChildFirstMessage}</p> + <p>$i18n{accountManagerChildSecondMessage}</p> + </template> </div> <div id="settings-box-user-message" class="settings-box first user-message"
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_search_box/os_search_result_row.html b/chrome/browser/resources/settings/chromeos/os_settings_search_box/os_search_result_row.html index b141b273f..7968cfe 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_search_box/os_search_result_row.html +++ b/chrome/browser/resources/settings/chromeos/os_settings_search_box/os_search_result_row.html
@@ -26,6 +26,10 @@ background-color: var(--cros-menu-button-bg-color-hover); } + :host-context([dir=rtl]) #actionTypeIcon { + transform: scaleX(-1); /* Invert X: flip on the Y axis (aka mirror). */ + } + [focus-row-container] { width: inherit; }
diff --git a/chrome/browser/resources/tab_strip/tab.js b/chrome/browser/resources/tab_strip/tab.js index db8fee45..32a2baba 100644 --- a/chrome/browser/resources/tab_strip/tab.js +++ b/chrome/browser/resources/tab_strip/tab.js
@@ -11,7 +11,7 @@ import {AlertIndicatorsElement} from './alert_indicators.js'; import {CustomElement} from './custom_element.js'; -import {TabStripEmbedderProxy} from './tab_strip_embedder_proxy.js'; +import {TabStripEmbedderProxy, TabStripEmbedderProxyImpl} from './tab_strip_embedder_proxy.js'; import {tabStripOptions} from './tab_strip_options.js'; import {TabSwiper} from './tab_swiper.js'; import {CloseTabAction, TabData, TabNetworkState, TabsApiProxy, TabsApiProxyImpl} from './tabs_api_proxy.js'; @@ -87,7 +87,7 @@ this.tabsApi_ = TabsApiProxyImpl.getInstance(); /** @private {!TabStripEmbedderProxy} */ - this.embedderApi_ = TabStripEmbedderProxy.getInstance(); + this.embedderApi_ = TabStripEmbedderProxyImpl.getInstance(); /** @private {!HTMLElement} */ this.titleTextEl_ = /** @type {!HTMLElement} */ (this.$('#titleText'));
diff --git a/chrome/browser/resources/tab_strip/tab_group.js b/chrome/browser/resources/tab_strip/tab_group.js index e50abdb..46d6da5 100644 --- a/chrome/browser/resources/tab_strip/tab_group.js +++ b/chrome/browser/resources/tab_strip/tab_group.js
@@ -5,7 +5,7 @@ import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {CustomElement} from './custom_element.js'; -import {TabStripEmbedderProxy} from './tab_strip_embedder_proxy.js'; +import {TabStripEmbedderProxy, TabStripEmbedderProxyImpl} from './tab_strip_embedder_proxy.js'; import {TabGroupVisualData} from './tabs_api_proxy.js'; export class TabGroupElement extends CustomElement { @@ -17,7 +17,7 @@ super(); /** @private @const {!TabStripEmbedderProxy} */ - this.embedderApi_ = TabStripEmbedderProxy.getInstance(); + this.embedderApi_ = TabStripEmbedderProxyImpl.getInstance(); /** @private @const {!HTMLElement} */ this.chip_ = /** @type {!HTMLElement} */ (this.$('#chip'));
diff --git a/chrome/browser/resources/tab_strip/tab_list.js b/chrome/browser/resources/tab_strip/tab_list.js index dd587ef..3417d6b 100644 --- a/chrome/browser/resources/tab_strip/tab_list.js +++ b/chrome/browser/resources/tab_strip/tab_list.js
@@ -17,7 +17,7 @@ import {DragManager, DragManagerDelegate} from './drag_manager.js'; import {TabElement} from './tab.js'; import {isTabGroupElement, TabGroupElement} from './tab_group.js'; -import {TabStripEmbedderProxy} from './tab_strip_embedder_proxy.js'; +import {TabStripEmbedderProxy, TabStripEmbedderProxyImpl} from './tab_strip_embedder_proxy.js'; import {tabStripOptions} from './tab_strip_options.js'; import {TabData, TabGroupVisualData, TabsApiProxy, TabsApiProxyImpl} from './tabs_api_proxy.js'; @@ -122,7 +122,7 @@ this.pinnedTabsElement_ = /** @type {!Element} */ (this.$('#pinnedTabs')); /** @private {!TabStripEmbedderProxy} */ - this.tabStripEmbedderProxy_ = TabStripEmbedderProxy.getInstance(); + this.tabStripEmbedderProxy_ = TabStripEmbedderProxyImpl.getInstance(); /** @private {!TabsApiProxy} */ this.tabsApi_ = TabsApiProxyImpl.getInstance();
diff --git a/chrome/browser/resources/tab_strip/tab_strip_embedder_proxy.js b/chrome/browser/resources/tab_strip/tab_strip_embedder_proxy.js index 898858e..3bfcc59f 100644 --- a/chrome/browser/resources/tab_strip/tab_strip_embedder_proxy.js +++ b/chrome/browser/resources/tab_strip/tab_strip_embedder_proxy.js
@@ -4,31 +4,24 @@ import {addSingletonGetter, addWebUIListener, sendWithPromise} from 'chrome://resources/js/cr.m.js'; +/** @interface */ export class TabStripEmbedderProxy { /** @return {boolean} */ - isVisible() { - return document.visibilityState === 'visible'; - } + isVisible() {} /** * @return {!Promise<!Object<string, string>>} Object with CSS variables * as keys and rgba strings as values */ - getColors() { - return sendWithPromise('getThemeColors'); - } + getColors() {} /** * @return {!Promise<!Object<string, string>>} Object with CSS variables * as keys and pixel lengths as values */ - getLayout() { - return sendWithPromise('getLayout'); - } + getLayout() {} - observeThemeChanges() { - chrome.send('observeThemeChanges'); - } + observeThemeChanges() {} /** * @param {string} groupId @@ -37,53 +30,97 @@ * @param {number} width * @param {number} height */ - showEditDialogForGroup(groupId, locationX, locationY, width, height) { - chrome.send( - 'showEditDialogForGroup', - [groupId, locationX, locationY, width, height]); - } + showEditDialogForGroup(groupId, locationX, locationY, width, height) {} /** * @param {number} tabId * @param {number} locationX * @param {number} locationY */ - showTabContextMenu(tabId, locationX, locationY) { - chrome.send('showTabContextMenu', [tabId, locationX, locationY]); - } + showTabContextMenu(tabId, locationX, locationY) {} /** * @param {number} locationX * @param {number} locationY */ - showBackgroundContextMenu(locationX, locationY) { - chrome.send('showBackgroundContextMenu', [locationX, locationY]); - } + showBackgroundContextMenu(locationX, locationY) {} - closeContainer() { - chrome.send('closeContainer'); - } + closeContainer() {} /** @param {number} durationMs Activation duration time in ms. */ - reportTabActivationDuration(durationMs) { - chrome.send('reportTabActivationDuration', [durationMs]); - } + reportTabActivationDuration(durationMs) {} /** * @param {number} tabCount Number of tabs. * @param {number} durationMs Activation duration time in ms. */ - reportTabDataReceivedDuration(tabCount, durationMs) { - chrome.send('reportTabDataReceivedDuration', [tabCount, durationMs]); - } + reportTabDataReceivedDuration(tabCount, durationMs) {} /** * @param {number} tabCount Number of tabs. * @param {number} durationMs Creation duration time in ms. */ + reportTabCreationDuration(tabCount, durationMs) {} +} + +/** @implements {TabStripEmbedderProxy} */ +export class TabStripEmbedderProxyImpl { + /** @override */ + isVisible() { + return document.visibilityState === 'visible'; + } + + /** @override */ + getColors() { + return sendWithPromise('getThemeColors'); + } + + /** @override */ + getLayout() { + return sendWithPromise('getLayout'); + } + + /** @override */ + observeThemeChanges() { + chrome.send('observeThemeChanges'); + } + + /** @override */ + showEditDialogForGroup(groupId, locationX, locationY, width, height) { + chrome.send( + 'showEditDialogForGroup', + [groupId, locationX, locationY, width, height]); + } + + /** @override */ + showTabContextMenu(tabId, locationX, locationY) { + chrome.send('showTabContextMenu', [tabId, locationX, locationY]); + } + + /** @override */ + showBackgroundContextMenu(locationX, locationY) { + chrome.send('showBackgroundContextMenu', [locationX, locationY]); + } + + /** @override */ + closeContainer() { + chrome.send('closeContainer'); + } + + /** @override */ + reportTabActivationDuration(durationMs) { + chrome.send('reportTabActivationDuration', [durationMs]); + } + + /** @override */ + reportTabDataReceivedDuration(tabCount, durationMs) { + chrome.send('reportTabDataReceivedDuration', [tabCount, durationMs]); + } + + /** @override */ reportTabCreationDuration(tabCount, durationMs) { chrome.send('reportTabCreationDuration', [tabCount, durationMs]); } } -addSingletonGetter(TabStripEmbedderProxy); +addSingletonGetter(TabStripEmbedderProxyImpl);
diff --git a/chrome/browser/resources/tools/rollup_plugin.js b/chrome/browser/resources/tools/rollup_plugin.js index f9d68b5c..d6c49bf 100644 --- a/chrome/browser/resources/tools/rollup_plugin.js +++ b/chrome/browser/resources/tools/rollup_plugin.js
@@ -15,6 +15,7 @@ const nonGeneratedFiles = [ 'action_link.js', 'certificate_manager_types.js', + 'certificate_provisioning_browser_proxy.js', 'certificates_browser_proxy.js', 'cr.m.js', 'cr_splitter.js',
diff --git a/chrome/browser/service_sandbox_type.h b/chrome/browser/service_sandbox_type.h index 1a662238..0339a195 100644 --- a/chrome/browser/service_sandbox_type.h +++ b/chrome/browser/service_sandbox_type.h
@@ -55,4 +55,32 @@ return content::SandboxType::kNoSandbox; } +// printing::mojom::PrintingService +#if defined(OS_WIN) +namespace printing { +namespace mojom { +class PrintingService; +} +} // namespace printing +template <> +inline content::SandboxType +content::GetServiceSandboxType<printing::mojom::PrintingService>() { + return content::SandboxType::kPdfConversion; +} +#endif // defined(OS_WIN) + +// proxy_resolver::mojom::ProxyResolverFactory +#if defined(OS_WIN) +namespace proxy_resolver { +namespace mojom { +class ProxyResolverFactory; +} +} // namespace proxy_resolver +template <> +inline content::SandboxType +content::GetServiceSandboxType<proxy_resolver::mojom::ProxyResolverFactory>() { + return content::SandboxType::kProxyResolver; +} +#endif // defined(OS_WIN) + #endif // CHROME_BROWSER_SERVICE_SANDBOX_TYPE_H_
diff --git a/chrome/browser/settings/BUILD.gn b/chrome/browser/settings/BUILD.gn index 3de774ae..2522aba8 100644 --- a/chrome/browser/settings/BUILD.gn +++ b/chrome/browser/settings/BUILD.gn
@@ -30,12 +30,14 @@ ":test_support_java", "//chrome/android:chrome_java", "//chrome/test/android:chrome_java_test_support", + "//components/browser_ui/settings/android:java", "//content/public/test/android:content_java_test_support", "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:androidx_preference_preference_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", "//third_party/espresso:espresso_all_java", + "//third_party/guava:guava_android_java", "//third_party/hamcrest:hamcrest_java", "//third_party/junit", ] @@ -47,9 +49,13 @@ sources = [ "android/java/src/org/chromium/chrome/browser/settings/SettingsActivityTestRule.java" ] deps = [ + "//base:base_java", "//chrome/android:chrome_java", + "//chrome/browser/settings:java", "//content/public/test/android:content_java_test_support", "//third_party/android_deps:androidx_preference_preference_java", "//third_party/android_support_test_runner:rules_java", + "//third_party/android_support_test_runner:runner_java", + "//third_party/junit", ] }
diff --git a/chrome/browser/share/DEPS b/chrome/browser/share/DEPS index 05083d6..b67d2d4 100644 --- a/chrome/browser/share/DEPS +++ b/chrome/browser/share/DEPS
@@ -1,18 +1,12 @@ include_rules = [ # TODO(crbug/1022172): Remove this dependency when ShareActivity is moved to # chrome/browser/share. - "+chrome/android/java/src/org/chromium/chrome/browser/share", "+chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java", "+chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java", "+chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java", "+chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java", - "+chrome/android/java/src/org/chromium/chrome/browser/modules/ModuleInstallUi.java", - "+chrome/android/java/src/org/chromium/chrome/browser/screenshot/EditorScreenshotTask.java", - "+chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java", - "+chrome/services/qrcode_generator", - "+content/public/android/java/src/org/chromium/content_public/browser/RenderWidgetHostView.java", - "+content/public/android/java/src/org/chromium/content_public/browser/WebContents.java", "+chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java", + "+chrome/android/java/src/org/chromium/chrome/browser/modules/ModuleInstallUi.java", "+chrome/android/java/src/org/chromium/chrome/browser/notifications/ChromeNotificationBuilder.java", "+chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilderFactory.java", "+chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationConstants.java", @@ -20,6 +14,12 @@ "+chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java", "+chrome/android/java/src/org/chromium/chrome/browser/notifications/PendingIntentProvider.java", "+chrome/android/java/src/org/chromium/chrome/browser/notifications/channels/ChromeChannelDefinitions.java", + "+chrome/android/java/src/org/chromium/chrome/browser/screenshot/EditorScreenshotTask.java", + "+chrome/android/java/src/org/chromium/chrome/browser/share", + "+chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java", + "+chrome/services/qrcode_generator", "+components/browser_ui/notifications/android", "+components/browser_ui/share/android", + "+content/public/android/java/src/org/chromium/content_public/browser/RenderWidgetHostView.java", + "+content/public/android/java/src/org/chromium/content_public/browser/WebContents.java", ]
diff --git a/chrome/browser/share/android/BUILD.gn b/chrome/browser/share/android/BUILD.gn index a2f5d56..abd9483 100644 --- a/chrome/browser/share/android/BUILD.gn +++ b/chrome/browser/share/android/BUILD.gn
@@ -7,12 +7,17 @@ android_resources("java_resources") { sources = [ "java/res/drawable/camera_img.xml", + "java/res/drawable/delete.xml", + "java/res/drawable/edit.xml", "java/res/drawable/qrcode_background.xml", + "java/res/drawable/save.xml", + "java/res/drawable/share.xml", "java/res/layout/qrcode_camera_error_layout.xml", "java/res/layout/qrcode_dialog.xml", "java/res/layout/qrcode_open_settings_layout.xml", "java/res/layout/qrcode_permission_layout.xml", "java/res/layout/qrcode_share_layout.xml", + "java/res/layout/screenshot_share_sheet.xml", "java/res/values-night/colors.xml", "java/res/values-sw600dp/dimens.xml", "java/res/values/colors.xml",
diff --git a/chrome/browser/share/android/java/res/drawable/delete.xml b/chrome/browser/share/android/java/res/drawable/delete.xml new file mode 100644 index 0000000..d9b4434b --- /dev/null +++ b/chrome/browser/share/android/java/res/drawable/delete.xml
@@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2020 The Chromium Authors. All rights reserved. +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. --> + <vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <group> + <clip-path + android:pathData="m15,4v-1h-6v1h-5v2h1v13c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2v-13h1v-2zM17,19h-10v-13h10zM9,8h2v9h-2zM13,8h2v9h-2z"/> + <path + android:pathData="m0,0h24v24h-24z" + android:fillColor="@color/modern_grey_800" + android:fillType="evenOdd"/> + </group> + </vector>
diff --git a/chrome/browser/share/android/java/res/drawable/edit.xml b/chrome/browser/share/android/java/res/drawable/edit.xml new file mode 100644 index 0000000..8d46de29 --- /dev/null +++ b/chrome/browser/share/android/java/res/drawable/edit.xml
@@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2020 The Chromium Authors. All rights reserved. +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. --> + <vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <group> + <clip-path android:pathData="m20.41,4.94 l-1.35,-1.35c-0.78,-0.78 -2.05,-0.78 -2.83,0l-2.83,2.82 -10.4,10.41v4.18h4.18l10.46,-10.46 2.77,-2.77c0.79,-0.78 0.79,-2.05 0,-2.83zM6.41,19.06 L5,19v-1.36l9.82,-9.82 1.41,1.41z"/> + <path + android:fillColor="@color/modern_grey_800" + android:fillType="evenOdd" + android:pathData="m0,0h24v24h-24z"/> + </group> + </vector>
diff --git a/chrome/browser/share/android/java/res/drawable/save.xml b/chrome/browser/share/android/java/res/drawable/save.xml new file mode 100644 index 0000000..d27d366 --- /dev/null +++ b/chrome/browser/share/android/java/res/drawable/save.xml
@@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2020 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <group> + <clip-path + android:pathData="m8.41,9.09 l-1.41,1.41 5,5 5,-5 -1.41,-1.41 -2.59,2.58v-8.67h-2v8.67zM21,19v-14c0,-1.11 -0.9,-2 -2,-2h-4v2h4v14h-14v-14h4v-2h-4c-1.1,0 -2,0.89 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2z"/> + <path + android:pathData="m0,0h24v24h-24z" + android:fillColor="@color/modern_grey_800" + android:fillType="evenOdd"/> + </group> +</vector>
diff --git a/chrome/browser/share/android/java/res/drawable/share.xml b/chrome/browser/share/android/java/res/drawable/share.xml new file mode 100644 index 0000000..aeec4f3f --- /dev/null +++ b/chrome/browser/share/android/java/res/drawable/share.xml
@@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2020 The Chromium Authors. All rights reserved. +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. --> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:pathData="m16.5,15.7333c-0.6333,0 -1.2,0.25 -1.6333,0.6417l-5.9417,-3.4583c0.0417,-0.1917 0.075,-0.3833 0.075,-0.5833s-0.0333,-0.3917 -0.075,-0.5833l5.875,-3.425c0.45,0.4167 1.0417,0.675 1.7,0.675 1.3833,0 2.5,-1.1167 2.5,-2.5s-1.1167,-2.5 -2.5,-2.5 -2.5,1.1167 -2.5,2.5c0,0.2 0.0333,0.3917 0.075,0.5833l-5.875,3.425c-0.45,-0.4167 -1.0417,-0.675 -1.7,-0.675 -1.3833,0 -2.5,1.1167 -2.5,2.5 0,1.3833 1.1167,2.5 2.5,2.5 0.6583,0 1.25,-0.2583 1.7,-0.675l5.9333,3.4667c-0.0417,0.175 -0.0667,0.3583 -0.0667,0.5417 0,1.3417 1.0917,2.4333 2.4333,2.4333s2.4333,-1.0917 2.4333,-2.4333c0,-1.3417 -1.0917,-2.4333 -2.4333,-2.4333z" + android:fillColor="@color/modern_grey_800" + android:fillType="evenOdd"/> +</vector>
diff --git a/chrome/browser/share/android/java/res/layout/screenshot_share_sheet.xml b/chrome/browser/share/android/java/res/layout/screenshot_share_sheet.xml new file mode 100644 index 0000000..bdfd64c --- /dev/null +++ b/chrome/browser/share/android/java/res/layout/screenshot_share_sheet.xml
@@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2020 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> +<org.chromium.chrome.browser.share.screenshot.ScreenshotShareSheetView + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <RelativeLayout + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <org.chromium.ui.widget.ChromeImageButton + android:id="@+id/close_button" + style="@style/ToolbarButton" + android:src="@drawable/btn_close" + android:contentDescription="@string/close" + app:tint="@color/default_icon_color_tint_list" /> + + <!-- TODO: Add a frame layout to hold the screenshot preview. --> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="56dp" + android:layout_marginStart="36dp" + android:layout_marginEnd="36dp" + android:weightSum="4" + android:orientation="horizontal" + android:layout_gravity="start|bottom"> + + <TextView + android:id="@+id/edit" + android:text="@string/screenshot_edit_title" + style="@style/SplitToolbarButton" + android:drawableTop="@drawable/edit" + android:layout_weight="1" + android:gravity="center" + android:layout_gravity="end|bottom" + android:background="?attr/selectableItemBackgroundBorderless" + app:tint="@color/default_icon_color_tint_list" /> + + <TextView + android:id="@+id/delete" + android:text="@string/screenshot_delete_title" + style="@style/SplitToolbarButton" + android:drawableTop="@drawable/delete" + android:layout_weight="1" + android:gravity="center" + android:layout_gravity="center|bottom" + android:background="?attr/selectableItemBackgroundBorderless" + app:tint="@color/default_icon_color_tint_list" /> + + <TextView + android:id="@+id/save" + android:text="@string/screenshot_save_title" + style="@style/SplitToolbarButton" + android:drawableTop="@drawable/save" + android:layout_weight="1" + android:gravity="center" + android:layout_gravity="center|bottom" + android:background="?attr/selectableItemBackgroundBorderless" + app:tint="@color/default_icon_color_tint_list" /> + + <TextView + android:id="@+id/share" + android:text="@string/screenshot_share_title" + style="@style/SplitToolbarButton" + android:drawableTop="@drawable/share" + android:layout_weight="1" + android:gravity="center" + android:layout_gravity="start|bottom" + android:background="?attr/selectableItemBackgroundBorderless" + app:tint="@color/default_icon_color_tint_list" /> + + </LinearLayout> + + + </RelativeLayout> + +</org.chromium.chrome.browser.share.screenshot.ScreenshotShareSheetView>
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotCoordinator.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotCoordinator.java index 16d0efd..1511fb9 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotCoordinator.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotCoordinator.java
@@ -78,15 +78,17 @@ * Opens the screenshot sharesheet. */ private void launchSharesheet() { - // TODO(crbug/1024586): Open screenshot sharesheet. + ScreenshotShareSheetCoordinator shareSheet = new ScreenshotShareSheetCoordinator(mActivity); + shareSheet.showShareSheet(); + mScreenshot = null; } /** - * Installs the DFM and shows UI (i.e. toasts and a retry dialog) informing the user of the - * installation status. + * Installs the DFM and shows UI (i.e. toasts and a retry dialog) informing the + * user of the installation status. */ private void installEditor() { - ModuleInstallUi ui = new ModuleInstallUi( + final ModuleInstallUi ui = new ModuleInstallUi( mTab, R.string.image_editor_module_title, new ModuleInstallUi.FailureUiListener() { @Override public void onFailureUiResponse(boolean retry) { @@ -94,6 +96,8 @@ // User initiated retries are not counted toward the maximum number // of install attempts per session. installEditor(); + } else { + launchSharesheet(); } } }); @@ -104,7 +108,7 @@ ui.showInstallSuccessUi(); launchEditor(); } else { - ui.showInstallFailureUi(); + launchSharesheet(); } }); }
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetCoordinator.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetCoordinator.java new file mode 100644 index 0000000..75e14d92 --- /dev/null +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetCoordinator.java
@@ -0,0 +1,42 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.share.screenshot; + +import android.app.Activity; +import android.app.FragmentManager; + +/** + * Coordinator for displaying the screenshot share sheet. + */ +public class ScreenshotShareSheetCoordinator { + private final ScreenshotShareSheetDialog mDialog; + private final FragmentManager mFragmentManager; + + /** + * Constructs a new ShareSheetCoordinator. + * + * @param context The context to use for user permissions. + */ + public ScreenshotShareSheetCoordinator(Activity activity) { + mDialog = new ScreenshotShareSheetDialog(); + + mFragmentManager = activity.getFragmentManager(); + // TODO(crbug/1024586) Flesh out MVC for the upstream screenshot MVC. + } + + /** + * Show the main share sheet dialog. + */ + protected void showShareSheet() { + mDialog.show(mFragmentManager, null); + } + + /** + * Dismiss the main dialog. + */ + public void dismiss() { + mDialog.dismiss(); + } +}
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetDialog.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetDialog.java new file mode 100644 index 0000000..74d5457 --- /dev/null +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetDialog.java
@@ -0,0 +1,53 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.share.screenshot; + +import android.app.Dialog; +import android.app.DialogFragment; +import android.content.Context; +import android.os.Bundle; +import android.view.View; + +import androidx.appcompat.app.AlertDialog; + +import org.chromium.chrome.R; +import org.chromium.ui.widget.ChromeImageButton; + +/** + * ScreenshotShareSheetDialog is the main view for sharing non edited screenshots. + */ +public class ScreenshotShareSheetDialog extends DialogFragment { + private Context mContext; + + /** + * The ScreenshotShareSheetDialog constructor. + */ + public ScreenshotShareSheetDialog() {} + + @Override + public void onAttach(Context context) { + super.onAttach(context); + mContext = context; + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + AlertDialog.Builder builder = + new AlertDialog.Builder(getActivity(), R.style.Theme_Chromium_Fullscreen); + builder.setView(getDialogView()); + return builder.create(); + } + + private View getDialogView() { + ScreenshotShareSheetView dialogView = + (ScreenshotShareSheetView) getActivity().getLayoutInflater().inflate( + org.chromium.chrome.browser.share.R.layout.screenshot_share_sheet, null); + ChromeImageButton closeButton = + (ChromeImageButton) dialogView.findViewById(R.id.close_button); + closeButton.setOnClickListener(v -> dismiss()); + + return dialogView; + } +}
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetMediator.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetMediator.java new file mode 100644 index 0000000..11c6a3b --- /dev/null +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetMediator.java
@@ -0,0 +1,28 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.share.screenshot; + +import android.content.Context; + +import org.chromium.ui.modelutil.PropertyModel; + +/** + * ScreenshotShareSheetMediator is in charge of calculating and setting values for + * ScreenshotShareSheetViewProperties. + */ +class ScreenshotShareSheetMediator implements ShareImageFileUtils.OnImageSaveListener { + private final Context mContext; + private final PropertyModel mPropertyModel; + + /** + * The ScreenshotShareSheetMediator constructor. + * @param context The context to use. + * @param propertyModel The property modelto use to communicate with views. + */ + ScreenshotShareSheetMediator(Context context, PropertyModel propertyModel) { + mContext = context; + mPropertyModel = propertyModel; + } +}
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetView.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetView.java new file mode 100644 index 0000000..301b757 --- /dev/null +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetView.java
@@ -0,0 +1,19 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.share.screenshot; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.FrameLayout; + +/** + * Manages the Android View representing the Screenshot share panel. + */ +class ScreenshotShareSheetView extends FrameLayout { + /** Constructor for use from XML. */ + public ScreenshotShareSheetView(Context context, AttributeSet attrs) { + super(context, attrs); + } +}
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetViewBinder.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetViewBinder.java new file mode 100644 index 0000000..1bdafae5 --- /dev/null +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetViewBinder.java
@@ -0,0 +1,16 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.share.screenshot; + +import org.chromium.ui.modelutil.PropertyKey; +import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.modelutil.PropertyModelChangeProcessor.ViewBinder; + +/** The view binder for the Screenshot Share Sheet. */ +class ScreenshotShareSheetViewBinder + implements ViewBinder<PropertyModel, ScreenshotShareSheetView, PropertyKey> { + @Override + public void bind(PropertyModel model, ScreenshotShareSheetView view, PropertyKey propertyKey) {} +}
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetViewProperties.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetViewProperties.java new file mode 100644 index 0000000..41407a88 --- /dev/null +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetViewProperties.java
@@ -0,0 +1,11 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.share.screenshot; + +import org.chromium.ui.modelutil.PropertyKey; + +class ScreenshotShareSheetViewProperties { + public static final PropertyKey[] ALL_KEYS = {}; +}
diff --git a/chrome/browser/share/android/java_sources.gni b/chrome/browser/share/android/java_sources.gni index afc755de..0533fb5 100644 --- a/chrome/browser/share/android/java_sources.gni +++ b/chrome/browser/share/android/java_sources.gni
@@ -27,4 +27,9 @@ "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/share_tab/QrCodeShareViewBinder.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/share_tab/QrCodeShareViewProperties.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotCoordinator.java", + "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetCoordinator.java", + "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetDialog.java", + "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetView.java", + "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetViewBinder.java", + "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetViewProperties.java", ]
diff --git a/chrome/browser/signin/chrome_signin_helper.cc b/chrome/browser/signin/chrome_signin_helper.cc index 89ec38c6..8f17876e 100644 --- a/chrome/browser/signin/chrome_signin_helper.cc +++ b/chrome/browser/signin/chrome_signin_helper.cc
@@ -304,6 +304,8 @@ signin_metrics::LogAccountReconcilorStateOnGaiaResponse( account_reconcilor->GetState()); auto* window = web_contents->GetNativeView()->GetWindowAndroid(); + if (!window) + return; SigninUtils::OpenAccountManagementScreen(window, service_type, manage_accounts_params.email); }
diff --git a/chrome/browser/thumbnail/generator/BUILD.gn b/chrome/browser/thumbnail/generator/BUILD.gn index a4dd63a..361335f2 100644 --- a/chrome/browser/thumbnail/generator/BUILD.gn +++ b/chrome/browser/thumbnail/generator/BUILD.gn
@@ -114,6 +114,7 @@ "//chrome/browser/flags:java", "//chrome/browser/util:java", "//chrome/test/android:chrome_java_test_support", + "//components/browser_ui/util/android:java", "//content/public/android:content_java", "//content/public/test/android:content_java_test_support", "//third_party/android_deps:android_support_v4_java",
diff --git a/chrome/browser/touch_to_fill/android/BUILD.gn b/chrome/browser/touch_to_fill/android/BUILD.gn index de15117..44409ab6 100644 --- a/chrome/browser/touch_to_fill/android/BUILD.gn +++ b/chrome/browser/touch_to_fill/android/BUILD.gn
@@ -47,13 +47,21 @@ sources = [ "junit/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillControllerTest.java" ] deps = [ + "//base:base_java", "//base:base_java_test_support", "//base:base_junit_test_support", + "//chrome/android:chrome_java", "//chrome/android:chrome_test_util_java", + "//chrome/browser/touch_to_fill/android:public_java", "//chrome/browser/touch_to_fill/android/internal:java", + "//chrome/browser/ui/android/favicon:java", + "//chrome/test/android:chrome_java_test_support", "//components/module_installer/android:module_installer_java", + "//components/url_formatter/android:url_formatter_java", + "//third_party/hamcrest:hamcrest_java", "//third_party/junit", "//third_party/mockito:mockito_java", + "//ui/android:ui_full_java", ] }
diff --git a/chrome/browser/touch_to_fill/android/internal/BUILD.gn b/chrome/browser/touch_to_fill/android/internal/BUILD.gn index 28683e96..66dfa82c 100644 --- a/chrome/browser/touch_to_fill/android/internal/BUILD.gn +++ b/chrome/browser/touch_to_fill/android/internal/BUILD.gn
@@ -17,6 +17,7 @@ "//chrome/browser/touch_to_fill/android:public_java", "//chrome/browser/ui/android/favicon:java", "//chrome/browser/util:java", + "//components/browser_ui/android/bottomsheet:java", "//components/embedder_support/android:util_java", "//components/url_formatter/android:url_formatter_java", "//third_party/android_deps:androidx_recyclerview_recyclerview_java",
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 1a2322cf..d4d9f737 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1741,6 +1741,8 @@ "views/touch_selection_menu_chromeos.h", "views/touch_selection_menu_runner_chromeos.cc", "views/touch_selection_menu_runner_chromeos.h", + "webui/certificate_provisioning_ui_handler.cc", + "webui/certificate_provisioning_ui_handler.h", "webui/chromeos/account_manager_error_ui.cc", "webui/chromeos/account_manager_error_ui.h", "webui/chromeos/account_manager_welcome_dialog.cc", @@ -4494,6 +4496,12 @@ "ash/test_session_controller.h", "ash/test_wallpaper_controller.cc", "ash/test_wallpaper_controller.h", + "webui/settings/chromeos/fake_hierarchy.cc", + "webui/settings/chromeos/fake_hierarchy.h", + "webui/settings/chromeos/fake_os_settings_section.cc", + "webui/settings/chromeos/fake_os_settings_section.h", + "webui/settings/chromeos/fake_os_settings_sections.cc", + "webui/settings/chromeos/fake_os_settings_sections.h", ] deps += [ "//ash/public/cpp",
diff --git a/chrome/browser/ui/android/appmenu/internal/BUILD.gn b/chrome/browser/ui/android/appmenu/internal/BUILD.gn index 81e5cda..01b9a75 100644 --- a/chrome/browser/ui/android/appmenu/internal/BUILD.gn +++ b/chrome/browser/ui/android/appmenu/internal/BUILD.gn
@@ -30,6 +30,7 @@ "//components/browser_ui/widget/android:java", "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:androidx_annotation_annotation_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", "//ui/android:ui_java", ] } @@ -74,6 +75,7 @@ "//components/browser_ui/widget/android:test_support_java", "//content/public/test/android:content_java_test_support", "//third_party/android_deps:android_support_v7_appcompat_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", "//third_party/junit", @@ -110,5 +112,8 @@ deps = [ ":java", "//base:base_junit_test_support", + "//third_party/junit", + "//third_party/mockito:mockito_java", + "//third_party/robolectric:robolectric_all_java", ] }
diff --git a/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.cc b/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.cc index 2f2f2d1..8bb9f80 100644 --- a/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.cc +++ b/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.cc
@@ -154,7 +154,6 @@ confirm, ResourceMapper::MapToJavaDrawableId(controller_->GetCvcImageRid()), controller_->ShouldRequestExpirationDate(), - controller_->CanStoreLocally(), controller_->GetStoreLocallyStartState(), controller_->ShouldOfferWebauthn(), controller_->GetWebauthnOfferStartState(),
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index 186b225..245d952 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -3666,6 +3666,24 @@ <message name="IDS_QR_CODE_FAILED_DOWNLOAD_TEXT" desc="Notification text for failed QR code download."> Something went wrong </message> + + <!-- Share Screenshot strings --> + <message name="IDS_SCREENSHOT_EDIT_TITLE" desc="The text shown on the share option for screenshots."> + Edit + </message> + + <message name="IDS_SCREENSHOT_DELETE_TITLE" desc="The text shown on the delete option for screenshots."> + Delete + </message> + + <message name="IDS_SCREENSHOT_SAVE_TITLE" desc="The text shown on the save option for screenshots."> + Save + </message> + + <message name="IDS_SCREENSHOT_SHARE_TITLE" desc="The text shown on the share option for screenshots."> + Share + </message> + <!-- Chime DFM module strings --> <message name="IDS_CHIME_MODULE_TITLE" desc="Text shown when the chime module is referenced in install start, success, failure UI (e.g. in IDS_MODULE_INSTALL_START_TEXT, which will expand to 'Installing Google Notifications Platform for Chrome…')."> Google Notifications Platform
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SCREENSHOT_DELETE_TITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SCREENSHOT_DELETE_TITLE.png.sha1 new file mode 100644 index 0000000..64d9d58 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SCREENSHOT_DELETE_TITLE.png.sha1
@@ -0,0 +1 @@ +1a93040ac25614a480537ad983fb5f5f28c0d3df \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SCREENSHOT_EDIT_TITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SCREENSHOT_EDIT_TITLE.png.sha1 new file mode 100644 index 0000000..64d9d58 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SCREENSHOT_EDIT_TITLE.png.sha1
@@ -0,0 +1 @@ +1a93040ac25614a480537ad983fb5f5f28c0d3df \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SCREENSHOT_SAVE_TITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SCREENSHOT_SAVE_TITLE.png.sha1 new file mode 100644 index 0000000..64d9d58 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SCREENSHOT_SAVE_TITLE.png.sha1
@@ -0,0 +1 @@ +1a93040ac25614a480537ad983fb5f5f28c0d3df \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SCREENSHOT_SHARE_TITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SCREENSHOT_SHARE_TITLE.png.sha1 new file mode 100644 index 0000000..64d9d58 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SCREENSHOT_SHARE_TITLE.png.sha1
@@ -0,0 +1 @@ +1a93040ac25614a480537ad983fb5f5f28c0d3df \ No newline at end of file
diff --git a/chrome/browser/ui/ash/OWNERS b/chrome/browser/ui/ash/OWNERS index aee95f3..59d8dd0 100644 --- a/chrome/browser/ui/ash/OWNERS +++ b/chrome/browser/ui/ash/OWNERS
@@ -4,6 +4,7 @@ xiyuan@chromium.org per-file chrome_keyboard_ui*=yhanada@chromium.org +per-file *login*=file://ash/login/OWNERS per-file keyboard_*=yhanada@chromium.org per-file *wallpaper*=file://ash/wallpaper/OWNERS
diff --git a/chrome/browser/ui/ash/assistant/assistant_browsertest.cc b/chrome/browser/ui/ash/assistant/assistant_browsertest.cc index ee0520be..8edbf62 100644 --- a/chrome/browser/ui/ash/assistant/assistant_browsertest.cc +++ b/chrome/browser/ui/ash/assistant/assistant_browsertest.cc
@@ -11,8 +11,6 @@ #include "chromeos/dbus/power_manager/backlight.pb.h" #include "chromeos/services/assistant/public/cpp/features.h" #include "content/public/test/browser_test.h" -#include "ui/message_center/message_center.h" -#include "ui/message_center/public/cpp/notification.h" namespace chromeos { namespace assistant { @@ -25,14 +23,6 @@ constexpr int kStartBrightnessPercent = 50; -// Ensures that |str_| starts with |prefix_|. If it doesn't, this will print a -// nice error message. -#define EXPECT_STARTS_WITH(str_, prefix_) \ - ({ \ - EXPECT_TRUE(base::StartsWith(str_, prefix_, base::CompareCase::SENSITIVE)) \ - << "Expected '" << str_ << "'' to start with '" << prefix_ << "'"; \ - }) - // Ensures that |value_| is within the range {min_, max_}. If it isn't, this // will print a nice error message. #define EXPECT_WITHIN_RANGE(min_, value_, max_) \ @@ -238,61 +228,5 @@ // response processing v1 as well as response processing v2. INSTANTIATE_TEST_SUITE_P(All, AssistantBrowserTest, testing::Bool()); -// TODO(b/153485859): Move to assistant_timers_browsertest.cc. -class AssistantTimersV2BrowserTest : public MixinBasedInProcessBrowserTest { - public: - AssistantTimersV2BrowserTest() { - feature_list_.InitAndEnableFeature(features::kAssistantTimersV2); - } - - AssistantTimersV2BrowserTest(const AssistantTimersV2BrowserTest&) = delete; - AssistantTimersV2BrowserTest& operator=(const AssistantTimersV2BrowserTest&) = - delete; - - ~AssistantTimersV2BrowserTest() override = default; - - void ShowAssistantUi() { - if (!tester()->IsVisible()) - tester()->PressAssistantKey(); - } - - AssistantTestMixin* tester() { return &tester_; } - - private: - base::test::ScopedFeatureList feature_list_; - AssistantTestMixin tester_{&mixin_host_, this, embedded_test_server(), kMode, - kVersion}; -}; - -IN_PROC_BROWSER_TEST_F(AssistantTimersV2BrowserTest, - ShouldDismissTimerNotificationsWhenDisablingAssistant) { - tester()->StartAssistantAndWaitForReady(); - - ShowAssistantUi(); - EXPECT_TRUE(tester()->IsVisible()); - - // Confirm no Assistant notifications are currently being shown. - auto* message_center = message_center::MessageCenter::Get(); - EXPECT_TRUE(message_center->FindNotificationsByAppId("assistant").empty()); - - // Start a timer for one minute. - tester()->SendTextQuery("Set a timer for 1 minute."); - - // Check for a stable substring of the expected answers. - tester()->ExpectTextResponse("1 min."); - - // Confirm that an Assistant timer notification is now showing. - auto notifications = message_center->FindNotificationsByAppId("assistant"); - ASSERT_EQ(1u, notifications.size()); - EXPECT_STARTS_WITH((*notifications.begin())->id(), "assistant/timer"); - - // Disable Assistant. - tester()->SetAssistantEnabled(false); - base::RunLoop().RunUntilIdle(); - - // Confirm that our Assistant timer notification has been dismissed. - EXPECT_TRUE(message_center->FindNotificationsByAppId("assistant").empty()); -} - } // namespace assistant } // namespace chromeos
diff --git a/chrome/browser/ui/ash/assistant/assistant_timers_browsertest.cc b/chrome/browser/ui/ash/assistant/assistant_timers_browsertest.cc index b764975..0ab8ebb 100644 --- a/chrome/browser/ui/ash/assistant/assistant_timers_browsertest.cc +++ b/chrome/browser/ui/ash/assistant/assistant_timers_browsertest.cc
@@ -29,8 +29,9 @@ namespace { -// Please remember to set auth token when running in |kProxy| mode. +// Please remember to set auth token when *not* running in |kReplay| mode. constexpr auto kMode = FakeS3Mode::kReplay; + // Update this when you introduce breaking changes to existing tests. constexpr int kVersion = 1; @@ -173,6 +174,34 @@ // Tests ----------------------------------------------------------------------- +// Timer notifications should be dismissed when disabling Assistant in settings. +IN_PROC_BROWSER_TEST_F(AssistantTimersBrowserTest, + ShouldDismissTimerNotificationsWhenDisablingAssistant) { + tester()->StartAssistantAndWaitForReady(); + + ShowAssistantUi(); + EXPECT_TRUE(tester()->IsVisible()); + + // Confirm no Assistant notifications are currently being shown. + EXPECT_TRUE(FindAssistantNotifications().empty()); + + // Start a timer for one minute. + tester()->SendTextQuery("Set a timer for 1 minute."); + + // Check for a stable substring of the expected answers. + tester()->ExpectTextResponse("1 min."); + + // Confirm that an Assistant timer notification is now showing. + ASSERT_EQ(1u, FindVisibleNotificationsByPrefixedId("assistant/timer").size()); + + // Disable Assistant. + tester()->SetAssistantEnabled(false); + base::RunLoop().RunUntilIdle(); + + // Confirm that our Assistant timer notification has been dismissed. + EXPECT_TRUE(FindAssistantNotifications().empty()); +} + // Pressing the "STOP" action button in a timer notification should result in // the timer being removed. IN_PROC_BROWSER_TEST_F(AssistantTimersBrowserTest,
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index 76a8804..5a81625 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -641,9 +641,7 @@ GetPersonalDataManager(), GetPersonalDataManager()->app_locale())), unmask_controller_( - user_prefs::UserPrefs::Get(web_contents->GetBrowserContext()), - Profile::FromBrowserContext(web_contents->GetBrowserContext()) - ->IsOffTheRecord()) { + user_prefs::UserPrefs::Get(web_contents->GetBrowserContext())) { // TODO(crbug.com/928595): Replace the closure with a callback to the renderer // that indicates if log messages should be sent from the renderer. log_manager_ =
diff --git a/chrome/browser/ui/autofill/payments/card_unmask_prompt_view_browsertest.cc b/chrome/browser/ui/autofill/payments/card_unmask_prompt_view_browsertest.cc index 99d7ca8..a5971dbc 100644 --- a/chrome/browser/ui/autofill/payments/card_unmask_prompt_view_browsertest.cc +++ b/chrome/browser/ui/autofill/payments/card_unmask_prompt_view_browsertest.cc
@@ -70,8 +70,7 @@ content::WebContents* contents, scoped_refptr<content::MessageLoopRunner> runner) : CardUnmaskPromptControllerImpl( - user_prefs::UserPrefs::Get(contents->GetBrowserContext()), - false), + user_prefs::UserPrefs::Get(contents->GetBrowserContext())), runner_(runner) {} // CardUnmaskPromptControllerImpl:.
diff --git a/chrome/browser/ui/extensions/settings_api_bubble_helpers.cc b/chrome/browser/ui/extensions/settings_api_bubble_helpers.cc index 2412a85..75c77574 100644 --- a/chrome/browser/ui/extensions/settings_api_bubble_helpers.cc +++ b/chrome/browser/ui/extensions/settings_api_bubble_helpers.cc
@@ -74,11 +74,31 @@ content::WebContents* web_contents, AutocompleteMatch::Type match_type) { #if defined(OS_WIN) || defined(OS_MACOSX) - if (AutocompleteMatch::IsSearchType(match_type) && - match_type != AutocompleteMatchType::SEARCH_OTHER_ENGINE) { - Browser* browser = chrome::FindBrowserWithWebContents(web_contents); - if (browser) - ShowSettingsApiBubble(BUBBLE_TYPE_SEARCH_ENGINE, browser); + if (!AutocompleteMatch::IsSearchType(match_type) || + match_type == AutocompleteMatchType::SEARCH_OTHER_ENGINE) { + return; + } + + Browser* browser = chrome::FindBrowserWithWebContents(web_contents); + if (!browser) + return; + + if (base::FeatureList::IsEnabled( + features::kExtensionSettingsOverriddenDialogs)) { + base::Optional<ExtensionSettingsOverriddenDialog::Params> params = + settings_overridden_params::GetSearchOverriddenParams( + browser->profile()); + if (!params) + return; + + auto dialog = std::make_unique<ExtensionSettingsOverriddenDialog>( + std::move(*params), browser->profile()); + if (!dialog->ShouldShow()) + return; + + chrome::ShowExtensionSettingsOverriddenDialog(std::move(dialog), browser); + } else { + ShowSettingsApiBubble(BUBBLE_TYPE_SEARCH_ENGINE, browser); } #endif }
diff --git a/chrome/browser/ui/extensions/settings_overridden_params_providers.cc b/chrome/browser/ui/extensions/settings_overridden_params_providers.cc index a88c135..cb4b84a 100644 --- a/chrome/browser/ui/extensions/settings_overridden_params_providers.cc +++ b/chrome/browser/ui/extensions/settings_overridden_params_providers.cc
@@ -7,9 +7,15 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/extension_web_ui.h" #include "chrome/browser/extensions/ntp_overridden_bubble_delegate.h" +#include "chrome/browser/extensions/settings_api_bubble_delegate.h" +#include "chrome/browser/extensions/settings_api_helpers.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/common/webui_url_constants.h" #include "chrome/grit/generated_resources.h" +#include "components/search_engines/template_url.h" +#include "components/search_engines/template_url_service.h" +#include "components/url_formatter/url_formatter.h" #include "ui/base/l10n/l10n_util.h" namespace settings_overridden_params { @@ -43,4 +49,57 @@ std::move(dialog_message)); } +base::Optional<ExtensionSettingsOverriddenDialog::Params> +GetSearchOverriddenParams(Profile* profile) { + const extensions::Extension* extension = + extensions::GetExtensionOverridingSearchEngine(profile); + if (!extension) + return base::nullopt; + + // We deliberately re-use the same preference that the bubble UI uses. This + // way, users won't see the bubble or dialog UI if they've already + // acknowledged either version. + const char* preference_name = + extensions::SettingsApiBubbleDelegate::kAcknowledgedPreference; + + constexpr char kHistogramName[] = + "Extensions.SettingsOverridden.GenericSearchOverriddenDialogResult"; + + // Find the active search engine (which is provided by the extension). + TemplateURLService* template_url_service = + TemplateURLServiceFactory::GetForProfile(profile); + DCHECK(template_url_service->IsExtensionControlledDefaultSearch()); + const TemplateURL* default_search = + template_url_service->GetDefaultSearchProvider(); + DCHECK(default_search); + DCHECK_EQ(TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION, + default_search->type()); + + // NOTE: For most TemplateURLs, there's no guarantee that search_url is a + // valid URL (it could contain placeholders, etc). However, for extension- + // provided search engines, we require they be valid URLs. + GURL search_url(default_search->url()); + DCHECK(search_url.is_valid()) << default_search->url(); + + // Format the URL for display. + const url_formatter::FormatUrlTypes kFormatRules = + url_formatter::kFormatUrlOmitTrivialSubdomains | + url_formatter::kFormatUrlTrimAfterHost | + url_formatter::kFormatUrlOmitHTTPS; + base::string16 formatted_search_url = url_formatter::FormatUrl( + search_url, kFormatRules, net::UnescapeRule::SPACES, nullptr, nullptr, + nullptr); + + // TODO(devlin): Adjust these strings based on the previous search engine. + base::string16 dialog_title = l10n_util::GetStringUTF16( + IDS_EXTENSION_SEARCH_OVERRIDDEN_DIALOG_TITLE_GENERIC); + base::string16 dialog_message = l10n_util::GetStringFUTF16( + IDS_EXTENSION_SEARCH_OVERRIDDEN_DIALOG_BODY_GENERIC, formatted_search_url, + base::UTF8ToUTF16(extension->name().c_str())); + + return ExtensionSettingsOverriddenDialog::Params( + extension->id(), preference_name, kHistogramName, std::move(dialog_title), + std::move(dialog_message)); +} + } // namespace settings_overridden_params
diff --git a/chrome/browser/ui/extensions/settings_overridden_params_providers.h b/chrome/browser/ui/extensions/settings_overridden_params_providers.h index 94fd7c6a..38ba84cc 100644 --- a/chrome/browser/ui/extensions/settings_overridden_params_providers.h +++ b/chrome/browser/ui/extensions/settings_overridden_params_providers.h
@@ -15,6 +15,12 @@ base::Optional<ExtensionSettingsOverriddenDialog::Params> GetNtpOverriddenParams(Profile* profile); +// Retrieves the params for displaying the dialog indicating that the default +// search engine has been overridden, if there is a controlling extension. +// Otherwise, returns an empty optional. +base::Optional<ExtensionSettingsOverriddenDialog::Params> +GetSearchOverriddenParams(Profile* profile); + } // namespace settings_overridden_params #endif // CHROME_BROWSER_UI_EXTENSIONS_SETTINGS_OVERRIDDEN_PARAMS_PROVIDERS_H_
diff --git a/chrome/browser/ui/extensions/settings_overridden_params_providers_browsertest.cc b/chrome/browser/ui/extensions/settings_overridden_params_providers_browsertest.cc new file mode 100644 index 0000000..1075cd8 --- /dev/null +++ b/chrome/browser/ui/extensions/settings_overridden_params_providers_browsertest.cc
@@ -0,0 +1,69 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/extensions/settings_overridden_params_providers.h" + +#include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" +#include "chrome/browser/extensions/extension_browsertest.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/extensions/settings_api_helpers.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser.h" +#include "content/public/test/browser_test.h" +#include "extensions/browser/extension_system.h" +#include "extensions/common/extension_builder.h" +#include "extensions/common/value_builder.h" + +class SettingsOverriddenParamsProvidersBrowserTest + : public extensions::ExtensionBrowserTest { + public: + // Installs a new extension that controls the default search engine. + const extensions::Extension* AddExtensionControllingSearch() { + const extensions::Extension* extension = + InstallExtensionWithPermissionsGranted( + test_data_dir_.AppendASCII("search_provider_override"), 1); + EXPECT_EQ(extension, + extensions::GetExtensionOverridingSearchEngine(profile())); + return extension; + } +}; + +// The chrome_settings_overrides API that allows extensions to override the +// default search provider is only available on Windows and Mac. +#if defined(OS_WIN) || defined(OS_MACOSX) + +// NOTE: It's very unfortunate that this has to be a browsertest. Unfortunately, +// a few bits here - the TemplateURLService in particular - don't play nicely +// with a unittest environment. +IN_PROC_BROWSER_TEST_F(SettingsOverriddenParamsProvidersBrowserTest, + GetExtensionControllingSearch) { + // With no extensions installed, there should be no controlling extension. + EXPECT_EQ(base::nullopt, + settings_overridden_params::GetSearchOverriddenParams(profile())); + + // Install an extension, but not one that overrides the default search engine. + // There should still be no controlling extension. + InstallExtensionWithPermissionsGranted( + test_data_dir_.AppendASCII("simple_with_icon"), 1); + EXPECT_EQ(base::nullopt, + settings_overridden_params::GetSearchOverriddenParams(profile())); + + // Finally, install an extension that overrides the default search engine. + // It should be the controlling extension. + const extensions::Extension* search_extension = + AddExtensionControllingSearch(); + base::Optional<ExtensionSettingsOverriddenDialog::Params> params = + settings_overridden_params::GetSearchOverriddenParams(profile()); + ASSERT_TRUE(params); + EXPECT_EQ(search_extension->id(), params->controlling_extension_id); + + // Validate the body message, since it has a bit of formatting applied. + EXPECT_EQ( + "The Search Override Extension extension changed search to use " + "example.com", + base::UTF16ToUTF8(params->dialog_message)); +} + +#endif // defined(OS_WIN) || defined(OS_MACOSX)
diff --git a/chrome/browser/ui/messages/android/BUILD.gn b/chrome/browser/ui/messages/android/BUILD.gn index 44070c1..cc63b83 100644 --- a/chrome/browser/ui/messages/android/BUILD.gn +++ b/chrome/browser/ui/messages/android/BUILD.gn
@@ -65,6 +65,7 @@ "//components/infobars/core:infobar_enums_java", "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:androidx_appcompat_appcompat_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", "//ui/android:ui_full_java", "//ui/android:ui_utils_java", ]
diff --git a/chrome/browser/ui/views/autofill/payments/card_unmask_prompt_views.cc b/chrome/browser/ui/views/autofill/payments/card_unmask_prompt_views.cc index 25cb448..15f8243 100644 --- a/chrome/browser/ui/views/autofill/payments/card_unmask_prompt_views.cc +++ b/chrome/browser/ui/views/autofill/payments/card_unmask_prompt_views.cc
@@ -64,19 +64,6 @@ return overlay_layout; } -std::unique_ptr<views::Checkbox> CreateSaveCheckbox(bool start_state) { - auto storage_checkbox = - std::make_unique<views::Checkbox>(l10n_util::GetStringUTF16( - IDS_AUTOFILL_CARD_UNMASK_PROMPT_STORAGE_CHECKBOX)); - storage_checkbox->SetBorder(views::CreateEmptyBorder(gfx::Insets())); - storage_checkbox->SetChecked(start_state); - storage_checkbox->SetEnabledTextColors(views::style::GetColor( - *storage_checkbox.get(), ChromeTextContext::CONTEXT_BODY_TEXT_SMALL, - views::style::STYLE_SECONDARY)); - - return storage_checkbox; -} - } // namespace CardUnmaskPromptViews::CardUnmaskPromptViews( @@ -84,11 +71,6 @@ content::WebContents* web_contents) : controller_(controller), web_contents_(web_contents) { chrome::RecordDialogCreation(chrome::DialogIdentifier::CARD_UNMASK); - if (controller_->CanStoreLocally()) { - storage_checkbox_ = SetFootnoteView( - CreateSaveCheckbox(controller_->GetStoreLocallyStartState())); - } - UpdateButtons(); }
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_browsertest.cc b/chrome/browser/ui/views/autofill/payments/local_card_migration_browsertest.cc index 215650b..f72811b0 100644 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_browsertest.cc +++ b/chrome/browser/ui/views/autofill/payments/local_card_migration_browsertest.cc
@@ -385,7 +385,7 @@ void ClickOnDialogViewAndWait( views::View* view, - views::DialogDelegateView* local_card_migration_view) { + views::BubbleDialogDelegateView* local_card_migration_view) { CHECK(local_card_migration_view); views::test::WidgetDestroyedWaiter destroyed_waiter( local_card_migration_view->GetWidget()); @@ -402,7 +402,7 @@ views::View* FindViewInDialogById( DialogViewId view_id, - views::DialogDelegateView* local_card_migration_view) { + views::BubbleDialogDelegateView* local_card_migration_view) { CHECK(local_card_migration_view); views::View* specified_view = @@ -417,14 +417,15 @@ return specified_view; } - void ClickOnOkButton(views::DialogDelegateView* local_card_migration_view) { + void ClickOnOkButton( + views::BubbleDialogDelegateView* local_card_migration_view) { views::View* ok_button = local_card_migration_view->GetOkButton(); ClickOnDialogViewAndWait(ok_button, local_card_migration_view); } void ClickOnCancelButton( - views::DialogDelegateView* local_card_migration_view) { + views::BubbleDialogDelegateView* local_card_migration_view) { views::View* cancel_button = local_card_migration_view->GetCancelButton(); ClickOnDialogViewAndWait(cancel_button, local_card_migration_view); } @@ -441,7 +442,7 @@ ->local_card_migration_bubble_view()); } - views::DialogDelegateView* GetLocalCardMigrationMainDialogView() { + views::BubbleDialogDelegateView* GetLocalCardMigrationMainDialogView() { LocalCardMigrationDialogControllerImpl* local_card_migration_dialog_controller_impl = LocalCardMigrationDialogControllerImpl::FromWebContents(
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc b/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc index 14ba443..ae4eb3b 100644 --- a/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc +++ b/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc
@@ -817,23 +817,6 @@ DISALLOW_COPY_AND_ASSIGN(SaveCardBubbleViewsFullFormBrowserTest); }; -class SaveCardBubbleViewsFullFormBrowserTestWithEditableExpirationDate - : public SaveCardBubbleViewsFullFormBrowserTest { - public: - SaveCardBubbleViewsFullFormBrowserTestWithEditableExpirationDate() { - // Enable the EditableExpirationDate experiment. - feature_list_.InitWithFeatures( - // Enabled - {features::kAutofillUpstreamEditableExpirationDate, - features::kAutofillUpstream}, - // Disabled - {}); - } - - private: - base::test::ScopedFeatureList feature_list_; -}; - // TODO(crbug.com/932818): Remove this class after experiment flag is cleaned // up. Otherwise we need it because the toolbar is init-ed before each test is // set up. Thus need to enable the feature in the general browsertest SetUp(). @@ -1776,7 +1759,7 @@ // Tests the upload save bubble. Ensures that the bubble surfaces a pair of // dropdowns requesting expiration date if expiration date is missing. IN_PROC_BROWSER_TEST_F( - SaveCardBubbleViewsFullFormBrowserTestWithEditableExpirationDate, + SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstream, Upload_SubmittingFormWithMissingExpirationDateRequestsExpirationDate) { SetUpForEditableExpirationDate(); FillFormWithoutExpirationDate(); @@ -1787,7 +1770,7 @@ // Tests the upload save bubble. Ensures that the bubble surfaces a pair of // dropdowns requesting expiration date if expiration date is expired. IN_PROC_BROWSER_TEST_F( - SaveCardBubbleViewsFullFormBrowserTestWithEditableExpirationDate, + SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstream, Upload_SubmittingFormWithExpiredExpirationDateRequestsExpirationDate) { SetUpForEditableExpirationDate(); FillFormWithSpecificExpirationDate("08", "2000"); @@ -1795,51 +1778,10 @@ VerifyExpirationDateDropdownsAreVisible(); } -class - SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstreamAndNoEditableExpirationDate - : public SaveCardBubbleViewsFullFormBrowserTest { - public: - SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstreamAndNoEditableExpirationDate() { - // Disable the EditableExpirationDate experiment. - feature_list_.InitWithFeatures( - // Enabled - {features::kAutofillUpstream}, - // Disabled - {features::kAutofillUpstreamEditableExpirationDate}); - } - - private: - base::test::ScopedFeatureList feature_list_; -}; - -// Tests the upload save bubble. Ensures that the bubble is not shown when -// expiration date is passed, but the flag is disabled. -IN_PROC_BROWSER_TEST_F( - SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstreamAndNoEditableExpirationDate, - Logic_ShouldNotOfferToSaveIfSubmittingExpiredExpirationDateAndExpOff) { - // The credit card will not be imported if the expiration date is expired and - // experiment is off. - FillFormWithSpecificExpirationDate("08", "2000"); - SubmitForm(); - EXPECT_FALSE(GetSaveCardBubbleViews()); -} - -// Tests the upload save bubble. Ensures that the bubble is not shown when -// expiration date is missing, but the flag is disabled. -IN_PROC_BROWSER_TEST_F( - SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstreamAndNoEditableExpirationDate, - Logic_ShouldNotOfferToSaveIfMissingExpirationDateAndExpOff) { - // The credit card will not be imported if there is no expiration date and - // experiment is off. - FillFormWithoutExpirationDate(); - SubmitForm(); - EXPECT_FALSE(GetSaveCardBubbleViews()); -} - // Tests the upload save bubble. Ensures that the bubble does not surface the // expiration date dropdowns if it is not needed. IN_PROC_BROWSER_TEST_F( - SaveCardBubbleViewsFullFormBrowserTestWithEditableExpirationDate, + SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstream, Upload_ShouldNotRequestExpirationDateInHappyPath) { SetUpForEditableExpirationDate(); FillForm(); @@ -1858,7 +1800,7 @@ // Tests the upload save bubble. Ensures that if the expiration date drop down // box is changing, [Save] button will change status correctly. IN_PROC_BROWSER_TEST_F( - SaveCardBubbleViewsFullFormBrowserTestWithEditableExpirationDate, + SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstream, Upload_SaveButtonStatusResetBetweenExpirationDateSelectionChanges) { SetUpForEditableExpirationDate(); FillFormWithoutExpirationDate(); @@ -1890,7 +1832,7 @@ // Tests the upload save bubble. Ensures that if the user is selecting an // expired expiration date, it is not allowed to click [Save]. IN_PROC_BROWSER_TEST_F( - SaveCardBubbleViewsFullFormBrowserTestWithEditableExpirationDate, + SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstream, Upload_SaveButtonIsDisabledIfExpiredExpirationDateAndExpirationDateRequested) { SetUpForEditableExpirationDate(); FillFormWithoutExpirationDate(); @@ -1916,7 +1858,7 @@ // dropdowns requesting expiration date with year pre-populated if year is valid // but month is missing. IN_PROC_BROWSER_TEST_F( - SaveCardBubbleViewsFullFormBrowserTestWithEditableExpirationDate, + SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstream, Upload_SubmittingFormWithMissingExpirationDateMonthAndWithValidYear) { SetUpForEditableExpirationDate(); // Submit the form with a year value, but not a month value. @@ -1934,7 +1876,7 @@ // dropdowns requesting expiration date with month pre-populated if month is // detected but year is missing. IN_PROC_BROWSER_TEST_F( - SaveCardBubbleViewsFullFormBrowserTestWithEditableExpirationDate, + SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstream, Upload_SubmittingFormWithMissingExpirationDateYearAndWithMonth) { SetUpForEditableExpirationDate(); // Submit the form with a month value, but not a year value. @@ -1952,7 +1894,7 @@ // dropdowns requesting expiration date if month is missing and year is detected // but out of the range of dropdown. IN_PROC_BROWSER_TEST_F( - SaveCardBubbleViewsFullFormBrowserTestWithEditableExpirationDate, + SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstream, Upload_SubmittingFormWithExpirationDateMonthAndWithYearIsOutOfRange) { SetUpForEditableExpirationDate(); // Fill form but with an expiration year ten years in the future which is out @@ -1970,7 +1912,7 @@ // dropdowns requesting expiration date if expiration date month is missing and // year is detected but passed. IN_PROC_BROWSER_TEST_F( - SaveCardBubbleViewsFullFormBrowserTestWithEditableExpirationDate, + SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstream, Upload_SubmittingFormWithExpirationDateMonthAndYearExpired) { SetUpForEditableExpirationDate(); // Fill form with a valid month but a passed year. @@ -1988,7 +1930,7 @@ // dropdowns requesting expiration date if expiration date is expired but is // current year. IN_PROC_BROWSER_TEST_F( - SaveCardBubbleViewsFullFormBrowserTestWithEditableExpirationDate, + SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstream, Upload_SubmittingFormWithExpirationDateMonthAndCurrentYear) { SetUpForEditableExpirationDate(); const base::Time kJune2017 = base::Time::FromDoubleT(1497552271);
diff --git a/chrome/browser/ui/views/extensions/expandable_container_view.cc b/chrome/browser/ui/views/extensions/expandable_container_view.cc index 8cd08bf0..824f24a 100644 --- a/chrome/browser/ui/views/extensions/expandable_container_view.cc +++ b/chrome/browser/ui/views/extensions/expandable_container_view.cc
@@ -39,13 +39,9 @@ } } -gfx::Size ExpandableContainerView::DetailsView::CalculatePreferredSize() const { - return expanded_ ? views::View::CalculatePreferredSize() : gfx::Size(); -} - void ExpandableContainerView::DetailsView::ToggleExpanded() { expanded_ = !expanded_; - PreferredSizeChanged(); + SetVisible(expanded_); } // ExpandableContainerView ----------------------------------------------------- @@ -54,29 +50,17 @@ const std::vector<base::string16>& details, int available_width) { DCHECK(!details.empty()); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); - views::GridLayout* layout = - SetLayoutManager(std::make_unique<views::GridLayout>()); - constexpr int kColumnSetId = 0; - views::ColumnSet* column_set = layout->AddColumnSet(kColumnSetId); - - // Even though we only have one column, using a GridLayout here will - // properly handle a 0 height row when |details_view_| is collapsed. - column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::LEADING, - views::GridLayout::kFixedSize, - views::GridLayout::ColumnSize::kFixed, available_width, - 0); - - layout->StartRow(views::GridLayout::kFixedSize, kColumnSetId); - details_view_ = layout->AddView(std::make_unique<DetailsView>(details)); - - layout->StartRow(views::GridLayout::kFixedSize, kColumnSetId); + details_view_ = AddChildView(std::make_unique<DetailsView>(details)); + details_view_->SetVisible(false); auto details_link = std::make_unique<views::Link>( l10n_util::GetStringUTF16(IDS_EXTENSIONS_SHOW_DETAILS)); details_link->set_callback(base::BindRepeating( &ExpandableContainerView::ToggleDetailLevel, base::Unretained(this))); details_link->SetHorizontalAlignment(gfx::ALIGN_LEFT); - details_link_ = layout->AddView(std::move(details_link)); + details_link_ = AddChildView(std::move(details_link)); } ExpandableContainerView::~ExpandableContainerView() = default;
diff --git a/chrome/browser/ui/views/extensions/expandable_container_view.h b/chrome/browser/ui/views/extensions/expandable_container_view.h index 682a161..f110005 100644 --- a/chrome/browser/ui/views/extensions/expandable_container_view.h +++ b/chrome/browser/ui/views/extensions/expandable_container_view.h
@@ -28,6 +28,10 @@ ExpandableContainerView(const ExpandableContainerView&) = delete; ExpandableContainerView& operator=(const ExpandableContainerView&) = delete; + // Accessors for testing. + View* details_view() { return details_view_; } + void ToggleDetailLevelForTest() { ToggleDetailLevel(); } + private: // Helper class representing the list of details, that can hide itself. class DetailsView : public views::View { @@ -35,9 +39,6 @@ explicit DetailsView(const std::vector<base::string16>& details); ~DetailsView() override; - // views::View: - gfx::Size CalculatePreferredSize() const override; - // Expands or collapses this view. void ToggleExpanded();
diff --git a/chrome/browser/ui/views/extensions/expandable_container_view_unittest.cc b/chrome/browser/ui/views/extensions/expandable_container_view_unittest.cc new file mode 100644 index 0000000..e19e050 --- /dev/null +++ b/chrome/browser/ui/views/extensions/expandable_container_view_unittest.cc
@@ -0,0 +1,29 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/extensions/expandable_container_view.h" + +#include "base/strings/utf_string_conversions.h" +#include "chrome/test/views/chrome_views_test_base.h" + +using ExpandableContainerViewTest = ChromeViewsTestBase; + +TEST_F(ExpandableContainerViewTest, DetailLevelVisibility) { + std::vector<base::string16> details; + details.push_back(base::ASCIIToUTF16("Detail 1")); + details.push_back(base::ASCIIToUTF16("Detail 2")); + details.push_back(base::ASCIIToUTF16("Detail 2")); + + int content_width = 100; + auto container = + std::make_unique<ExpandableContainerView>(details, content_width); + + // Initially the details view should not be expanded or visible. + EXPECT_FALSE(container->details_view()->GetVisible()); + + // When the link is triggered, the details should get expanded and become + // visible. + container->ToggleDetailLevelForTest(); + EXPECT_TRUE(container->details_view()->GetVisible()); +}
diff --git a/chrome/browser/ui/views/extensions/extension_install_dialog_view.h b/chrome/browser/ui/views/extensions/extension_install_dialog_view.h index ce8f2b4..fe0cabd 100644 --- a/chrome/browser/ui/views/extensions/extension_install_dialog_view.h +++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view.h
@@ -53,7 +53,6 @@ // Changes the widget size to accommodate the contents' preferred size. void ResizeWidget(); - private: // views::BubbleDialogDelegate: gfx::Size CalculatePreferredSize() const override; void VisibilityChanged(views::View* starting_from, bool is_visible) override; @@ -61,6 +60,7 @@ bool IsDialogButtonEnabled(ui::DialogButton button) const override; bool ShouldShowCloseButton() const override; + private: void CloseDialog(); // extensions::ExtensionRegistryObserver:
diff --git a/chrome/browser/ui/views/extensions/extension_install_dialog_view_browsertest.cc b/chrome/browser/ui/views/extensions/extension_install_dialog_view_browsertest.cc index 3e560b7e..9c41e7f 100644 --- a/chrome/browser/ui/views/extensions/extension_install_dialog_view_browsertest.cc +++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view_browsertest.cc
@@ -186,12 +186,12 @@ const ExtensionInstallDialogViewTest&) = delete; protected: - views::DialogDelegateView* CreateAndShowPrompt( + ExtensionInstallDialogView* CreateAndShowPrompt( ExtensionInstallPromptTestHelper* helper) { auto dialog = std::make_unique<ExtensionInstallDialogView>( profile(), web_contents(), helper->GetCallback(), CreatePrompt(ExtensionInstallPrompt::INSTALL_PROMPT)); - views::DialogDelegateView* delegate_view = dialog.get(); + ExtensionInstallDialogView* delegate_view = dialog.get(); views::Widget* modal_dialog = views::DialogDelegate::CreateDialogWidget( dialog.release(), nullptr, @@ -207,14 +207,14 @@ { // User presses install. ExtensionInstallPromptTestHelper helper; - views::DialogDelegateView* delegate_view = CreateAndShowPrompt(&helper); + ExtensionInstallDialogView* delegate_view = CreateAndShowPrompt(&helper); delegate_view->AcceptDialog(); EXPECT_EQ(ExtensionInstallPrompt::Result::ACCEPTED, helper.result()); } { // User presses cancel. ExtensionInstallPromptTestHelper helper; - views::DialogDelegateView* delegate_view = CreateAndShowPrompt(&helper); + ExtensionInstallDialogView* delegate_view = CreateAndShowPrompt(&helper); delegate_view->CancelDialog(); EXPECT_EQ(ExtensionInstallPrompt::Result::USER_CANCELED, helper.result()); } @@ -222,7 +222,7 @@ // Dialog is closed without the user explicitly choosing to proceed or // cancel. ExtensionInstallPromptTestHelper helper; - views::DialogDelegateView* delegate_view = CreateAndShowPrompt(&helper); + ExtensionInstallDialogView* delegate_view = CreateAndShowPrompt(&helper); CloseAndWait(delegate_view->GetWidget()); // TODO(devlin): Should this be ABORTED? EXPECT_EQ(ExtensionInstallPrompt::Result::USER_CANCELED, helper.result()); @@ -234,7 +234,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionInstallDialogViewTest, InstallButtonDelay) { ExtensionInstallDialogView::SetInstallButtonDelayForTesting(0); ExtensionInstallPromptTestHelper helper; - views::DialogDelegateView* delegate_view = CreateAndShowPrompt(&helper); + ExtensionInstallDialogView* delegate_view = CreateAndShowPrompt(&helper); // Check that dialog is visible. EXPECT_TRUE(delegate_view->GetVisible()); @@ -617,7 +617,7 @@ prompt->AddPermissionSet(permissions); auto dialog = std::make_unique<ExtensionInstallDialogView>( profile(), web_contents(), helper.GetCallback(), std::move(prompt)); - views::DialogDelegateView* delegate_view = dialog.get(); + views::BubbleDialogDelegateView* delegate_view = dialog.get(); views::Widget* modal_dialog = views::DialogDelegate::CreateDialogWidget( dialog.release(), nullptr,
diff --git a/chrome/browser/ui/views/extensions/extension_install_dialog_view_supervised_browsertest.cc b/chrome/browser/ui/views/extensions/extension_install_dialog_view_supervised_browsertest.cc index 81ad8e8..5867f1f9 100644 --- a/chrome/browser/ui/views/extensions/extension_install_dialog_view_supervised_browsertest.cc +++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view_supervised_browsertest.cc
@@ -45,7 +45,7 @@ content::WebContents* web_contents() { return web_contents_; } protected: - views::DialogDelegateView* CreateAndShowPrompt( + ExtensionInstallDialogView* CreateAndShowPrompt( ExtensionInstallPromptTestHelper* helper, std::unique_ptr<ExtensionInstallPrompt::Prompt> prompt); @@ -91,13 +91,13 @@ return prompt; } -views::DialogDelegateView* +ExtensionInstallDialogView* ExtensionInstallDialogViewTestSupervised::CreateAndShowPrompt( ExtensionInstallPromptTestHelper* helper, std::unique_ptr<ExtensionInstallPrompt::Prompt> prompt) { auto dialog = std::make_unique<ExtensionInstallDialogView>( profile(), web_contents(), helper->GetCallback(), std::move(prompt)); - views::DialogDelegateView* delegate_view = dialog.get(); + ExtensionInstallDialogView* delegate_view = dialog.get(); views::Widget* modal_dialog = views::DialogDelegate::CreateDialogWidget( dialog.release(), nullptr, @@ -150,7 +150,7 @@ task_runner->FastForwardBy(duration); // Supervised user presses "Ask a parent". - views::DialogDelegateView* delegate_view = + ExtensionInstallDialogView* delegate_view = CreateAndShowPrompt(&helper, install_prompt.GetPromptForTesting()); delegate_view->AcceptDialog(); EXPECT_EQ(ExtensionInstallPrompt::Result::ACCEPTED, helper.result()); @@ -222,7 +222,7 @@ task_runner->FastForwardBy(duration); // Supervised user presses "Cancel". - views::DialogDelegateView* delegate_view = + ExtensionInstallDialogView* delegate_view = CreateAndShowPrompt(&helper, install_prompt.GetPromptForTesting()); delegate_view->CancelDialog(); EXPECT_EQ(ExtensionInstallPrompt::Result::USER_CANCELED, helper.result());
diff --git a/chrome/browser/ui/views/extensions/settings_overridden_dialog_view_browsertest.cc b/chrome/browser/ui/views/extensions/settings_overridden_dialog_view_browsertest.cc index a65c342..bea07a3 100644 --- a/chrome/browser/ui/views/extensions/settings_overridden_dialog_view_browsertest.cc +++ b/chrome/browser/ui/views/extensions/settings_overridden_dialog_view_browsertest.cc
@@ -7,18 +7,22 @@ #include "base/path_service.h" #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_feature_list.h" +#include "base/time/time.h" +#include "build/build_config.h" #include "chrome/browser/extensions/chrome_test_extension_loader.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/extensions/settings_api_bubble_helpers.h" #include "chrome/browser/ui/extensions/settings_overridden_dialog_controller.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/test/test_browser_dialog.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/webui_url_constants.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" namespace { @@ -51,10 +55,13 @@ ~SettingsOverriddenDialogViewBrowserTest() override = default; void ShowUi(const std::string& name) override { + test_name_ = name; if (name == "SimpleDialog") ShowSimpleDialog(); else if (name == "NtpOverriddenDialog") ShowNtpOverriddenDialog(); + else if (name == "SearchOverriddenDialog") + ShowSearchOverriddenDialog(); else NOTREACHED() << name; } @@ -88,7 +95,45 @@ ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); } + void ShowSearchOverriddenDialog() { + base::FilePath test_root_path; + ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &test_root_path)); + + // Load up an extension that overrides search. + Profile* const profile = browser()->profile(); + scoped_refptr<const extensions::Extension> extension = + extensions::ChromeTestExtensionLoader(profile).LoadExtension( + test_root_path.AppendASCII("extensions/search_provider_override")); + ASSERT_TRUE(extension); + + // Perform a search via the omnibox to trigger the dialog. + ui_test_utils::SendToOmniboxAndSubmit(browser(), "Penguin", + base::TimeTicks::Now()); + content::WaitForLoadStop( + browser()->tab_strip_model()->GetActiveWebContents()); + } + + bool VerifyUi() override { + if (!DialogBrowserTest::VerifyUi()) + return false; + + if (test_name_ == "SearchOverriddenDialog") { + // Note: Because this is a test, we don't actually expect this navigation + // to succeed. But we can still check that the user was sent to + // example.com (the new search engine). + EXPECT_EQ("www.example.com", browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetLastCommittedURL() + .host_piece()); + } + + return true; + } + private: + std::string test_name_; + base::test::ScopedFeatureList scoped_feature_list_; }; @@ -105,3 +150,12 @@ ShowAndVerifyUi(); extensions::SetNtpPostInstallUiEnabledForTesting(false); } + +// The chrome_settings_overrides API that allows extensions to override the +// default search provider is only available on Windows and Mac. +#if defined(OS_WIN) || defined(OS_MACOSX) +IN_PROC_BROWSER_TEST_F(SettingsOverriddenDialogViewBrowserTest, + InvokeUi_SearchOverriddenDialog) { + ShowAndVerifyUi(); +} +#endif // defined(OS_WIN) || defined(OS_MACOSX)
diff --git a/chrome/browser/ui/views/passwords/password_dialog_view_browsertest.cc b/chrome/browser/ui/views/passwords/password_dialog_view_browsertest.cc index e0a259e..4ebf33ba 100644 --- a/chrome/browser/ui/views/passwords/password_dialog_view_browsertest.cc +++ b/chrome/browser/ui/views/passwords/password_dialog_view_browsertest.cc
@@ -322,7 +322,8 @@ url::Origin::Create(origin)); EXPECT_TRUE(controller()->current_account_chooser()); - views::DialogDelegateView* dialog = controller()->current_account_chooser(); + views::BubbleDialogDelegateView* dialog = + controller()->current_account_chooser(); views::test::WidgetClosingObserver bubble_observer(dialog->GetWidget()); EXPECT_CALL(*this, OnChooseCredential(testing::Pointee(form))); dialog->Accept();
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 3d28409..fc37c54 100644 --- a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc +++ b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
@@ -349,9 +349,8 @@ void BrowserTabStripController::ToggleTabGroupCollapsedState( const tab_groups::TabGroupId group) { - tab_groups::TabGroupVisualData new_data(GetGroupTitle(group), - GetGroupColorId(group), - !GetGroupCollapsedState(group)); + tab_groups::TabGroupVisualData new_data( + GetGroupTitle(group), GetGroupColorId(group), !IsGroupCollapsed(group)); model_->group_model()->GetTabGroup(group)->SetVisualData(new_data, true); } @@ -474,7 +473,7 @@ return model_->group_model()->GetTabGroup(group)->visual_data()->color(); } -bool BrowserTabStripController::GetGroupCollapsedState( +bool BrowserTabStripController::IsGroupCollapsed( const tab_groups::TabGroupId& group) const { return model_->group_model()->ContainsTabGroup(group) && model_->group_model()
diff --git a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.h b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.h index 8a096b65..3658e421 100644 --- a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.h +++ b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.h
@@ -94,8 +94,7 @@ const tab_groups::TabGroupId& group_id) const override; tab_groups::TabGroupColorId GetGroupColorId( const tab_groups::TabGroupId& group_id) const override; - bool GetGroupCollapsedState( - const tab_groups::TabGroupId& group) const override; + bool IsGroupCollapsed(const tab_groups::TabGroupId& group) const override; void SetVisualDataForGroup( const tab_groups::TabGroupId& group,
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 e6fb6c6..bada6aa 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
@@ -89,7 +89,7 @@ return fake_group_data_.color(); } -bool FakeBaseTabStripController::GetGroupCollapsedState( +bool FakeBaseTabStripController::IsGroupCollapsed( const tab_groups::TabGroupId& group) const { return fake_group_data_.is_collapsed(); }
diff --git a/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.h b/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.h index 64be95e..78acda2 100644 --- a/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.h +++ b/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.h
@@ -67,8 +67,7 @@ const tab_groups::TabGroupId& group_id) const override; tab_groups::TabGroupColorId GetGroupColorId( const tab_groups::TabGroupId& group_id) const override; - bool GetGroupCollapsedState( - const tab_groups::TabGroupId& group) const override; + bool IsGroupCollapsed(const tab_groups::TabGroupId& group) const override; void SetVisualDataForGroup( const tab_groups::TabGroupId& group, const tab_groups::TabGroupVisualData& visual_data) override;
diff --git a/chrome/browser/ui/views/tabs/tab_group_views.cc b/chrome/browser/ui/views/tabs/tab_group_views.cc index 8e16b451..1136ea1 100644 --- a/chrome/browser/ui/views/tabs/tab_group_views.cc +++ b/chrome/browser/ui/views/tabs/tab_group_views.cc
@@ -46,7 +46,7 @@ } gfx::Rect TabGroupViews::GetBounds() const { - if (tab_strip_->controller()->GetGroupCollapsedState(group_)) + if (tab_strip_->controller()->IsGroupCollapsed(group_)) return header_->bounds(); const Tab* last_tab = GetLastTabInGroup();
diff --git a/chrome/browser/ui/views/tabs/tab_strip_controller.h b/chrome/browser/ui/views/tabs/tab_strip_controller.h index 963b77db..9e5f1a9 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_controller.h +++ b/chrome/browser/ui/views/tabs/tab_strip_controller.h
@@ -152,8 +152,9 @@ virtual tab_groups::TabGroupColorId GetGroupColorId( const tab_groups::TabGroupId& group) const = 0; - virtual bool GetGroupCollapsedState( - const tab_groups::TabGroupId& group) const = 0; + // Returns the |group| collapsed state. Returns false if the group does not + // exist or is not collapsed. + virtual bool IsGroupCollapsed(const tab_groups::TabGroupId& group) const = 0; // Sets the title and color ID of the given |group|. virtual void SetVisualDataForGroup(
diff --git a/chrome/browser/ui/views/tabs/tab_strip_layout_helper.cc b/chrome/browser/ui/views/tabs/tab_strip_layout_helper.cc index 35b3158..87063e68 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_layout_helper.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_layout_helper.cc
@@ -344,7 +344,7 @@ base::Optional<tab_groups::TabGroupId> id = slots_[i].view->group(); bool slot_is_collapsed_tab = (slots_[i].type == ViewType::kTab && id.has_value()) - ? controller_->GetGroupCollapsedState(id.value()) + ? controller_->IsGroupCollapsed(id.value()) : false; auto open = (slots_[i].animation->IsClosing() || slot_is_collapsed_tab)
diff --git a/chrome/browser/ui/webui/certificate_manager_localized_strings_provider.cc b/chrome/browser/ui/webui/certificate_manager_localized_strings_provider.cc index 1fb5f60..d250a38 100644 --- a/chrome/browser/ui/webui/certificate_manager_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/certificate_manager_localized_strings_provider.cc
@@ -15,74 +15,92 @@ void AddLocalizedStrings(content::WebUIDataSource* html_source) { static constexpr webui::LocalizedString kLocalizedStrings[] = { - {"certificateManagerExpandA11yLabel", - IDS_SETTINGS_CERTIFICATE_MANAGER_EXPAND_ACCESSIBILITY_LABEL}, - {"certificateManagerNoCertificates", - IDS_SETTINGS_CERTIFICATE_MANAGER_NO_CERTIFICATES}, - {"certificateManagerYourCertificates", - IDS_SETTINGS_CERTIFICATE_MANAGER_YOUR_CERTIFICATES}, - {"certificateManagerYourCertificatesDescription", - IDS_SETTINGS_CERTIFICATE_MANAGER_YOUR_CERTIFICATES_DESCRIPTION}, - {"certificateManagerServers", IDS_SETTINGS_CERTIFICATE_MANAGER_SERVERS}, - {"certificateManagerServersDescription", - IDS_SETTINGS_CERTIFICATE_MANAGER_SERVERS_DESCRIPTION}, - {"certificateManagerAuthorities", - IDS_SETTINGS_CERTIFICATE_MANAGER_AUTHORITIES}, - {"certificateManagerAuthoritiesDescription", - IDS_SETTINGS_CERTIFICATE_MANAGER_AUTHORITIES_DESCRIPTION}, - {"certificateManagerOthers", IDS_SETTINGS_CERTIFICATE_MANAGER_OTHERS}, - {"certificateManagerOthersDescription", - IDS_SETTINGS_CERTIFICATE_MANAGER_OTHERS_DESCRIPTION}, - {"certificateManagerView", IDS_SETTINGS_CERTIFICATE_MANAGER_VIEW}, - {"certificateManagerImport", IDS_SETTINGS_CERTIFICATE_MANAGER_IMPORT}, - {"certificateManagerImportAndBind", - IDS_SETTINGS_CERTIFICATE_MANAGER_IMPORT_AND_BIND}, - {"certificateManagerExport", IDS_SETTINGS_CERTIFICATE_MANAGER_EXPORT}, - {"certificateManagerDelete", IDS_SETTINGS_DELETE}, - {"certificateManagerUntrusted", - IDS_SETTINGS_CERTIFICATE_MANAGER_UNTRUSTED}, - // CA trust edit dialog. - {"certificateManagerCaTrustEditDialogTitle", - IDS_SETTINGS_CERTIFICATE_MANAGER_CA_TRUST_EDIT_DIALOG_TITLE}, - {"certificateManagerCaTrustEditDialogDescription", - IDS_SETTINGS_CERTIFICATE_MANAGER_CA_TRUST_EDIT_DIALOG_DESCRIPTION}, - {"certificateManagerCaTrustEditDialogExplanation", - IDS_SETTINGS_CERTIFICATE_MANAGER_CA_TRUST_EDIT_DIALOG_EXPLANATION}, - {"certificateManagerCaTrustEditDialogSsl", - IDS_SETTINGS_CERTIFICATE_MANAGER_CA_TRUST_EDIT_DIALOG_SSL}, - {"certificateManagerCaTrustEditDialogEmail", - IDS_SETTINGS_CERTIFICATE_MANAGER_CA_TRUST_EDIT_DIALOG_EMAIL}, - {"certificateManagerCaTrustEditDialogObjSign", - IDS_SETTINGS_CERTIFICATE_MANAGER_CA_TRUST_EDIT_DIALOG_OBJ_SIGN}, - // Certificate delete confirmation dialog. - {"certificateManagerDeleteUserTitle", - IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_USER_TITLE}, - {"certificateManagerDeleteUserDescription", - IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_USER_DESCRIPTION}, - {"certificateManagerDeleteServerTitle", - IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_SERVER_TITLE}, - {"certificateManagerDeleteServerDescription", - IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_SERVER_DESCRIPTION}, - {"certificateManagerDeleteCaTitle", - IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_CA_TITLE}, - {"certificateManagerDeleteCaDescription", - IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_CA_DESCRIPTION}, - {"certificateManagerDeleteOtherTitle", - IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_OTHER_TITLE}, - // Encrypt/decrypt password dialogs. - {"certificateManagerEncryptPasswordTitle", - IDS_SETTINGS_CERTIFICATE_MANAGER_ENCRYPT_PASSWORD_TITLE}, - {"certificateManagerDecryptPasswordTitle", - IDS_SETTINGS_CERTIFICATE_MANAGER_DECRYPT_PASSWORD_TITLE}, - {"certificateManagerEncryptPasswordDescription", - IDS_SETTINGS_CERTIFICATE_MANAGER_ENCRYPT_PASSWORD_DESCRIPTION}, - {"certificateManagerPassword", IDS_SETTINGS_CERTIFICATE_MANAGER_PASSWORD}, - {"certificateManagerConfirmPassword", - IDS_SETTINGS_CERTIFICATE_MANAGER_CONFIRM_PASSWORD}, - {"certificateImportErrorFormat", - IDS_SETTINGS_CERTIFICATE_MANAGER_IMPORT_ERROR_FORMAT}, - // For A11y. - {"menu", IDS_MENU}, + {"certificateManagerExpandA11yLabel", + IDS_SETTINGS_CERTIFICATE_MANAGER_EXPAND_ACCESSIBILITY_LABEL}, + {"certificateManagerNoCertificates", + IDS_SETTINGS_CERTIFICATE_MANAGER_NO_CERTIFICATES}, + {"certificateManagerYourCertificates", + IDS_SETTINGS_CERTIFICATE_MANAGER_YOUR_CERTIFICATES}, + {"certificateManagerYourCertificatesDescription", + IDS_SETTINGS_CERTIFICATE_MANAGER_YOUR_CERTIFICATES_DESCRIPTION}, + {"certificateManagerServers", IDS_SETTINGS_CERTIFICATE_MANAGER_SERVERS}, + {"certificateManagerServersDescription", + IDS_SETTINGS_CERTIFICATE_MANAGER_SERVERS_DESCRIPTION}, + {"certificateManagerAuthorities", + IDS_SETTINGS_CERTIFICATE_MANAGER_AUTHORITIES}, + {"certificateManagerAuthoritiesDescription", + IDS_SETTINGS_CERTIFICATE_MANAGER_AUTHORITIES_DESCRIPTION}, + {"certificateManagerOthers", IDS_SETTINGS_CERTIFICATE_MANAGER_OTHERS}, + {"certificateManagerOthersDescription", + IDS_SETTINGS_CERTIFICATE_MANAGER_OTHERS_DESCRIPTION}, + {"certificateManagerView", IDS_SETTINGS_CERTIFICATE_MANAGER_VIEW}, + {"certificateManagerImport", IDS_SETTINGS_CERTIFICATE_MANAGER_IMPORT}, + {"certificateManagerImportAndBind", + IDS_SETTINGS_CERTIFICATE_MANAGER_IMPORT_AND_BIND}, + {"certificateManagerExport", IDS_SETTINGS_CERTIFICATE_MANAGER_EXPORT}, + {"certificateManagerDelete", IDS_SETTINGS_DELETE}, + {"certificateManagerUntrusted", IDS_SETTINGS_CERTIFICATE_MANAGER_UNTRUSTED}, + // CA trust edit dialog. + {"certificateManagerCaTrustEditDialogTitle", + IDS_SETTINGS_CERTIFICATE_MANAGER_CA_TRUST_EDIT_DIALOG_TITLE}, + {"certificateManagerCaTrustEditDialogDescription", + IDS_SETTINGS_CERTIFICATE_MANAGER_CA_TRUST_EDIT_DIALOG_DESCRIPTION}, + {"certificateManagerCaTrustEditDialogExplanation", + IDS_SETTINGS_CERTIFICATE_MANAGER_CA_TRUST_EDIT_DIALOG_EXPLANATION}, + {"certificateManagerCaTrustEditDialogSsl", + IDS_SETTINGS_CERTIFICATE_MANAGER_CA_TRUST_EDIT_DIALOG_SSL}, + {"certificateManagerCaTrustEditDialogEmail", + IDS_SETTINGS_CERTIFICATE_MANAGER_CA_TRUST_EDIT_DIALOG_EMAIL}, + {"certificateManagerCaTrustEditDialogObjSign", + IDS_SETTINGS_CERTIFICATE_MANAGER_CA_TRUST_EDIT_DIALOG_OBJ_SIGN}, + // Certificate delete confirmation dialog. + {"certificateManagerDeleteUserTitle", + IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_USER_TITLE}, + {"certificateManagerDeleteUserDescription", + IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_USER_DESCRIPTION}, + {"certificateManagerDeleteServerTitle", + IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_SERVER_TITLE}, + {"certificateManagerDeleteServerDescription", + IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_SERVER_DESCRIPTION}, + {"certificateManagerDeleteCaTitle", + IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_CA_TITLE}, + {"certificateManagerDeleteCaDescription", + IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_CA_DESCRIPTION}, + {"certificateManagerDeleteOtherTitle", + IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_OTHER_TITLE}, + // Encrypt/decrypt password dialogs. + {"certificateManagerEncryptPasswordTitle", + IDS_SETTINGS_CERTIFICATE_MANAGER_ENCRYPT_PASSWORD_TITLE}, + {"certificateManagerDecryptPasswordTitle", + IDS_SETTINGS_CERTIFICATE_MANAGER_DECRYPT_PASSWORD_TITLE}, + {"certificateManagerEncryptPasswordDescription", + IDS_SETTINGS_CERTIFICATE_MANAGER_ENCRYPT_PASSWORD_DESCRIPTION}, + {"certificateManagerPassword", IDS_SETTINGS_CERTIFICATE_MANAGER_PASSWORD}, + {"certificateManagerConfirmPassword", + IDS_SETTINGS_CERTIFICATE_MANAGER_CONFIRM_PASSWORD}, + {"certificateImportErrorFormat", + IDS_SETTINGS_CERTIFICATE_MANAGER_IMPORT_ERROR_FORMAT}, +#if defined(OS_CHROMEOS) + {"certificateProvisioningListHeader", + IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_LIST_HEADER}, + {"certificateProvisioningRefresh", + IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_REFRESH}, + {"certificateProvisioningDetails", + IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_DETAILS}, + {"certificateProvisioningAdvancedSectionTitle", + IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_ADVANCED}, + {"certificateProvisioningProfile", + IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_CERTIFICATE_PROFILE}, + {"certificateProvisioningStatus", + IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS}, + {"certificateProvisioningStatusId", + IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_ID}, + {"certificateProvisioningLastUpdate", + IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_LAST_UPDATE}, + {"certificateProvisioningPublicKey", IDS_CERT_DETAILS_SUBJECT_KEY}, +#endif // defined(OS_CHROMEOS) + // For A11y. + {"menu", IDS_MENU}, }; AddLocalizedStringsBulk(html_source, kLocalizedStrings); }
diff --git a/chrome/browser/ui/webui/certificate_provisioning_ui_handler.cc b/chrome/browser/ui/webui/certificate_provisioning_ui_handler.cc new file mode 100644 index 0000000..1542ce87 --- /dev/null +++ b/chrome/browser/ui/webui/certificate_provisioning_ui_handler.cc
@@ -0,0 +1,247 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <string> + +#include "chrome/browser/ui/webui/certificate_provisioning_ui_handler.h" + +#include "base/bind.h" +#include "base/containers/span.h" +#include "base/strings/string16.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/time/time.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_process_platform_part.h" +#include "chrome/browser/chromeos/cert_provisioning/cert_provisioning_common.h" +#include "chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler.h" +#include "chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler_user_service.h" +#include "chrome/browser/chromeos/cert_provisioning/cert_provisioning_worker.h" +#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/common/net/x509_certificate_model_nss.h" +#include "chrome/grit/generated_resources.h" +#include "components/user_manager/user.h" +#include "components/user_manager/user_manager.h" +#include "content/public/browser/web_ui.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/l10n/time_format.h" + +namespace chromeos { +namespace cert_provisioning { + +namespace { + +// Returns localized representation for the state of a certificate provisioning +// process. +base::string16 GetProvisioningProcessStatus( + chromeos::cert_provisioning::CertProvisioningWorkerState state) { + using CertProvisioningWorkerState = + chromeos::cert_provisioning::CertProvisioningWorkerState; + switch (state) { + case CertProvisioningWorkerState ::kInitState: + return l10n_util::GetStringUTF16( + IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_PREPARING_CSR); + case CertProvisioningWorkerState ::kKeypairGenerated: + return l10n_util::GetStringUTF16( + IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_PREPARING_CSR_WAITING); + case CertProvisioningWorkerState::kStartCsrResponseReceived: + // Intentional fall-through. + case CertProvisioningWorkerState::kVaChallengeFinished: + // Intentional fall-through. + case CertProvisioningWorkerState::kKeyRegistered: + // Intentional fall-through. + case CertProvisioningWorkerState::kKeypairMarked: + return l10n_util::GetStringUTF16( + IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_PREPARING_CSR); + case CertProvisioningWorkerState::kSignCsrFinished: + return l10n_util::GetStringUTF16( + IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_PREPARING_CSR_WAITING); + case CertProvisioningWorkerState::kFinishCsrResponseReceived: + return l10n_util::GetStringUTF16( + IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_WAITING_FOR_CA); + case CertProvisioningWorkerState::kSucceeded: + return l10n_util::GetStringUTF16( + IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_SUCCESS); + case CertProvisioningWorkerState::kFailed: + return l10n_util::GetStringUTF16( + IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_FAILURE); + case CertProvisioningWorkerState::kInconsistentDataError: + return l10n_util::GetStringUTF16( + IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_PREPARING_CSR_WAITING); + case CertProvisioningWorkerState::kCanceled: + return l10n_util::GetStringUTF16( + IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_STATUS_CANCELED); + } + NOTREACHED(); +} + +// Returns a localized representation of the last update time as a delay (e.g. +// "5 minutes ago". +base::string16 GetTimeSinceLastUpdate(base::Time last_update_time) { + const base::Time now = base::Time::NowFromSystemTime(); + if (last_update_time.is_null() || last_update_time > now) + return base::string16(); + const base::TimeDelta elapsed_time = now - last_update_time; + return ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_ELAPSED, + ui::TimeFormat::LENGTH_SHORT, elapsed_time); +} + +base::Value CreateProvisioningProcessEntry( + const std::string& cert_profile_id, + bool is_device_wide, + chromeos::cert_provisioning::CertProvisioningWorkerState state, + base::Time time_since_last_update, + const std::string& public_key_spki_der) { + base::Value entry(base::Value::Type::DICTIONARY); + entry.SetStringKey("certProfileId", cert_profile_id); + entry.SetBoolKey("isDeviceWide", is_device_wide); + entry.SetStringKey("status", GetProvisioningProcessStatus(state)); + entry.SetIntKey("stateId", static_cast<int>(state)); + entry.SetStringKey("timeSinceLastUpdate", + GetTimeSinceLastUpdate(time_since_last_update)); + + auto spki_der_bytes = base::as_bytes(base::make_span(public_key_spki_der)); + entry.SetStringKey( + "publicKey", + x509_certificate_model::ProcessRawSubjectPublicKeyInfo(spki_der_bytes)); + + return entry; +} + +// Collects information about certificate provisioning processes from +// |cert_provisioning_scheduler| and appends them to |list_to_append_to|. +void CollectProvisioningProcesses( + base::Value* list_to_append_to, + CertProvisioningScheduler* cert_provisioning_scheduler, + bool is_device_wide) { + for (const auto& worker_entry : cert_provisioning_scheduler->GetWorkers()) { + CertProvisioningWorker* worker = worker_entry.second.get(); + list_to_append_to->Append(CreateProvisioningProcessEntry( + worker_entry.first, is_device_wide, worker->GetState(), + worker->GetLastUpdateTime(), worker->GetPublicKey())); + } + for (const auto& failed_worker_entry : + cert_provisioning_scheduler->GetFailedCertProfileIds()) { + const chromeos::cert_provisioning::FailedWorkerInfo& worker = + failed_worker_entry.second; + list_to_append_to->Append(CreateProvisioningProcessEntry( + failed_worker_entry.first, is_device_wide, worker.state, + worker.last_update_time, worker.public_key)); + } +} + +} // namespace + +CertificateProvisioningUiHandler::CertificateProvisioningUiHandler() = default; +CertificateProvisioningUiHandler::~CertificateProvisioningUiHandler() = default; + +void CertificateProvisioningUiHandler::RegisterMessages() { + // Passing base::Unretained(this) to web_ui()->RegisterMessageCallback is fine + // because in chrome Web UI, web_ui() has acquired ownership of |this| and + // maintains the life time of |this| accordingly. + web_ui()->RegisterMessageCallback( + "refreshCertificateProvisioningProcessses", + base::BindRepeating(&CertificateProvisioningUiHandler:: + HandleRefreshCertificateProvisioningProcesses, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "triggerCertificateProvisioningProcessUpdate", + base::BindRepeating(&CertificateProvisioningUiHandler:: + HandleTriggerCertificateProvisioningProcessUpdate, + base::Unretained(this))); +} + +CertProvisioningScheduler* +CertificateProvisioningUiHandler::GetCertProvisioningSchedulerForUser( + Profile* user_profile) { + chromeos::cert_provisioning::CertProvisioningSchedulerUserService* + user_service = chromeos::cert_provisioning:: + CertProvisioningSchedulerUserServiceFactory::GetForProfile( + user_profile); + if (!user_service) + return nullptr; + return user_service->scheduler(); +} + +CertProvisioningScheduler* +CertificateProvisioningUiHandler::GetCertProvisioningSchedulerForDevice( + Profile* user_profile) { + const user_manager::User* user = + chromeos::ProfileHelper::Get()->GetUserByProfile(user_profile); + if (!user || !user->IsAffiliated()) + return nullptr; + + policy::BrowserPolicyConnectorChromeOS* connector = + g_browser_process->platform_part()->browser_policy_connector_chromeos(); + return connector->GetDeviceCertProvisioningScheduler(); +} + +void CertificateProvisioningUiHandler:: + HandleRefreshCertificateProvisioningProcesses(const base::ListValue* args) { + CHECK_EQ(0U, args->GetSize()); + AllowJavascript(); + RefreshCertificateProvisioningProcesses(); +} + +void CertificateProvisioningUiHandler:: + HandleTriggerCertificateProvisioningProcessUpdate( + const base::ListValue* args) { + CHECK_EQ(2U, args->GetSize()); + if (!args->is_list()) + return; + const base::Value& cert_profile_id = args->GetList()[0]; + if (!cert_profile_id.is_string()) + return; + const base::Value& device_wide = args->GetList()[1]; + if (!device_wide.is_bool()) + return; + + Profile* profile = Profile::FromWebUI(web_ui()); + CertProvisioningScheduler* scheduler = + device_wide.GetBool() ? GetCertProvisioningSchedulerForDevice(profile) + : GetCertProvisioningSchedulerForUser(profile); + if (!scheduler) + return; + + scheduler->UpdateOneCert(cert_profile_id.GetString()); + + // Send an update to the UI immediately to reflect a possible status change. + RefreshCertificateProvisioningProcesses(); + + // Trigger a refresh in a few seconds, in case the state has triggered a + // refresh with the server. + // TODO(https://crbug.com/1045895): Use a real observer instead. + constexpr base::TimeDelta kTimeToWaitBeforeRefresh = + base::TimeDelta::FromSeconds(10); + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&CertificateProvisioningUiHandler:: + RefreshCertificateProvisioningProcesses, + weak_ptr_factory_.GetWeakPtr()), + kTimeToWaitBeforeRefresh); +} + +void CertificateProvisioningUiHandler:: + RefreshCertificateProvisioningProcesses() { + Profile* profile = Profile::FromWebUI(web_ui()); + + base::ListValue all_processes; + CertProvisioningScheduler* scheduler_for_user = + GetCertProvisioningSchedulerForUser(profile); + if (scheduler_for_user) + CollectProvisioningProcesses(&all_processes, scheduler_for_user, + /*is_device_wide=*/false); + + CertProvisioningScheduler* scheduler_for_device = + GetCertProvisioningSchedulerForDevice(profile); + if (scheduler_for_device) + CollectProvisioningProcesses(&all_processes, scheduler_for_device, + /*is_device_wide=*/true); + + FireWebUIListener("certificate-provisioning-processes-changed", + std::move(all_processes)); +} + +} // namespace cert_provisioning +} // namespace chromeos
diff --git a/chrome/browser/ui/webui/certificate_provisioning_ui_handler.h b/chrome/browser/ui/webui/certificate_provisioning_ui_handler.h new file mode 100644 index 0000000..16c2808 --- /dev/null +++ b/chrome/browser/ui/webui/certificate_provisioning_ui_handler.h
@@ -0,0 +1,69 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_WEBUI_CERTIFICATE_PROVISIONING_UI_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_CERTIFICATE_PROVISIONING_UI_HANDLER_H_ + +#include "base/memory/weak_ptr.h" +#include "base/values.h" +#include "content/public/browser/web_ui_message_handler.h" + +class Profile; + +namespace chromeos { +namespace cert_provisioning { + +class CertProvisioningScheduler; + +class CertificateProvisioningUiHandler : public content::WebUIMessageHandler { + public: + CertificateProvisioningUiHandler(); + + CertificateProvisioningUiHandler( + const CertificateProvisioningUiHandler& other) = delete; + CertificateProvisioningUiHandler& operator=( + const CertificateProvisioningUiHandler& other) = delete; + + ~CertificateProvisioningUiHandler() override; + + // content::WebUIMessageHandler. + void RegisterMessages() override; + + private: + // Returns the per-user CertProvisioningScheduler for |user_profile|, if it + // has any. + chromeos::cert_provisioning::CertProvisioningScheduler* + GetCertProvisioningSchedulerForUser(Profile* user_profile); + + // Returns the per-device CertProvisioningScheduler, if |user_profile| is + // associated with a user that has access to device-wide client certificates. + chromeos::cert_provisioning::CertProvisioningScheduler* + GetCertProvisioningSchedulerForDevice(Profile* user_profile); + + // Send the list of certificate provisioning processes to the UI, triggered by + // the UI when it loads. + // |args| is expected to be empty. + void HandleRefreshCertificateProvisioningProcesses( + const base::ListValue* args); + + // Trigger an update / refresh on a certificate provisioning process. + // |args| is expected to contain two arguments: + // The argument at index 0 is a string specifying the certificate profile id + // of the process that an update should be triggered for. The argument at + // index 1 is a boolean specifying whether the process is a user-specific + // (false) or a device-wide (true) certificate provisioning process. + void HandleTriggerCertificateProvisioningProcessUpdate( + const base::ListValue* args); + + // Send the list of certificate provisioning processes to the UI. + void RefreshCertificateProvisioningProcesses(); + + base::WeakPtrFactory<CertificateProvisioningUiHandler> weak_ptr_factory_{ + this}; +}; + +} // namespace cert_provisioning +} // namespace chromeos + +#endif // CHROME_BROWSER_UI_WEBUI_CERTIFICATE_PROVISIONING_UI_HANDLER_H_
diff --git a/chrome/browser/ui/webui/chromeos/certificate_manager_dialog_ui.cc b/chrome/browser/ui/webui/chromeos/certificate_manager_dialog_ui.cc index 4fbfb465..518c0a2 100644 --- a/chrome/browser/ui/webui/chromeos/certificate_manager_dialog_ui.cc +++ b/chrome/browser/ui/webui/chromeos/certificate_manager_dialog_ui.cc
@@ -8,6 +8,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/certificate_manager_localized_strings_provider.h" +#include "chrome/browser/ui/webui/certificate_provisioning_ui_handler.h" #include "chrome/browser/ui/webui/certificates_handler.h" #include "chrome/browser/ui/webui/chromeos/bluetooth_dialog_localized_strings_provider.h" #include "chrome/common/url_constants.h" @@ -59,6 +60,9 @@ web_ui->AddMessageHandler( std::make_unique<certificate_manager::CertificatesHandler>()); + web_ui->AddMessageHandler( + std::make_unique< + chromeos::cert_provisioning::CertificateProvisioningUiHandler>()); content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), source); }
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc index f85f7e0..fe085d5 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
@@ -651,7 +651,7 @@ } void PrintPreviewUI::OnDidStartPreview( - const PrintHostMsg_DidStartPreview_Params& params, + const mojom::DidStartPreviewParams& params, int request_id) { DCHECK_GT(params.page_count, 0); DCHECK(!params.pages_to_render.empty());
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.h b/chrome/browser/ui/webui/print_preview/print_preview_ui.h index 1bdafd9..d8611a2 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_ui.h +++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.h
@@ -26,7 +26,6 @@ #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" -struct PrintHostMsg_DidStartPreview_Params; struct PrintHostMsg_PreviewIds; struct PrintHostMsg_RequestPrintPreview_Params; @@ -146,7 +145,7 @@ virtual void OnPrintPreviewRequest(int request_id); // Notifies the Web UI about the properties of the request preview. - void OnDidStartPreview(const PrintHostMsg_DidStartPreview_Params& params, + void OnDidStartPreview(const mojom::DidStartPreviewParams& params, int request_id); // Notifies the Web UI of the default page layout according to the currently
diff --git a/chrome/browser/ui/webui/settings/chromeos/fake_hierarchy.cc b/chrome/browser/ui/webui/settings/chromeos/fake_hierarchy.cc new file mode 100644 index 0000000..dff558c --- /dev/null +++ b/chrome/browser/ui/webui/settings/chromeos/fake_hierarchy.cc
@@ -0,0 +1,33 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/settings/chromeos/fake_hierarchy.h" + +namespace chromeos { +namespace settings { + +FakeHierarchy::FakeHierarchy() = default; + +FakeHierarchy::~FakeHierarchy() = default; + +void FakeHierarchy::AddSubpageMetadata( + mojom::Section section, + mojom::Subpage subpage, + base::Optional<mojom::Subpage> parent_subpage) { + auto pair = subpage_map_.emplace(subpage, section); + DCHECK(pair.second); + pair.first->second.parent_subpage = parent_subpage; +} + +void FakeHierarchy::AddSettingMetadata( + mojom::Section section, + mojom::Setting setting, + base::Optional<mojom::Subpage> parent_subpage) { + auto pair = setting_map_.emplace(setting, section); + DCHECK(pair.second); + pair.first->second.primary.second = parent_subpage; +} + +} // namespace settings +} // namespace chromeos
diff --git a/chrome/browser/ui/webui/settings/chromeos/fake_hierarchy.h b/chrome/browser/ui/webui/settings/chromeos/fake_hierarchy.h new file mode 100644 index 0000000..df08452 --- /dev/null +++ b/chrome/browser/ui/webui/settings/chromeos/fake_hierarchy.h
@@ -0,0 +1,36 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_FAKE_HIERARCHY_H_ +#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_FAKE_HIERARCHY_H_ + +#include "base/optional.h" +#include "chrome/browser/ui/webui/settings/chromeos/hierarchy.h" + +namespace chromeos { +namespace settings { + +// Fake Hierarchy implementation. Note that this class currently does not +// provide "alternate settings location" functionality. +class FakeHierarchy : public Hierarchy { + public: + FakeHierarchy(); + FakeHierarchy(const FakeHierarchy& other) = delete; + FakeHierarchy& operator=(const FakeHierarchy& other) = delete; + ~FakeHierarchy() override; + + void AddSubpageMetadata( + mojom::Section section, + mojom::Subpage subpage, + base::Optional<mojom::Subpage> parent_subpage = base::nullopt); + void AddSettingMetadata( + mojom::Section section, + mojom::Setting setting, + base::Optional<mojom::Subpage> parent_subpage = base::nullopt); +}; + +} // namespace settings +} // namespace chromeos + +#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_FAKE_HIERARCHY_H_
diff --git a/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_section.cc b/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_section.cc new file mode 100644 index 0000000..96eea8ab --- /dev/null +++ b/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_section.cc
@@ -0,0 +1,25 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/settings/chromeos/fake_os_settings_section.h" + +#include <sstream> + +namespace chromeos { +namespace settings { + +FakeOsSettingsSection::FakeOsSettingsSection(mojom::Section section) + : section_(section) {} + +FakeOsSettingsSection::~FakeOsSettingsSection() = default; + +std::string FakeOsSettingsSection::ModifySearchResultUrl( + const SearchConcept& concept) const { + std::stringstream ss; + ss << section_ << "::" << concept.url_path_with_parameters; + return ss.str(); +} + +} // namespace settings +} // namespace chromeos
diff --git a/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_section.h b/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_section.h new file mode 100644 index 0000000..3154bbb9 --- /dev/null +++ b/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_section.h
@@ -0,0 +1,41 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_FAKE_OS_SETTINGS_SECTION_H_ +#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_FAKE_OS_SETTINGS_SECTION_H_ + +#include "chrome/browser/ui/webui/settings/chromeos/os_settings_section.h" + +namespace chromeos { +namespace settings { + +// Fake OsSettingsSection implementation. +class FakeOsSettingsSection : public OsSettingsSection { + public: + explicit FakeOsSettingsSection(mojom::Section section); + ~FakeOsSettingsSection() override; + + FakeOsSettingsSection(const FakeOsSettingsSection& other) = delete; + FakeOsSettingsSection& operator=(const FakeOsSettingsSection& other) = delete; + + mojom::Section section() { return section_; } + + // OsSettingsSection: + void AddLoadTimeData(content::WebUIDataSource* html_source) override {} + void RegisterHierarchy(HierarchyGenerator* generator) const override {} + + // Prepends the section name and "::" to the URL in |concept|. For example, if + // the URL is "networkDetails" and the section is mojom::Section::kNetwork, + // the returned URL is "Section::kNetwork::networkDetails". + std::string ModifySearchResultUrl( + const SearchConcept& concept) const override; + + private: + const mojom::Section section_; +}; + +} // namespace settings +} // namespace chromeos + +#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_FAKE_OS_SETTINGS_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_sections.cc b/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_sections.cc new file mode 100644 index 0000000..253d965 --- /dev/null +++ b/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_sections.cc
@@ -0,0 +1,24 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/settings/chromeos/fake_os_settings_sections.h" + +#include "chrome/browser/ui/webui/settings/chromeos/constants/constants_util.h" +#include "chrome/browser/ui/webui/settings/chromeos/fake_os_settings_section.h" + +namespace chromeos { +namespace settings { + +FakeOsSettingsSections::FakeOsSettingsSections() : OsSettingsSections() { + for (const auto& section : constants::AllSections()) { + auto fake_section = std::make_unique<FakeOsSettingsSection>(section); + sections_map_[section] = fake_section.get(); + sections_.push_back(std::move(fake_section)); + } +} + +FakeOsSettingsSections::~FakeOsSettingsSections() = default; + +} // namespace settings +} // namespace chromeos
diff --git a/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_sections.h b/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_sections.h new file mode 100644 index 0000000..2c148a72 --- /dev/null +++ b/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_sections.h
@@ -0,0 +1,26 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_FAKE_OS_SETTINGS_SECTIONS_H_ +#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_FAKE_OS_SETTINGS_SECTIONS_H_ + +#include "chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h" + +namespace chromeos { +namespace settings { + +// Collection of FakeOsSettingsSections. +class FakeOsSettingsSections : public OsSettingsSections { + public: + FakeOsSettingsSections(); + FakeOsSettingsSections(const FakeOsSettingsSections& other) = delete; + FakeOsSettingsSections& operator=(const FakeOsSettingsSections& other) = + delete; + ~FakeOsSettingsSections() override; +}; + +} // namespace settings +} // namespace chromeos + +#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_FAKE_OS_SETTINGS_SECTIONS_H_
diff --git a/chrome/browser/ui/webui/settings/chromeos/hierarchy.cc b/chrome/browser/ui/webui/settings/chromeos/hierarchy.cc index adb79f5..7fbfe69 100644 --- a/chrome/browser/ui/webui/settings/chromeos/hierarchy.cc +++ b/chrome/browser/ui/webui/settings/chromeos/hierarchy.cc
@@ -126,6 +126,8 @@ } } +Hierarchy::Hierarchy() = default; + Hierarchy::~Hierarchy() = default; const Hierarchy::SubpageMetadata& Hierarchy::GetSubpageMetadata(
diff --git a/chrome/browser/ui/webui/settings/chromeos/hierarchy.h b/chrome/browser/ui/webui/settings/chromeos/hierarchy.h index 7ff4283..43e283c08 100644 --- a/chrome/browser/ui/webui/settings/chromeos/hierarchy.h +++ b/chrome/browser/ui/webui/settings/chromeos/hierarchy.h
@@ -36,7 +36,7 @@ explicit Hierarchy(const OsSettingsSections& sections); Hierarchy(const Hierarchy& other) = delete; Hierarchy& operator=(const Hierarchy& other) = delete; - ~Hierarchy(); + virtual ~Hierarchy(); struct SubpageMetadata { explicit SubpageMetadata(mojom::Section section); @@ -69,11 +69,15 @@ const SubpageMetadata& GetSubpageMetadata(mojom::Subpage subpage) const; const SettingMetadata& GetSettingMetadata(mojom::Setting setting) const; - private: - class PerSectionHierarchyGenerator; + protected: + // Used by tests. + Hierarchy(); std::unordered_map<mojom::Subpage, SubpageMetadata> subpage_map_; std::unordered_map<mojom::Setting, SettingMetadata> setting_map_; + + private: + class PerSectionHierarchyGenerator; }; } // namespace settings
diff --git a/chrome/browser/ui/webui/settings/chromeos/internet_section.cc b/chrome/browser/ui/webui/settings/chromeos/internet_section.cc index 36e2cde..676e0638 100644 --- a/chrome/browser/ui/webui/settings/chromeos/internet_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/internet_section.cc
@@ -8,6 +8,7 @@ #include "ash/public/cpp/network_config_service.h" #include "base/bind.h" #include "base/no_destructor.h" +#include "base/strings/stringprintf.h" #include "chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h" #include "chrome/browser/ui/webui/settings/chromeos/internet_handler.h" @@ -374,6 +375,44 @@ return *tags; } +const std::vector<mojom::Setting>& GetEthernetDetailsSettings() { + static const base::NoDestructor<std::vector<mojom::Setting>> settings({ + mojom::Setting::kConfigureEthernet, + mojom::Setting::kEthernetAutoConfigureIp, + mojom::Setting::kEthernetDns, + mojom::Setting::kEthernetProxy, + }); + return *settings; +} + +const std::vector<mojom::Setting>& GetWifiDetailsSettings() { + static const base::NoDestructor<std::vector<mojom::Setting>> settings({ + mojom::Setting::kDisconnectWifiNetwork, + mojom::Setting::kPreferWifiNetwork, + mojom::Setting::kForgetWifiNetwork, + mojom::Setting::kConfigureWifi, + mojom::Setting::kWifiAutoConfigureIp, + mojom::Setting::kWifiDns, + mojom::Setting::kWifiProxy, + mojom::Setting::kWifiAutoConnectToNetwork, + }); + return *settings; +} + +const std::vector<mojom::Setting>& GetCellularDetailsSettings() { + static const base::NoDestructor<std::vector<mojom::Setting>> settings({ + mojom::Setting::kCellularSimLock, + mojom::Setting::kCellularRoaming, + mojom::Setting::kCellularApn, + mojom::Setting::kDisconnectCellularNetwork, + mojom::Setting::kCellularAutoConfigureIp, + mojom::Setting::kCellularDns, + mojom::Setting::kCellularProxy, + mojom::Setting::kCellularAutoConnectToNetwork, + }); + return *settings; +} + bool IsConnected(network_config::mojom::ConnectionStateType connection_state) { return connection_state == network_config::mojom::ConnectionStateType::kOnline || @@ -381,6 +420,38 @@ network_config::mojom::ConnectionStateType::kConnected; } +bool IsPartOfDetailsSubpage(const SearchConcept& concept, + mojom::Subpage details_subpage) { + switch (concept.type) { + case mojom::SearchResultType::kSection: + // Applies to a section, not a details subpage. + return false; + + case mojom::SearchResultType::kSubpage: + return concept.id.subpage == details_subpage; + + case mojom::SearchResultType::kSetting: { + const mojom::Setting& setting = concept.id.setting; + switch (details_subpage) { + case mojom::Subpage::kEthernetDetails: + return base::Contains(GetEthernetDetailsSettings(), setting); + case mojom::Subpage::kWifiDetails: + return base::Contains(GetWifiDetailsSettings(), setting); + case mojom::Subpage::kCellularDetails: + return base::Contains(GetCellularDetailsSettings(), setting); + default: + return false; + } + } + } +} + +std::string GetDetailsSubpageUrl(const SearchConcept& concept, + const std::string& guid) { + return base::StringPrintf("%s?guid=%s", concept.url_path_with_parameters, + guid.c_str()); +} + } // namespace InternetSection::InternetSection(Profile* profile, @@ -563,14 +634,8 @@ void InternetSection::RegisterHierarchy(HierarchyGenerator* generator) const { // Ethernet details. generator->RegisterTopLevelSubpage(mojom::Subpage::kEthernetDetails); - static constexpr mojom::Setting kEthernetDetailsSettings[] = { - mojom::Setting::kConfigureEthernet, - mojom::Setting::kEthernetAutoConfigureIp, - mojom::Setting::kEthernetDns, - mojom::Setting::kEthernetProxy, - }; RegisterNestedSettingBulk(mojom::Subpage::kEthernetDetails, - kEthernetDetailsSettings, generator); + GetEthernetDetailsSettings(), generator); // Wi-Fi networks. generator->RegisterTopLevelSubpage(mojom::Subpage::kWifiNetworks); @@ -581,18 +646,8 @@ // Wi-Fi details. generator->RegisterNestedSubpage(mojom::Subpage::kWifiDetails, mojom::Subpage::kWifiNetworks); - static constexpr mojom::Setting kWifiDetailsSettings[] = { - mojom::Setting::kDisconnectWifiNetwork, - mojom::Setting::kPreferWifiNetwork, - mojom::Setting::kForgetWifiNetwork, - mojom::Setting::kConfigureWifi, - mojom::Setting::kWifiAutoConfigureIp, - mojom::Setting::kWifiDns, - mojom::Setting::kWifiProxy, - mojom::Setting::kWifiAutoConnectToNetwork, - }; - RegisterNestedSettingBulk(mojom::Subpage::kWifiDetails, kWifiDetailsSettings, - generator); + RegisterNestedSettingBulk(mojom::Subpage::kWifiDetails, + GetWifiDetailsSettings(), generator); // Known networks. generator->RegisterNestedSubpage(mojom::Subpage::kKnownNetworks, @@ -616,18 +671,8 @@ // to the cellular details page and skips over the mobile data subpage. generator->RegisterNestedSubpage(mojom::Subpage::kCellularDetails, mojom::Subpage::kMobileDataNetworks); - static constexpr mojom::Setting kCellularDetailsSettings[] = { - mojom::Setting::kCellularSimLock, - mojom::Setting::kCellularRoaming, - mojom::Setting::kCellularApn, - mojom::Setting::kDisconnectCellularNetwork, - mojom::Setting::kCellularAutoConfigureIp, - mojom::Setting::kCellularDns, - mojom::Setting::kCellularProxy, - mojom::Setting::kCellularAutoConnectToNetwork, - }; RegisterNestedSettingBulk(mojom::Subpage::kCellularDetails, - kCellularDetailsSettings, generator); + GetCellularDetailsSettings(), generator); // Instant Tethering. Although this is a multi-device feature, its UI resides // in the network section. @@ -640,6 +685,27 @@ generator->RegisterTopLevelSubpage(mojom::Subpage::kVpnDetails); } +std::string InternetSection::ModifySearchResultUrl( + const SearchConcept& concept) const { + if (IsPartOfDetailsSubpage(concept, mojom::Subpage::kEthernetDetails)) + return GetDetailsSubpageUrl(concept, *connected_ethernet_guid_); + + if (IsPartOfDetailsSubpage(concept, mojom::Subpage::kWifiDetails)) + return GetDetailsSubpageUrl(concept, *connected_wifi_guid_); + + if (IsPartOfDetailsSubpage(concept, mojom::Subpage::kCellularDetails)) + return GetDetailsSubpageUrl(concept, *connected_cellular_guid_); + + if (IsPartOfDetailsSubpage(concept, mojom::Subpage::kTetherDetails)) + return GetDetailsSubpageUrl(concept, *connected_tether_guid_); + + if (IsPartOfDetailsSubpage(concept, mojom::Subpage::kVpnDetails)) + return GetDetailsSubpageUrl(concept, *connected_vpn_guid_); + + // URL does not need to be modified; use default implementation. + return OsSettingsSection::ModifySearchResultUrl(concept); +} + void InternetSection::OnDeviceStateListChanged() { FetchDeviceList(); } @@ -722,28 +788,39 @@ registry()->RemoveSearchTags(GetInstantTetheringConnectedSearchConcepts()); registry()->RemoveSearchTags(GetVpnConnectedSearchConcepts()); + connected_ethernet_guid_.reset(); + connected_wifi_guid_.reset(); + connected_cellular_guid_.reset(); + connected_tether_guid_.reset(); + connected_vpn_guid_.reset(); + for (const auto& network : networks) { if (!IsConnected(network->connection_state)) continue; switch (network->type) { case NetworkType::kEthernet: + connected_ethernet_guid_ = network->guid; registry()->AddSearchTags(GetEthernetConnectedSearchConcepts()); break; case NetworkType::kWiFi: + connected_wifi_guid_ = network->guid; registry()->AddSearchTags(GetWifiConnectedSearchConcepts()); break; case NetworkType::kCellular: + connected_cellular_guid_ = network->guid; registry()->AddSearchTags(GetCellularConnectedSearchConcepts()); break; case NetworkType::kTether: + connected_tether_guid_ = network->guid; registry()->AddSearchTags(GetInstantTetheringConnectedSearchConcepts()); break; case NetworkType::kVPN: + connected_vpn_guid_ = network->guid; registry()->AddSearchTags(GetVpnConnectedSearchConcepts()); break;
diff --git a/chrome/browser/ui/webui/settings/chromeos/internet_section.h b/chrome/browser/ui/webui/settings/chromeos/internet_section.h index d2a5903..d382969 100644 --- a/chrome/browser/ui/webui/settings/chromeos/internet_section.h +++ b/chrome/browser/ui/webui/settings/chromeos/internet_section.h
@@ -5,8 +5,10 @@ #ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_INTERNET_SECTION_H_ #define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_INTERNET_SECTION_H_ +#include <string> #include <vector> +#include "base/optional.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_section.h" #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" #include "mojo/public/cpp/bindings/receiver.h" @@ -35,6 +37,8 @@ void AddLoadTimeData(content::WebUIDataSource* html_source) override; void AddHandlers(content::WebUI* web_ui) override; void RegisterHierarchy(HierarchyGenerator* generator) const override; + std::string ModifySearchResultUrl( + const SearchConcept& concept) const override; // network_config::mojom::CrosNetworkConfigObserver: void OnActiveNetworksChanged( @@ -56,6 +60,13 @@ void OnActiveNetworks( std::vector<network_config::mojom::NetworkStatePropertiesPtr> networks); + // Note: If not connected, the below fields are null. + base::Optional<std::string> connected_ethernet_guid_; + base::Optional<std::string> connected_wifi_guid_; + base::Optional<std::string> connected_cellular_guid_; + base::Optional<std::string> connected_tether_guid_; + base::Optional<std::string> connected_vpn_guid_; + mojo::Receiver<network_config::mojom::CrosNetworkConfigObserver> receiver_{ this}; mojo::Remote<network_config::mojom::CrosNetworkConfig> cros_network_config_;
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc b/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc index 5af6db5..705605e 100644 --- a/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc +++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc
@@ -45,7 +45,8 @@ hierarchy_(std::make_unique<Hierarchy>(*sections_)) { if (base::FeatureList::IsEnabled(features::kNewOsSettingsSearch)) { search_handler_ = std::make_unique<SearchHandler>( - search_tag_registry_.get(), local_search_service); + search_tag_registry_.get(), sections_.get(), hierarchy_.get(), + local_search_service); } }
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_section.cc b/chrome/browser/ui/webui/settings/chromeos/os_settings_section.cc index ef07d21..5f7227dc 100644 --- a/chrome/browser/ui/webui/settings/chromeos/os_settings_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_section.cc
@@ -7,6 +7,7 @@ #include "base/check.h" #include "base/strings/utf_string_conversions.h" #include "base/system/sys_info.h" +#include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h" namespace chromeos { namespace settings { @@ -36,5 +37,13 @@ DCHECK(search_tag_registry); } +OsSettingsSection::OsSettingsSection() = default; + +std::string OsSettingsSection::ModifySearchResultUrl( + const SearchConcept& concept) const { + // Default case for static URLs which do not need to be modified. + return concept.url_path_with_parameters; +} + } // namespace settings } // namespace chromeos
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_section.h b/chrome/browser/ui/webui/settings/chromeos/os_settings_section.h index 9c33240..3f14647 100644 --- a/chrome/browser/ui/webui/settings/chromeos/os_settings_section.h +++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_section.h
@@ -24,6 +24,7 @@ namespace chromeos { namespace settings { +struct SearchConcept; class SearchTagRegistry; // Represents one top-level section of the settings app (i.e., one item on the @@ -98,6 +99,13 @@ // Registers the subpages and/or settings which reside in this section. virtual void RegisterHierarchy(HierarchyGenerator* generator) const = 0; + // Modifies a URL to be used by settings search. Some URLs require dynamic + // content (e.g., network detail settings use the GUID of the network as a URL + // parameter to route to details for a specific network). By default, this + // function simply returns the URL contained in |concept|, which provides + // functionality for static URLs. + virtual std::string ModifySearchResultUrl(const SearchConcept& concept) const; + protected: static base::string16 GetHelpUrlWithBoard(const std::string& original_url); static void RegisterNestedSettingBulk( @@ -107,6 +115,9 @@ OsSettingsSection(Profile* profile, SearchTagRegistry* search_tag_registry); + // Used by tests. + OsSettingsSection(); + Profile* profile() { return profile_; } SearchTagRegistry* registry() { return search_tag_registry_; }
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.cc b/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.cc index a71ad20e..13cb3091 100644 --- a/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.cc +++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.cc
@@ -131,6 +131,8 @@ sections_.push_back(std::move(about_section)); } +OsSettingsSections::OsSettingsSections() = default; + OsSettingsSections::~OsSettingsSections() = default; const OsSettingsSection* OsSettingsSections::GetSection(
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h b/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h index cd67db83..d152648 100644 --- a/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h +++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h
@@ -54,7 +54,7 @@ CupsPrintersManager* printers_manager); OsSettingsSections(const OsSettingsSections& other) = delete; OsSettingsSections& operator=(const OsSettingsSections& other) = delete; - ~OsSettingsSections(); + virtual ~OsSettingsSections(); const OsSettingsSection* GetSection(mojom::Section section) const; @@ -62,7 +62,10 @@ return sections_; } - private: + protected: + // Used by tests. + OsSettingsSections(); + std::unordered_map<mojom::Section, OsSettingsSection*> sections_map_; std::vector<std::unique_ptr<OsSettingsSection>> sections_; };
diff --git a/chrome/browser/ui/webui/settings/chromeos/people_section.cc b/chrome/browser/ui/webui/settings/chromeos/people_section.cc index 1866315..91c1cb9 100644 --- a/chrome/browser/ui/webui/settings/chromeos/people_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/people_section.cc
@@ -243,6 +243,10 @@ {"accountManagerDescription", IDS_SETTINGS_ACCOUNT_MANAGER_DESCRIPTION}, {"accountManagerChildDescription", IDS_SETTINGS_ACCOUNT_MANAGER_CHILD_DESCRIPTION}, + {"accountManagerChildFirstMessage", + IDS_SETTINGS_ACCOUNT_MANAGER_CHILD_FIRST_MESSAGE}, + {"accountManagerChildSecondMessage", + IDS_SETTINGS_ACCOUNT_MANAGER_CHILD_SECOND_MESSAGE}, {"accountListHeader", IDS_SETTINGS_ACCOUNT_MANAGER_LIST_HEADER}, {"accountManagerPrimaryAccountTooltip", IDS_SETTINGS_ACCOUNT_MANAGER_PRIMARY_ACCOUNT_TOOLTIP},
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc b/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc index 47c0052..54219e2c 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc
@@ -7,6 +7,8 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/chromeos/local_search_service/local_search_service.h" +#include "chrome/browser/ui/webui/settings/chromeos/hierarchy.h" +#include "chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" @@ -35,8 +37,12 @@ SearchHandler::SearchHandler( SearchTagRegistry* search_tag_registry, + OsSettingsSections* sections, + Hierarchy* hierarchy, local_search_service::LocalSearchService* local_search_service) : search_tag_registry_(search_tag_registry), + sections_(sections), + hierarchy_(hierarchy), index_(local_search_service->GetIndex( local_search_service::IndexId::kCrosSettings)) {} @@ -102,30 +108,43 @@ if (!concept) return nullptr; + std::string url; mojom::SearchResultIdentifierPtr result_id; switch (concept->type) { - case mojom::SearchResultType::kSection: - result_id = - mojom::SearchResultIdentifier::NewSection(concept->id.section); + case mojom::SearchResultType::kSection: { + mojom::Section section = concept->id.section; + url = GetModifiedUrl(*concept, section); + result_id = mojom::SearchResultIdentifier::NewSection(section); break; - case mojom::SearchResultType::kSubpage: - result_id = - mojom::SearchResultIdentifier::NewSubpage(concept->id.subpage); + } + case mojom::SearchResultType::kSubpage: { + mojom::Subpage subpage = concept->id.subpage; + url = GetModifiedUrl(*concept, + hierarchy_->GetSubpageMetadata(subpage).section); + result_id = mojom::SearchResultIdentifier::NewSubpage(subpage); break; - case mojom::SearchResultType::kSetting: - result_id = - mojom::SearchResultIdentifier::NewSetting(concept->id.setting); + } + case mojom::SearchResultType::kSetting: { + mojom::Setting setting = concept->id.setting; + url = GetModifiedUrl( + *concept, hierarchy_->GetSettingMetadata(setting).primary.first); + result_id = mojom::SearchResultIdentifier::NewSetting(setting); break; + } } // TODO(https://crbug.com/1071700): Generate real hierarchy instead of using // GenerateDummySettingsHierarchy(). return mojom::SearchResult::New( - l10n_util::GetStringUTF16(message_id), concept->url_path_with_parameters, - concept->icon, result.score, + l10n_util::GetStringUTF16(message_id), url, concept->icon, result.score, GenerateDummySettingsHierarchy(concept->url_path_with_parameters), concept->default_rank, concept->type, std::move(result_id)); } +std::string SearchHandler::GetModifiedUrl(const SearchConcept& concept, + mojom::Section section) const { + return sections_->GetSection(section)->ModifySearchResultUrl(concept); +} + } // namespace settings } // namespace chromeos
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h b/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h index 8247ccc..12ba659 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h +++ b/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h
@@ -21,6 +21,9 @@ namespace chromeos { namespace settings { +class Hierarchy; +class OsSettingsSections; +struct SearchConcept; class SearchTagRegistry; // Handles search queries for Chrome OS settings. Search() is expected to be @@ -37,6 +40,8 @@ static const size_t kNumMaxResults; SearchHandler(SearchTagRegistry* search_tag_registry, + OsSettingsSections* sections, + Hierarchy* hierarchy, local_search_service::LocalSearchService* local_search_service); ~SearchHandler() override; @@ -58,8 +63,12 @@ local_search_service_results); mojom::SearchResultPtr ResultToSearchResult( const local_search_service::Result& result); + std::string GetModifiedUrl(const SearchConcept& concept, + mojom::Section section) const; SearchTagRegistry* search_tag_registry_; + OsSettingsSections* sections_; + Hierarchy* hierarchy_; local_search_service::Index* index_; // Note: Expected to have multiple clients, so a ReceiverSet is used.
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc index f2c9d42..8e0d7b0 100644 --- a/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc
@@ -10,6 +10,8 @@ #include "base/test/task_environment.h" #include "chrome/browser/chromeos/local_search_service/local_search_service.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h" +#include "chrome/browser/ui/webui/settings/chromeos/fake_hierarchy.h" +#include "chrome/browser/ui/webui/settings/chromeos/fake_os_settings_sections.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom-test-utils.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/grit/generated_resources.h" @@ -58,7 +60,10 @@ protected: SearchHandlerTest() : search_tag_registry_(&local_search_service_), - handler_(&search_tag_registry_, &local_search_service_) {} + handler_(&search_tag_registry_, + &fake_sections_, + &fake_hierarchy_, + &local_search_service_) {} ~SearchHandlerTest() override = default; // testing::Test: @@ -66,12 +71,21 @@ scoped_feature_list_.InitAndEnableFeature( chromeos::features::kNewOsSettingsSearch); handler_.BindInterface(handler_remote_.BindNewPipeAndPassReceiver()); + + fake_hierarchy_.AddSubpageMetadata(mojom::Section::kPrinting, + mojom::Subpage::kPrintingDetails); + fake_hierarchy_.AddSettingMetadata(mojom::Section::kPrinting, + mojom::Setting::kAddPrinter); + fake_hierarchy_.AddSettingMetadata(mojom::Section::kPrinting, + mojom::Setting::kSavedPrinters); } base::test::TaskEnvironment task_environment_; base::test::ScopedFeatureList scoped_feature_list_; local_search_service::LocalSearchService local_search_service_; SearchTagRegistry search_tag_registry_; + FakeOsSettingsSections fake_sections_; + FakeHierarchy fake_hierarchy_; SearchHandler handler_; mojo::Remote<mojom::SearchHandler> handler_remote_; }; @@ -99,5 +113,22 @@ EXPECT_TRUE(search_results.empty()); } +TEST_F(SearchHandlerTest, UrlModification) { + // Add printing search tags to registry and search for "Saved". + search_tag_registry_.AddSearchTags(GetPrintingSearchConcepts()); + std::vector<mojom::SearchResultPtr> search_results; + mojom::SearchHandlerAsyncWaiter(handler_remote_.get()) + .Search(base::ASCIIToUTF16("Saved"), &search_results); + + // Only the "saved printers" item should be returned. + EXPECT_EQ(search_results.size(), 1u); + + // The URL should have bee modified according to the FakeOsSettingSection + // scheme. + EXPECT_EQ( + std::string("Section::kPrinting::") + mojom::kPrintingDetailsSubpagePath, + search_results[0]->url_path_with_parameters); +} + } // namespace settings } // namespace chromeos
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index b029747..1ffdbb2 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -882,6 +882,8 @@ {"passwordDetailsTitle", IDS_SETTINGS_PASSWORDS_VIEW_DETAILS_TITLE}, {"passwordViewDetails", IDS_SETTINGS_PASSWORD_DETAILS}, {"copyPassword", IDS_SETTINGS_PASSWORD_COPY}, + {"passwordStoredOnDevice", IDS_SETTINGS_PASSWORD_STORED_ON_DEVICE}, + {"passwordStoredInAccount", IDS_SETTINGS_PASSWORD_STORED_IN_ACCOUNT}, {"editPasswordWebsiteLabel", IDS_SETTINGS_PASSWORDS_WEBSITE}, {"editPasswordUsernameLabel", IDS_SETTINGS_PASSWORDS_USERNAME}, {"editPasswordPasswordLabel", IDS_SETTINGS_PASSWORDS_PASSWORD},
diff --git a/chrome/browser/ui/webui/settings/settings_ui.cc b/chrome/browser/ui/webui/settings/settings_ui.cc index 3cace0b6..9b6537e6 100644 --- a/chrome/browser/ui/webui/settings/settings_ui.cc +++ b/chrome/browser/ui/webui/settings/settings_ui.cc
@@ -103,6 +103,7 @@ #include "chrome/browser/chromeos/android_sms/android_sms_service_factory.h" #include "chrome/browser/chromeos/multidevice_setup/multidevice_setup_client_factory.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/browser/ui/webui/certificate_provisioning_ui_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/account_manager_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/android_apps_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h" @@ -170,6 +171,11 @@ #elif defined(OS_WIN) || defined(OS_MACOSX) AddSettingsPageUIHandler(std::make_unique<NativeCertificatesHandler>()); #endif // defined(USE_NSS_CERTS) +#if defined(OS_CHROMEOS) + AddSettingsPageUIHandler( + std::make_unique< + chromeos::cert_provisioning::CertificateProvisioningUiHandler>()); +#endif AddSettingsPageUIHandler(std::make_unique<AccessibilityMainHandler>()); AddSettingsPageUIHandler(std::make_unique<BrowserLifetimeHandler>());
diff --git a/chrome/browser/ui/webui/signin/inline_login_ui.cc b/chrome/browser/ui/webui/signin/inline_login_ui.cc index afc33054..3a2bbff 100644 --- a/chrome/browser/ui/webui/signin/inline_login_ui.cc +++ b/chrome/browser/ui/webui/signin/inline_login_ui.cc
@@ -52,17 +52,9 @@ source->AddLocalizedString("backButton", IDS_EDU_LOGIN_BACK); source->AddLocalizedString("nextButton", IDS_EDU_LOGIN_NEXT); - source->AddLocalizedString("welcomeTitle", IDS_EDU_LOGIN_WELCOME_TITLE); - source->AddLocalizedString("welcomeBody", IDS_EDU_LOGIN_WELCOME_BODY); - source->AddLocalizedString("welcomeReauthTitle", - IDS_EDU_LOGIN_WELCOME_REAUTH_TITLE); - source->AddLocalizedString("welcomeReauthBody", - IDS_EDU_LOGIN_WELCOME_REAUTH_BODY); - source->AddLocalizedString("parentsListTitle", - IDS_EDU_LOGIN_PARENTS_LIST_TITLE); - source->AddLocalizedString("parentsListBody", - IDS_EDU_LOGIN_PARENTS_LIST_BODY); - + source->AddLocalizedString("parentsListTitle", IDS_EDU_LOGIN_WELCOME_TITLE_2); + source->AddLocalizedString("parentsListBody", IDS_EDU_LOGIN_WELCOME_BODY_2); + source->AddLocalizedString("reauthBody", IDS_EDU_LOGIN_WELCOME_REAUTH_BODY); source->AddLocalizedString("parentSigninTitle", IDS_EDU_LOGIN_PARENT_SIGNIN_TITLE); source->AddString( @@ -131,7 +123,6 @@ {"icons.js", IDR_EDU_LOGIN_ICONS_JS}, {"browser_proxy.js", IDR_EDU_LOGIN_BROWSER_PROXY_JS}, {"edu_login_util.js", IDR_EDU_LOGIN_EDU_LOGIN_UTIL_JS}, - {"edu_login_welcome.js", IDR_EDU_LOGIN_EDU_LOGIN_WELCOME_JS}, {"edu_login_parents.js", IDR_EDU_LOGIN_EDU_LOGIN_PARENTS_JS}, {"edu_login_parent_signin.js", IDR_EDU_LOGIN_EDU_LOGIN_PARENT_SIGNIN_JS}, {"edu_login_parent_info.js", IDR_EDU_LOGIN_EDU_LOGIN_PARENT_INFO_JS},
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 2de65953..ebcb14f 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-master-1589874680-5ac33befa963a769a0374aa0b67592d28e114a8a.profdata \ No newline at end of file +chrome-mac-master-1589903980-9824f0da2e5a5b705292a405f6736e894a220581.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 31e99c01..4e53c09e 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-master-1589874680-5bafae5c8594e160e392ef10b9fbea3d577d4fff.profdata \ No newline at end of file +chrome-win32-master-1589903980-88790d48e5518ac3f655ae4b6dd9841a6fd4af4d.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 3335164..f1960db 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-master-1589831941-f19e09eb6f138b832047fb84f08c61ae600030fb.profdata \ No newline at end of file +chrome-win64-master-1589903980-ca5fa5e99fa1c661edfdfa4ab3f1c52b9013445e.profdata
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn index 7aec455..25f5f64 100644 --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn
@@ -106,8 +106,6 @@ "chrome_descriptors.h", "chrome_isolated_world_ids.h", "chrome_result_codes.h", - "chrome_ui_features_prefs.cc", - "chrome_ui_features_prefs.h", "common_message_generator.cc", "common_message_generator.h", "component_flash_hint_file_linux.cc",
diff --git a/chrome/common/chrome_ui_features_prefs.cc b/chrome/common/chrome_ui_features_prefs.cc deleted file mode 100644 index 7e06f82f..0000000 --- a/chrome/common/chrome_ui_features_prefs.cc +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/common/chrome_ui_features_prefs.h" - -#include "chrome/common/pref_names.h" -#include "components/prefs/pref_registry_simple.h" - -namespace chrome_ui_features_prefs { - -void RegisterProfilePrefs(PrefRegistrySimple* registry) { - registry->RegisterBooleanPref(prefs::kUseLegacyFormControls, - /*default_value=*/false); -} - -} // namespace chrome_ui_features_prefs
diff --git a/chrome/common/chrome_ui_features_prefs.h b/chrome/common/chrome_ui_features_prefs.h deleted file mode 100644 index 9f18b97..0000000 --- a/chrome/common/chrome_ui_features_prefs.h +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_COMMON_CHROME_UI_FEATURES_PREFS_H_ -#define CHROME_COMMON_CHROME_UI_FEATURES_PREFS_H_ - -class PrefRegistrySimple; - -namespace chrome_ui_features_prefs { - -// Register preferences for Chrome UI Features. -void RegisterProfilePrefs(PrefRegistrySimple* registry); - -} // namespace chrome_ui_features_prefs - -#endif // CHROME_COMMON_CHROME_UI_FEATURES_PREFS_H_
diff --git a/chrome/common/media_router/media_source.h b/chrome/common/media_router/media_source.h index 3c781cf..edf2111 100644 --- a/chrome/common/media_router/media_source.h +++ b/chrome/common/media_router/media_source.h
@@ -11,9 +11,6 @@ #include "base/hash/hash.h" #include "url/gurl.h" -// TODO(takumif): Move all Chromecast-specific constants out of this file, since -// they are not directly related to MediaSource. - namespace media_router { // URL schemes used by Presentation URLs for Cast and DIAL. @@ -31,6 +28,9 @@ constexpr char kMirroringAppUri[] = "cast:0F5096E8"; // Strings used in presentation IDs by the Cast SDK implementation. +// TODO(takumif): Move them out of this file, since they are not directly +// related to MediaSource. +// // This value must be the same as |chrome.cast.AUTO_JOIN_PRESENTATION_ID| in the // component extension. constexpr char kAutoJoinPresentationId[] = "auto-join";
diff --git a/chrome/common/media_router/providers/cast/cast_media_source.cc b/chrome/common/media_router/providers/cast/cast_media_source.cc index add2491..97002d0 100644 --- a/chrome/common/media_router/providers/cast/cast_media_source.cc +++ b/chrome/common/media_router/providers/cast/cast_media_source.cc
@@ -23,9 +23,6 @@ using cast_channel::CastDeviceCapability; using cast_channel::ReceiverAppType; -constexpr char kGoogleDocsOrigin[] = "https://docs.google.com"; -constexpr char kGoogleMeetOrigin[] = "https://meet.google.com"; - namespace cast_util { using media_router::AutoJoinPolicy; @@ -426,26 +423,6 @@ return app_ids; } -std::vector<url::Origin> CastMediaSource::GetAllowedOrigins() const { - // Initiation of tab mirroring via a cast: URL is permitted for Slides and - // Meet until web APIs can meet their needs. - return ContainsStreamingApp() - ? std::vector<url::Origin>( - {url::Origin::Create(GURL(kGoogleDocsOrigin)), - url::Origin::Create(GURL(kGoogleMeetOrigin))}) - : std::vector<url::Origin>(); -} - -bool CastMediaSource::IsAllowedOrigin(const url::Origin& origin) const { - // TODO(crbug.com/1047834): Check a specific origin for browser requested - // streaming. - if (ContainsStreamingApp() && origin.scheme() == url::kHttpsScheme) { - return base::Contains(GetAllowedOrigins(), origin); - } else { - return true; - } -} - void CastMediaSource::set_supported_app_types( const std::vector<ReceiverAppType>& types) { DCHECK(!types.empty());
diff --git a/chrome/common/media_router/providers/cast/cast_media_source.h b/chrome/common/media_router/providers/cast/cast_media_source.h index 1abbfd5..09c0449 100644 --- a/chrome/common/media_router/providers/cast/cast_media_source.h +++ b/chrome/common/media_router/providers/cast/cast_media_source.h
@@ -16,7 +16,6 @@ #include "chrome/common/media_router/media_source.h" #include "components/cast_channel/cast_message_util.h" #include "components/cast_channel/cast_socket.h" -#include "url/origin.h" using cast_channel::ReceiverAppType; @@ -147,14 +146,6 @@ // Returns a list of App IDs in this CastMediaSource. std::vector<std::string> GetAppIds() const; - // Returns a list of origins that are allowed to use this source. An empty - // list means any origin is allowed. For now, non-empty origins are websites - // allowed to use this source via the Presentation API. - std::vector<url::Origin> GetAllowedOrigins() const; - - // Returns true if |origin| is allowed according to GetAllowedOrigins(). - bool IsAllowedOrigin(const url::Origin& origin) const; - const MediaSource::Id& source_id() const { return source_id_; } const std::vector<CastAppInfo>& app_infos() const { return app_infos_; } const std::string& client_id() const { return client_id_; }
diff --git a/chrome/common/media_router/providers/cast/cast_media_source_unittest.cc b/chrome/common/media_router/providers/cast/cast_media_source_unittest.cc index 9439ca0..42c5c66 100644 --- a/chrome/common/media_router/providers/cast/cast_media_source_unittest.cc +++ b/chrome/common/media_router/providers/cast/cast_media_source_unittest.cc
@@ -161,30 +161,4 @@ "https://google.com/cast#__castAppId__=/param=foo")); } -TEST(CastMediaSourceTest, TestIsAllowedOrigin) { - const auto cast_app_source = CastMediaSource::FromAppId("ABCDEFAB"); - ASSERT_TRUE(cast_app_source); - ASSERT_FALSE(cast_app_source->ContainsStreamingApp()); - - const auto cast_streaming_source = - CastMediaSource::FromAppId(kCastStreamingAppId); - ASSERT_TRUE(cast_streaming_source); - ASSERT_TRUE(cast_streaming_source->ContainsStreamingApp()); - - const url::Origin empty_origin = url::Origin::Create(GURL()); - const url::Origin site_origin = - url::Origin::Create(GURL("https://www.example.com")); - const url::Origin docs_origin = - url::Origin::Create(GURL("https://docs.google.com")); - - EXPECT_TRUE(cast_app_source->IsAllowedOrigin(empty_origin)); - EXPECT_TRUE(cast_app_source->IsAllowedOrigin(site_origin)); - EXPECT_TRUE(cast_app_source->IsAllowedOrigin(docs_origin)); - - // Cast streaming apps are only allowed on whitelisted origins. - EXPECT_FALSE(cast_streaming_source->IsAllowedOrigin(site_origin)); - EXPECT_TRUE(cast_streaming_source->IsAllowedOrigin(empty_origin)); - EXPECT_TRUE(cast_streaming_source->IsAllowedOrigin(docs_origin)); -} - } // namespace media_router
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 87c8118f..4f720ae 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -2972,11 +2972,6 @@ const char kExternalProtocolDialogShowAlwaysOpenCheckbox[] = "external_protocol_dialog.show_always_open_checkbox"; -// This pref allows the FormControlsRefresh feature to be disabled temporarily -// from M81 through M84. -// TODO(1034611): Remove this after M84. -const char kUseLegacyFormControls[] = "use_legacy_form_controls"; - // This pref enables the ScrollToTextFragment feature. const char kScrollToTextFragmentEnabled[] = "scroll_to_text_fragment_enabled";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 6e1e935..46acf1e0 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -1041,8 +1041,6 @@ extern const char kExternalProtocolDialogShowAlwaysOpenCheckbox[]; -extern const char kUseLegacyFormControls[]; - extern const char kScrollToTextFragmentEnabled[]; #if defined(OS_ANDROID)
diff --git a/chrome/common/profiler/thread_profiler.cc b/chrome/common/profiler/thread_profiler.cc index f32a9ef3..06a489d 100644 --- a/chrome/common/profiler/thread_profiler.cc +++ b/chrome/common/profiler/thread_profiler.cc
@@ -26,6 +26,10 @@ #include "content/public/common/service_names.mojom.h" #include "services/service_manager/embedder/switches.h" +#if defined(OS_ANDROID) +#include "chrome/android/modules/stack_unwinder/public/module.h" +#endif + using CallStackProfileBuilder = metrics::CallStackProfileBuilder; using CallStackProfileParams = metrics::CallStackProfileParams; using StackSamplingProfiler = base::StackSamplingProfiler; @@ -62,6 +66,46 @@ return CallStackProfileParams::UNKNOWN_PROCESS; } +const base::RepeatingCallback<std::unique_ptr<base::Unwinder>()>& +GetNativeUnwinderFactory() { + const auto create_native_unwinder_factory = []() { +#if defined(OS_ANDROID) + // The module is loadable if the profiler is enabled for the current + // process. + CHECK(StackSamplingConfiguration::Get() + ->IsProfilerEnabledForCurrentProcess()); + + struct UnwinderCreationState { + std::unique_ptr<stack_unwinder::Module> module; + std::unique_ptr<stack_unwinder::MemoryRegionsMap> memory_regions_map; + }; + const auto create_native_unwinder = + [](UnwinderCreationState* creation_state) { + return creation_state->module->CreateNativeUnwinder( + creation_state->memory_regions_map.get()); + }; + + std::unique_ptr<stack_unwinder::Module> module = + stack_unwinder::Module::Load(); + std::unique_ptr<stack_unwinder::MemoryRegionsMap> memory_regions_map = + module->CreateMemoryRegionsMap(); + return base::BindRepeating( + create_native_unwinder, + base::Owned(new UnwinderCreationState{std::move(module), + std::move(memory_regions_map)})); +#else + return base::BindRepeating( + []() -> std::unique_ptr<base::Unwinder> { return nullptr; }); +#endif + }; + + static base::NoDestructor< + base::RepeatingCallback<std::unique_ptr<base::Unwinder>()>> + native_unwinder_factory(create_native_unwinder_factory()); + + return *native_unwinder_factory; +} + } // namespace // The scheduler works by splitting execution time into repeated periods such @@ -239,7 +283,8 @@ std::make_unique<CallStackProfileBuilder>( CallStackProfileParams(GetProcess(), thread, CallStackProfileParams::PROCESS_STARTUP), - work_id_recorder_.get())); + work_id_recorder_.get()), + GetNativeUnwinderFactory().Run()); startup_profiler_->Start(); @@ -303,7 +348,8 @@ work_id_recorder_.get(), base::BindOnce(&ThreadProfiler::OnPeriodicCollectionCompleted, owning_thread_task_runner_, - weak_factory_.GetWeakPtr()))); + weak_factory_.GetWeakPtr())), + GetNativeUnwinderFactory().Run()); if (aux_unwinder_factory_) periodic_profiler_->AddAuxUnwinder(aux_unwinder_factory_.Run());
diff --git a/chrome/common/profiler/thread_profiler.h b/chrome/common/profiler/thread_profiler.h index 6302c75..6c2b4f8 100644 --- a/chrome/common/profiler/thread_profiler.h +++ b/chrome/common/profiler/thread_profiler.h
@@ -7,6 +7,7 @@ #include <memory> +#include "base/callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/profiler/stack_sampling_profiler.h"
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 27f0064..6fb4442 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1270,6 +1270,7 @@ "../browser/ui/extensions/extension_message_bubble_browsertest.cc", "../browser/ui/extensions/extension_message_bubble_browsertest.h", "../browser/ui/extensions/hosted_app_browsertest.cc", + "../browser/ui/extensions/settings_overridden_params_providers_browsertest.cc", "../browser/ui/find_bar/find_bar_controller_browsertest.cc", "../browser/ui/find_bar/find_bar_host_browsertest.cc", "../browser/ui/find_bar/find_bar_platform_helper_mac_browsertest.mm", @@ -5398,6 +5399,7 @@ "../browser/ui/views/download/download_in_progress_dialog_view_unittest.cc", "../browser/ui/views/download/download_item_view_unittest.cc", "../browser/ui/views/extensions/chooser_dialog_view_unittest.cc", + "../browser/ui/views/extensions/expandable_container_view_unittest.cc", "../browser/ui/views/extensions/extensions_menu_item_unittest.cc", "../browser/ui/views/extensions/extensions_menu_view_unittest.cc", "../browser/ui/views/extensions/media_galleries_dialog_views_unittest.cc",
diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn index b6aab09..71b8017 100644 --- a/chrome/test/android/BUILD.gn +++ b/chrome/test/android/BUILD.gn
@@ -64,6 +64,8 @@ ] deps = [ ":chrome_java_test_pagecontroller", + "//base:base_java_test_support", + "//content/public/test/android:content_java_test_support", "//third_party/junit", ] @@ -104,6 +106,11 @@ sources = [ "javatests/src/org/chromium/chrome/test/pagecontroller/tests/webapk/MapsGoFirstRunTest.java" ] deps = [ ":chrome_java_test_pagecontroller", + "//base:base_java", + "//chrome/android:chrome_java", + "//chrome/android/webapk/libs/client:client_java", + "//content/public/test/android:content_java_test_support", + "//third_party/android_support_test_runner:runner_java", "//third_party/junit", ]
diff --git a/chrome/test/data/android/url_overriding/navigation_to_cct_via_intent_uri_spoofing.html b/chrome/test/data/android/url_overriding/navigation_to_cct_via_intent_uri_spoofing.html new file mode 100644 index 0000000..aa58863 --- /dev/null +++ b/chrome/test/data/android/url_overriding/navigation_to_cct_via_intent_uri_spoofing.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> +<!-- +Intent URI example taken from crbug.com/1056754 with package modification here. +--> +<head> + <meta name="viewport" + content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> +</head> + +<body> +<a id="link" target='_blank' href='intent://about:blank#Intent;package=org.chromium.chrome.tests;action=android.intent.action.VIEW;scheme=http;S.android.support.customtabs.extra.SESSION=;i.org.chromium.chrome.browser.customtabs.EXTRA_UI_TYPE=2;end;'> + Click to open App!! +</a> +</body> + +</html> \ No newline at end of file
diff --git a/chrome/test/data/extensions/search_provider_override/_locales/en/messages.json b/chrome/test/data/extensions/search_provider_override/_locales/en/messages.json new file mode 100644 index 0000000..d3c54780 --- /dev/null +++ b/chrome/test/data/extensions/search_provider_override/_locales/en/messages.json
@@ -0,0 +1,6 @@ +{ + "url_domain": { + "message": "com", + "description": "TLD for the search provider" + } +}
diff --git a/chrome/test/data/extensions/search_provider_override/manifest.json b/chrome/test/data/extensions/search_provider_override/manifest.json new file mode 100644 index 0000000..b20d4e82 --- /dev/null +++ b/chrome/test/data/extensions/search_provider_override/manifest.json
@@ -0,0 +1,17 @@ +{ + "name": "Search Override Extension", + "manifest_version": 2, + "version": "0.1", + "description": "A simple extension that overrides the search engine", + "default_locale": "en", + "chrome_settings_overrides": { + "search_provider": { + "search_url": "https://www.example.com/?q={searchTerms}", + "name": "Example", + "keyword": "word", + "encoding": "UTF-8", + "is_default": true, + "favicon_url": "https://example.com/favicon.ico" + } + } +}
diff --git a/chrome/test/data/geolocation/geolocation_on_load.html b/chrome/test/data/geolocation/geolocation_on_load.html index 69b0bb5..d83a0f6 100644 --- a/chrome/test/data/geolocation/geolocation_on_load.html +++ b/chrome/test/data/geolocation/geolocation_on_load.html
@@ -29,12 +29,14 @@ var lng = position.coords.longitude; document.getElementById('lat').innerHTML = lat; document.getElementById('lng').innerHTML = lng; + window.document.title = "Granted:1"; } function showError(positionError) { document.getElementById('lat').innerHTML = - positionError.message; + positionError.message; document.getElementById('lng').innerHTML = ''; + window.document.title = "Denied:1"; } </script>
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 0ba461d..f73409a 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -3466,7 +3466,7 @@ }, "UseLegacyFormControls": { - "note": "This policy has been removed. See https://bugs.chromium.org/p/chromium/issues/detail?id=1083085" + "note": "This policy has been removed, as of M85." }, "ScrollToTextFragmentEnabled": { @@ -5612,8 +5612,7 @@ }, "DeviceLoginScreenIsolateOrigins": { - "os": ["chromeos"], - "note": "Chrome OS device policy used by session_manager only" + "note": "This policy has been removed in Chrome 77, see https://crbug.com/964068 ." }, "DeviceLoginScreenSitePerProcess": {
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn index f3daa5da..038ed77 100644 --- a/chrome/test/data/webui/BUILD.gn +++ b/chrome/test/data/webui/BUILD.gn
@@ -332,6 +332,7 @@ group("closure_compile") { deps = [ ":closure_compile_local", + "cr_components:closure_compile", "cr_elements:closure_compile", "print_preview:closure_compile", "settings:closure_compile",
diff --git a/chrome/test/data/webui/cr_components/BUILD.gn b/chrome/test/data/webui/cr_components/BUILD.gn index cd151876..1646606e 100644 --- a/chrome/test/data/webui/cr_components/BUILD.gn +++ b/chrome/test/data/webui/cr_components/BUILD.gn
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//third_party/closure_compiler/compile_js.gni") import("//ui/webui/resources/tools/js_modulizer.gni") import("../namespace_rewrites.gni") @@ -9,3 +10,25 @@ input_files = [ "managed_footnote_test.js" ] namespace_rewrites = test_namespace_rewrites } + +js_type_check("closure_compile") { + is_polymer3 = true + closure_flags = default_closure_args + [ + "browser_resolver_prefix_replacements=\"chrome://settings/=../../chrome/browser/resources/settings/\"", + "js_module_root=../../chrome/test/data/webui/", + "js_module_root=./gen/chrome/test/data/webui/", + ] + + deps = [ ":certificate_manager_provisioning_test" ] +} + +js_library("certificate_manager_provisioning_test") { + deps = [ + "..:chai_assert", + "..:test_browser_proxy.m", + "//ui/webui/resources/cr_components/certificate_manager:certificate_provisioning_details_dialog", + "//ui/webui/resources/cr_components/certificate_manager:certificate_provisioning_entry", + "//ui/webui/resources/cr_components/certificate_manager:certificate_provisioning_list", + ] + externs_list = [ "$externs_path/mocha-2.5.js" ] +}
diff --git a/chrome/test/data/webui/cr_components/certificate_manager_provisioning_test.js b/chrome/test/data/webui/cr_components/certificate_manager_provisioning_test.js new file mode 100644 index 0000000..fd4b0f9 --- /dev/null +++ b/chrome/test/data/webui/cr_components/certificate_manager_provisioning_test.js
@@ -0,0 +1,220 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://settings/strings.m.js'; +import 'chrome://resources/cr_components/certificate_manager/certificate_provisioning_details_dialog.js'; +import 'chrome://resources/cr_components/certificate_manager/certificate_provisioning_entry.js'; +import 'chrome://resources/cr_components/certificate_manager/certificate_provisioning_list.js'; + +import {CertificateProvisioningActionEventDetail, CertificateProvisioningViewDetailsActionEvent} from 'chrome://resources/cr_components/certificate_manager/certificate_manager_types.js'; +import {CertificateProvisioningBrowserProxy, CertificateProvisioningBrowserProxyImpl, CertificateProvisioningProcess} from 'chrome://resources/cr_components/certificate_manager/certificate_provisioning_browser_proxy.js'; +import {webUIListenerCallback} from 'chrome://resources/js/cr.m.js'; +import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {assertEquals, assertFalse, assertTrue} from '../chai_assert.js'; +import {TestBrowserProxy} from '../test_browser_proxy.m.js'; +import {eventToPromise} from '../test_util.m.js'; + + +/** + * A test version of CertificateProvisioningBrowserProxy. + * Provides helper methods for allowing tests to know when a method was called, + * as well as specifying mock responses. + * + * @implements {CertificateProvisioningBrowserProxy} + */ +class TestCertificateProvisioningBrowserProxy extends TestBrowserProxy { + constructor() { + super([ + 'refreshCertificateProvisioningProcesses', + 'triggerCertificateProvisioningProcessUpdate', + ]); + } + + /** override */ + refreshCertificateProvisioningProcesses() { + this.methodCalled('refreshCertificateProvisioningProcesses'); + } + + /** override */ + triggerCertificateProvisioningProcessUpdate(certProfileId, isDeviceWide) { + this.methodCalled( + 'triggerCertificateProvisioningProcessUpdate', + {certProfileId, isDeviceWide}); + } +} + +/** @return {!CertificateProvisioningProcess} */ +function createSampleCertificateProvisioningProcess() { + return { + certProfileId: 'dummyProfileId', + isDeviceWide: true, + publicKey: 'dummyPublicKey', + stateId: 8, + status: 'dummyStateName', + timeSinceLastUpdate: 'dummyTimeSinceLastUpdate', + }; +} + +/** + * @param {?CertificateProvisioningListElement} certProvisioningList + * @return {!NodeList<!Element>} + */ +function getEntries(certProvisioningList) { + assertTrue(!!certProvisioningList); + return certProvisioningList.shadowRoot.querySelectorAll( + 'certificate-provisioning-entry'); +} + +suite('CertificateProvisioningEntryTests', function() { + /** @type {?CertificateProvisioningEntryElement} */ + let entry = null; + + /** @type {?TestCertificateProvisioningBrowserProxy} */ + let browserProxy = null; + + /** + * @return {!Promise} A promise firing once + * |CertificateProvisioningViewDetailsActionEvent| fires. + */ + function actionEventToPromise() { + return eventToPromise(CertificateProvisioningViewDetailsActionEvent, entry); + } + + setup(function() { + browserProxy = new TestCertificateProvisioningBrowserProxy(); + CertificateProvisioningBrowserProxyImpl.instance_ = browserProxy; + entry = /** @type {!CertificateProvisioningEntryElement} */ ( + document.createElement('certificate-provisioning-entry')); + entry.model = createSampleCertificateProvisioningProcess(); + document.body.appendChild(entry); + + // Bring up the popup menu for the following tests to use. + entry.$$('#dots').click(); + flush(); + }); + + teardown(function() { + entry.remove(); + }); + + // Test case where 'Details' option is tapped. + test('MenuOptions_Details', function() { + const detailsButton = entry.$$('#details'); + const waitForActionEvent = actionEventToPromise(); + detailsButton.click(); + return waitForActionEvent.then(function(event) { + const detail = + /** @type {!CertificateProvisioningActionEventDetail} */ ( + event.detail); + assertEquals(entry.model, detail.model); + }); + }); +}); + +suite('CertificateManagerProvisioningTests', function() { + /** @type {?CertificateProvisioningListElement} */ + let certProvisioningList = null; + + /** @type {?TestCertificateProvisioningBrowserProxy} */ + let browserProxy = null; + + setup(function() { + browserProxy = new TestCertificateProvisioningBrowserProxy(); + CertificateProvisioningBrowserProxyImpl.instance_ = browserProxy; + certProvisioningList = + /** @type {!CertificateProvisioningListElement} */ ( + document.createElement('certificate-provisioning-list')); + document.body.appendChild(certProvisioningList); + }); + + teardown(function() { + certProvisioningList.remove(); + }); + + /** + * Test that the certProvisioningList requests information about certificate + * provisioning processesfrom the browser on startup and that it gets + * populated accordingly. + */ + test('Initialization', function() { + assertEquals(0, getEntries(certProvisioningList).length); + + return browserProxy.whenCalled('refreshCertificateProvisioningProcesses') + .then(function() { + webUIListenerCallback( + 'certificate-provisioning-processes-changed', + [createSampleCertificateProvisioningProcess()]); + + flush(); + + assertEquals(1, getEntries(certProvisioningList).length); + }); + }); + + test('OpensDialog_ViewDetails', function() { + const dialogId = 'certificate-provisioning-details-dialog'; + const anchorForTest = document.createElement('a'); + document.body.appendChild(anchorForTest); + + assertFalse(!!certProvisioningList.$$(dialogId)); + const whenDialogOpen = + eventToPromise('cr-dialog-open', certProvisioningList); + certProvisioningList.fire( + CertificateProvisioningViewDetailsActionEvent, + /** @type {!CertificateProvisioningActionEventDetail} */ ({ + model: createSampleCertificateProvisioningProcess(), + anchor: anchorForTest + })); + + return whenDialogOpen + .then(() => { + const dialog = certProvisioningList.$$(dialogId); + assertTrue(!!dialog); + const whenDialogClosed = eventToPromise('close', dialog); + dialog.$$('#dialog').$$('#close').click(); + return whenDialogClosed; + }) + .then(() => { + const dialog = certProvisioningList.$$(dialogId); + assertFalse(!!dialog); + }); + }); +}); + +suite('DetailsDialogTests', function() { + /** @type {?CertificateProvisioningDetailsDialogElement} */ + let dialog = null; + + /** @type {?TestCertificateProvisioningBrowserProxy} */ + let browserProxy = null; + + setup(async function() { + browserProxy = new TestCertificateProvisioningBrowserProxy(); + + CertificateProvisioningBrowserProxyImpl.instance_ = browserProxy; + dialog = /** @type {!CertificateProvisioningDetailsDialogElement} */ ( + document.createElement('certificate-provisioning-details-dialog')); + }); + + teardown(function() { + dialog.remove(); + }); + + test('RefreshProcess', function() { + dialog.model = createSampleCertificateProvisioningProcess(); + document.body.appendChild(dialog); + + // Simulate clicking 'Refresh'. + dialog.$.refresh.click(); + + browserProxy.whenCalled('triggerCertificateProvisioningProcessUpdate') + .then(function({certProfileId, isDeviceWide}) { + assertEquals(dialog.model.certProfileId, certProfileId); + assertEquals(dialog.model.isDeviceWide, isDeviceWide); + // Check that the dialog is still open. + assertTrue(dialog.$$('#dialog').open); + }); + }); +});
diff --git a/chrome/test/data/webui/cr_components/cr_components_v3_browsertest.js b/chrome/test/data/webui/cr_components/cr_components_v3_browsertest.js index 2c5a322..443cc6e9 100644 --- a/chrome/test/data/webui/cr_components/cr_components_v3_browsertest.js +++ b/chrome/test/data/webui/cr_components/cr_components_v3_browsertest.js
@@ -74,3 +74,26 @@ }); GEN('#endif // defined(USE_NSS_CERTS)'); + + +GEN('#if defined(USE_NSS_CERTS) && defined(OS_CHROMEOS)'); + +/** + * ChromeOS specific test fixture for chrome://settings/certificates, testing + * the certificate provisioning UI. This tests the certificate-manager component + * in the context of the Settings privacy page. + */ +// eslint-disable-next-line no-var +var CrComponentsCertificateManagerProvisioningV3Test = + class extends CrComponentsCertificateManagerV3Test { + /** @override */ + get browsePreload() { + return 'chrome://settings/test_loader.html?module=cr_components/certificate_manager_provisioning_test.js'; + } +}; + +TEST_F('CrComponentsCertificateManagerProvisioningV3Test', 'All', function() { + mocha.run(); +}); + +GEN('#endif // defined(USE_NSS_CERTS) && defined(OS_CHROMEOS)');
diff --git a/chrome/test/data/webui/settings/passwords_section_test.js b/chrome/test/data/webui/settings/passwords_section_test.js index c328452d9..8e2f37b3 100644 --- a/chrome/test/data/webui/settings/passwords_section_test.js +++ b/chrome/test/data/webui/settings/passwords_section_test.js
@@ -544,6 +544,46 @@ assertTrue(passwordDialog.$.showPasswordButton.hidden); }); + test('verifyStorageDetailsInEditDialogForAccountPassword', function() { + const accountPassword = createPasswordEntry('goo.gl', 'bart'); + accountPassword.fromAccountStore = true; + const accountPasswordDialog = + elementFactory.createPasswordEditDialog(accountPassword); + flush(); + + // By default no message is displayed. + assertTrue(accountPasswordDialog.$.storageDetails.hidden); + + // Display the message. + accountPasswordDialog.shouldShowStorageDetails = true; + flush(); + assertFalse(accountPasswordDialog.$.storageDetails.hidden); + assertEquals( + accountPasswordDialog.i18nAdvanced( + 'passwordStoredInAccount', {tags: ['b']}), + accountPasswordDialog.$.storageDetails.innerHTML); + }); + + test('verifyStorageDetailsInEditDialogForDevicePassword', function() { + const devicePassword = createPasswordEntry('goo.gl', 'bart'); + devicePassword.fromAccountStore = false; + const devicePasswordDialog = + elementFactory.createPasswordEditDialog(devicePassword); + flush(); + + // By default no message is displayed. + assertTrue(devicePasswordDialog.$.storageDetails.hidden); + + // Display the message. + devicePasswordDialog.shouldShowStorageDetails = true; + flush(); + assertFalse(devicePasswordDialog.$.storageDetails.hidden); + assertEquals( + devicePasswordDialog.i18nAdvanced( + 'passwordStoredOnDevice', {tags: ['b']}), + devicePasswordDialog.$.storageDetails.innerHTML); + }); + test('showSavedPasswordEditDialog', function() { const PASSWORD = 'bAn@n@5'; const item = createPasswordEntry('goo.gl', 'bart');
diff --git a/chrome/test/data/webui/tab_strip/BUILD.gn b/chrome/test/data/webui/tab_strip/BUILD.gn index 5488f66..7b07912 100644 --- a/chrome/test/data/webui/tab_strip/BUILD.gn +++ b/chrome/test/data/webui/tab_strip/BUILD.gn
@@ -21,11 +21,18 @@ #":tab_list_test", #":tab_swiper_test", #":tab_test", - #":test_tab_strip_embedder_proxy", + ":test_tab_strip_embedder_proxy", ":test_tabs_api_proxy", ] } +js_library("test_tab_strip_embedder_proxy") { + deps = [ + "..:test_browser_proxy.m", + "//chrome/browser/resources/tab_strip:tab_strip_embedder_proxy", + ] +} + js_library("test_tabs_api_proxy") { deps = [ "..:test_browser_proxy.m",
diff --git a/chrome/test/data/webui/tab_strip/tab_group_test.js b/chrome/test/data/webui/tab_strip/tab_group_test.js index 1c9def82..be281e9c 100644 --- a/chrome/test/data/webui/tab_strip/tab_group_test.js +++ b/chrome/test/data/webui/tab_strip/tab_group_test.js
@@ -5,7 +5,7 @@ import 'chrome://tab-strip/tab.js'; import 'chrome://tab-strip/tab_group.js'; -import {TabStripEmbedderProxy} from 'chrome://tab-strip/tab_strip_embedder_proxy.js'; +import {TabStripEmbedderProxyImpl} from 'chrome://tab-strip/tab_strip_embedder_proxy.js'; import {TestTabStripEmbedderProxy} from './test_tab_strip_embedder_proxy.js'; suite('TabGroup', () => { @@ -16,7 +16,7 @@ setup(() => { testTabStripEmbedderProxy = new TestTabStripEmbedderProxy(); - TabStripEmbedderProxy.instance_ = testTabStripEmbedderProxy; + TabStripEmbedderProxyImpl.instance_ = testTabStripEmbedderProxy; document.body.innerHTML = ''; tabGroupElement = document.createElement('tabstrip-tab-group');
diff --git a/chrome/test/data/webui/tab_strip/tab_list_test.js b/chrome/test/data/webui/tab_strip/tab_list_test.js index fe5ff4f..c3a9e0a 100644 --- a/chrome/test/data/webui/tab_strip/tab_list_test.js +++ b/chrome/test/data/webui/tab_strip/tab_list_test.js
@@ -6,7 +6,7 @@ import {FocusOutlineManager} from 'chrome://resources/js/cr/ui/focus_outline_manager.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {setScrollAnimationEnabledForTesting} from 'chrome://tab-strip/tab_list.js'; -import {TabStripEmbedderProxy} from 'chrome://tab-strip/tab_strip_embedder_proxy.js'; +import {TabStripEmbedderProxyImpl} from 'chrome://tab-strip/tab_strip_embedder_proxy.js'; import {TabsApiProxyImpl} from 'chrome://tab-strip/tabs_api_proxy.js'; import {eventToPromise} from '../test_util.m.js'; @@ -91,7 +91,7 @@ '--width': '150px', }); testTabStripEmbedderProxy.setVisible(true); - TabStripEmbedderProxy.instance_ = testTabStripEmbedderProxy; + TabStripEmbedderProxyImpl.instance_ = testTabStripEmbedderProxy; setScrollAnimationEnabledForTesting(false);
diff --git a/chrome/test/data/webui/tab_strip/tab_test.js b/chrome/test/data/webui/tab_strip/tab_test.js index 1c235e4..19558c7 100644 --- a/chrome/test/data/webui/tab_strip/tab_test.js +++ b/chrome/test/data/webui/tab_strip/tab_test.js
@@ -6,7 +6,7 @@ import {getFavicon} from 'chrome://resources/js/icon.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; -import {TabStripEmbedderProxy} from 'chrome://tab-strip/tab_strip_embedder_proxy.js'; +import {TabStripEmbedderProxy, TabStripEmbedderProxyImpl} from 'chrome://tab-strip/tab_strip_embedder_proxy.js'; import {CloseTabAction, TabNetworkState, TabsApiProxyImpl} from 'chrome://tab-strip/tabs_api_proxy.js'; import {TestTabStripEmbedderProxy} from './test_tab_strip_embedder_proxy.js'; @@ -44,7 +44,7 @@ document.body.style.setProperty('--tabstrip-tab-spacing', '20px'); testTabStripEmbedderProxy = new TestTabStripEmbedderProxy(); - TabStripEmbedderProxy.instance_ = testTabStripEmbedderProxy; + TabStripEmbedderProxyImpl.instance_ = testTabStripEmbedderProxy; testTabsApiProxy = new TestTabsApiProxy(); TabsApiProxyImpl.instance_ = testTabsApiProxy;
diff --git a/chrome/test/data/webui/tab_strip/test_tab_strip_embedder_proxy.js b/chrome/test/data/webui/tab_strip/test_tab_strip_embedder_proxy.js index 1e8903c..424dd375 100644 --- a/chrome/test/data/webui/tab_strip/test_tab_strip_embedder_proxy.js +++ b/chrome/test/data/webui/tab_strip/test_tab_strip_embedder_proxy.js
@@ -2,8 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {TestBrowserProxy} from 'chrome://test/test_browser_proxy.m.js'; +import {TabStripEmbedderProxy} from 'chrome://tab-strip/tab_strip_embedder_proxy.js'; +import {TestBrowserProxy} from '../test_browser_proxy.m.js'; + +/** @implements {TabStripEmbedderProxy} */ export class TestTabStripEmbedderProxy extends TestBrowserProxy { constructor() { super([ @@ -20,69 +23,87 @@ 'reportTabCreationDuration', ]); + /** @private {!Object<string, string>} */ this.colors_ = {}; + + /** @private {!Object<string, string>} */ this.layout_ = {}; + + /** @private {boolean} */ this.visible_ = false; } + /** @override */ getColors() { this.methodCalled('getColors'); return Promise.resolve(this.colors_); } + /** @override */ getLayout() { this.methodCalled('getLayout'); return Promise.resolve(this.layout_); } + /** @override */ isVisible() { this.methodCalled('isVisible'); return this.visible_; } + /** @param {!Object<string, string>} colors */ setColors(colors) { this.colors_ = colors; } + /** @param {!Object<string, string>} layout */ setLayout(layout) { this.layout_ = layout; } + /** @param {boolean} visible */ setVisible(visible) { this.visible_ = visible; } + /** @override */ observeThemeChanges() { this.methodCalled('observeThemeChanges'); } + /** @override */ closeContainer() { this.methodCalled('closeContainer'); - return Promise.resolve(); } + /** @override */ showBackgroundContextMenu(locationX, locationY) { this.methodCalled('showBackgroundContextMenu', [locationX, locationY]); } + /** @override */ showEditDialogForGroup(groupId, locationX, locationY, width, height) { this.methodCalled( 'showEditDialogForGroup', [groupId, locationX, locationY, width, height]); } + /** @override */ showTabContextMenu(tabId, locationX, locationY) { this.methodCalled('showTabContextMenu', [tabId, locationX, locationY]); } + /** @override */ reportTabActivationDuration(durationMs) { this.methodCalled('reportTabActivationDuration', [durationMs]); } + /** @override */ reportTabDataReceivedDuration(tabCount, durationMs) { this.methodCalled('reportTabDataReceivedDuration', [tabCount, durationMs]); } + /** @override */ reportTabCreationDuration(tabCount, durationMs) { this.methodCalled('reportTabCreationDuration', [tabCount, durationMs]); }
diff --git a/chromecast/ui/media_control_ui.cc b/chromecast/ui/media_control_ui.cc index 7338bf8..8bc8564 100644 --- a/chromecast/ui/media_control_ui.cc +++ b/chromecast/ui/media_control_ui.cc
@@ -66,52 +66,38 @@ // |touch_view| will detect touch events and decide whether to show // or hide |view_|, which contains the media controls. - touch_view_ = std::make_unique<TouchView>(base::BindRepeating( + auto touch_view = std::make_unique<TouchView>(base::BindRepeating( &MediaControlUi::OnTapped, weak_factory_.GetWeakPtr())); // Main view. - view_ = std::make_unique<views::View>(); - view_->set_owned_by_client(); - view_->SetVisible(false); - view_->SetBackground( + auto view = std::make_unique<views::View>(); + view->SetVisible(false); + view->SetBackground( views::CreateSolidBackground(SkColorSetA(SK_ColorBLACK, 0x80))); - view_->SetBoundsRect( + view->SetBoundsRect( window_manager_->GetRootWindow()->GetBoundsInRootWindow()); - touch_view_->AddChildView(view_.get()); + view_ = touch_view->AddChildView(std::move(view)); // Buttons. - btn_previous_ = - CreateImageButton(vector_icons::kPreviousIcon, kButtonSmallHeight); - btn_previous_->set_owned_by_client(); - view_->AddChildView(btn_previous_.get()); - btn_play_pause_ = - CreateImageButton(vector_icons::kPlayIcon, kButtonBigHeight); - btn_play_pause_->set_owned_by_client(); - view_->AddChildView(btn_play_pause_.get()); - btn_next_ = CreateImageButton(vector_icons::kNextIcon, kButtonSmallHeight); - btn_next_->set_owned_by_client(); - view_->AddChildView(btn_next_.get()); - btn_replay30_ = - CreateImageButton(vector_icons::kBack30Icon, kButtonSmallHeight); - btn_replay30_->set_owned_by_client(); - view_->AddChildView(btn_replay30_.get()); - btn_forward30_ = - CreateImageButton(vector_icons::kForward30Icon, kButtonSmallHeight); - btn_forward30_->set_owned_by_client(); - view_->AddChildView(btn_forward30_.get()); + btn_previous_ = view_->AddChildView( + CreateImageButton(vector_icons::kPreviousIcon, kButtonSmallHeight)); + btn_play_pause_ = view_->AddChildView( + CreateImageButton(vector_icons::kPlayIcon, kButtonBigHeight)); + btn_next_ = view_->AddChildView( + CreateImageButton(vector_icons::kNextIcon, kButtonSmallHeight)); + btn_replay30_ = view_->AddChildView( + CreateImageButton(vector_icons::kBack30Icon, kButtonSmallHeight)); + btn_forward30_ = view_->AddChildView( + CreateImageButton(vector_icons::kForward30Icon, kButtonSmallHeight)); // Labels. - lbl_title_ = std::make_unique<views::Label>(base::string16()); - lbl_title_->set_owned_by_client(); - view_->AddChildView(lbl_title_.get()); - lbl_meta_ = std::make_unique<views::Label>(base::string16()); - lbl_meta_->set_owned_by_client(); - view_->AddChildView(lbl_meta_.get()); + lbl_title_ = + view_->AddChildView(std::make_unique<views::Label>(base::string16())); + lbl_meta_ = + view_->AddChildView(std::make_unique<views::Label>(base::string16())); // Progress Bar. - progress_bar_ = std::make_unique<views::ProgressBar>(); - progress_bar_->set_owned_by_client(); - view_->AddChildView(progress_bar_.get()); + progress_bar_ = view_->AddChildView(std::make_unique<views::ProgressBar>()); LayoutElements(); @@ -123,7 +109,7 @@ params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent; params.bounds = window_manager_->GetRootWindow()->GetBoundsInRootWindow(); widget_->Init(std::move(params)); - widget_->SetContentsView(touch_view_.release()); // Ownership passed. + widget_->SetContentsView(std::move(touch_view)); window_manager_->SetZOrder(widget_->GetNativeView(), mojom::ZOrder::MEDIA_INFO); @@ -161,9 +147,8 @@ if (is_paused_ && !visible()) { ShowMediaControls(true); } - SetButtonImage(btn_play_pause_.get(), is_paused_ - ? vector_icons::kPlayIcon - : vector_icons::kPauseIcon); + SetButtonImage(btn_play_pause_, is_paused_ ? vector_icons::kPlayIcon + : vector_icons::kPauseIcon); } if (attributes->duration > 0.0) { @@ -235,15 +220,15 @@ return; } - if (sender == btn_previous_.get()) { + if (sender == btn_previous_) { client_->Execute(mojom::MediaCommand::PREVIOUS); - } else if (sender == btn_play_pause_.get()) { + } else if (sender == btn_play_pause_) { client_->Execute(mojom::MediaCommand::TOGGLE_PLAY_PAUSE); - } else if (sender == btn_next_.get()) { + } else if (sender == btn_next_) { client_->Execute(mojom::MediaCommand::NEXT); - } else if (sender == btn_replay30_.get()) { + } else if (sender == btn_replay30_) { client_->Execute(mojom::MediaCommand::REPLAY_30_SECONDS); - } else if (sender == btn_forward30_.get()) { + } else if (sender == btn_forward30_) { client_->Execute(mojom::MediaCommand::FORWARD_30_SECONDS); } else { NOTREACHED();
diff --git a/chromecast/ui/media_control_ui.h b/chromecast/ui/media_control_ui.h index 5c29aa9d..0916c83 100644 --- a/chromecast/ui/media_control_ui.h +++ b/chromecast/ui/media_control_ui.h
@@ -71,22 +71,21 @@ // UI components std::unique_ptr<views::Widget> widget_; - std::unique_ptr<views::View> touch_view_; - std::unique_ptr<views::View> view_; + views::View* view_; // Controls - std::unique_ptr<views::ImageButton> btn_previous_; - std::unique_ptr<views::ImageButton> btn_play_pause_; - std::unique_ptr<views::ImageButton> btn_next_; - std::unique_ptr<views::ImageButton> btn_replay30_; - std::unique_ptr<views::ImageButton> btn_forward30_; + views::ImageButton* btn_previous_; + views::ImageButton* btn_play_pause_; + views::ImageButton* btn_next_; + views::ImageButton* btn_replay30_; + views::ImageButton* btn_forward30_; // Labels - std::unique_ptr<views::Label> lbl_meta_; - std::unique_ptr<views::Label> lbl_title_; + views::Label* lbl_meta_; + views::Label* lbl_title_; // Progress - std::unique_ptr<views::ProgressBar> progress_bar_; + views::ProgressBar* progress_bar_; bool is_paused_;
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.cc b/chromeos/services/assistant/assistant_manager_service_impl.cc index 76353f6..66627401 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.cc +++ b/chromeos/services/assistant/assistant_manager_service_impl.cc
@@ -1054,7 +1054,7 @@ // There can only be one |AssistantManager| instance at any given time. DCHECK(!assistant_manager_); new_display_connection_ = std::make_unique<CrosDisplayConnection>( - this, assistant::features::IsFeedbackUiEnabled(), + this, /*feedback_ui_enabled=*/true, assistant::features::IsMediaSessionIntegrationEnabled()); new_assistant_manager_ = delegate_->CreateAssistantManager(
diff --git a/chromeos/services/assistant/public/cpp/features.cc b/chromeos/services/assistant/public/cpp/features.cc index 82e5fc1..a76014c 100644 --- a/chromeos/services/assistant/public/cpp/features.cc +++ b/chromeos/services/assistant/public/cpp/features.cc
@@ -13,12 +13,6 @@ const base::Feature kAssistantAudioEraser{"AssistantAudioEraser", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kAssistantFeedbackUi{"AssistantFeedbackUi", - base::FEATURE_ENABLED_BY_DEFAULT}; - -const base::Feature kAssistantWarmerWelcomeFeature{ - "AssistantWarmerWelcome", base::FEATURE_ENABLED_BY_DEFAULT}; - const base::Feature kAssistantAppSupport{"AssistantAppSupport", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -149,10 +143,6 @@ return base::FeatureList::IsEnabled(kEnableDspHotword); } -bool IsFeedbackUiEnabled() { - return base::FeatureList::IsEnabled(kAssistantFeedbackUi); -} - bool IsLauncherChipIntegrationEnabled() { return base::FeatureList::IsEnabled(kAssistantLauncherChipIntegration); } @@ -213,10 +203,6 @@ (IsResponseProcessingV2Enabled() || IsRoutinesEnabled()); } -bool IsWarmerWelcomeEnabled() { - return base::FeatureList::IsEnabled(kAssistantWarmerWelcomeFeature); -} - } // namespace features } // namespace assistant } // namespace chromeos
diff --git a/chromeos/services/assistant/public/cpp/features.h b/chromeos/services/assistant/public/cpp/features.h index 342c71f..bba53c0f 100644 --- a/chromeos/services/assistant/public/cpp/features.h +++ b/chromeos/services/assistant/public/cpp/features.h
@@ -20,14 +20,6 @@ COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) extern const base::Feature kAssistantAudioEraser; -// Enable Assistant Feedback UI. -COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) -extern const base::Feature kAssistantFeedbackUi; - -// Enables Assistant warmer welcome. -COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) -extern const base::Feature kAssistantWarmerWelcomeFeature; - // Enables Assistant app support. COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) extern const base::Feature kAssistantAppSupport;
diff --git a/chromeos/services/secure_channel/ble_weave_client_connection.cc b/chromeos/services/secure_channel/ble_weave_client_connection.cc index cab424d2..c530f762 100644 --- a/chromeos/services/secure_channel/ble_weave_client_connection.cc +++ b/chromeos/services/secure_channel/ble_weave_client_connection.cc
@@ -692,8 +692,9 @@ if (sub_status() == SubStatus::CONNECTED_AND_IDLE) SetSubStatus(SubStatus::CONNECTED_AND_SENDING_MESSAGE); - characteristic->DeprecatedWriteRemoteCharacteristic( + characteristic->WriteRemoteCharacteristic( pending_write_request_->value, + device::BluetoothRemoteGattCharacteristic::WriteType::kWithoutResponse, base::BindOnce(&BluetoothLowEnergyWeaveClientConnection:: OnRemoteCharacteristicWritten, weak_ptr_factory_.GetWeakPtr()),
diff --git a/chromeos/services/secure_channel/ble_weave_client_connection_unittest.cc b/chromeos/services/secure_channel/ble_weave_client_connection_unittest.cc index c7cd1a6..ff4fc9c 100644 --- a/chromeos/services/secure_channel/ble_weave_client_connection_unittest.cc +++ b/chromeos/services/secure_channel/ble_weave_client_connection_unittest.cc
@@ -487,12 +487,11 @@ // WAITING_CONNECTION_RESPONSE state. void NotifySessionStarted( TestBluetoothLowEnergyWeaveClientConnection* connection) { - EXPECT_CALL(*tx_characteristic_, - DeprecatedWriteRemoteCharacteristic_(_, _, _)) + EXPECT_CALL(*tx_characteristic_, WriteRemoteCharacteristic_(_, _, _, _)) .WillOnce( DoAll(SaveArg<0>(&last_value_written_on_tx_characteristic_), - MoveArg<1>(&write_remote_characteristic_success_callback_), - MoveArg<2>(&write_remote_characteristic_error_callback_))); + MoveArg<2>(&write_remote_characteristic_success_callback_), + MoveArg<3>(&write_remote_characteristic_error_callback_))); EXPECT_FALSE(notify_session_error_callback_.is_null()); ASSERT_FALSE(notify_session_success_callback_.is_null()); @@ -548,12 +547,11 @@ // state. void Disconnect(TestBluetoothLowEnergyWeaveClientConnection* connection) { if (connection->IsConnected()) { - EXPECT_CALL(*tx_characteristic_, - DeprecatedWriteRemoteCharacteristic_(_, _, _)) + EXPECT_CALL(*tx_characteristic_, WriteRemoteCharacteristic_(_, _, _, _)) .WillOnce( DoAll(SaveArg<0>(&last_value_written_on_tx_characteristic_), - MoveArg<1>(&write_remote_characteristic_success_callback_), - MoveArg<2>(&write_remote_characteristic_error_callback_))); + MoveArg<2>(&write_remote_characteristic_success_callback_), + MoveArg<3>(&write_remote_characteristic_error_callback_))); } connection->Disconnect(); @@ -573,12 +571,11 @@ connection) { bool was_connected = (*connection)->IsConnected(); if (was_connected) { - EXPECT_CALL(*tx_characteristic_, - DeprecatedWriteRemoteCharacteristic_(_, _, _)) + EXPECT_CALL(*tx_characteristic_, WriteRemoteCharacteristic_(_, _, _, _)) .WillOnce( DoAll(SaveArg<0>(&last_value_written_on_tx_characteristic_), - MoveArg<1>(&write_remote_characteristic_success_callback_), - MoveArg<2>(&write_remote_characteristic_error_callback_))); + MoveArg<2>(&write_remote_characteristic_success_callback_), + MoveArg<3>(&write_remote_characteristic_error_callback_))); } connection->reset(); @@ -791,12 +788,11 @@ InitializeConnection(connection.get(), kDefaultMaxPacketSize); EXPECT_EQ(connection->sub_status(), SubStatus::CONNECTED_AND_IDLE); - EXPECT_CALL(*tx_characteristic_, - DeprecatedWriteRemoteCharacteristic_(_, _, _)) + EXPECT_CALL(*tx_characteristic_, WriteRemoteCharacteristic_(_, _, _, _)) .WillOnce( DoAll(SaveArg<0>(&last_value_written_on_tx_characteristic_), - MoveArg<1>(&write_remote_characteristic_success_callback_), - MoveArg<2>(&write_remote_characteristic_error_callback_))); + MoveArg<2>(&write_remote_characteristic_success_callback_), + MoveArg<3>(&write_remote_characteristic_error_callback_))); // Call Disconnect() twice; this should only result in one "close connection" // message (verified via WillOnce() above). @@ -919,8 +915,7 @@ ConnectGatt(connection.get()); CharacteristicsFound(connection.get()); - EXPECT_CALL(*tx_characteristic_, - DeprecatedWriteRemoteCharacteristic_(_, _, _)) + EXPECT_CALL(*tx_characteristic_, WriteRemoteCharacteristic_(_, _, _, _)) .Times(0); EXPECT_FALSE(notify_session_success_callback_.is_null()); ASSERT_FALSE(notify_session_error_callback_.is_null()); @@ -948,16 +943,15 @@ // |connection| will call WriteRemoteCharacteristics(_,_) to try to send the // message |kMaxNumberOfTries| times. There is already one EXPECT_CALL for - // DeprecatedWriteRemoteCharacteristic(_,_,_) in NotifySessionStated, that's - // why we use |kMaxNumberOfTries-1| in the EXPECT_CALL statement. + // WriteRemoteCharacteristic(_,_,_) in NotifySessionStated, that's why we use + // |kMaxNumberOfTries-1| in the EXPECT_CALL statement. EXPECT_EQ(0, connection_observer_->num_send_completed()); - EXPECT_CALL(*tx_characteristic_, - DeprecatedWriteRemoteCharacteristic_(_, _, _)) + EXPECT_CALL(*tx_characteristic_, WriteRemoteCharacteristic_(_, _, _, _)) .Times(kMaxNumberOfTries - 1) .WillRepeatedly( DoAll(SaveArg<0>(&last_value_written_on_tx_characteristic_), - MoveArg<1>(&write_remote_characteristic_success_callback_), - MoveArg<2>(&write_remote_characteristic_error_callback_))); + MoveArg<2>(&write_remote_characteristic_success_callback_), + MoveArg<3>(&write_remote_characteristic_error_callback_))); for (int i = 0; i < kMaxNumberOfTries; i++) { EXPECT_EQ(last_value_written_on_tx_characteristic_, kConnectionRequest); @@ -1030,14 +1024,13 @@ CreateConnection(true /* should_set_low_connection_latency */)); InitializeConnection(connection.get(), kDefaultMaxPacketSize); - // Expecting a first call of DeprecatedWriteRemoteCharacteristic, after - // SendMessage is called. - EXPECT_CALL(*tx_characteristic_, - DeprecatedWriteRemoteCharacteristic_(_, _, _)) + // Expecting a first call of WriteRemoteCharacteristic, after SendMessage is + // called. + EXPECT_CALL(*tx_characteristic_, WriteRemoteCharacteristic_(_, _, _, _)) .WillOnce( DoAll(SaveArg<0>(&last_value_written_on_tx_characteristic_), - MoveArg<1>(&write_remote_characteristic_success_callback_), - MoveArg<2>(&write_remote_characteristic_error_callback_))); + MoveArg<2>(&write_remote_characteristic_success_callback_), + MoveArg<3>(&write_remote_characteristic_error_callback_))); connection->SendMessage( std::make_unique<FakeWireMessage>(kSmallMessage, kTestFeature)); @@ -1064,14 +1057,13 @@ InitializeConnection(connection.get(), kLargeMaxPacketSize); - // Expecting a first call of DeprecatedWriteRemoteCharacteristic, after - // SendMessage is called. - EXPECT_CALL(*tx_characteristic_, - DeprecatedWriteRemoteCharacteristic_(_, _, _)) + // Expecting a first call of WriteRemoteCharacteristic, after SendMessage is + // called. + EXPECT_CALL(*tx_characteristic_, WriteRemoteCharacteristic_(_, _, _, _)) .WillOnce( DoAll(SaveArg<0>(&last_value_written_on_tx_characteristic_), - MoveArg<1>(&write_remote_characteristic_success_callback_), - MoveArg<2>(&write_remote_characteristic_error_callback_))); + MoveArg<2>(&write_remote_characteristic_success_callback_), + MoveArg<3>(&write_remote_characteristic_error_callback_))); connection->SendMessage( std::make_unique<FakeWireMessage>(kLargeMessage, kTestFeature)); @@ -1081,12 +1073,11 @@ last_value_written_on_tx_characteristic_.begin() + 1, last_value_written_on_tx_characteristic_.end()); - EXPECT_CALL(*tx_characteristic_, - DeprecatedWriteRemoteCharacteristic_(_, _, _)) + EXPECT_CALL(*tx_characteristic_, WriteRemoteCharacteristic_(_, _, _, _)) .WillOnce( DoAll(SaveArg<0>(&last_value_written_on_tx_characteristic_), - MoveArg<1>(&write_remote_characteristic_success_callback_), - MoveArg<2>(&write_remote_characteristic_error_callback_))); + MoveArg<2>(&write_remote_characteristic_success_callback_), + MoveArg<3>(&write_remote_characteristic_error_callback_))); RunWriteCharacteristicSuccessCallback(); VerifyGattWriteCharacteristicResult(true /* success */, 2 /* num_writes */); @@ -1118,13 +1109,12 @@ CreateConnection(true /* should_set_low_connection_latency */)); InitializeConnection(connection.get(), kDefaultMaxPacketSize); - EXPECT_CALL(*tx_characteristic_, - DeprecatedWriteRemoteCharacteristic_(_, _, _)) + EXPECT_CALL(*tx_characteristic_, WriteRemoteCharacteristic_(_, _, _, _)) .Times(kMaxNumberOfTries) .WillRepeatedly( DoAll(SaveArg<0>(&last_value_written_on_tx_characteristic_), - MoveArg<1>(&write_remote_characteristic_success_callback_), - MoveArg<2>(&write_remote_characteristic_error_callback_))); + MoveArg<2>(&write_remote_characteristic_success_callback_), + MoveArg<3>(&write_remote_characteristic_error_callback_))); connection->SendMessage( std::make_unique<FakeWireMessage>(kSmallMessage, kTestFeature)); @@ -1181,12 +1171,11 @@ InitializeConnection(connection.get(), kDefaultMaxPacketSize); - EXPECT_CALL(*tx_characteristic_, - DeprecatedWriteRemoteCharacteristic_(_, _, _)) + EXPECT_CALL(*tx_characteristic_, WriteRemoteCharacteristic_(_, _, _, _)) .WillOnce( DoAll(SaveArg<0>(&last_value_written_on_tx_characteristic_), - MoveArg<1>(&write_remote_characteristic_success_callback_), - MoveArg<2>(&write_remote_characteristic_error_callback_))); + MoveArg<2>(&write_remote_characteristic_success_callback_), + MoveArg<3>(&write_remote_characteristic_error_callback_))); connection->GattCharacteristicValueChanged( adapter_.get(), rx_characteristic_.get(), kErroneousPacket); @@ -1212,12 +1201,11 @@ InitializeConnection(connection.get(), kLargeMaxPacketSize); - EXPECT_CALL(*tx_characteristic_, - DeprecatedWriteRemoteCharacteristic_(_, _, _)) + EXPECT_CALL(*tx_characteristic_, WriteRemoteCharacteristic_(_, _, _, _)) .WillOnce( DoAll(SaveArg<0>(&last_value_written_on_tx_characteristic_), - MoveArg<1>(&write_remote_characteristic_success_callback_), - MoveArg<2>(&write_remote_characteristic_error_callback_))); + MoveArg<2>(&write_remote_characteristic_success_callback_), + MoveArg<3>(&write_remote_characteristic_error_callback_))); connection->SendMessage( std::make_unique<FakeWireMessage>(kLargeMessage, kTestFeature)); @@ -1227,12 +1215,11 @@ EXPECT_EQ(last_value_written_on_tx_characteristic_, kLargePackets0); - EXPECT_CALL(*tx_characteristic_, - DeprecatedWriteRemoteCharacteristic_(_, _, _)) + EXPECT_CALL(*tx_characteristic_, WriteRemoteCharacteristic_(_, _, _, _)) .WillOnce( DoAll(SaveArg<0>(&last_value_written_on_tx_characteristic_), - MoveArg<1>(&write_remote_characteristic_success_callback_), - MoveArg<2>(&write_remote_characteristic_error_callback_))); + MoveArg<2>(&write_remote_characteristic_success_callback_), + MoveArg<3>(&write_remote_characteristic_error_callback_))); RunWriteCharacteristicSuccessCallback(); VerifyGattWriteCharacteristicResult(true /* success */, 2 /* num_writes */); @@ -1260,12 +1247,11 @@ InitializeConnection(connection, kDefaultMaxPacketSize); - EXPECT_CALL(*tx_characteristic_, - DeprecatedWriteRemoteCharacteristic_(_, _, _)) + EXPECT_CALL(*tx_characteristic_, WriteRemoteCharacteristic_(_, _, _, _)) .WillOnce( DoAll(SaveArg<0>(&last_value_written_on_tx_characteristic_), - MoveArg<1>(&write_remote_characteristic_success_callback_), - MoveArg<2>(&write_remote_characteristic_error_callback_))); + MoveArg<2>(&write_remote_characteristic_success_callback_), + MoveArg<3>(&write_remote_characteristic_error_callback_))); connection->GattCharacteristicValueChanged( adapter_.get(), rx_characteristic_.get(), kErroneousPacket); @@ -1294,13 +1280,12 @@ InitializeConnection(connection, kDefaultMaxPacketSize); - EXPECT_CALL(*tx_characteristic_, - DeprecatedWriteRemoteCharacteristic_(_, _, _)) + EXPECT_CALL(*tx_characteristic_, WriteRemoteCharacteristic_(_, _, _, _)) .Times(2) .WillRepeatedly( DoAll(SaveArg<0>(&last_value_written_on_tx_characteristic_), - MoveArg<1>(&write_remote_characteristic_success_callback_), - MoveArg<2>(&write_remote_characteristic_error_callback_))); + MoveArg<2>(&write_remote_characteristic_success_callback_), + MoveArg<3>(&write_remote_characteristic_error_callback_))); connection->SendMessage( std::make_unique<FakeWireMessage>(kSmallMessage, kTestFeature)); @@ -1332,12 +1317,11 @@ InitializeConnection(connection.get(), kDefaultMaxPacketSize); EXPECT_EQ(connection->sub_status(), SubStatus::CONNECTED_AND_IDLE); - EXPECT_CALL(*tx_characteristic_, - DeprecatedWriteRemoteCharacteristic_(_, _, _)) + EXPECT_CALL(*tx_characteristic_, WriteRemoteCharacteristic_(_, _, _, _)) .WillOnce( DoAll(SaveArg<0>(&last_value_written_on_tx_characteristic_), - MoveArg<1>(&write_remote_characteristic_success_callback_), - MoveArg<2>(&write_remote_characteristic_error_callback_))); + MoveArg<2>(&write_remote_characteristic_success_callback_), + MoveArg<3>(&write_remote_characteristic_error_callback_))); connection->Disconnect(); EXPECT_EQ(connection->sub_status(), SubStatus::CONNECTED_AND_SENDING_MESSAGE); @@ -1348,12 +1332,11 @@ EXPECT_FALSE(write_remote_characteristic_success_callback_.is_null()); if (i != kMaxNumberOfTries - 1) { - EXPECT_CALL(*tx_characteristic_, - DeprecatedWriteRemoteCharacteristic_(_, _, _)) + EXPECT_CALL(*tx_characteristic_, WriteRemoteCharacteristic_(_, _, _, _)) .WillOnce( DoAll(SaveArg<0>(&last_value_written_on_tx_characteristic_), - MoveArg<1>(&write_remote_characteristic_success_callback_), - MoveArg<2>(&write_remote_characteristic_error_callback_))); + MoveArg<2>(&write_remote_characteristic_success_callback_), + MoveArg<3>(&write_remote_characteristic_error_callback_))); } std::move(write_remote_characteristic_error_callback_) @@ -1632,8 +1615,7 @@ InitializeConnection(connection.get(), kDefaultMaxPacketSize); EXPECT_EQ(connection->sub_status(), SubStatus::CONNECTED_AND_IDLE); - EXPECT_CALL(*tx_characteristic_, - DeprecatedWriteRemoteCharacteristic_(_, _, _)); + EXPECT_CALL(*tx_characteristic_, WriteRemoteCharacteristic_(_, _, _, _)); connection->SendMessage( std::make_unique<FakeWireMessage>(kSmallMessage, kTestFeature));
diff --git a/components/autofill/android/BUILD.gn b/components/autofill/android/BUILD.gn index f246bae..42a9a9b 100644 --- a/components/autofill/android/BUILD.gn +++ b/components/autofill/android/BUILD.gn
@@ -41,6 +41,7 @@ "//base:base_java", "//content/public/android:content_java", "//third_party/android_deps:android_support_v7_appcompat_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", "//ui/android:ui_java", ] sources = [
diff --git a/components/autofill/android/junit/BUILD.gn b/components/autofill/android/junit/BUILD.gn index 0f58b8ac..3e3e800 100644 --- a/components/autofill/android/junit/BUILD.gn +++ b/components/autofill/android/junit/BUILD.gn
@@ -16,6 +16,9 @@ "//base:base_junit_test_support", "//components/autofill/android:provider_java", "//content/public/android:content_java", + "//third_party/junit", + "//third_party/mockito:mockito_java", + "//third_party/robolectric:robolectric_all_java", "//ui/android:ui_java", ] }
diff --git a/components/autofill/core/browser/autofill_experiments.cc b/components/autofill/core/browser/autofill_experiments.cc index ef21685..86f1fbc 100644 --- a/components/autofill/core/browser/autofill_experiments.cc +++ b/components/autofill/core/browser/autofill_experiments.cc
@@ -225,34 +225,4 @@ return group_name == "Disabled"; } -bool OfferStoreUnmaskedCards(bool is_off_the_record) { -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) - // The checkbox can be forced on with a flag, but by default we don't store - // on Linux due to lack of system keychain integration. See crbug.com/162735 - return base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableOfferStoreUnmaskedWalletCards); -#else - // Never offer to store unmasked cards when off the record. - if (is_off_the_record) { - return false; - } - - // Query the field trial before checking command line flags to ensure UMA - // reports the correct group. - std::string group_name = - base::FieldTrialList::FindFullName("OfferStoreUnmaskedWalletCards"); - - // The checkbox can be forced on or off with flags. - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableOfferStoreUnmaskedWalletCards)) - return true; - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableOfferStoreUnmaskedWalletCards)) - return false; - - // Otherwise use the field trial to show the checkbox or not. - return group_name != "Disabled"; -#endif -} - } // namespace autofill
diff --git a/components/autofill/core/browser/autofill_experiments.h b/components/autofill/core/browser/autofill_experiments.h index d291ce0a..d5b92be5 100644 --- a/components/autofill/core/browser/autofill_experiments.h +++ b/components/autofill/core/browser/autofill_experiments.h
@@ -44,11 +44,6 @@ // disables providing suggestions. bool IsInAutofillSuggestionsDisabledExperiment(); -// Returns true if the user should be offered to locally store unmasked cards. -// This controls whether the option is presented at all rather than the default -// response of the option. -bool OfferStoreUnmaskedCards(bool is_off_the_record); - } // namespace autofill #endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_EXPERIMENTS_H_
diff --git a/components/autofill/core/browser/form_data_importer.cc b/components/autofill/core/browser/form_data_importer.cc index 8b0b4070..e4147d4 100644 --- a/components/autofill/core/browser/form_data_importer.cc +++ b/components/autofill/core/browser/form_data_importer.cc
@@ -679,17 +679,12 @@ } } - // If editable expiration date experiment is enabled, the card with invalid - // expiration date can be uploaded. However, the card with invalid card number - // must be ignored. + // Cards with invalid expiration dates can be uploaded due to the existence of + // the expiration date fix flow. However, cards with invalid card numbers must + // still be ignored. if (!candidate_credit_card.HasValidCardNumber()) { return false; } - if (!candidate_credit_card.HasValidExpirationDate() && - !base::FeatureList::IsEnabled( - features::kAutofillUpstreamEditableExpirationDate)) { - return false; - } // Can import one valid card per form. Start by treating it as NEW_CARD, but // overwrite this type if we discover it is already a local or server card.
diff --git a/components/autofill/core/browser/form_data_importer_unittest.cc b/components/autofill/core/browser/form_data_importer_unittest.cc index ca166dfa..7eabf94d 100644 --- a/components/autofill/core/browser/form_data_importer_unittest.cc +++ b/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -1507,39 +1507,10 @@ ASSERT_EQ(0U, personal_data_manager_->GetCreditCards().size()); } -// Tests that an invalid credit card expiration is not extracted when the -// expiration date fix flow experiment is disabled. -TEST_F(FormDataImporterTest, ImportCreditCard_InvalidExpiryDate) { - scoped_feature_list_.InitAndDisableFeature( - features::kAutofillUpstreamEditableExpirationDate); - FormData form; - form.url = GURL("https://wwww.foo.com"); - - AddFullCreditCardForm(&form, "Smalls Biggie", "4111-1111-1111-1111", "0", - "2999"); - - FormStructure form_structure(form); - form_structure.DetermineHeuristicTypes(); - std::unique_ptr<CreditCard> imported_credit_card; - base::HistogramTester histogram_tester; - EXPECT_FALSE(ImportCreditCard(form_structure, false, &imported_credit_card)); - ASSERT_FALSE(imported_credit_card); - histogram_tester.ExpectUniqueSample("Autofill.SubmittedCardState", - AutofillMetrics::HAS_CARD_NUMBER_ONLY, 1); - - // Since no refresh is expected, reload the data from the database to make - // sure no changes were written out. - ResetPersonalDataManager(USER_MODE_NORMAL); - - ASSERT_EQ(0U, personal_data_manager_->GetCreditCards().size()); -} - -// Tests that an empty credit card expiration is extracted when editable -// expiration date experiment on. +// Tests that a credit card with an empty expiration can be extracted due to the +// expiration date fix flow. TEST_F(FormDataImporterTest, ImportCreditCard_InvalidExpiryDate_EditableExpirationExpOn) { - scoped_feature_list_.InitAndEnableFeature( - features::kAutofillUpstreamEditableExpirationDate); FormData form; form.url = GURL("https://wwww.foo.com"); @@ -1555,12 +1526,10 @@ AutofillMetrics::HAS_CARD_NUMBER_ONLY, 1); } -// Tests that an expired credit card is extracted when editable expiration date -// experiment on. +// Tests that an expired credit card can be extracted due to the expiration date +// fix flow. TEST_F(FormDataImporterTest, ImportCreditCard_ExpiredExpiryDate_EditableExpirationExpOn) { - scoped_feature_list_.InitAndEnableFeature( - features::kAutofillUpstreamEditableExpirationDate); FormData form; form.url = GURL("https://wwww.foo.com"); @@ -2458,38 +2427,7 @@ // Ensures that |imported_credit_card_record_type_| is set correctly. TEST_F( FormDataImporterTest, - ImportFormData_ImportCreditCardRecordType_NoCard_ExpiredCard_EditableExpDateOff) { - scoped_feature_list_.InitAndDisableFeature( - features::kAutofillUpstreamEditableExpirationDate); - // Simulate a form submission with an expired credit card. - FormData form; - form.url = GURL("https://wwww.foo.com"); - - AddFullCreditCardForm(&form, "Biggie Smalls", "4111 1111 1111 1111", "01", - "1999"); - - FormStructure form_structure(form); - form_structure.DetermineHeuristicTypes(); - std::unique_ptr<CreditCard> imported_credit_card; - base::Optional<std::string> imported_upi_id; - EXPECT_FALSE(form_data_importer_->ImportFormData( - form_structure, /*profile_autofill_enabled=*/true, - /*credit_card_autofill_enabled=*/true, - /*should_return_local_card=*/true, &imported_credit_card, - &imported_upi_id)); - ASSERT_FALSE(imported_credit_card); - // |imported_credit_card_record_type_| should be NO_CARD because no valid card - // was successfully imported from the form. - ASSERT_TRUE(form_data_importer_->imported_credit_card_record_type_ == - FormDataImporter::ImportedCreditCardRecordType::NO_CARD); -} - -// Ensures that |imported_credit_card_record_type_| is set correctly. -TEST_F( - FormDataImporterTest, ImportFormData_ImportCreditCardRecordType_NewCard_ExpiredCard_WithExpDateFixFlow) { - scoped_feature_list_.InitAndEnableFeature( - features::kAutofillUpstreamEditableExpirationDate); // Simulate a form submission with an expired credit card. FormData form; form.url = GURL("https://wwww.foo.com"); @@ -3110,8 +3048,6 @@ // server card and user submitted an invalid expiration date month. TEST_F(FormDataImporterTest, Metrics_SubmittedServerCardExpirationStatus_EmptyExpirationMonth) { - scoped_feature_list_.InitAndEnableFeature( - features::kAutofillUpstreamEditableExpirationDate); EnableWalletCardImport(); std::vector<CreditCard> server_cards; @@ -3160,8 +3096,6 @@ // server card and user submitted an invalid expiration date year. TEST_F(FormDataImporterTest, Metrics_SubmittedServerCardExpirationStatus_EmptyExpirationYear) { - scoped_feature_list_.InitAndEnableFeature( - features::kAutofillUpstreamEditableExpirationDate); EnableWalletCardImport(); std::vector<CreditCard> server_cards; @@ -3211,8 +3145,6 @@ TEST_F( FormDataImporterTest, Metrics_SubmittedDifferentServerCardExpirationStatus_EmptyExpirationYear) { - scoped_feature_list_.InitAndEnableFeature( - features::kAutofillUpstreamEditableExpirationDate); EnableWalletCardImport(); std::vector<CreditCard> server_cards;
diff --git a/components/autofill/core/browser/payments/credit_card_save_manager.cc b/components/autofill/core/browser/payments/credit_card_save_manager.cc index 617c2f2..a42eab0f8 100644 --- a/components/autofill/core/browser/payments/credit_card_save_manager.cc +++ b/components/autofill/core/browser/payments/credit_card_save_manager.cc
@@ -255,8 +255,6 @@ (should_request_expiration_date_from_user_ && personal_data_manager_->GetSyncSigninState() == AutofillSyncSigninState::kSignedInAndWalletSyncTransportEnabled)) { - DCHECK(base::FeatureList::IsEnabled( - features::kAutofillUpstreamEditableExpirationDate)); LogCardUploadDecisions(upload_decision_metrics_); pending_upload_request_origin_ = url::Origin(); return; @@ -731,43 +729,39 @@ detected_values |= DetectedValue::HAS_GOOGLE_PAYMENTS_ACCOUNT; } - if (base::FeatureList::IsEnabled( - features::kAutofillUpstreamEditableExpirationDate)) { - // If expiration date month or expiration year are missing, signal that - // expiration date will be explicitly requested in the offer-to-save bubble. - if (!upload_request_.card - .GetInfo(AutofillType(CREDIT_CARD_EXP_MONTH), app_locale_) - .empty()) { - detected_values |= DetectedValue::CARD_EXPIRATION_MONTH; - } - if (!(upload_request_.card - .GetInfo(AutofillType(CREDIT_CARD_EXP_4_DIGIT_YEAR), app_locale_) - .empty())) { - detected_values |= DetectedValue::CARD_EXPIRATION_YEAR; - } + // If expiration date month or expiration year are missing, signal that + // expiration date will be explicitly requested in the offer-to-save bubble. + if (!upload_request_.card + .GetInfo(AutofillType(CREDIT_CARD_EXP_MONTH), app_locale_) + .empty()) { + detected_values |= DetectedValue::CARD_EXPIRATION_MONTH; + } + if (!(upload_request_.card + .GetInfo(AutofillType(CREDIT_CARD_EXP_4_DIGIT_YEAR), app_locale_) + .empty())) { + detected_values |= DetectedValue::CARD_EXPIRATION_YEAR; + } - // Set |USER_PROVIDED_EXPIRATION_DATE| if expiration date is detected as - // expired or missing. - if (detected_values & DetectedValue::CARD_EXPIRATION_MONTH && - detected_values & DetectedValue::CARD_EXPIRATION_YEAR) { - int month_value = 0, year_value = 0; - bool parsable = - base::StringToInt( - upload_request_.card.GetInfo(AutofillType(CREDIT_CARD_EXP_MONTH), - app_locale_), - &month_value) && - base::StringToInt( - upload_request_.card.GetInfo( - AutofillType(CREDIT_CARD_EXP_4_DIGIT_YEAR), app_locale_), - &year_value); - DCHECK(parsable); - if (!IsValidCreditCardExpirationDate(year_value, month_value, - AutofillClock::Now())) { - detected_values |= DetectedValue::USER_PROVIDED_EXPIRATION_DATE; - } - } else { + // Set |USER_PROVIDED_EXPIRATION_DATE| if expiration date is detected as + // expired or missing. + if (detected_values & DetectedValue::CARD_EXPIRATION_MONTH && + detected_values & DetectedValue::CARD_EXPIRATION_YEAR) { + int month_value = 0, year_value = 0; + bool parsable = + base::StringToInt(upload_request_.card.GetInfo( + AutofillType(CREDIT_CARD_EXP_MONTH), app_locale_), + &month_value) && + base::StringToInt( + upload_request_.card.GetInfo( + AutofillType(CREDIT_CARD_EXP_4_DIGIT_YEAR), app_locale_), + &year_value); + DCHECK(parsable); + if (!IsValidCreditCardExpirationDate(year_value, month_value, + AutofillClock::Now())) { detected_values |= DetectedValue::USER_PROVIDED_EXPIRATION_DATE; } + } else { + detected_values |= DetectedValue::USER_PROVIDED_EXPIRATION_DATE; } // If cardholder name is conflicting/missing and the user does NOT have a
diff --git a/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc b/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc index 184326bc..8798b03 100644 --- a/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc +++ b/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc
@@ -2619,9 +2619,6 @@ TEST_F( CreditCardSaveManagerTest, UploadCreditCard_ShouldRequestExpirationDate_ResetBetweenConsecutiveSaves) { - scoped_feature_list_.InitAndEnableFeature( - features::kAutofillUpstreamEditableExpirationDate); - // Create, fill and submit an address form in order to establish a recent // profile which can be selected for the upload request. FormData address_form; @@ -2670,9 +2667,6 @@ TEST_F( CreditCardSaveManagerTest, UploadCreditCard_WalletSyncTransportEnabled_ShouldNotRequestExpirationDate) { - scoped_feature_list_.InitAndEnableFeature( - features::kAutofillUpstreamEditableExpirationDate); - // Wallet Sync Transport is enabled. personal_data_.SetSyncAndSignInState( AutofillSyncSigninState::kSignedInAndWalletSyncTransportEnabled); @@ -2709,9 +2703,6 @@ TEST_F( CreditCardSaveManagerTest, UploadCreditCard_WalletSyncTransportNotEnabled_ShouldRequestExpirationDate) { - scoped_feature_list_.InitAndEnableFeature( - features::kAutofillUpstreamEditableExpirationDate); - // Wallet Sync Transport is not enabled. personal_data_.SetSyncAndSignInState( AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled); @@ -2750,9 +2741,6 @@ TEST_F( CreditCardSaveManagerTest, UploadCreditCard_DoNotRequestExpirationDateIfMissingNameAndExpirationDate) { - scoped_feature_list_.InitAndEnableFeature( - features::kAutofillUpstreamEditableExpirationDate); - // Create, fill and submit an address form in order to establish a recent // profile which can be selected for the upload request. FormData address_form; @@ -2782,36 +2770,6 @@ } TEST_F(CreditCardSaveManagerTest, - UploadCreditCard_DoNotRequestExpirationDate_EditableExpDateOff) { - scoped_feature_list_.InitAndDisableFeature( - features::kAutofillUpstreamEditableExpirationDate); - // Create, fill and submit an address form in order to establish a recent - // profile which can be selected for the upload request. - FormData address_form; - test::CreateTestAddressFormData(&address_form); - FormsSeen(std::vector<FormData>(1, address_form)); - ManuallyFillAddressForm("John", "Smith", "77401", "US", &address_form); - FormSubmitted(address_form); - - // Set up our credit card form data. - FormData credit_card_form; - CreateTestCreditCardFormData(&credit_card_form, CreditCardFormOptions()); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - credit_card_form.fields[0].value = ASCIIToUTF16("John Smith"); - credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111"); - credit_card_form.fields[2].value = ASCIIToUTF16(""); - credit_card_form.fields[3].value = ASCIIToUTF16(""); - credit_card_form.fields[4].value = ASCIIToUTF16("123"); - - base::HistogramTester histogram_tester; - FormSubmitted(credit_card_form); - EXPECT_FALSE(autofill_client_.ConfirmSaveCardLocallyWasCalled()); - EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded()); -} - -TEST_F(CreditCardSaveManagerTest, UploadCreditCard_RequestExpirationDateViaExpDateFixFlow) { #if defined(OS_IOS) // iOS should always provide a valid expiration date when attempting to @@ -2824,8 +2782,6 @@ } #endif - scoped_feature_list_.InitAndEnableFeature( - features::kAutofillUpstreamEditableExpirationDate); // Create, fill and submit an address form in order to establish a recent // profile which can be selected for the upload request. FormData address_form; @@ -2878,8 +2834,6 @@ } #endif - scoped_feature_list_.InitAndEnableFeature( - features::kAutofillUpstreamEditableExpirationDate); // Create, fill and submit an address form in order to establish a recent // profile which can be selected for the upload request. FormData address_form; @@ -2932,8 +2886,6 @@ } #endif - scoped_feature_list_.InitAndEnableFeature( - features::kAutofillUpstreamEditableExpirationDate); // Create, fill and submit an address form in order to establish a recent // profile which can be selected for the upload request. FormData address_form; @@ -2986,8 +2938,6 @@ } #endif - scoped_feature_list_.InitAndEnableFeature( - features::kAutofillUpstreamEditableExpirationDate); // Create, fill and submit an address form in order to establish a recent // profile which can be selected for the upload request. FormData address_form; @@ -3041,8 +2991,6 @@ } #endif - scoped_feature_list_.InitAndEnableFeature( - features::kAutofillUpstreamEditableExpirationDate); // Create, fill and submit an address form in order to establish a recent // profile which can be selected for the upload request. FormData address_form;
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc index e45d579f..c313b05 100644 --- a/components/autofill/core/browser/personal_data_manager.cc +++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -445,11 +445,6 @@ ReceiveLoadedDbValues(h, result.get(), &pending_server_creditcards_query_, &server_credit_cards_); - - // If the user has a saved unmasked server card and the experiment is - // disabled, force mask all cards back to the unsaved state. - if (!OfferStoreUnmaskedCards(is_off_the_record_)) - ResetFullServerCards(); } break; case AUTOFILL_CLOUDTOKEN_RESULT:
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc index 766044927..5ac47822 100644 --- a/components/autofill/core/browser/personal_data_manager_unittest.cc +++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -1433,136 +1433,6 @@ EXPECT_EQ(0, local_card.Compare(*personal_data_->GetCreditCards()[0])); } -// Makes sure that full cards are re-masked when full PAN storage is off. -TEST_F(PersonalDataManagerTest, RefuseToStoreFullCard) { -// On Linux this should be disabled automatically. Elsewhere, only if the -// flag is passed. -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) - EXPECT_FALSE(base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableOfferStoreUnmaskedWalletCards)); -#else - base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kDisableOfferStoreUnmaskedWalletCards); -#endif - - std::vector<CreditCard> server_cards; - server_cards.push_back(CreditCard(CreditCard::FULL_SERVER_CARD, "c789")); - test::SetCreditCardInfo(&server_cards.back(), "Clyde Barrow", - "378282246310005" /* American Express */, "04", - "2999", "1"); - SetServerCards(server_cards); - personal_data_->Refresh(); - - WaitForOnPersonalDataChanged(); - - ASSERT_EQ(1U, personal_data_->GetCreditCards().size()); - EXPECT_EQ(CreditCard::MASKED_SERVER_CARD, - personal_data_->GetCreditCards()[0]->record_type()); -} - -// Makes sure that full cards are only added as masked card when full PAN -// storage is disabled. -TEST_F(PersonalDataManagerTest, AddFullCardAsMaskedCard) { -// On Linux this should be disabled automatically. Elsewhere, only if the -// flag is passed. -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) - EXPECT_FALSE(base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableOfferStoreUnmaskedWalletCards)); -#else - base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kDisableOfferStoreUnmaskedWalletCards); -#endif - - CreditCard server_card(CreditCard::FULL_SERVER_CARD, "c789"); - test::SetCreditCardInfo(&server_card, "Clyde Barrow", - "378282246310005" /* American Express */, "04", - "2999", "1"); - - personal_data_->AddFullServerCreditCard(server_card); - - WaitForOnPersonalDataChanged(); - - ASSERT_EQ(1U, personal_data_->GetCreditCards().size()); - EXPECT_EQ(CreditCard::MASKED_SERVER_CARD, - personal_data_->GetCreditCards()[0]->record_type()); -} - -TEST_F(PersonalDataManagerTest, OfferStoreUnmaskedCards) { -#if defined(OS_CHROMEOS) || defined(OS_WIN) || defined(OS_MACOSX) || \ - defined(OS_IOS) || defined(OS_ANDROID) || defined(OS_FUCHSIA) - bool should_offer = true; -#elif defined(OS_LINUX) - bool should_offer = false; -#endif - EXPECT_EQ(should_offer, OfferStoreUnmaskedCards(/*is_off_the_record=*/false)); -} - -// Tests that OfferStoreUnmaskedCards always returns false if the user is off -// the record. -TEST_F(PersonalDataManagerTest, OfferStoreUnmaskedCards_OffTheRecord) { - EXPECT_EQ(false, OfferStoreUnmaskedCards(/*is_off_the_record=*/true)); -} - -// Tests that UpdateServerCreditCard can be used to mask or unmask server cards. -TEST_F(PersonalDataManagerTest, UpdateServerCreditCards) { - EnableWalletCardImport(); - - std::vector<CreditCard> server_cards; - server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "a123")); - test::SetCreditCardInfo(&server_cards.back(), "John Dillinger", - "3456" /* Visa */, "01", "2999", "1"); - server_cards.back().SetNetworkForMaskedCard(kVisaCard); - - server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "b456")); - test::SetCreditCardInfo(&server_cards.back(), "Bonnie Parker", - "5100" /* Mastercard */, "12", "2999", "1"); - server_cards.back().SetNetworkForMaskedCard(kMasterCard); - - server_cards.push_back(CreditCard(CreditCard::FULL_SERVER_CARD, "c789")); - test::SetCreditCardInfo(&server_cards.back(), "Clyde Barrow", - "378282246310005" /* American Express */, "04", - "2999", "1"); - - SetServerCards(server_cards); - personal_data_->Refresh(); - - WaitForOnPersonalDataChanged(); - - ASSERT_EQ(3U, personal_data_->GetCreditCards().size()); - if (!OfferStoreUnmaskedCards(/*is_off_the_record=*/false)) { - for (CreditCard* card : personal_data_->GetCreditCards()) { - EXPECT_EQ(CreditCard::MASKED_SERVER_CARD, card->record_type()); - } - // The rest of this test doesn't work if we're force-masking all unmasked - // cards. - return; - } - - // The GUIDs will be different, so just compare the data. - for (size_t i = 0; i < 3; ++i) - EXPECT_EQ(0, server_cards[i].Compare(*personal_data_->GetCreditCards()[i])); - - CreditCard* unmasked_card = &server_cards.front(); - unmasked_card->set_record_type(CreditCard::FULL_SERVER_CARD); - unmasked_card->SetNumber(base::ASCIIToUTF16("4234567890123456")); - personal_data_->UpdateServerCreditCard(*unmasked_card); - - WaitForOnPersonalDataChanged(); - - for (size_t i = 0; i < 3; ++i) - EXPECT_EQ(0, server_cards[i].Compare(*personal_data_->GetCreditCards()[i])); - - CreditCard* remasked_card = &server_cards.back(); - remasked_card->set_record_type(CreditCard::MASKED_SERVER_CARD); - remasked_card->SetNumber(base::ASCIIToUTF16("0005")); - personal_data_->UpdateServerCreditCard(*remasked_card); - - WaitForOnPersonalDataChanged(); - - for (size_t i = 0; i < 3; ++i) - EXPECT_EQ(0, server_cards[i].Compare(*personal_data_->GetCreditCards()[i])); -} - TEST_F(PersonalDataManagerTest, AddProfilesAndCreditCards) { AutofillProfile profile0(base::GenerateGUID(), test::kEmptyOrigin); test::SetProfileInfo(&profile0, "Marion", "Mitchell", "Morrison", @@ -4036,120 +3906,6 @@ EXPECT_EQ(kArbitraryTime, added_card->modification_date()); } -TEST_F(PersonalDataManagerTest, UpdateServerCreditCardUsageStats) { - EnableWalletCardImport(); - - std::vector<CreditCard> server_cards; - server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "a123")); - test::SetCreditCardInfo(&server_cards.back(), "John Dillinger", - "3456" /* Visa */, "01", "2999", "1"); - server_cards.back().SetNetworkForMaskedCard(kVisaCard); - - server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "b456")); - test::SetCreditCardInfo(&server_cards.back(), "Bonnie Parker", - "4444" /* Mastercard */, "12", "2999", "1"); - server_cards.back().SetNetworkForMaskedCard(kMasterCard); - - server_cards.push_back(CreditCard(CreditCard::FULL_SERVER_CARD, "c789")); - test::SetCreditCardInfo(&server_cards.back(), "Clyde Barrow", - "378282246310005" /* American Express */, "04", - "2999", "1"); - - // Create the test clock and set the time to a specific value. - TestAutofillClock test_clock; - test_clock.SetNow(kArbitraryTime); - - SetServerCards(server_cards); - - // Make sure everything is set up correctly. - personal_data_->Refresh(); - WaitForOnPersonalDataChanged(); - EXPECT_EQ(3U, personal_data_->GetCreditCards().size()); - - if (!OfferStoreUnmaskedCards(/*is_off_the_record=*/false)) { - for (CreditCard* card : personal_data_->GetCreditCards()) { - EXPECT_EQ(CreditCard::MASKED_SERVER_CARD, card->record_type()); - } - // The rest of this test doesn't work if we're force-masking all unmasked - // cards. - return; - } - - // The GUIDs will be different, so just compare the data. - for (size_t i = 0; i < 3; ++i) - EXPECT_EQ(0, server_cards[i].Compare(*personal_data_->GetCreditCards()[i])); - - CreditCard* unmasked_card = &server_cards.front(); - unmasked_card->set_record_type(CreditCard::FULL_SERVER_CARD); - unmasked_card->SetNumber(base::ASCIIToUTF16("4234567890123456")); - personal_data_->UpdateServerCreditCard(*unmasked_card); - - WaitForOnPersonalDataChanged(); - ASSERT_EQ(3U, personal_data_->GetCreditCards().size()); - - for (size_t i = 0; i < 3; ++i) - EXPECT_EQ(0, server_cards[i].Compare(*personal_data_->GetCreditCards()[i])); - - // For an unmasked card, usage data starts out as 2 because of the unmasking - // which is considered a use. The use date should now be the specified Now() - // time kArbitraryTime. - EXPECT_EQ(2U, personal_data_->GetCreditCards()[0]->use_count()); - EXPECT_EQ(kArbitraryTime, personal_data_->GetCreditCards()[0]->use_date()); - - EXPECT_EQ(1U, personal_data_->GetCreditCards()[1]->use_count()); - EXPECT_NE(kArbitraryTime, personal_data_->GetCreditCards()[1]->use_date()); - - // Having unmasked this card, usage stats should be 2 and - // kArbitraryTime. - EXPECT_EQ(2U, personal_data_->GetCreditCards()[2]->use_count()); - EXPECT_EQ(kArbitraryTime, personal_data_->GetCreditCards()[2]->use_date()); - - // Change the Now() value for a second time. - test_clock.SetNow(kSomeLaterTime); - - server_cards.back().set_guid(personal_data_->GetCreditCards()[2]->guid()); - personal_data_->RecordUseOf(server_cards.back()); - - WaitForOnPersonalDataChanged(); - ASSERT_EQ(3U, personal_data_->GetCreditCards().size()); - EXPECT_EQ(2U, personal_data_->GetCreditCards()[0]->use_count()); - EXPECT_EQ(kArbitraryTime, personal_data_->GetCreditCards()[0]->use_date()); - - EXPECT_EQ(1U, personal_data_->GetCreditCards()[1]->use_count()); - EXPECT_NE(kArbitraryTime, personal_data_->GetCreditCards()[1]->use_date()); - - // The RecordUseOf call should have incremented the use_count to 3 and set the - // use_date to kSomeLaterTime. - EXPECT_EQ(3U, personal_data_->GetCreditCards()[2]->use_count()); - EXPECT_EQ(kSomeLaterTime, personal_data_->GetCreditCards()[2]->use_date()); - - // Can record usage stats on masked cards. - server_cards[1].set_guid(personal_data_->GetCreditCards()[1]->guid()); - personal_data_->RecordUseOf(server_cards[1]); - - WaitForOnPersonalDataChanged(); - ASSERT_EQ(3U, personal_data_->GetCreditCards().size()); - EXPECT_EQ(2U, personal_data_->GetCreditCards()[1]->use_count()); - EXPECT_EQ(kSomeLaterTime, personal_data_->GetCreditCards()[1]->use_date()); - - // Change Now()'s return value for a third time. - test_clock.SetNow(kMuchLaterTime); - - // Upgrading to unmasked retains the usage stats (and increments them). - CreditCard* unmasked_card2 = &server_cards[1]; - unmasked_card2->set_record_type(CreditCard::FULL_SERVER_CARD); - unmasked_card2->SetNumber(base::ASCIIToUTF16("5555555555554444")); - personal_data_->UpdateServerCreditCard(*unmasked_card2); - - server_cards[1].set_guid(personal_data_->GetCreditCards()[1]->guid()); - personal_data_->RecordUseOf(server_cards[1]); - - WaitForOnPersonalDataChanged(); - ASSERT_EQ(3U, personal_data_->GetCreditCards().size()); - EXPECT_EQ(3U, personal_data_->GetCreditCards()[1]->use_count()); - EXPECT_EQ(kMuchLaterTime, personal_data_->GetCreditCards()[1]->use_date()); -} - TEST_F(PersonalDataManagerTest, ClearAllServerData) { // Add a server card. std::vector<CreditCard> server_cards; @@ -6746,21 +6502,6 @@ } } -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) -// Make sure that it's not possible to add full server cards on Linux. -TEST_F(PersonalDataManagerTest, CannotAddFullServerCardOnLinux) { - SetUpThreeCardTypes(); - - // Check that cards were masked and other were untouched. - EXPECT_EQ(3U, personal_data_->GetCreditCards().size()); - std::vector<CreditCard*> server_cards = - personal_data_->GetServerCreditCards(); - EXPECT_EQ(2U, server_cards.size()); - for (CreditCard* card : server_cards) - EXPECT_TRUE(card->record_type() == CreditCard::MASKED_SERVER_CARD); -} -#endif // #if defined(OS_LINUX) && !defined(OS_CHROMEOS) - // These tests are not applicable on Linux since it does not support full server // cards. #if !defined(OS_LINUX) || defined(OS_CHROMEOS)
diff --git a/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller.h b/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller.h index d2a1cb31..d980b36 100644 --- a/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller.h +++ b/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller.h
@@ -32,7 +32,6 @@ virtual base::string16 GetOkButtonLabel() const = 0; virtual int GetCvcImageRid() const = 0; virtual bool ShouldRequestExpirationDate() const = 0; - virtual bool CanStoreLocally() const = 0; virtual bool GetStoreLocallyStartState() const = 0; #if defined(OS_ANDROID) virtual bool ShouldOfferWebauthn() const = 0;
diff --git a/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.cc b/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.cc index d3ac2eae..f693be0 100644 --- a/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.cc +++ b/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.cc
@@ -27,9 +27,8 @@ namespace autofill { CardUnmaskPromptControllerImpl::CardUnmaskPromptControllerImpl( - PrefService* pref_service, - bool is_off_the_record) - : pref_service_(pref_service), is_off_the_record_(is_off_the_record) {} + PrefService* pref_service) + : pref_service_(pref_service) {} CardUnmaskPromptControllerImpl::~CardUnmaskPromptControllerImpl() { if (card_unmask_view_) @@ -125,23 +124,15 @@ pending_details_.exp_month = exp_month; pending_details_.exp_year = exp_year; } - if (CanStoreLocally()) { - pending_details_.should_store_pan = should_store_pan; - // Remember the last choice the user made (on this device). - pref_service_->SetBoolean(prefs::kAutofillWalletImportStorageCheckboxState, - should_store_pan); - } else { - DCHECK(!should_store_pan); - pending_details_.should_store_pan = false; - } + DCHECK(!should_store_pan); + pending_details_.should_store_pan = false; - // On Android, the FIDO authentication checkbox is only shown when the local - // storage checkbox is not shown and the flag is turned on. If it is shown, - // then remember the last choice the user made on this device. + // On Android, the FIDO authentication checkbox is only shown when the flag is + // turned on. If it is shown, then remember the last choice the user made on + // this device. #if defined(OS_ANDROID) if (base::FeatureList::IsEnabled( - features::kAutofillCreditCardAuthentication) && - !CanStoreLocally()) { + features::kAutofillCreditCardAuthentication)) { pending_details_.enable_fido_auth = enable_fido_auth; pref_service_->SetBoolean( prefs::kAutofillCreditCardFidoAuthOfferCheckboxState, enable_fido_auth); @@ -212,22 +203,6 @@ new_card_link_clicked_; } -bool CardUnmaskPromptControllerImpl::CanStoreLocally() const { - if (base::FeatureList::IsEnabled( - features::kAutofillNoLocalSaveOnUnmaskSuccess)) { - return false; - } - // Never offer to save for incognito. - if (is_off_the_record_) - return false; - if (reason_ == AutofillClient::UNMASK_FOR_PAYMENT_REQUEST) - return false; - if (card_.record_type() == CreditCard::LOCAL_CARD) - return false; - - return OfferStoreUnmaskedCards(is_off_the_record_); -} - bool CardUnmaskPromptControllerImpl::GetStoreLocallyStartState() const { return pref_service_->GetBoolean( prefs::kAutofillWalletImportStorageCheckboxState); @@ -326,22 +301,6 @@ AutofillMetrics::UNMASK_PROMPT_SAVED_CARD_LOCALLY, card_.HasValidNickname()); } - - if (CanStoreLocally()) { - // Tracking changes in local save preference. - AutofillMetrics::UnmaskPromptEvent event; - if (unmasking_initial_should_store_pan_ && final_should_store_pan) { - event = AutofillMetrics::UNMASK_PROMPT_LOCAL_SAVE_DID_NOT_OPT_OUT; - } else if (!unmasking_initial_should_store_pan_ && - !final_should_store_pan) { - event = AutofillMetrics::UNMASK_PROMPT_LOCAL_SAVE_DID_NOT_OPT_IN; - } else if (unmasking_initial_should_store_pan_ && !final_should_store_pan) { - event = AutofillMetrics::UNMASK_PROMPT_LOCAL_SAVE_DID_OPT_OUT; - } else { - event = AutofillMetrics::UNMASK_PROMPT_LOCAL_SAVE_DID_OPT_IN; - } - AutofillMetrics::LogUnmaskPromptEvent(event, card_.HasValidNickname()); - } } AutofillMetrics::UnmaskPromptEvent
diff --git a/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.h b/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.h index 67e6622b..d5c31d3 100644 --- a/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.h +++ b/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.h
@@ -22,8 +22,7 @@ class CardUnmaskPromptControllerImpl : public CardUnmaskPromptController { public: - CardUnmaskPromptControllerImpl(PrefService* pref_service, - bool is_off_the_record); + explicit CardUnmaskPromptControllerImpl(PrefService* pref_service); virtual ~CardUnmaskPromptControllerImpl(); // This should be OnceCallback<unique_ptr<CardUnmaskPromptView>> but there are @@ -54,7 +53,6 @@ base::string16 GetOkButtonLabel() const override; int GetCvcImageRid() const override; bool ShouldRequestExpirationDate() const override; - bool CanStoreLocally() const override; bool GetStoreLocallyStartState() const override; #if defined(OS_ANDROID) bool ShouldOfferWebauthn() const override; @@ -78,7 +76,6 @@ PrefService* pref_service_; bool new_card_link_clicked_ = false; - bool is_off_the_record_; CreditCard card_; AutofillClient::UnmaskCardReason reason_; base::WeakPtr<CardUnmaskDelegate> delegate_;
diff --git a/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl_unittest.cc b/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl_unittest.cc index fba820d9..27ee299 100644 --- a/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl_unittest.cc +++ b/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl_unittest.cc
@@ -69,15 +69,11 @@ public: explicit TestCardUnmaskPromptController( TestingPrefServiceSimple* pref_service) - : CardUnmaskPromptControllerImpl(pref_service, false), - can_store_locally_(!base::FeatureList::IsEnabled( - features::kAutofillNoLocalSaveOnUnmaskSuccess)) {} + : CardUnmaskPromptControllerImpl(pref_service) {} - bool CanStoreLocally() const override { return can_store_locally_; } #if defined(OS_ANDROID) bool ShouldOfferWebauthn() const override { return should_offer_webauthn_; } #endif - void set_can_store_locally(bool can) { can_store_locally_ = can; } void set_should_offer_webauthn(bool should) { should_offer_webauthn_ = should; } @@ -87,7 +83,6 @@ } private: - bool can_store_locally_; bool should_offer_webauthn_; base::WeakPtrFactory<TestCardUnmaskPromptController> weak_factory_{this}; @@ -173,7 +168,6 @@ FidoAuthOfferCheckboxStatePersistent) { scoped_feature_list_.InitAndEnableFeature( features::kAutofillCreditCardAuthentication); - controller_->set_can_store_locally(false); ShowPromptAndSimulateResponse(/*should_store_pan=*/false, /*enable_fido_auth=*/true); EXPECT_TRUE(pref_service_->GetBoolean( @@ -189,7 +183,6 @@ PopulateCheckboxToUserProvidedUnmaskDetails) { scoped_feature_list_.InitAndEnableFeature( features::kAutofillCreditCardAuthentication); - controller_->set_can_store_locally(false); ShowPromptAndSimulateResponse(/*should_store_pan=*/false, /*enable_fido_auth=*/true); @@ -486,7 +479,6 @@ } TEST_P(LoggingValidationTestForNickname, DontLogForHiddenCheckbox) { - controller_->set_can_store_locally(false); ShowPromptAndSimulateResponse(/*should_store_pan=*/false, /*enable_fido_auth=*/false); base::HistogramTester histogram_tester;
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc index 3965dc90..fe2e5a5 100644 --- a/components/autofill/core/common/autofill_payments_features.cc +++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -90,11 +90,6 @@ const base::Feature kAutofillEnableVirtualCard{ "AutofillEnableVirtualCard", base::FEATURE_DISABLED_BY_DEFAULT}; -// When enabled, will remove the option to save unmasked server cards as -// FULL_SERVER_CARDs upon successful unmask. -const base::Feature kAutofillNoLocalSaveOnUnmaskSuccess{ - "AutofillNoLocalSaveOnUnmaskSuccess", base::FEATURE_ENABLED_BY_DEFAULT}; - // When enabled, the Save Card infobar will be dismissed by a user initiated // navigation other than one caused by submitted form. const base::Feature kAutofillSaveCardDismissOnNavigation{ @@ -117,9 +112,6 @@ const base::Feature kAutofillUpstreamAllowAllEmailDomains{ "AutofillUpstreamAllowAllEmailDomains", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kAutofillUpstreamEditableExpirationDate{ - "AutofillUpstreamEditableExpirationDate", base::FEATURE_ENABLED_BY_DEFAULT}; - bool ShouldShowImprovedUserConsentForCreditCardSave() { #if defined(OS_WIN) || defined(OS_MACOSX) || \ (defined(OS_LINUX) && !defined(OS_CHROMEOS))
diff --git a/components/autofill/core/common/autofill_payments_features.h b/components/autofill/core/common/autofill_payments_features.h index 4e5c628c..99b59e82 100644 --- a/components/autofill/core/common/autofill_payments_features.h +++ b/components/autofill/core/common/autofill_payments_features.h
@@ -31,12 +31,10 @@ extern const base::Feature kAutofillEnableSurfacingServerCardNickname; extern const base::Feature kAutofillEnableToolbarStatusChip; extern const base::Feature kAutofillEnableVirtualCard; -extern const base::Feature kAutofillNoLocalSaveOnUnmaskSuccess; extern const base::Feature kAutofillSaveCardDismissOnNavigation; extern const base::Feature kAutofillSaveCardInfobarEditSupport; extern const base::Feature kAutofillUpstream; extern const base::Feature kAutofillUpstreamAllowAllEmailDomains; -extern const base::Feature kAutofillUpstreamEditableExpirationDate; // Return whether a [No thanks] button and new messaging is shown in the save // card bubbles. This will be called only on desktop platforms.
diff --git a/components/background_task_scheduler/BUILD.gn b/components/background_task_scheduler/BUILD.gn index 8a71072..521dfef 100644 --- a/components/background_task_scheduler/BUILD.gn +++ b/components/background_task_scheduler/BUILD.gn
@@ -119,6 +119,7 @@ ] deps = [ + ":background_task_scheduler_task_ids_java", "$google_play_services_package:google_play_services_auth_base_java", "$google_play_services_package:google_play_services_base_java", "$google_play_services_package:google_play_services_basement_java", @@ -131,6 +132,8 @@ "//base:base_junit_test_support", "//components/background_task_scheduler:public_java", "//third_party/junit", + "//third_party/mockito:mockito_java", + "//third_party/robolectric:robolectric_all_java", ] } }
diff --git a/components/browser_ui/settings/android/BUILD.gn b/components/browser_ui/settings/android/BUILD.gn index 806560d..1959792 100644 --- a/components/browser_ui/settings/android/BUILD.gn +++ b/components/browser_ui/settings/android/BUILD.gn
@@ -25,6 +25,7 @@ "//base:base_java", "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:androidx_annotation_annotation_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", "//third_party/android_deps:androidx_preference_preference_java", "//ui/android:ui_java", ]
diff --git a/components/browser_ui/site_settings/android/BUILD.gn b/components/browser_ui/site_settings/android/BUILD.gn index 894e9a34..fa50c2c 100644 --- a/components/browser_ui/site_settings/android/BUILD.gn +++ b/components/browser_ui/site_settings/android/BUILD.gn
@@ -105,7 +105,9 @@ sources = [ "javatests/src/org/chromium/components/browser_ui/site_settings/WebsiteAddressTest.java" ] deps = [ ":java", + "//base:base_java", "//base:base_java_test_support", + "//third_party/junit", ] }
diff --git a/components/browser_ui/styles/android/BUILD.gn b/components/browser_ui/styles/android/BUILD.gn index df181094..5295f4d 100644 --- a/components/browser_ui/styles/android/BUILD.gn +++ b/components/browser_ui/styles/android/BUILD.gn
@@ -11,6 +11,7 @@ ":java_resources", "//base:base_java", "//third_party/android_deps:android_support_v7_appcompat_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", ] }
diff --git a/components/browser_ui/util/android/BUILD.gn b/components/browser_ui/util/android/BUILD.gn index 5b7a7d3..f089bb4 100644 --- a/components/browser_ui/util/android/BUILD.gn +++ b/components/browser_ui/util/android/BUILD.gn
@@ -17,6 +17,7 @@ "//base:base_java", "//components/embedder_support/android:util_java", "//content/public/android:content_java", + "//third_party/android_deps:androidx_core_core_java", ] } @@ -44,5 +45,9 @@ "//base:base_java_test_support", "//base:base_junit_test_support", "//base/test:test_support_java", + "//content/public/android:content_java", + "//third_party/junit", + "//third_party/mockito:mockito_java", + "//third_party/robolectric:robolectric_all_java", ] }
diff --git a/components/browser_ui/widget/android/BUILD.gn b/components/browser_ui/widget/android/BUILD.gn index 2eaf6be..e9d5adb 100644 --- a/components/browser_ui/widget/android/BUILD.gn +++ b/components/browser_ui/widget/android/BUILD.gn
@@ -101,6 +101,7 @@ "//components/embedder_support/android:util_java", "//third_party/android_deps:android_support_v4_java", "//third_party/android_deps:android_support_v7_appcompat_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", "//third_party/android_deps:androidx_interpolator_interpolator_java", "//third_party/android_deps:androidx_recyclerview_recyclerview_java", "//ui/android:ui_java", @@ -235,6 +236,7 @@ "//base:base_java_test_support", "//content/public/test/android:content_java_test_support", "//third_party/android_deps:androidx_appcompat_appcompat_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", "//third_party/android_deps:androidx_core_core_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", @@ -284,5 +286,8 @@ "//base:base_java_test_support", "//base:base_junit_test_support", "//base/test:test_support_java", + "//third_party/junit", + "//third_party/mockito:mockito_java", + "//third_party/robolectric:robolectric_all_java", ] }
diff --git a/components/embedder_support/android/BUILD.gn b/components/embedder_support/android/BUILD.gn index 49f264a0..9cb9084 100644 --- a/components/embedder_support/android/BUILD.gn +++ b/components/embedder_support/android/BUILD.gn
@@ -256,6 +256,8 @@ deps = [ ":util_java", "//base:base_junit_test_support", + "//third_party/junit", + "//third_party/robolectric:robolectric_all_java", ] }
diff --git a/components/exo/wayland/clients/rects.cc b/components/exo/wayland/clients/rects.cc index d4d101c..8f34046 100644 --- a/components/exo/wayland/clients/rects.cc +++ b/components/exo/wayland/clients/rects.cc
@@ -438,7 +438,7 @@ } GrContext* gr_context = gr_context_.get(); if (gr_context) { - gr_context->flush(); + gr_context->flushAndSubmit(); #if defined(USE_GBM) if (egl_sync_type_) {
diff --git a/components/external_intents/android/BUILD.gn b/components/external_intents/android/BUILD.gn index 530cfa2..224c144 100644 --- a/components/external_intents/android/BUILD.gn +++ b/components/external_intents/android/BUILD.gn
@@ -25,6 +25,7 @@ "//components/embedder_support/android:util_java", "//components/navigation_interception/android:navigation_interception_java", "//content/public/android:content_java", + "//services/network/public/mojom:mojom_java", "//third_party/android_deps:androidx_annotation_annotation_java", "//ui/android:ui_java", "//url:gurl_java", @@ -72,7 +73,10 @@ "//base:base_java_test_support", "//content/public/test/android:content_java_test_support", "//third_party/android_deps:androidx_core_core_java", + "//third_party/android_sdk:android_test_mock_java", "//third_party/android_sdk/androidx_browser:androidx_browser_java", + "//third_party/android_support_test_runner:runner_java", + "//third_party/junit", "//ui/android:ui_java", ] }
diff --git a/components/feed/core/common/pref_names.cc b/components/feed/core/common/pref_names.cc index a4736ac..b3dc860 100644 --- a/components/feed/core/common/pref_names.cc +++ b/components/feed/core/common/pref_names.cc
@@ -39,6 +39,7 @@ "feedv2.request_throttler.last_request_time"; const char kDebugStreamData[] = "feedv2.debug_stream_data"; const char kRequestSchedule[] = "feedv2.request_schedule"; +const char kMetricsData[] = "feedv2.metrics_data"; } // namespace prefs @@ -55,6 +56,7 @@ base::Time()); registry->RegisterStringPref(feed::prefs::kDebugStreamData, std::string()); registry->RegisterDictionaryPref(feed::prefs::kRequestSchedule); + registry->RegisterDictionaryPref(feed::prefs::kMetricsData); UserClassifier::RegisterProfilePrefs(registry); }
diff --git a/components/feed/core/common/pref_names.h b/components/feed/core/common/pref_names.h index b23c155..67a1d1ee 100644 --- a/components/feed/core/common/pref_names.h +++ b/components/feed/core/common/pref_names.h
@@ -52,6 +52,8 @@ extern const char kDebugStreamData[]; // The pref name for storing the request schedule. extern const char kRequestSchedule[]; +// The pref name for storing the persistent metrics data. +extern const char kMetricsData[]; } // namespace prefs
diff --git a/components/feed/core/v2/feed_stream.cc b/components/feed/core/v2/feed_stream.cc index 4544d65..11c1ed5 100644 --- a/components/feed/core/v2/feed_stream.cc +++ b/components/feed/core/v2/feed_stream.cc
@@ -500,5 +500,8 @@ void FeedStream::ReportStreamScrolled(int distance_dp) { metrics_reporter_->StreamScrolled(distance_dp); } +void FeedStream::ReportStreamScrollStart() { + metrics_reporter_->StreamScrollStart(); +} } // namespace feed
diff --git a/components/feed/core/v2/feed_stream.h b/components/feed/core/v2/feed_stream.h index d92d8895..c0df33d 100644 --- a/components/feed/core/v2/feed_stream.h +++ b/components/feed/core/v2/feed_stream.h
@@ -140,6 +140,7 @@ void ReportManageInterestsAction() override; void ReportContextMenuOpened() override; void ReportStreamScrolled(int distance_dp) override; + void ReportStreamScrollStart() override; // offline_pages::TaskQueue::Delegate. void OnTaskQueueIsIdle() override;
diff --git a/components/feed/core/v2/feed_stream_unittest.cc b/components/feed/core/v2/feed_stream_unittest.cc index d0325fb..8f1da2ee 100644 --- a/components/feed/core/v2/feed_stream_unittest.cc +++ b/components/feed/core/v2/feed_stream_unittest.cc
@@ -359,8 +359,8 @@ class TestMetricsReporter : public MetricsReporter { public: - explicit TestMetricsReporter(const base::TickClock* clock) - : MetricsReporter(clock) {} + explicit TestMetricsReporter(const base::TickClock* clock, PrefService* prefs) + : MetricsReporter(clock, prefs) {} // MetricsReporter. void ContentSliceViewed(SurfaceId surface_id, int index_in_stream) override { @@ -402,8 +402,10 @@ void SetUp() override { feed::prefs::RegisterFeedSharedProfilePrefs(profile_prefs_.registry()); feed::RegisterProfilePrefs(profile_prefs_.registry()); - CHECK_EQ(kTestTimeEpoch, task_environment_.GetMockClock()->Now()); + metrics_reporter_ = std::make_unique<TestMetricsReporter>( + task_environment_.GetMockTickClock(), &profile_prefs_); + CHECK_EQ(kTestTimeEpoch, task_environment_.GetMockClock()->Now()); CreateStream(); } @@ -436,7 +438,7 @@ chrome_info.channel = version_info::Channel::STABLE; chrome_info.version = base::Version({99, 1, 9911, 2}); stream_ = std::make_unique<FeedStream>( - &refresh_scheduler_, &metrics_reporter_, this, &profile_prefs_, + &refresh_scheduler_, metrics_reporter_.get(), this, &profile_prefs_, &network_, store_.get(), task_environment_.GetMockClock(), task_environment_.GetMockTickClock(), chrome_info); @@ -495,8 +497,8 @@ protected: base::test::TaskEnvironment task_environment_{ base::test::TaskEnvironment::TimeSource::MOCK_TIME}; - TestMetricsReporter metrics_reporter_{task_environment_.GetMockTickClock()}; TestingPrefServiceSimple profile_prefs_; + std::unique_ptr<TestMetricsReporter> metrics_reporter_; TestFeedNetwork network_; TestWireResponseTranslator response_translator_; @@ -531,7 +533,7 @@ stream_->ExecuteRefreshTask(); EXPECT_TRUE(refresh_scheduler_.refresh_task_complete); EXPECT_EQ(LoadStreamStatus::kLoadNotAllowedArticlesListHidden, - metrics_reporter_.background_refresh_status); + metrics_reporter_->background_refresh_status); } TEST_F(FeedStreamTest, BackgroundRefreshSuccess) { @@ -544,7 +546,7 @@ // network. ASSERT_TRUE(refresh_scheduler_.refresh_task_complete); EXPECT_EQ(LoadStreamStatus::kLoadedFromNetwork, - metrics_reporter_.background_refresh_status); + metrics_reporter_->background_refresh_status); EXPECT_TRUE(response_translator_.InjectedResponseConsumed()); EXPECT_FALSE(stream_->GetModel()); TestSurface surface(stream_.get()); @@ -558,7 +560,7 @@ stream_->ExecuteRefreshTask(); WaitForIdleTaskQueue(); - EXPECT_EQ(metrics_reporter_.background_refresh_status, + EXPECT_EQ(metrics_reporter_->background_refresh_status, LoadStreamStatus::kModelAlreadyLoaded); } @@ -570,7 +572,7 @@ stream_->ExecuteRefreshTask(); WaitForIdleTaskQueue(); - EXPECT_EQ(metrics_reporter_.background_refresh_status, + EXPECT_EQ(metrics_reporter_->background_refresh_status, LoadStreamStatus::kModelAlreadyLoaded); } @@ -837,7 +839,7 @@ WaitForIdleTaskQueue(); EXPECT_EQ(LoadStreamStatus::kProtoTranslationFailed, - metrics_reporter_.load_stream_status); + metrics_reporter_->load_stream_status); } TEST_F(FeedStreamTest, DoNotLoadFromNetworkWhenOffline) { @@ -847,7 +849,7 @@ WaitForIdleTaskQueue(); EXPECT_EQ(LoadStreamStatus::kCannotLoadFromNetworkOffline, - metrics_reporter_.load_stream_status); + metrics_reporter_->load_stream_status); EXPECT_EQ("loading -> cant-refresh", surface.DescribeUpdates()); } @@ -858,7 +860,7 @@ WaitForIdleTaskQueue(); EXPECT_EQ(LoadStreamStatus::kLoadNotAllowedArticlesListHidden, - metrics_reporter_.load_stream_status); + metrics_reporter_->load_stream_status); EXPECT_EQ("no-cards", surface.DescribeUpdates()); } @@ -869,7 +871,7 @@ WaitForIdleTaskQueue(); EXPECT_EQ(LoadStreamStatus::kLoadNotAllowedEulaNotAccepted, - metrics_reporter_.load_stream_status); + metrics_reporter_->load_stream_status); EXPECT_EQ("no-cards", surface.DescribeUpdates()); } @@ -900,7 +902,7 @@ EXPECT_EQ("loading -> no-cards", surface.DescribeUpdates()); EXPECT_EQ(LoadStreamStatus::kCannotLoadFromNetworkSupressedForHistoryDelete, - metrics_reporter_.load_stream_status); + metrics_reporter_->load_stream_status); surface.Detach(); task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(2)); @@ -1028,7 +1030,7 @@ stream_->ReportSliceViewed( surface.GetSurfaceId(), surface.initial_state->updated_slices(1).slice().slice_id()); - EXPECT_EQ(1, metrics_reporter_.slice_viewed_index); + EXPECT_EQ(1, metrics_reporter_->slice_viewed_index); } TEST_F(FeedStreamTest, LoadMoreAppendsContent) {
diff --git a/components/feed/core/v2/metrics_reporter.cc b/components/feed/core/v2/metrics_reporter.cc index 975db91..bdf8c34 100644 --- a/components/feed/core/v2/metrics_reporter.cc +++ b/components/feed/core/v2/metrics_reporter.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "components/feed/core/v2/metrics_reporter.h" +#include <algorithm> #include <cmath> #include "base/metrics/histogram_functions.h" @@ -10,6 +11,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/time/tick_clock.h" #include "base/time/time.h" +#include "components/feed/core/v2/prefs.h" namespace feed { namespace { @@ -23,6 +25,12 @@ // Maximum time to wait before declaring opening a card a failure. // For ContentSuggestions.Feed.UserJourney.OpenCard. constexpr base::TimeDelta kOpenTimeout = base::TimeDelta::FromSeconds(20); +// For ContentSuggestions.Feed.TimeSpentInFeed, we want to get a measure +// of how much time the user is spending with the Feed. If the user stops +// interacting with the Feed, we stop counting it as time spent after this +// timeout. +constexpr base::TimeDelta kTimeSpentInFeedInteractionTimeout = + base::TimeDelta::FromSeconds(30); void ReportEngagementTypeHistogram(FeedEngagementType engagement_type) { base::UmaHistogramEnumeration("ContentSuggestions.Feed.EngagementType", @@ -41,10 +49,16 @@ } // namespace -MetricsReporter::MetricsReporter(const base::TickClock* clock) - : clock_(clock) {} +MetricsReporter::MetricsReporter(const base::TickClock* clock, + PrefService* profile_prefs) + : clock_(clock), profile_prefs_(profile_prefs) { + persistent_data_ = prefs::GetPersistentMetricsData(profile_prefs_); + ReportPersistentDataIfDayIsDone(); +} -MetricsReporter::~MetricsReporter() = default; +MetricsReporter::~MetricsReporter() { + FinalizeMetrics(); +} void MetricsReporter::OnEnterBackground() { FinalizeMetrics(); @@ -57,6 +71,28 @@ ReportEngagementTypeHistogram(FeedEngagementType::kFeedInteracted); } +void MetricsReporter::TrackTimeSpentInFeed(bool interacted_or_scrolled) { + if (time_in_feed_start_) { + ReportPersistentDataIfDayIsDone(); + persistent_data_.accumulated_time_spent_in_feed += + std::min(kTimeSpentInFeedInteractionTimeout, + clock_->NowTicks() - *time_in_feed_start_); + time_in_feed_start_ = base::nullopt; + } + + if (interacted_or_scrolled) { + time_in_feed_start_ = clock_->NowTicks(); + } +} + +void MetricsReporter::FinalizeVisit() { + if (!engaged_simple_reported_) + return; + engaged_reported_ = false; + engaged_simple_reported_ = false; + TrackTimeSpentInFeed(false); +} + void MetricsReporter::RecordEngagement(int scroll_distance_dp, bool interacted) { scroll_distance_dp = std::abs(scroll_distance_dp); @@ -64,12 +100,13 @@ auto now = clock_->NowTicks(); const base::TimeDelta kVisitTimeout = base::TimeDelta::FromMinutes(5); if (now - visit_start_time_ > kVisitTimeout) { - engaged_reported_ = false; - engaged_simple_reported_ = false; + FinalizeVisit(); } // Reset the last active time for session measurement. visit_start_time_ = now; + TrackTimeSpentInFeed(true); + // Report the user as engaged-simple if they have scrolled any amount or // interacted with the card, and we have not already reported it for this // chrome run. @@ -89,6 +126,13 @@ } } +void MetricsReporter::StreamScrollStart() { + // Note that |TrackTimeSpentInFeed()| is called as a result of + // |StreamScrolled()| as well. Tracking the start of scroll events ensures we + // don't miss out on long and slow scrolling. + TrackTimeSpentInFeed(true); +} + void MetricsReporter::StreamScrolled(int distance_dp) { RecordEngagement(distance_dp, /*interacted=*/false); @@ -188,6 +232,8 @@ } void MetricsReporter::SurfaceOpened(SurfaceId surface_id) { + ReportPersistentDataIfDayIsDone(); + surfaces_waiting_for_content_.emplace(surface_id, clock_->NowTicks()); ReportUserActionHistogram(FeedUserActionType::kOpenedFeedSurface); base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( @@ -203,6 +249,7 @@ } void MetricsReporter::FinalizeMetrics() { + FinalizeVisit(); ReportCardOpenEndIfNeeded(false); for (auto iter = surfaces_waiting_for_content_.begin(); iter != surfaces_waiting_for_content_.end();) { @@ -212,6 +259,7 @@ iter != surfaces_waiting_for_more_content_.end();) { ReportGetMoreIfNeeded((iter++)->first, false); } + prefs::SetPersistentMetricsData(persistent_data_, profile_prefs_); } void MetricsReporter::ReportOpenFeedIfNeeded(SurfaceId surface_id, @@ -344,4 +392,34 @@ /*bucket_count=*/50); } +void MetricsReporter::ReportPersistentDataIfDayIsDone() { + // Reset the persistent data if 24 hours have elapsed, or if it has never + // been initialized. + bool reset_data = false; + if (persistent_data_.current_day_start.is_null()) { + reset_data = true; + } else { + // Report metrics if 24 hours have passed since the day started. + const base::TimeDelta since_day_start = + (base::Time::Now() - persistent_data_.current_day_start); + if (since_day_start > base::TimeDelta::FromDays(1) + // Allow up to 1 hour of negative delta, for expected clock changes. + || since_day_start < -base::TimeDelta::FromHours(1)) { + if (persistent_data_.accumulated_time_spent_in_feed > base::TimeDelta()) { + base::UmaHistogramLongTimes( + "ContentSuggestions.Feed.TimeSpentInFeed", + persistent_data_.accumulated_time_spent_in_feed); + } + + reset_data = true; + } + } + + if (reset_data) { + persistent_data_ = PersistentMetricsData(); + persistent_data_.current_day_start = base::Time::Now().LocalMidnight(); + prefs::SetPersistentMetricsData(persistent_data_, profile_prefs_); + } +} + } // namespace feed
diff --git a/components/feed/core/v2/metrics_reporter.h b/components/feed/core/v2/metrics_reporter.h index d680f1e..e9dcb5d 100644 --- a/components/feed/core/v2/metrics_reporter.h +++ b/components/feed/core/v2/metrics_reporter.h
@@ -5,6 +5,8 @@ #ifndef COMPONENTS_FEED_CORE_V2_METRICS_REPORTER_H_ #define COMPONENTS_FEED_CORE_V2_METRICS_REPORTER_H_ +#include <map> + #include "base/memory/weak_ptr.h" #include "base/optional.h" #include "base/time/time.h" @@ -54,7 +56,8 @@ // Note this is inherited only for testing. class MetricsReporter { public: - explicit MetricsReporter(const base::TickClock* clock); + explicit MetricsReporter(const base::TickClock* clock, + PrefService* profile_prefs); virtual ~MetricsReporter(); MetricsReporter(const MetricsReporter&) = delete; MetricsReporter& operator=(const MetricsReporter&) = delete; @@ -77,6 +80,7 @@ // Indicates the user scrolled the feed by |distance_dp| and then stopped // scrolling. void StreamScrolled(int distance_dp); + void StreamScrollStart(); // Called when the Feed surface is opened and closed. void SurfaceOpened(SurfaceId surface_id); @@ -104,16 +108,23 @@ base::WeakPtr<MetricsReporter> GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } + void ReportPersistentDataIfDayIsDone(); void CardOpenBegin(); void CardOpenTimeout(base::TimeTicks start_ticks); void ReportCardOpenEndIfNeeded(bool success); void RecordEngagement(int scroll_distance_dp, bool interacted); + void TrackTimeSpentInFeed(bool interacted_or_scrolled); void RecordInteraction(); void ReportOpenFeedIfNeeded(SurfaceId surface_id, bool success); void ReportGetMoreIfNeeded(SurfaceId surface_id, bool success); void FinalizeMetrics(); + void FinalizeVisit(); const base::TickClock* clock_; + PrefService* profile_prefs_; + // Persistent data stored in prefs. Data is read in the constructor, and then + // written back to prefs on backgrounding. + PersistentMetricsData persistent_data_; base::TimeTicks visit_start_time_; bool engaged_simple_reported_ = false; @@ -132,6 +143,11 @@ // loading the page succeeds, the open is considered successful. base::Optional<base::TimeTicks> pending_open_; + // For tracking time spent in the Feed. + base::Optional<base::TimeTicks> time_in_feed_start_; + // For TimeSpentOnFeed. + base::TimeDelta tracked_visit_time_in_feed_; + base::WeakPtrFactory<MetricsReporter> weak_ptr_factory_{this}; }; } // namespace feed
diff --git a/components/feed/core/v2/metrics_reporter_unittest.cc b/components/feed/core/v2/metrics_reporter_unittest.cc index 7300a16..58e9143 100644 --- a/components/feed/core/v2/metrics_reporter_unittest.cc +++ b/components/feed/core/v2/metrics_reporter_unittest.cc
@@ -5,10 +5,14 @@ #include "components/feed/core/v2/metrics_reporter.h" #include <map> +#include <memory> #include "base/test/metrics/histogram_tester.h" #include "base/test/metrics/user_action_tester.h" #include "base/test/task_environment.h" +#include "components/feed/core/common/pref_names.h" +#include "components/feed/core/shared_prefs/pref_names.h" +#include "components/prefs/testing_pref_service.h" #include "testing/gtest/include/gtest/gtest.h" namespace feed { @@ -19,6 +23,17 @@ class MetricsReporterTest : public testing::Test { protected: + void SetUp() override { + feed::prefs::RegisterFeedSharedProfilePrefs(profile_prefs_.registry()); + feed::RegisterProfilePrefs(profile_prefs_.registry()); + + // Tests start at the beginning of a day. + task_environment_.AdvanceClock( + (base::Time::Now().LocalMidnight() + base::TimeDelta::FromDays(1)) - + base::Time::Now() + base::TimeDelta::FromSeconds(1)); + + RecreateMetricsReporter(); + } std::map<FeedEngagementType, int> ReportedEngagementType() { std::map<FeedEngagementType, int> result; for (const auto& bucket : @@ -28,21 +43,27 @@ return result; } + void RecreateMetricsReporter() { + reporter_ = std::make_unique<MetricsReporter>( + task_environment_.GetMockTickClock(), &profile_prefs_); + } + protected: base::test::TaskEnvironment task_environment_{ base::test::TaskEnvironment::TimeSource::MOCK_TIME}; - MetricsReporter reporter_{task_environment_.GetMockTickClock()}; + TestingPrefServiceSimple profile_prefs_; + std::unique_ptr<MetricsReporter> reporter_; base::HistogramTester histogram_; base::UserActionTester user_actions_; }; TEST_F(MetricsReporterTest, SliceViewedReportsSuggestionShown) { - reporter_.ContentSliceViewed(kSurfaceId, 5); + reporter_->ContentSliceViewed(kSurfaceId, 5); histogram_.ExpectUniqueSample("NewTabPage.ContentSuggestions.Shown", 5, 1); } TEST_F(MetricsReporterTest, ScrollingSmall) { - reporter_.StreamScrolled(100); + reporter_->StreamScrolled(100); std::map<FeedEngagementType, int> want({ {FeedEngagementType::kFeedScrolled, 1}, @@ -52,7 +73,7 @@ } TEST_F(MetricsReporterTest, ScrollingCanTriggerEngaged) { - reporter_.StreamScrolled(161); + reporter_->StreamScrolled(161); std::map<FeedEngagementType, int> want({ {FeedEngagementType::kFeedScrolled, 1}, @@ -63,7 +84,7 @@ } TEST_F(MetricsReporterTest, OpeningContentIsInteracting) { - reporter_.OpenAction(5); + reporter_->OpenAction(5); std::map<FeedEngagementType, int> want({ {FeedEngagementType::kFeedEngaged, 1}, @@ -74,7 +95,7 @@ } TEST_F(MetricsReporterTest, RemovingContentIsInteracting) { - reporter_.RemoveAction(); + reporter_->RemoveAction(); std::map<FeedEngagementType, int> want({ {FeedEngagementType::kFeedEngaged, 1}, @@ -85,7 +106,7 @@ } TEST_F(MetricsReporterTest, NotInterestedInIsInteracting) { - reporter_.NotInterestedInAction(); + reporter_->NotInterestedInAction(); std::map<FeedEngagementType, int> want({ {FeedEngagementType::kFeedEngaged, 1}, @@ -96,7 +117,7 @@ } TEST_F(MetricsReporterTest, ManageInterestsInIsInteracting) { - reporter_.ManageInterestsAction(); + reporter_->ManageInterestsAction(); std::map<FeedEngagementType, int> want({ {FeedEngagementType::kFeedEngaged, 1}, @@ -107,11 +128,11 @@ } TEST_F(MetricsReporterTest, VisitsCanLastMoreThanFiveMinutes) { - reporter_.StreamScrolled(1); + reporter_->StreamScrolled(1); task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(5) - kEpsilon); - reporter_.OpenAction(0); + reporter_->OpenAction(0); task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(5) - kEpsilon); - reporter_.StreamScrolled(1); + reporter_->StreamScrolled(1); std::map<FeedEngagementType, int> want({ {FeedEngagementType::kFeedEngaged, 1}, @@ -123,11 +144,11 @@ } TEST_F(MetricsReporterTest, NewVisitAfterInactivity) { - reporter_.OpenAction(0); - reporter_.StreamScrolled(1); + reporter_->OpenAction(0); + reporter_->StreamScrolled(1); task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(5) + kEpsilon); - reporter_.OpenAction(0); - reporter_.StreamScrolled(1); + reporter_->OpenAction(0); + reporter_->StreamScrolled(1); std::map<FeedEngagementType, int> want({ {FeedEngagementType::kFeedEngaged, 2}, @@ -139,8 +160,8 @@ } TEST_F(MetricsReporterTest, ReportsLoadStreamStatus) { - reporter_.OnLoadStream(LoadStreamStatus::kDataInStoreIsStale, - LoadStreamStatus::kLoadedFromNetwork); + reporter_->OnLoadStream(LoadStreamStatus::kDataInStoreIsStale, + LoadStreamStatus::kLoadedFromNetwork); histogram_.ExpectUniqueSample( "ContentSuggestions.Feed.LoadStreamStatus.Initial", @@ -151,8 +172,8 @@ } TEST_F(MetricsReporterTest, ReportsLoadStreamStatusIgnoresNoStatusFromStore) { - reporter_.OnLoadStream(LoadStreamStatus::kNoStatus, - LoadStreamStatus::kLoadedFromNetwork); + reporter_->OnLoadStream(LoadStreamStatus::kNoStatus, + LoadStreamStatus::kLoadedFromNetwork); histogram_.ExpectUniqueSample( "ContentSuggestions.Feed.LoadStreamStatus.Initial", @@ -162,7 +183,7 @@ } TEST_F(MetricsReporterTest, ReportsLoadMoreStatus) { - reporter_.OnLoadMore(LoadStreamStatus::kLoadedFromNetwork); + reporter_->OnLoadMore(LoadStreamStatus::kLoadedFromNetwork); histogram_.ExpectUniqueSample( "ContentSuggestions.Feed.LoadStreamStatus.LoadMore", @@ -170,7 +191,7 @@ } TEST_F(MetricsReporterTest, ReportsBackgroundRefreshStatus) { - reporter_.OnBackgroundRefresh(LoadStreamStatus::kLoadedFromNetwork); + reporter_->OnBackgroundRefresh(LoadStreamStatus::kLoadedFromNetwork); histogram_.ExpectUniqueSample( "ContentSuggestions.Feed.LoadStreamStatus.BackgroundRefresh", @@ -178,7 +199,7 @@ } TEST_F(MetricsReporterTest, OpenAction) { - reporter_.OpenAction(5); + reporter_->OpenAction(5); std::map<FeedEngagementType, int> want({ {FeedEngagementType::kFeedEngaged, 1}, @@ -194,7 +215,7 @@ } TEST_F(MetricsReporterTest, OpenInNewTabAction) { - reporter_.OpenInNewTabAction(5); + reporter_->OpenInNewTabAction(5); std::map<FeedEngagementType, int> want({ {FeedEngagementType::kFeedEngaged, 1}, @@ -210,7 +231,7 @@ } TEST_F(MetricsReporterTest, OpenInNewIncognitoTabAction) { - reporter_.OpenInNewIncognitoTabAction(); + reporter_->OpenInNewIncognitoTabAction(); std::map<FeedEngagementType, int> want({ {FeedEngagementType::kFeedEngaged, 1}, @@ -227,7 +248,7 @@ } TEST_F(MetricsReporterTest, SendFeedbackAction) { - reporter_.SendFeedbackAction(); + reporter_->SendFeedbackAction(); std::map<FeedEngagementType, int> want({ {FeedEngagementType::kFeedEngaged, 1}, @@ -242,7 +263,7 @@ } TEST_F(MetricsReporterTest, DownloadAction) { - reporter_.DownloadAction(); + reporter_->DownloadAction(); std::map<FeedEngagementType, int> want({ {FeedEngagementType::kFeedEngaged, 1}, @@ -257,7 +278,7 @@ } TEST_F(MetricsReporterTest, LearnMoreAction) { - reporter_.LearnMoreAction(); + reporter_->LearnMoreAction(); std::map<FeedEngagementType, int> want({ {FeedEngagementType::kFeedEngaged, 1}, @@ -272,7 +293,7 @@ } TEST_F(MetricsReporterTest, RemoveAction) { - reporter_.RemoveAction(); + reporter_->RemoveAction(); std::map<FeedEngagementType, int> want({ {FeedEngagementType::kFeedEngaged, 1}, @@ -287,7 +308,7 @@ } TEST_F(MetricsReporterTest, NotInterestedInAction) { - reporter_.NotInterestedInAction(); + reporter_->NotInterestedInAction(); std::map<FeedEngagementType, int> want({ {FeedEngagementType::kFeedEngaged, 1}, @@ -302,7 +323,7 @@ } TEST_F(MetricsReporterTest, ManageInterestsAction) { - reporter_.ManageInterestsAction(); + reporter_->ManageInterestsAction(); std::map<FeedEngagementType, int> want({ {FeedEngagementType::kFeedEngaged, 1}, @@ -317,7 +338,7 @@ } TEST_F(MetricsReporterTest, ContextMenuOpened) { - reporter_.ContextMenuOpened(); + reporter_->ContextMenuOpened(); std::map<FeedEngagementType, int> want_empty; EXPECT_EQ(want_empty, ReportedEngagementType()); @@ -328,7 +349,7 @@ } TEST_F(MetricsReporterTest, SurfaceOpened) { - reporter_.SurfaceOpened(kSurfaceId); + reporter_->SurfaceOpened(kSurfaceId); std::map<FeedEngagementType, int> want_empty; EXPECT_EQ(want_empty, ReportedEngagementType()); @@ -337,9 +358,9 @@ } TEST_F(MetricsReporterTest, OpenFeedSuccessDuration) { - reporter_.SurfaceOpened(kSurfaceId); + reporter_->SurfaceOpened(kSurfaceId); task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(9)); - reporter_.ContentSliceViewed(kSurfaceId, 0); + reporter_->ContentSliceViewed(kSurfaceId, 0); histogram_.ExpectUniqueTimeSample( "ContentSuggestions.Feed.UserJourney.OpenFeed.SuccessDuration", @@ -347,7 +368,7 @@ } TEST_F(MetricsReporterTest, OpenFeedLoadTimeout) { - reporter_.SurfaceOpened(kSurfaceId); + reporter_->SurfaceOpened(kSurfaceId); task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(16)); histogram_.ExpectUniqueTimeSample( @@ -358,9 +379,9 @@ } TEST_F(MetricsReporterTest, OpenFeedCloseBeforeLoad) { - reporter_.SurfaceOpened(kSurfaceId); + reporter_->SurfaceOpened(kSurfaceId); task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(14)); - reporter_.SurfaceClosed(kSurfaceId); + reporter_->SurfaceClosed(kSurfaceId); histogram_.ExpectUniqueTimeSample( "ContentSuggestions.Feed.UserJourney.OpenFeed.FailureDuration", @@ -370,21 +391,19 @@ } TEST_F(MetricsReporterTest, OpenCardSuccessDuration) { - reporter_.OpenAction(0); + reporter_->OpenAction(0); task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(19)); - reporter_.PageLoaded(); + reporter_->PageLoaded(); - histogram_.ExpectTotalCount( - "ContentSuggestions.Feed.UserJourney.OpenCard.SuccessDuration", 1); histogram_.ExpectUniqueTimeSample( "ContentSuggestions.Feed.UserJourney.OpenCard.SuccessDuration", base::TimeDelta::FromSeconds(19), 1); } TEST_F(MetricsReporterTest, OpenCardTimeout) { - reporter_.OpenAction(0); + reporter_->OpenAction(0); task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(21)); - reporter_.PageLoaded(); + reporter_->PageLoaded(); histogram_.ExpectUniqueSample( "ContentSuggestions.Feed.UserJourney.OpenCard.Failure", 1, 1); @@ -393,10 +412,10 @@ } TEST_F(MetricsReporterTest, OpenCardFailureTwiceAndThenSucceed) { - reporter_.OpenAction(0); - reporter_.OpenAction(1); - reporter_.OpenAction(2); - reporter_.PageLoaded(); + reporter_->OpenAction(0); + reporter_->OpenAction(1); + reporter_->OpenAction(2); + reporter_->PageLoaded(); histogram_.ExpectUniqueSample( "ContentSuggestions.Feed.UserJourney.OpenCard.Failure", 1, 2); @@ -405,8 +424,8 @@ } TEST_F(MetricsReporterTest, OpenCardCloseChromeFailure) { - reporter_.OpenAction(0); - reporter_.OnEnterBackground(); + reporter_->OpenAction(0); + reporter_->OnEnterBackground(); histogram_.ExpectUniqueSample( "ContentSuggestions.Feed.UserJourney.OpenCard.Failure", 1, 1); @@ -414,4 +433,77 @@ "ContentSuggestions.Feed.UserJourney.OpenCard.SuccessDuration", 0); } +TEST_F(MetricsReporterTest, TimeSpentInFeedCountsOnlyForegroundTime) { + reporter_->OpenAction(0); + task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1)); + reporter_->OnEnterBackground(); + task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(2)); + reporter_->OpenAction(0); + task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(3)); + reporter_->OnEnterBackground(); + + // Trigger reporting the persistent metrics the next day. + task_environment_.FastForwardBy(base::TimeDelta::FromDays(1)); + RecreateMetricsReporter(); + + histogram_.ExpectUniqueTimeSample("ContentSuggestions.Feed.TimeSpentInFeed", + base::TimeDelta::FromSeconds(4), 1); +} + +TEST_F(MetricsReporterTest, TimeSpentInFeedLimitsIdleTime) { + reporter_->OpenAction(0); + task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(31)); + reporter_->OnEnterBackground(); + + // Trigger reporting the persistent metrics the next day. + task_environment_.FastForwardBy(base::TimeDelta::FromDays(1)); + RecreateMetricsReporter(); + + histogram_.ExpectUniqueTimeSample("ContentSuggestions.Feed.TimeSpentInFeed", + base::TimeDelta::FromSeconds(30), 1); +} + +TEST_F(MetricsReporterTest, TimeSpentInFeedIsPerDay) { + // One interaction every hour for 2 days. Should be reported at 30 seconds per + // interaction due to the interaction timeout. The 49th |OpenAction()| call + // triggers reporting the UMA for the previous day. + for (int i = 0; i < 49; ++i) { + reporter_->OpenAction(0); + task_environment_.FastForwardBy(base::TimeDelta::FromHours(1)); + } + + histogram_.ExpectUniqueTimeSample("ContentSuggestions.Feed.TimeSpentInFeed", + base::TimeDelta::FromSeconds(30) * 24, 2); +} + +TEST_F(MetricsReporterTest, TimeSpentIsPersisted) { + // Verify that the previous test also works when |MetricsReporter| is + // destroyed and recreated. The 49th |OpenAction()| call triggers reporting + // the UMA for the previous day. + for (int i = 0; i < 49; ++i) { + reporter_->OpenAction(0); + task_environment_.FastForwardBy(base::TimeDelta::FromHours(1)); + reporter_->OnEnterBackground(); + RecreateMetricsReporter(); + } + + histogram_.ExpectUniqueTimeSample("ContentSuggestions.Feed.TimeSpentInFeed", + base::TimeDelta::FromSeconds(30) * 24, 2); +} + +TEST_F(MetricsReporterTest, TimeSpentInFeedTracksWholeScrollTime) { + reporter_->StreamScrollStart(); + task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(2)); + reporter_->StreamScrolled(1); + task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1)); + reporter_->OnEnterBackground(); + + // Trigger reporting the persistent metrics the next day. + task_environment_.FastForwardBy(base::TimeDelta::FromDays(1)); + RecreateMetricsReporter(); + + histogram_.ExpectUniqueTimeSample("ContentSuggestions.Feed.TimeSpentInFeed", + base::TimeDelta::FromSeconds(3), 1); +} + } // namespace feed
diff --git a/components/feed/core/v2/prefs.cc b/components/feed/core/v2/prefs.cc index 589e445..c096bb3 100644 --- a/components/feed/core/v2/prefs.cc +++ b/components/feed/core/v2/prefs.cc
@@ -64,6 +64,15 @@ return RequestScheduleFromValue(*pref_service->Get(kRequestSchedule)); } +void SetPersistentMetricsData(const PersistentMetricsData& data, + PrefService* pref_service) { + pref_service->Set(kMetricsData, PersistentMetricsDataToValue(data)); +} + +PersistentMetricsData GetPersistentMetricsData(PrefService* pref_service) { + return PersistentMetricsDataFromValue(*pref_service->Get(kMetricsData)); +} + } // namespace prefs } // namespace feed
diff --git a/components/feed/core/v2/prefs.h b/components/feed/core/v2/prefs.h index 33437227..11793746 100644 --- a/components/feed/core/v2/prefs.h +++ b/components/feed/core/v2/prefs.h
@@ -9,6 +9,7 @@ #include "base/time/time.h" #include "components/feed/core/v2/public/types.h" +#include "components/feed/core/v2/types.h" class PrefService; @@ -36,6 +37,10 @@ PrefService* pref_service); RequestSchedule GetRequestSchedule(PrefService* pref_service); +PersistentMetricsData GetPersistentMetricsData(PrefService* pref_service); +void SetPersistentMetricsData(const PersistentMetricsData& data, + PrefService* pref_service); + } // namespace prefs } // namespace feed
diff --git a/components/feed/core/v2/public/feed_service.cc b/components/feed/core/v2/public/feed_service.cc index e3307d4..4c6dcef 100644 --- a/components/feed/core/v2/public/feed_service.cc +++ b/components/feed/core/v2/public/feed_service.cc
@@ -141,8 +141,8 @@ stream_delegate_ = std::make_unique<StreamDelegateImpl>(local_state, delegate_.get()); network_delegate_ = std::make_unique<NetworkDelegateImpl>(delegate_.get()); - metrics_reporter_ = - std::make_unique<MetricsReporter>(base::DefaultTickClock::GetInstance()); + metrics_reporter_ = std::make_unique<MetricsReporter>( + base::DefaultTickClock::GetInstance(), profile_prefs); feed_network_ = std::make_unique<FeedNetworkImpl>( network_delegate_.get(), identity_manager, api_key, url_loader_factory, base::DefaultTickClock::GetInstance(), profile_prefs);
diff --git a/components/feed/core/v2/public/feed_stream_api.h b/components/feed/core/v2/public/feed_stream_api.h index 6699db2..66e3ad3 100644 --- a/components/feed/core/v2/public/feed_stream_api.h +++ b/components/feed/core/v2/public/feed_stream_api.h
@@ -109,6 +109,9 @@ virtual void ReportContextMenuOpened() = 0; // The user scrolled the feed by |distance_dp| and then stopped. virtual void ReportStreamScrolled(int distance_dp) = 0; + // The user started scrolling the feed. Typically followed by a call to + // |ReportStreamScrolled()|. + virtual void ReportStreamScrollStart() = 0; // The following methods are used for the internals page.
diff --git a/components/feed/core/v2/types.cc b/components/feed/core/v2/types.cc index b3b0267..009cf009 100644 --- a/components/feed/core/v2/types.cc +++ b/components/feed/core/v2/types.cc
@@ -9,6 +9,8 @@ #include "base/base64.h" #include "base/pickle.h" #include "base/strings/string_number_conversions.h" +#include "base/value_conversions.h" +#include "base/values.h" #include "components/feed/core/v2/public/types.h" // Note: This file contains implementation for both types.h and public/types.h. @@ -99,4 +101,30 @@ DebugStreamData::DebugStreamData(const DebugStreamData&) = default; DebugStreamData& DebugStreamData::operator=(const DebugStreamData&) = default; +base::Value PersistentMetricsDataToValue(const PersistentMetricsData& data) { + base::Value dict(base::Value::Type::DICTIONARY); + dict.SetKey("day_start", base::CreateTimeValue(data.current_day_start)); + dict.SetKey("time_spent_in_feed", + base::CreateTimeDeltaValue(data.accumulated_time_spent_in_feed)); + return dict; +} + +PersistentMetricsData PersistentMetricsDataFromValue(const base::Value& value) { + PersistentMetricsData result; + if (!value.is_dict()) + return result; + const base::Value* day_start = value.FindKey("day_start"); + if (!day_start || + !base::GetValueAsTime(*day_start, &result.current_day_start)) + return result; + const base::Value* time_spent_in_feed = value.FindKey("time_spent_in_feed"); + if (time_spent_in_feed) { + // Ignore return value, OK to keep going on failure. + (void)base::GetValueAsTimeDelta(*time_spent_in_feed, + &result.accumulated_time_spent_in_feed); + } + + return result; +} + } // namespace feed
diff --git a/components/feed/core/v2/types.h b/components/feed/core/v2/types.h index 4b6bf0b..02ecc6a 100644 --- a/components/feed/core/v2/types.h +++ b/components/feed/core/v2/types.h
@@ -8,6 +8,7 @@ #include <string> #include "base/util/type_safety/id_type.h" +#include "base/values.h" #include "components/feed/core/v2/public/types.h" namespace feed { @@ -34,6 +35,17 @@ DisplayMetrics display_metrics; }; +// Data internal to MetricsReporter which is persisted to Prefs. +struct PersistentMetricsData { + // The midnight time for the day in which this metric was recorded. + base::Time current_day_start; + // The total recorded time spent on the Feed for the current day. + base::TimeDelta accumulated_time_spent_in_feed; +}; + +base::Value PersistentMetricsDataToValue(const PersistentMetricsData& data); +PersistentMetricsData PersistentMetricsDataFromValue(const base::Value& value); + } // namespace feed #endif // COMPONENTS_FEED_CORE_V2_TYPES_H_
diff --git a/components/feed/core/v2/types_unittest.cc b/components/feed/core/v2/types_unittest.cc index c7dcfd33..95938d4f 100644 --- a/components/feed/core/v2/types_unittest.cc +++ b/components/feed/core/v2/types_unittest.cc
@@ -4,10 +4,22 @@ #include "components/feed/core/v2/types.h" +#include "base/json/json_writer.h" +#include "base/strings/string_util.h" #include "testing/gtest/include/gtest/gtest.h" namespace feed { namespace { + +std::string ToJSON(const base::Value& value) { + std::string json; + CHECK(base::JSONWriter::WriteWithOptions( + value, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json)); + // Don't use \r\n on windows. + base::RemoveChars(json, "\r", &json); + return json; +} + DebugStreamData MakeDebugStreamData() { NetworkResponseInfo fetch_info; fetch_info.status_code = 200; @@ -60,4 +72,24 @@ ASSERT_EQ(base::nullopt, DeserializeDebugStreamData({})); } +TEST(PersistentMetricsData, SerializesAndDeserializes) { + PersistentMetricsData data; + data.accumulated_time_spent_in_feed = base::TimeDelta::FromHours(2); + data.current_day_start = base::Time::UnixEpoch(); + + const base::Value serialized_value = PersistentMetricsDataToValue(data); + const PersistentMetricsData deserialized_value = + PersistentMetricsDataFromValue(serialized_value); + + EXPECT_EQ(R"({ + "day_start": "11644473600000000", + "time_spent_in_feed": "7200000000" +} +)", + ToJSON(serialized_value)); + EXPECT_EQ(data.accumulated_time_spent_in_feed, + deserialized_value.accumulated_time_spent_in_feed); + EXPECT_EQ(data.current_day_start, deserialized_value.current_day_start); +} + } // namespace feed
diff --git a/components/gcm_driver/android/BUILD.gn b/components/gcm_driver/android/BUILD.gn index 1e358bae..16085019 100644 --- a/components/gcm_driver/android/BUILD.gn +++ b/components/gcm_driver/android/BUILD.gn
@@ -42,5 +42,7 @@ "//base:base_java_test_support", "//base:base_junit_test_support", "//third_party/hamcrest:hamcrest_java", + "//third_party/junit", + "//third_party/robolectric:robolectric_all_java", ] }
diff --git a/components/module_installer/android/BUILD.gn b/components/module_installer/android/BUILD.gn index d072a62..00d7d2a 100644 --- a/components/module_installer/android/BUILD.gn +++ b/components/module_installer/android/BUILD.gn
@@ -59,6 +59,8 @@ "//base:base_java", "//base:base_java_test_support", "//base:base_junit_test_support", + "//third_party/google_android_play_core:com_google_android_play_core_java", + "//third_party/hamcrest:hamcrest_java", ] }
diff --git a/components/page_info/android/BUILD.gn b/components/page_info/android/BUILD.gn index e456e5e..78f59db 100644 --- a/components/page_info/android/BUILD.gn +++ b/components/page_info/android/BUILD.gn
@@ -100,6 +100,7 @@ "//components/embedder_support/android:browser_context_java", "//components/embedder_support/android:util_java", "//components/feature_engagement/public:public_java", + "//components/location/android:location_java", "//components/omnibox/browser:browser_java", "//components/permissions/android:java", "//components/security_state/content/android:java",
diff --git a/components/paint_preview/player/android/BUILD.gn b/components/paint_preview/player/android/BUILD.gn index 471b734..7622506 100644 --- a/components/paint_preview/player/android/BUILD.gn +++ b/components/paint_preview/player/android/BUILD.gn
@@ -152,5 +152,6 @@ "//base:base_java", "//base:base_java_test_support", "//base:base_junit_test_support", + "//ui/android:ui_full_java", ] }
diff --git a/components/password_manager/core/browser/leak_detection_delegate.cc b/components/password_manager/core/browser/leak_detection_delegate.cc index 6197daf..ee6e9d1d 100644 --- a/components/password_manager/core/browser/leak_detection_delegate.cc +++ b/components/password_manager/core/browser/leak_detection_delegate.cc
@@ -57,6 +57,8 @@ DCHECK(!form.password_value.empty()); leak_check_ = leak_factory_->TryCreateLeakCheck( this, client_->GetIdentityManager(), client_->GetURLLoaderFactory()); + // Reset the helper to avoid notifications from the currently running check. + helper_.reset(); if (leak_check_) { is_leaked_timer_ = std::make_unique<base::ElapsedTimer>(); leak_check_->Start(form.origin, form.username_value, form.password_value);
diff --git a/components/password_manager/core/browser/leak_detection_delegate_helper_unittest.cc b/components/password_manager/core/browser/leak_detection_delegate_helper_unittest.cc index d3c0dd6..c58890c 100644 --- a/components/password_manager/core/browser/leak_detection_delegate_helper_unittest.cc +++ b/components/password_manager/core/browser/leak_detection_delegate_helper_unittest.cc
@@ -23,6 +23,8 @@ using base::MockCallback; using base::Unretained; using testing::_; +using testing::ByMove; +using testing::Return; using testing::StrictMock; using testing::WithArg; @@ -48,16 +50,6 @@ return form; } -// Used to mimic the callback of the |PasswordStore|. Converts the vector of -// |PasswordForm|s to a vector of unique pointers to |PasswordForm|s. -ACTION_P(InvokeConsumerWithPasswordForms, forms) { - std::vector<std::unique_ptr<PasswordForm>> results; - for (const auto& form : forms) { - results.push_back(std::make_unique<PasswordForm>(form)); - } - arg0->OnGetPasswordStoreResults(std::move(results)); -} - } // namespace class LeakDetectionDelegateHelperTest : public testing::Test { @@ -84,14 +76,18 @@ delegate_helper_->ProcessLeakedPassword(GURL(kLeakedOrigin), ASCIIToUTF16(kLeakedUsername), ASCIIToUTF16(kLeakedPassword)); + task_environment_.RunUntilIdle(); } // Sets the |PasswordForm|s which are retrieve from the |PasswordStore|. void SetGetLoginByPasswordConsumerInvocation( std::vector<PasswordForm> password_forms) { - EXPECT_CALL(*store_.get(), GetLoginsByPassword(_, _)) - .WillRepeatedly( - WithArg<1>(InvokeConsumerWithPasswordForms(password_forms))); + std::vector<std::unique_ptr<PasswordForm>> results; + for (auto& form : password_forms) { + results.push_back(std::make_unique<PasswordForm>(std::move(form))); + } + EXPECT_CALL(*store_, FillMatchingLoginsByPassword) + .WillOnce(Return(ByMove(std::move(results)))); } // Set the expectation for the |CredentialLeakType| in the callback_. @@ -204,7 +200,6 @@ ASCIIToUTF16(kLeakedUsername), base::Time::Now(), CompromiseType::kLeaked})); InitiateGetCredentialLeakType(); - task_environment_.RunUntilIdle(); } // Credential with the same canonicalized username marked as leaked. @@ -221,7 +216,6 @@ ASCIIToUTF16(kLeakedUsernameNonCanonicalized), base::Time::Now(), CompromiseType::kLeaked})); InitiateGetCredentialLeakType(); - task_environment_.RunUntilIdle(); } } // namespace password_manager
diff --git a/components/password_manager/core/browser/leak_detection_delegate_unittest.cc b/components/password_manager/core/browser/leak_detection_delegate_unittest.cc index 72b80392..edea5aa94 100644 --- a/components/password_manager/core/browser/leak_detection_delegate_unittest.cc +++ b/components/password_manager/core/browser/leak_detection_delegate_unittest.cc
@@ -38,14 +38,6 @@ using testing::Return; using testing::WithArg; -ACTION_P(InvokeConsumerWithPasswordForms, forms) { - std::vector<std::unique_ptr<autofill::PasswordForm>> results; - for (const auto& form : forms) { - results.push_back(std::make_unique<autofill::PasswordForm>(form)); - } - arg0->OnGetPasswordStoreResults(std::move(results)); -} - autofill::PasswordForm CreateTestForm() { autofill::PasswordForm form; form.origin = GURL("http://www.example.com/a/LoginAuth"); @@ -277,9 +269,7 @@ EXPECT_CALL(client(), GetProfilePasswordStore()) .WillRepeatedly(testing::Return(store())); - EXPECT_CALL(*store(), GetLoginsByPassword) - .WillRepeatedly(WithArg<1>(InvokeConsumerWithPasswordForms( - std::vector<autofill::PasswordForm>()))); + EXPECT_CALL(*store(), FillMatchingLoginsByPassword); EXPECT_CALL(factory(), TryCreateLeakCheck) .WillOnce( Return(ByMove(std::make_unique<NiceMock<MockLeakDetectionCheck>>()))); @@ -293,6 +283,7 @@ delegate_interface->OnLeakDetectionDone( /*is_leaked=*/true, form.origin, form.username_value, form.password_value); + WaitForPasswordStore(); histogram_tester.ExpectTotalCount( "PasswordManager.LeakDetection.NotifyIsLeakedTime", 1); } @@ -305,9 +296,10 @@ EXPECT_CALL(client(), GetProfilePasswordStore()) .WillRepeatedly(testing::Return(store())); - EXPECT_CALL(*store(), GetLoginsByPassword) - .WillRepeatedly(WithArg<1>(InvokeConsumerWithPasswordForms( - std::vector<autofill::PasswordForm>{form}))); + std::vector<std::unique_ptr<autofill::PasswordForm>> forms; + forms.push_back(std::make_unique<autofill::PasswordForm>(form)); + EXPECT_CALL(*store(), FillMatchingLoginsByPassword) + .WillOnce(Return(ByMove(std::move(forms)))); EXPECT_CALL(factory(), TryCreateLeakCheck) .WillOnce( Return(ByMove(std::make_unique<NiceMock<MockLeakDetectionCheck>>()))); @@ -326,4 +318,43 @@ WaitForPasswordStore(); } +// crbug.com/1083937 regression +TEST_F(LeakDetectionDelegateTest, CallStartTwice) { + EXPECT_CALL(client(), GetProfilePasswordStore()) + .WillRepeatedly(testing::Return(store())); + EXPECT_CALL(*store(), FillMatchingLoginsByPassword) + .Times(testing::AtLeast(1)); + auto check_instance = std::make_unique<NiceMock<MockLeakDetectionCheck>>(); + EXPECT_CALL(factory(), TryCreateLeakCheck(&delegate(), _, _)) + .WillOnce(Return(ByMove(std::move(check_instance)))); + autofill::PasswordForm form = CreateTestForm(); + delegate().StartLeakCheck(form); + ASSERT_TRUE(delegate().leak_check()); + + // The delegate analyses the password store after this call. + LeakDetectionDelegateInterface* delegate_interface = &delegate(); + delegate_interface->OnLeakDetectionDone( + /*is_leaked=*/true, form.origin, form.username_value, + form.password_value); + + // Start the check again on another form in the mean time. + check_instance = std::make_unique<NiceMock<MockLeakDetectionCheck>>(); + EXPECT_CALL(factory(), TryCreateLeakCheck(&delegate(), _, _)) + .WillOnce(Return(ByMove(std::move(check_instance)))); + form.username_value = ASCIIToUTF16("username"); + form.password_value = ASCIIToUTF16("password"); + delegate().StartLeakCheck(form); + ASSERT_TRUE(delegate().leak_check()); + + // Simulate the previous check is complete now. + WaitForPasswordStore(); + + // The second check is finishing and talking to the password store. It should + // not crash. + delegate_interface->OnLeakDetectionDone( + /*is_leaked=*/true, form.origin, form.username_value, + form.password_value); + WaitForPasswordStore(); +} + } // namespace password_manager
diff --git a/components/password_manager/core/browser/mock_password_store.h b/components/password_manager/core/browser/mock_password_store.h index 3603f91..9f7b5ff 100644 --- a/components/password_manager/core/browser/mock_password_store.h +++ b/components/password_manager/core/browser/mock_password_store.h
@@ -27,8 +27,6 @@ void(const PasswordStore::FormDigest&, base::OnceClosure)); MOCK_METHOD2(GetLogins, void(const PasswordStore::FormDigest&, PasswordStoreConsumer*)); - MOCK_METHOD2(GetLoginsByPassword, - void(const base::string16&, PasswordStoreConsumer*)); MOCK_METHOD1(AddLogin, void(const autofill::PasswordForm&)); MOCK_METHOD1(UpdateLogin, void(const autofill::PasswordForm&)); MOCK_METHOD2(UpdateLoginWithPrimaryKey,
diff --git a/components/password_manager/core/browser/password_store.h b/components/password_manager/core/browser/password_store.h index 322b234..11a39f9 100644 --- a/components/password_manager/core/browser/password_store.h +++ b/components/password_manager/core/browser/password_store.h
@@ -223,8 +223,8 @@ // Searches for credentials with the specified |plain_text_password|, and // notifies |consumer| on completion. The request will be cancelled if the // consumer is destroyed. - virtual void GetLoginsByPassword(const base::string16& plain_text_password, - PasswordStoreConsumer* consumer); + void GetLoginsByPassword(const base::string16& plain_text_password, + PasswordStoreConsumer* consumer); // Gets the complete list of PasswordForms that are not blacklist entries--and // are thus auto-fillable. |consumer| will be notified on completion.
diff --git a/components/payments/content/android/BUILD.gn b/components/payments/content/android/BUILD.gn index 6e370ca8..18ef5156 100644 --- a/components/payments/content/android/BUILD.gn +++ b/components/payments/content/android/BUILD.gn
@@ -20,6 +20,8 @@ "payment_manifest_downloader_android.h", "payment_manifest_parser_android.cc", "payment_manifest_parser_android.h", + "payment_request_update_event_listener.cc", + "payment_request_update_event_listener.h", "payment_validator_android.cc", "url_util.cc", ] @@ -46,6 +48,10 @@ "java/src/org/chromium/components/payments/PaymentHandlerHost.java", "java/src/org/chromium/components/payments/PaymentManifestDownloader.java", "java/src/org/chromium/components/payments/PaymentManifestParser.java", + + # TODO(crbug.com/1083242): Use PaymentRequestUpdateEventListener.java after + # updating dependencies. + "java/src/org/chromium/components/payments/PaymentApp.java", "java/src/org/chromium/components/payments/PaymentValidator.java", "java/src/org/chromium/components/payments/UrlUtil.java", ] @@ -66,6 +72,7 @@ "java/src/org/chromium/components/payments/PaymentHandlerHost.java", "java/src/org/chromium/components/payments/PaymentManifestDownloader.java", "java/src/org/chromium/components/payments/PaymentManifestParser.java", + "java/src/org/chromium/components/payments/PaymentRequestUpdateEventListener.java", "java/src/org/chromium/components/payments/PaymentValidator.java", "java/src/org/chromium/components/payments/UrlUtil.java", "java/src/org/chromium/components/payments/WebAppManifestSection.java",
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentApp.java b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentApp.java index 7f8d259..c6edac9b 100644 --- a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentApp.java +++ b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentApp.java
@@ -8,6 +8,8 @@ import androidx.annotation.Nullable; +import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.JNINamespace; import org.chromium.base.task.PostTask; import org.chromium.components.autofill.EditableOption; import org.chromium.content_public.browser.UiThreadTaskTraits; @@ -19,6 +21,7 @@ import org.chromium.payments.mojom.PaymentRequestDetailsUpdate; import org.chromium.payments.mojom.PaymentShippingOption; +import java.nio.ByteBuffer; import java.util.List; import java.util.Map; import java.util.Set; @@ -26,6 +29,7 @@ /** * The base class for a single payment app, e.g., a payment handler. */ +@JNINamespace("payments::android") public abstract class PaymentApp extends EditableOption { /** * Whether complete and valid autofill data for merchant's request is available, e.g., if @@ -39,6 +43,8 @@ * The interface for listener to payment method, shipping address, and shipping option change * events. Note: What the spec calls "payment methods" in the context of a "change event", this * code calls "apps". + * TODO(crbug.com/1083242): Move this interface into PaymentRequestUpdateEventListener.java + * after updating dependencies. */ public interface PaymentRequestUpdateEventListener { /** @@ -52,6 +58,7 @@ * not be null. * @return Whether the payment state was valid. */ + @CalledByNative("PaymentRequestUpdateEventListener") boolean changePaymentMethodFromInvokedApp(String methodName, String stringifiedDetails); /** @@ -61,8 +68,9 @@ * * @param shippingOptionId Selected shipping option Identifier, Should not be null or * empty. - * @return Whether the payment state wa valid. + * @return Whether the payment state was valid. */ + @CalledByNative("PaymentRequestUpdateEventListener") boolean changeShippingOptionFromInvokedApp(String shippingOptionId); /** @@ -71,9 +79,22 @@ * https://w3c.github.io/payment-request/#dom-paymentrequestupdateevent * * @param shippingAddress Selected shipping address. Should not be null. - * @return Whether the payment state wa valid. + * @return Whether the payment state was valid. */ boolean changeShippingAddressFromInvokedApp(PaymentAddress shippingAddress); + + /** + * Called to notify merchant of shipping address change. The payment app should block user + * interaction until updateWith() or onPaymentDetailsNotUpdated(). + * https://w3c.github.io/payment-request/#dom-paymentrequestupdateevent + * + * @param shippingAddress Selected shipping address in serialized form. Should not be null. + * @return Whether the payment state was valid. + */ + @CalledByNative("PaymentRequestUpdateEventListener") + default boolean changeShippingAddress(ByteBuffer shippingAddress) { + return changeShippingAddressFromInvokedApp(PaymentAddress.deserialize(shippingAddress)); + } } /**
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentHandlerHost.java b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentHandlerHost.java index 1f4d531..6ea514a1 100644 --- a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentHandlerHost.java +++ b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentHandlerHost.java
@@ -4,11 +4,9 @@ package org.chromium.components.payments; -import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.NativeMethods; import org.chromium.content_public.browser.WebContents; -import org.chromium.payments.mojom.PaymentAddress; import org.chromium.payments.mojom.PaymentRequestDetailsUpdate; import java.nio.ByteBuffer; @@ -19,42 +17,6 @@ */ @JNINamespace("payments::android") public class PaymentHandlerHost { - /** - * The interface to be implemented by the object that can communicate to the merchant renderer - * process. - */ - public interface PaymentHandlerHostDelegate { - /** - * Notifies the merchant that the payment method has changed within a payment handler. The - * merchant may recalculate the total based on the changed billing address, for example. - * @param methodName The payment method identifier. - * @param stringifiedData The stringified method-specific data. - * @return "False" if not in a valid state. - */ - @CalledByNative("PaymentHandlerHostDelegate") - boolean changePaymentMethodFromPaymentHandler(String methodName, String stringifiedData); - - /** - * Notifies the merchant that the selected shipping option has changed within a payment - * handler. The merchant may recalculate the payment details (e.g. total) based on the - * updated shipping option. - * @param shippingOptionId The selected shipping option identifier. - * @return "False" if not in a valid state. - */ - @CalledByNative("PaymentHandlerHostDelegate") - boolean changeShippingOptionFromPaymentHandler(String shippingOptionId); - - /** - * Notifies the merchant that the selected shipping address has changed within a payment - * handler. The merchant may recalculate the payment details (e.g. total or shipping - * options) based on the updated shipping address. - * @param shippingAddress The selected shipping address. - * @return "False" if not in a valid state. - */ - @CalledByNative("PaymentHandlerHostDelegate") - boolean changeShippingAddressFromPaymentHandler(PaymentAddress shippingAddress); - } - /** Pointer to the native bridge. This Java object owns the native bridge. */ private long mNativePointer; @@ -63,10 +25,10 @@ * bridge. The caller must call destroy() when finished using this Java object. * @param webContents The web contents in the same browser context as the payment handler. Used * for logging in developer tools. - * @param delegate The object that can communicate to the merchant renderer process. + * @param listener The object that can communicate to the merchant renderer process. */ - public PaymentHandlerHost(WebContents webContents, PaymentHandlerHostDelegate delegate) { - mNativePointer = PaymentHandlerHostJni.get().init(webContents, delegate); + public PaymentHandlerHost(WebContents webContents, PaymentRequestUpdateEventListener listener) { + mNativePointer = PaymentHandlerHostJni.get().init(webContents, listener); } /** @@ -114,24 +76,6 @@ mNativePointer = 0; } - @CalledByNative - private static Object createShippingAddress(String country, String[] addressLine, String region, - String city, String dependentLocality, String postalCode, String sortingCode, - String organization, String recipient, String phone) { - PaymentAddress result = new PaymentAddress(); - result.country = country; - result.addressLine = addressLine; - result.region = region; - result.city = city; - result.dependentLocality = dependentLocality; - result.postalCode = postalCode; - result.sortingCode = sortingCode; - result.organization = organization; - result.recipient = recipient; - result.phone = phone; - return result; - } - /** * The interface implemented by the automatically generated JNI bindings class * PaymentHandlerHostJni. @@ -143,10 +87,10 @@ * call destroy(nativePaymentHandlerHost) when done. * @param webContents The web contents in the same browser context as the payment handler. * Used for logging in developer tools. - * @param delegate The object that can communicate to the merchant renderer process. + * @param listener The object that can communicate to the merchant renderer process. * @return The pointer to the native payment handler host bridge. */ - long init(WebContents webContents, PaymentHandlerHostDelegate delegate); + long init(WebContents webContents, PaymentRequestUpdateEventListener listener); /** * Checks whether any payment method, shipping address, or shipping option change is
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentRequestUpdateEventListener.java b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentRequestUpdateEventListener.java new file mode 100644 index 0000000..184b54e --- /dev/null +++ b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentRequestUpdateEventListener.java
@@ -0,0 +1,15 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.components.payments; + +/** + * The interface for listener to payment method, shipping address, and shipping option change + * events. Note: What the spec calls "payment methods" in the context of a "change event", this + * code calls "apps". + * TODO(crbug.com/1083242): Move PaymentApp.PaymentRequestUpdateEventListener interface here after + * updating dependencies. + */ +public interface PaymentRequestUpdateEventListener + extends PaymentApp.PaymentRequestUpdateEventListener {}
diff --git a/components/payments/content/android/payment_handler_host.cc b/components/payments/content/android/payment_handler_host.cc index 2f2f552..dd91e25 100644 --- a/components/payments/content/android/payment_handler_host.cc +++ b/components/payments/content/android/payment_handler_host.cc
@@ -19,18 +19,18 @@ jlong JNI_PaymentHandlerHost_Init( JNIEnv* env, const base::android::JavaParamRef<jobject>& web_contents, - const base::android::JavaParamRef<jobject>& delegate) { + const base::android::JavaParamRef<jobject>& listener) { return reinterpret_cast<intptr_t>( - new PaymentHandlerHost(web_contents, delegate)); + new PaymentHandlerHost(web_contents, listener)); } PaymentHandlerHost::PaymentHandlerHost( const base::android::JavaParamRef<jobject>& web_contents, - const base::android::JavaParamRef<jobject>& delegate) - : delegate_(delegate), + const base::android::JavaParamRef<jobject>& listener) + : listener_(listener), payment_handler_host_( content::WebContents::FromJavaWebContents(web_contents), - /*delegate=*/this) {} + /*delegate=*/&listener_) {} PaymentHandlerHost::~PaymentHandlerHost() {} @@ -62,49 +62,5 @@ payment_handler_host_.OnPaymentDetailsNotUpdated(); } -bool PaymentHandlerHost::ChangePaymentMethod( - const std::string& method_name, - const std::string& stringified_data) { - JNIEnv* env = base::android::AttachCurrentThread(); - return Java_PaymentHandlerHostDelegate_changePaymentMethodFromPaymentHandler( - env, delegate_, base::android::ConvertUTF8ToJavaString(env, method_name), - base::android::ConvertUTF8ToJavaString(env, stringified_data)); -} - -bool PaymentHandlerHost::ChangeShippingOption( - const std::string& shipping_option_id) { - JNIEnv* env = base::android::AttachCurrentThread(); - return Java_PaymentHandlerHostDelegate_changeShippingOptionFromPaymentHandler( - env, delegate_, - base::android::ConvertUTF8ToJavaString(env, shipping_option_id)); -} - -bool PaymentHandlerHost::ChangeShippingAddress( - mojom::PaymentAddressPtr shipping_address) { - JNIEnv* env = base::android::AttachCurrentThread(); - base::android::ScopedJavaLocalRef<jobject> jshipping_address = - Java_PaymentHandlerHost_createShippingAddress( - env, - base::android::ConvertUTF8ToJavaString(env, - shipping_address->country), - base::android::ToJavaArrayOfStrings(env, - shipping_address->address_line), - base::android::ConvertUTF8ToJavaString(env, shipping_address->region), - base::android::ConvertUTF8ToJavaString(env, shipping_address->city), - base::android::ConvertUTF8ToJavaString( - env, shipping_address->dependent_locality), - base::android::ConvertUTF8ToJavaString(env, - shipping_address->postal_code), - base::android::ConvertUTF8ToJavaString( - env, shipping_address->sorting_code), - base::android::ConvertUTF8ToJavaString( - env, shipping_address->organization), - base::android::ConvertUTF8ToJavaString(env, - shipping_address->recipient), - base::android::ConvertUTF8ToJavaString(env, shipping_address->phone)); - return Java_PaymentHandlerHostDelegate_changeShippingAddressFromPaymentHandler( - env, delegate_, jshipping_address); -} - } // namespace android } // namespace payments
diff --git a/components/payments/content/android/payment_handler_host.h b/components/payments/content/android/payment_handler_host.h index ef520967..0550c84 100644 --- a/components/payments/content/android/payment_handler_host.h +++ b/components/payments/content/android/payment_handler_host.h
@@ -9,6 +9,7 @@ #include "base/android/scoped_java_ref.h" #include "base/macros.h" +#include "components/payments/content/android/payment_request_update_event_listener.h" #include "components/payments/content/payment_handler_host.h" namespace payments { @@ -17,30 +18,36 @@ // The native bridge for Java to interact with the payment handler host. // Object relationship diagram: // -// PaymentRequestImpl.java ---- implements ----> PaymentHandlerHostDelegate +// PaymentRequestImpl.java --- implements ---> PaymentRequestUpdateEventListener // | ^ -// owns |_________ -// | | -// v | -// PaymentHandlerHost.java | -// | | -// owns | -// | delegate -// v | -// android/payment_handler_host.h -- implements -> PaymentHandlerHost::Delegate -// | ^ -// owns | +// owns |________________________ +// | | +// v | +// PaymentHandlerHost.java | +// | | +// owns | +// | listener +// v | +// android/payment_handler_host.h | +// | | | +// owns | | +// | owns | +// | | | +// | v | +// | android/payment_request_update_event_listener.h +// | ^ \ ---- implements ---> PaymentHandlerHost::Delegate +// | | // | delegate // v | // payment_handler_host.h -class PaymentHandlerHost : public payments::PaymentHandlerHost::Delegate { +class PaymentHandlerHost { public: - // The |delegate| must implement PaymentHandlerHostDelegate from - // PaymentHandlerHost.java. The |web_contents| should be from the same browser - // context as the payment handler and are used for logging in developr tools. + // The |listener| must implement PaymentRequestUpdateEventListener. The + // |web_contents| should be from the same browser context as the payment + // handler and are used for logging in developr tools. PaymentHandlerHost(const base::android::JavaParamRef<jobject>& web_contents, - const base::android::JavaParamRef<jobject>& delegate); - ~PaymentHandlerHost() override; + const base::android::JavaParamRef<jobject>& listener); + ~PaymentHandlerHost(); // Checks whether any payment method, shipping address or shipping option // change is currently in progress. @@ -64,14 +71,7 @@ void OnPaymentDetailsNotUpdated(JNIEnv* env); private: - // PaymentHandlerHost::Delegate implementation: - bool ChangePaymentMethod(const std::string& method_name, - const std::string& stringified_data) override; - bool ChangeShippingOption(const std::string& shipping_option_id) override; - bool ChangeShippingAddress( - mojom::PaymentAddressPtr shipping_address) override; - - base::android::ScopedJavaGlobalRef<jobject> delegate_; + PaymentRequestUpdateEventListener listener_; payments::PaymentHandlerHost payment_handler_host_; DISALLOW_COPY_AND_ASSIGN(PaymentHandlerHost);
diff --git a/components/payments/content/android/payment_request_update_event_listener.cc b/components/payments/content/android/payment_request_update_event_listener.cc new file mode 100644 index 0000000..25781931 --- /dev/null +++ b/components/payments/content/android/payment_request_update_event_listener.cc
@@ -0,0 +1,53 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/payments/content/android/payment_request_update_event_listener.h" + +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" + +// TODO(crbug.com/1083242): Use PaymentRequestUpdateEventListener_jni.h after +// updating dependencies. +#include "components/payments/content/android/jni_headers/PaymentApp_jni.h" + +namespace payments { +namespace android { + +PaymentRequestUpdateEventListener::PaymentRequestUpdateEventListener( + const base::android::JavaParamRef<jobject>& listener) + : listener_(listener) {} + +PaymentRequestUpdateEventListener::~PaymentRequestUpdateEventListener() {} + +bool PaymentRequestUpdateEventListener::ChangePaymentMethod( + const std::string& method_name, + const std::string& stringified_data) { + JNIEnv* env = base::android::AttachCurrentThread(); + return Java_PaymentRequestUpdateEventListener_changePaymentMethodFromInvokedApp( + env, listener_, base::android::ConvertUTF8ToJavaString(env, method_name), + base::android::ConvertUTF8ToJavaString(env, stringified_data)); +} + +bool PaymentRequestUpdateEventListener::ChangeShippingOption( + const std::string& shipping_option_id) { + JNIEnv* env = base::android::AttachCurrentThread(); + return Java_PaymentRequestUpdateEventListener_changeShippingOptionFromInvokedApp( + env, listener_, + base::android::ConvertUTF8ToJavaString(env, shipping_option_id)); +} + +bool PaymentRequestUpdateEventListener::ChangeShippingAddress( + mojom::PaymentAddressPtr shipping_address) { + std::vector<uint8_t> byte_vector = + mojom::PaymentAddress::Serialize(&shipping_address); + JNIEnv* env = base::android::AttachCurrentThread(); + return Java_PaymentRequestUpdateEventListener_changeShippingAddress( + env, listener_, + base::android::ScopedJavaLocalRef<jobject>( + env, + env->NewDirectByteBuffer(byte_vector.data(), byte_vector.size()))); +} + +} // namespace android +} // namespace payments
diff --git a/components/payments/content/android/payment_request_update_event_listener.h b/components/payments/content/android/payment_request_update_event_listener.h new file mode 100644 index 0000000..63708b05 --- /dev/null +++ b/components/payments/content/android/payment_request_update_event_listener.h
@@ -0,0 +1,37 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_PAYMENTS_CONTENT_ANDROID_PAYMENT_REQUEST_UPDATE_EVENT_LISTENER_H_ +#define COMPONENTS_PAYMENTS_CONTENT_ANDROID_PAYMENT_REQUEST_UPDATE_EVENT_LISTENER_H_ + +#include <jni.h> + +#include "base/android/scoped_java_ref.h" +#include "components/payments/content/payment_handler_host.h" + +namespace payments { +namespace android { + +class PaymentRequestUpdateEventListener + : public payments::PaymentHandlerHost::Delegate { + public: + explicit PaymentRequestUpdateEventListener( + const base::android::JavaParamRef<jobject>& listener); + ~PaymentRequestUpdateEventListener() override; + + // PaymentHandlerHost::Delegate implementation: + bool ChangePaymentMethod(const std::string& method_name, + const std::string& stringified_data) override; + bool ChangeShippingOption(const std::string& shipping_option_id) override; + bool ChangeShippingAddress( + mojom::PaymentAddressPtr shipping_address) override; + + private: + base::android::ScopedJavaGlobalRef<jobject> listener_; +}; + +} // namespace android +} // namespace payments + +#endif // COMPONENTS_PAYMENTS_CONTENT_ANDROID_PAYMENT_REQUEST_UPDATE_EVENT_LISTENER_H_
diff --git a/components/payments/content/payment_handler_host.h b/components/payments/content/payment_handler_host.h index b0900ac..c3814c4 100644 --- a/components/payments/content/payment_handler_host.h +++ b/components/payments/content/payment_handler_host.h
@@ -130,7 +130,8 @@ // The merchant page that invoked the Payment Request API. content::WebContents* web_contents_; - // Not null and outlives this object. Owns this object. + // Not null and outlives this object. Either owns this object or is owned by + // the owner of this object. Delegate* delegate_; // The origin of the payment handler / service worker registration scope. Used
diff --git a/components/permissions/android/BUILD.gn b/components/permissions/android/BUILD.gn index 6e409ee..7bbdc1d 100644 --- a/components/permissions/android/BUILD.gn +++ b/components/permissions/android/BUILD.gn
@@ -140,6 +140,9 @@ ":java", "//base:base_java_test_support", "//base:base_junit_test_support", + "//third_party/junit", + "//third_party/mockito:mockito_java", + "//third_party/robolectric:robolectric_all_java", "//ui/android:ui_java", ] }
diff --git a/components/policy/android/BUILD.gn b/components/policy/android/BUILD.gn index 9a6045e..bb0865bf7 100644 --- a/components/policy/android/BUILD.gn +++ b/components/policy/android/BUILD.gn
@@ -57,7 +57,11 @@ ":policy_java", ":policy_java_test_support", "//base:base_java", + "//base:base_java_test_support", "//base:base_junit_test_support", "//third_party/hamcrest:hamcrest_java", + "//third_party/junit", + "//third_party/mockito:mockito_java", + "//third_party/robolectric:robolectric_all_java", ] }
diff --git a/components/policy/android/java/src/org/chromium/policy/AppRestrictionsProvider.java b/components/policy/android/java/src/org/chromium/policy/AppRestrictionsProvider.java index 191af5be..bcd2c19 100644 --- a/components/policy/android/java/src/org/chromium/policy/AppRestrictionsProvider.java +++ b/components/policy/android/java/src/org/chromium/policy/AppRestrictionsProvider.java
@@ -9,8 +9,11 @@ import android.content.Intent; import android.os.Build; import android.os.Bundle; +import android.os.SystemClock; import android.os.UserManager; +import org.chromium.base.metrics.RecordHistogram; + /** * Concrete app restriction provider, that uses the default android mechanism to retrieve the * restrictions. @@ -34,7 +37,12 @@ protected Bundle getApplicationRestrictions(String packageName) { if (mUserManager == null) return new Bundle(); try { - return mUserManager.getApplicationRestrictions(packageName); + long startTime = SystemClock.elapsedRealtime(); + Bundle bundle = mUserManager.getApplicationRestrictions(packageName); + long endTime = SystemClock.elapsedRealtime(); + RecordHistogram.recordTimesHistogram( + "Enterprise.AppRestrictionLoadTime2", endTime - startTime); + return bundle; } catch (SecurityException e) { // Android bug may throw SecurityException. See crbug.com/886814. return new Bundle();
diff --git a/components/policy/core/common/BUILD.gn b/components/policy/core/common/BUILD.gn index 9c0ac07..5fc367d 100644 --- a/components/policy/core/common/BUILD.gn +++ b/components/policy/core/common/BUILD.gn
@@ -113,6 +113,8 @@ "policy_details.h", "policy_load_status.cc", "policy_load_status.h", + "policy_loader_common.cc", + "policy_loader_common.h", "policy_map.cc", "policy_map.h", "policy_merger.cc",
diff --git a/components/policy/core/common/features.cc b/components/policy/core/common/features.cc index 570fd883..c8bc82f 100644 --- a/components/policy/core/common/features.cc +++ b/components/policy/core/common/features.cc
@@ -14,6 +14,11 @@ const base::Feature kCBCMServiceAccounts{"CBCMServiceAccounts", base::FEATURE_DISABLED_BY_DEFAULT}; +#if defined(OS_MACOSX) +const base::Feature kIgnoreSensitivePoliciesOnUnmanagedMac{ + "IgnoreSensitivePoliciesOnUnmanagedMac", base::FEATURE_DISABLED_BY_DEFAULT}; +#endif + } // namespace features } // namespace policy
diff --git a/components/policy/core/common/features.h b/components/policy/core/common/features.h index 2ca3e9a2..5165e44a 100644 --- a/components/policy/core/common/features.h +++ b/components/policy/core/common/features.h
@@ -6,10 +6,10 @@ #define COMPONENTS_POLICY_CORE_COMMON_FEATURES_H_ #include "base/feature_list.h" +#include "build/build_config.h" #include "components/policy/policy_export.h" namespace policy { - namespace features { // TODO(994227) Remove references to this now unused feature. @@ -18,7 +18,14 @@ // Feature that controls whether the browser reads the service account // information from policy data. POLICY_EXPORT extern const base::Feature kCBCMServiceAccounts; -} + +#if defined(OS_MACOSX) +// Feature that controls whether the browser ignores sensitive policies on an +// unmanaged Mac. +POLICY_EXPORT extern const base::Feature kIgnoreSensitivePoliciesOnUnmanagedMac; +#endif + +} // namespace features } // namespace policy #endif // COMPONENTS_POLICY_CORE_COMMON_FEATURES_H_
diff --git a/components/policy/core/common/policy_loader_common.cc b/components/policy/core/common/policy_loader_common.cc new file mode 100644 index 0000000..9404ffcc --- /dev/null +++ b/components/policy/core/common/policy_loader_common.cc
@@ -0,0 +1,98 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/policy/core/common/policy_loader_common.h" + +#include "base/metrics/histogram_functions.h" +#include "base/metrics/histogram_macros.h" +#include "base/strings/string_util.h" +#include "components/policy/core/common/policy_map.h" +#include "components/policy/policy_constants.h" + +namespace policy { + +namespace { + +// The web store url that is the only trusted source for extensions. +const char kExpectedWebStoreUrl[] = + ";https://clients2.google.com/service/update2/crx"; + +// String to be prepended to each blocked entry. +const char kBlockedExtensionPrefix[] = "[BLOCKED]"; + +// List of policies that are considered only if the user is part of a AD domain +// on Windows or managed on the Mac. Please document any new additions in +// policy_templates.json! +const char* kSensitivePolicies[] = { + key::kChromeCleanupEnabled, + key::kChromeCleanupReportingEnabled, + key::kCommandLineFlagSecurityWarningsEnabled, + key::kDefaultSearchProviderEnabled, + key::kAutoOpenFileTypes, + key::kHomepageIsNewTabPage, + key::kHomepageLocation, + key::kMetricsReportingEnabled, + key::kNewTabPageLocation, + key::kPasswordProtectionChangePasswordURL, + key::kPasswordProtectionLoginURLs, + key::kRestoreOnStartup, + key::kRestoreOnStartupURLs, + key::kSafeBrowsingForTrustedSourcesEnabled, + key::kSafeBrowsingEnabled, + key::kSafeBrowsingWhitelistDomains, +}; + +} // namespace + +void FilterSensitivePolicies(PolicyMap* policy) { + int invalid_policies = 0; + const PolicyMap::Entry* map_entry = + policy->Get(key::kExtensionInstallForcelist); + if (map_entry && map_entry->value) { + const base::ListValue* policy_list_value = nullptr; + if (!map_entry->value->GetAsList(&policy_list_value)) + return; + + std::unique_ptr<base::ListValue> filtered_values(new base::ListValue); + for (const auto& list_entry : *policy_list_value) { + std::string entry; + if (!list_entry.GetAsString(&entry)) + continue; + size_t pos = entry.find(';'); + if (pos == std::string::npos) + continue; + // Only allow custom update urls in enterprise environments. + if (!base::LowerCaseEqualsASCII(entry.substr(pos), + kExpectedWebStoreUrl)) { + entry = kBlockedExtensionPrefix + entry; + invalid_policies++; + } + + filtered_values->AppendString(entry); + } + if (invalid_policies) { + PolicyMap::Entry filtered_entry = map_entry->DeepCopy(); + filtered_entry.value = std::move(filtered_values); + policy->Set(key::kExtensionInstallForcelist, std::move(filtered_entry)); + + const PolicyDetails* details = + GetChromePolicyDetails(key::kExtensionInstallForcelist); + base::UmaHistogramSparse("EnterpriseCheck.InvalidPolicies", details->id); + } + } + + for (const char* sensitive_policy : kSensitivePolicies) { + if (policy->Get(sensitive_policy)) { + policy->GetMutable(sensitive_policy)->SetBlocked(); + invalid_policies++; + const PolicyDetails* details = GetChromePolicyDetails(sensitive_policy); + base::UmaHistogramSparse("EnterpriseCheck.InvalidPolicies", details->id); + } + } + + UMA_HISTOGRAM_COUNTS_1M("EnterpriseCheck.InvalidPoliciesDetected", + invalid_policies); +} // namespace policy + +} // namespace policy
diff --git a/components/policy/core/common/policy_loader_common.h b/components/policy/core/common/policy_loader_common.h new file mode 100644 index 0000000..8e84bf89 --- /dev/null +++ b/components/policy/core/common/policy_loader_common.h
@@ -0,0 +1,20 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_POLICY_CORE_COMMON_POLICY_LOADER_COMMON_H_ +#define COMPONENTS_POLICY_CORE_COMMON_POLICY_LOADER_COMMON_H_ + +#include "components/policy/policy_export.h" + +namespace policy { + +class PolicyMap; + +// Blocks sensitive policies from having an effect in the specified source. +// Modifies the |policy| in place. Only call this if the source is untrusted. +POLICY_EXPORT void FilterSensitivePolicies(PolicyMap* policy); + +} // namespace policy + +#endif // COMPONENTS_POLICY_CORE_COMMON_POLICY_LOADER_COMMON_H_
diff --git a/components/policy/core/common/policy_loader_mac.mm b/components/policy/core/common/policy_loader_mac.mm index 7c95301..c22f2a2 100644 --- a/components/policy/core/common/policy_loader_mac.mm +++ b/components/policy/core/common/policy_loader_mac.mm
@@ -10,6 +10,7 @@ #include "base/bind_helpers.h" #include "base/callback.h" #include "base/enterprise_util.h" +#include "base/feature_list.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/mac/foundation_util.h" @@ -19,9 +20,11 @@ #include "base/values.h" #include "build/build_config.h" #include "components/policy/core/common/external_data_fetcher.h" +#include "components/policy/core/common/features.h" #include "components/policy/core/common/mac_util.h" #include "components/policy/core/common/policy_bundle.h" #include "components/policy/core/common/policy_load_status.h" +#include "components/policy/core/common/policy_loader_common.h" #include "components/policy/core/common/policy_map.h" #include "components/policy/core/common/preferences_mac.h" #include "components/policy/core/common/schema.h" @@ -31,6 +34,24 @@ namespace policy { +namespace { + +// Encapsulates logic to determine if enterprise policies should be honored. +bool ShouldHonorPolicies() { + base::DeviceUserDomainJoinState join_state = + base::AreDeviceAndUserJoinedToDomain(); + // IsDeviceRegisteredWithManagementNew is only available after 10.13.4. + // Eventually switch to it when that is the minimum OS required by Chromium. + base::MacDeviceManagementStateOld mdm_state = + base::IsDeviceRegisteredWithManagementOld(); + + // Only honor sensitive policies if the Mac is managed externally. + return join_state.device_joined || + mdm_state == base::MacDeviceManagementStateOld::kMDMEnrollment; +} + +} // namespace + PolicyLoaderMac::PolicyLoaderMac( scoped_refptr<base::SequencedTaskRunner> task_runner, const base::FilePath& managed_policy_path, @@ -125,6 +146,12 @@ // Load policy for the registered components. LoadPolicyForDomain(POLICY_DOMAIN_EXTENSIONS, "extensions", bundle.get()); + if (base::FeatureList::IsEnabled( + policy::features::kIgnoreSensitivePoliciesOnUnmanagedMac) && + !ShouldHonorPolicies()) { + FilterSensitivePolicies(&chrome_policy); + } + return bundle; }
diff --git a/components/policy/core/common/policy_loader_win.cc b/components/policy/core/common/policy_loader_win.cc index bb7abdd6..2f3acf4 100644 --- a/components/policy/core/common/policy_loader_win.cc +++ b/components/policy/core/common/policy_loader_win.cc
@@ -40,6 +40,7 @@ #include "base/win/windows_version.h" #include "components/policy/core/common/policy_bundle.h" #include "components/policy/core/common/policy_load_status.h" +#include "components/policy/core/common/policy_loader_common.h" #include "components/policy/core/common/policy_map.h" #include "components/policy/core/common/policy_namespace.h" #include "components/policy/core/common/policy_types.h" @@ -55,33 +56,6 @@ const char kKeyRecommended[] = "recommended"; const char kKeyThirdParty[] = "3rdparty"; -// The web store url that is the only trusted source for extensions. -const char kExpectedWebStoreUrl[] = - ";https://clients2.google.com/service/update2/crx"; -// String to be prepended to each blocked entry. -const char kBlockedExtensionPrefix[] = "[BLOCKED]"; - -// List of policies that are considered only if the user is part of a AD domain. -// Please document any new additions in policy_templates.json! -const char* kInsecurePolicies[] = { - key::kChromeCleanupEnabled, - key::kChromeCleanupReportingEnabled, - key::kCommandLineFlagSecurityWarningsEnabled, - key::kDefaultSearchProviderEnabled, - key::kAutoOpenFileTypes, - key::kHomepageIsNewTabPage, - key::kHomepageLocation, - key::kMetricsReportingEnabled, - key::kNewTabPageLocation, - key::kPasswordProtectionChangePasswordURL, - key::kPasswordProtectionLoginURLs, - key::kRestoreOnStartup, - key::kRestoreOnStartupURLs, - key::kSafeBrowsingForTrustedSourcesEnabled, - key::kSafeBrowsingEnabled, - key::kSafeBrowsingWhitelistDomains, -}; - // The list of possible errors that can occur while collecting information about // the current enterprise environment. // This enum is used to define the buckets for an enumerated UMA histogram. @@ -95,8 +69,7 @@ DOMAIN_CHECK_ERROR_SIZE, // Not a DomainCheckError. Must be last. }; -// Encapculates logic to determine if enterprise policies should be honored. -// This is used in various places below. +// Encapsulates logic to determine if enterprise policies should be honored. bool ShouldHonorPolicies() { bool is_enterprise_version = base::win::OSInfo::GetInstance()->version_type() != base::win::SUITE_HOME; @@ -105,62 +78,6 @@ is_enterprise_version); } -// Verifies that untrusted policies contain only safe values. Modifies the -// |policy| in place. -void FilterUntrustedPolicy(PolicyMap* policy) { - if (ShouldHonorPolicies()) - return; - - int invalid_policies = 0; - const PolicyMap::Entry* map_entry = - policy->Get(key::kExtensionInstallForcelist); - if (map_entry && map_entry->value) { - const base::ListValue* policy_list_value = nullptr; - if (!map_entry->value->GetAsList(&policy_list_value)) - return; - - std::unique_ptr<base::ListValue> filtered_values(new base::ListValue); - for (const auto& list_entry : *policy_list_value) { - std::string entry; - if (!list_entry.GetAsString(&entry)) - continue; - size_t pos = entry.find(';'); - if (pos == std::string::npos) - continue; - // Only allow custom update urls in enterprise environments. - if (!base::LowerCaseEqualsASCII(entry.substr(pos), - kExpectedWebStoreUrl)) { - entry = kBlockedExtensionPrefix + entry; - invalid_policies++; - } - - filtered_values->AppendString(entry); - } - if (invalid_policies) { - PolicyMap::Entry filtered_entry = map_entry->DeepCopy(); - filtered_entry.value = std::move(filtered_values); - policy->Set(key::kExtensionInstallForcelist, std::move(filtered_entry)); - - const PolicyDetails* details = - GetChromePolicyDetails(key::kExtensionInstallForcelist); - base::UmaHistogramSparse("EnterpriseCheck.InvalidPolicies", details->id); - } - } - - for (size_t i = 0; i < base::size(kInsecurePolicies); ++i) { - if (policy->Get(kInsecurePolicies[i])) { - policy->GetMutable(kInsecurePolicies[i])->SetBlocked(); - invalid_policies++; - const PolicyDetails* details = - GetChromePolicyDetails(kInsecurePolicies[i]); - base::UmaHistogramSparse("EnterpriseCheck.InvalidPolicies", details->id); - } - } - - UMA_HISTOGRAM_COUNTS_1M("EnterpriseCheck.InvalidPoliciesDetected", - invalid_policies); -} - // Parses |gpo_dict| according to |schema| and writes the resulting policy // settings to |policy| for the given |scope| and |level|. void ParsePolicy(const RegistryDict* gpo_dict, @@ -406,7 +323,8 @@ const Schema* chrome_schema = schema_map()->GetSchema(PolicyNamespace(POLICY_DOMAIN_CHROME, "")); ParsePolicy(gpo_dict, level, scope, *chrome_schema, &policy); - FilterUntrustedPolicy(&policy); + if (!ShouldHonorPolicies()) + FilterSensitivePolicies(&policy); chrome_policy_map->MergeFrom(policy); }
diff --git a/components/policy/proto/chrome_device_policy.proto b/components/policy/proto/chrome_device_policy.proto index 9775131..3cfc6a29 100644 --- a/components/policy/proto/chrome_device_policy.proto +++ b/components/policy/proto/chrome_device_policy.proto
@@ -1361,22 +1361,22 @@ // Specifies a list of origins. Each of the specified origins will run in its // own process on the sign-in screen. -message DeviceLoginScreenIsolateOriginsProto { +message OBSOLETE_DeviceLoginScreenIsolateOriginsProto { // A comma-separated list of the origins to be run in a separate process on // the sign-in screen. // If the value of this policy does not match the value of the user policy // IsolateOrigins, the chrome process will be restarted on user sign-in to // apply the value specified by the user policy. - optional string isolate_origins = 1; + optional string OBSOLETE_isolate_origins = 1 [deprecated = true]; } // Specifies if each site should run in its own process on the sign-in screen. -message DeviceLoginScreenSitePerProcessProto { +message OBSOLETE_DeviceLoginScreenSitePerProcessProto { // If true, each site will run in its own process on the sign-in screen. // If the value of this policy does not match the value of the user policy // SitePerProcess, the chrome process will be restarted on user sign-in to // apply the value specified by the user policy. - optional bool site_per_process = 1; + optional bool OBSOLETE_site_per_process = 1 [deprecated = true]; } // Setting to control if running virtual machines on Chrome OS is allowed. @@ -1682,10 +1682,10 @@ 65; optional DeviceUserPolicyLoopbackProcessingModeProto device_user_policy_loopback_processing_mode = 66; - optional DeviceLoginScreenIsolateOriginsProto - device_login_screen_isolate_origins = 67; - optional DeviceLoginScreenSitePerProcessProto - device_login_screen_site_per_process = 68; + optional OBSOLETE_DeviceLoginScreenIsolateOriginsProto + device_login_screen_isolate_origins = 67 [deprecated = true]; + optional OBSOLETE_DeviceLoginScreenSitePerProcessProto + device_login_screen_site_per_process = 68 [deprecated = true]; optional VirtualMachinesAllowedProto virtual_machines_allowed = 69; optional DeviceMachinePasswordChangeRateProto device_machine_password_change_rate = 70;
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index bdfcb68..3c1797efb 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -6752,15 +6752,9 @@ 'id': 563, 'caption': '''Enable App Recommendations in Zero State of Search Box''', 'tags': [], - 'desc': '''Enable App Recommendation in Zero State of search box in launcher. + 'desc': '''Setting the policy to True can make app recommendations appear in the zero-state search. Setting the policy to False means these recommendations don't appear. - If this policy is set to true, App recommendations may appear in the zero state search. - - If this policy is set to false, App recommendations will not appear in the zero state search. - - If you set this policy, users cannot change or override it. - - If this policy is left unset, the default is False for managed devices.''' + If you set the policy, users can't change it. If not set, managed devices default to a False setting.''' }, { 'name': 'TranslateEnabled', @@ -13331,13 +13325,7 @@ 'caption': '''Enable ARC''', 'tags': [], 'desc': - '''When this policy is set to true, ARC will be enabled for the user - (subject to additional policy settings checks - ARC will still be - unavailable if either ephemeral mode or multiple sign-in is enabled - in the current user session). - - If this setting is disabled or not configured then enterprise users are - unable to use ARC.''', + '''Unless Ephemeral mode or multiple sign-in is on during the user's session, setting ArcEnabled to True turns ARC on for the user. Setting the policy to False or leaving it unset means enterprise users can't use ARC.''', }, { 'name': 'ArcPolicy', @@ -13395,9 +13383,7 @@ 'caption': '''Configure ARC''', 'tags': [], 'desc': - '''Specifies a set of policies that will be handed over to the ARC runtime. The value must be valid JSON. - - This policy can be used to configure which Android apps are automatically installed on the device. + '''Setting the policy specifies a set of policies to hand over to the ARC runtime. Admins can use it to select the Android apps that autoinstall. Enter value in valid JSON format. To pin apps to the launcher, see PinnedLauncherApps.''' }, @@ -13870,9 +13856,9 @@ 'id': 330, 'caption': '''Set certificate availability for ARC-apps''', 'tags': ['system-security'], - 'desc': '''If set to SyncDisabled or not configured, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> certificates are not available for ARC-apps. + 'desc': '''Setting the policy to CopyCaCerts makes all ONC-installed CA certificates with <ph name="WEB_TRUSTED_BIT">Web TrustBit</ph> available for ARC-apps. - If set to CopyCaCerts, all ONC-installed CA certificates with <ph name="WEB_TRUSTED_BIT">Web TrustBit</ph> are available for ARC-apps.''', + Setting to None or leaving it unset makes <ph name="PRODUCT_OS_NAME">$2<ex>Chrome OS</ex></ph> certificates unavailable for ARC-apps.''', }, { 'name': 'AllowedDomainsForApps', @@ -15364,11 +15350,9 @@ 'id': 397, 'caption': '''Allow unaffiliated users to use ARC''', 'tags': [], - 'desc': '''If the policy is set to false, unaffiliated users will not be allowed to use ARC. + 'desc': '''Unless ARC is turned off by other means, then setting the policy to True or leaving it unset lets users use ARC. Setting the policy to False means unaffiliated users may not use ARC. - If the policy is unset or set to true, all users are allowed to use ARC (unless ARC is disabled by other means). - - Changes to the policy will only be applied while ARC is not running, e.g. while Chrome OS is starting.''', + Changes to the policy only apply while ARC isn't running, for example, while starting Chrome OS.''', }, { 'name': 'IsolateOrigins', @@ -15426,7 +15410,7 @@ 'owners': ['file://components/policy/resources/OWNERS'], 'type': 'string', 'schema': { 'type': 'string' }, - 'supported_on': ['chrome_os:66-'], + 'supported_on': ['chrome_os:66-76'], 'device_only': True, 'features': { 'dynamic_refresh': False, @@ -15437,6 +15421,7 @@ 'caption': '''Enable Site Isolation for specified origins''', 'tags': ['system-security'], 'desc': ''' + This policy was removed in M77. This policy applies to the sign-in screen. Please see also the <ph name="ISOLATE_ORIGINS_POLICY_NAME">IsolateOrigins</ph> policy which applies to the user session. If the policy is enabled, each of the named origins in a comma-separated list will run in its own process. This will also isolate origins named by subdomains; e.g. specifying https://example.com/ will also cause https://foo.example.com/ to be isolated as part of the https://example.com/ site. If the policy is not configured or disabled, the platform default site isolation settings will be used for the sign-in screen. @@ -15458,6 +15443,7 @@ 'caption': '''Enable Site Isolation for every site''', 'tags': ['system-security'], 'desc': ''' + This policy was removed in M77. This policy applies to the sign-in screen. Please see also the <ph name="SITE_PER_PROCESS_POLICY_NAME">SitePerProcess</ph> policy which applies to the user session. It is recommended to set both policies to the same value. If the values don't match, a delay may be incurred when entering a user session while the value specified by user policy is being applied. ''', }, @@ -16552,10 +16538,7 @@ 'id': 447, 'caption': '''Log events for Android app installs''', 'tags': ['google-sharing'], - 'desc': '''Enables reporting of key events during Android app installation to Google. Events are captured only for apps whose installation was triggered via policy. - - If the policy is set to true, events will be logged. - If the policy is set to false or unset, events will not be logged.''', + 'desc': '''Setting the policy to True sends reports of key, policy-triggered Android app installation events to Google. Setting the policy to False means no events are captured.''', }, { 'name': 'UsageTimeLimit', @@ -16762,15 +16745,11 @@ 'caption': '''Control Android backup and restore service''', 'tags': ['google-sharing'], 'desc': - '''This policy controls the initial state of Android backup and restore. + '''Setting the policy to <ph name="BR_ENABLED">BackupAndRestoreEnabled</ph> means Android backup and restore is initially on. Setting the policy to <ph name="BR_DISABLED">BackupAndRestoreDisabled</ph> or leaving it unset keeps backup and restore off during setup. - When this policy is not configured or set to <ph name="BR_DISABLED">BackupAndRestoreDisabled</ph>, Android backup and restore is initially disabled. + Setting the policy to <ph name="BR_UNDER_USER_CONTROL">BackupAndRestoreUnderUserControl</ph> means users see prompts to use backup and restore. If they turn on backup and restore, Android app data is uploaded to Android backup servers and restored during reinstallations of compatible apps. - When this policy is set to <ph name="BR_ENABLED">BackupAndRestoreEnabled</ph>, Android backup and restore is initially enabled. - - When this policy is set to <ph name="BR_UNDER_USER_CONTROL">BackupAndRestoreUnderUserControl</ph>, the user is asked to choose whether to use Android backup and restore. If the user enables backup and restore, Android app data is uploaded to Android backup servers and restored from them upon app re-installations for compatible apps. - - Note that this policy controls the state of Android backup and restore during initial setup only. The user can open Android settings afterward and turn Android backup and restore on/off.''', + After initial setup, users can turn backup and restore on or off.''', }, { 'name': 'ArcGoogleLocationServicesEnabled', @@ -16808,17 +16787,11 @@ 'caption': '''Control Android Google location services''', 'tags': ['google-sharing'], 'desc': - '''This policy controls the initial state of Google location services. + '''Unless the <ph name="DEFAULT_GEOLOCATION_SETTING_POLICY_NAME">DefaultGeolocationSetting</ph> policy is set to <ph name="BLOCK_GEOLOCATION_SETTING">BlockGeolocation</ph>, then setting <ph name="GLS_ENABLED">GoogleLocationServicesEnabled</ph> turns Google location services on during initial setup. Setting the policy to <ph name="GLS_DISABLED">GoogleLocationServicesDisabled</ph> or leaving it unset keeps location services off during setup. - When this policy is not configured or set to <ph name="GLS_DISABLED">GoogleLocationServicesDisabled</ph>, Google location services are initially disabled. + Setting policy to <ph name="BR_UNDER_USER_CONTROL">BackupAndRestoreUnderUserControl</ph> prompts users about whether or not to use Google location services. If they turn it on, Android apps use the services to search the device location and send anonymous location data to Google. - When this policy is set to <ph name="GLS_ENABLED">GoogleLocationServicesEnabled</ph>, Google location services are initially enabled. - - When this policy is set to <ph name="GLS_UNDER_USER_CONTROL">GoogleLocationServicesUnderUserControl</ph>, the user is asked to choose whether to use Google location services. This will allow Android apps to use the services to query the device location, and also will enable submitting of anonymous location data to Google. - - Note that this policy controls the state of Google location services during initial setup only. The user can open Android settings afterward and turn Google location services on/off. - - Note that this policy is ignored and Google location services are always disabled when the <ph name="DEFAULT_GEOLOCATION_SETTING_POLICY_NAME">DefaultGeolocationSetting</ph> policy is set to <ph name="BLOCK_GEOLOCATION_SETTING">BlockGeolocation</ph>.''', + After initial setup, users can turn Google location services on or off.''', }, { 'name': 'EnableSyncConsent', @@ -18474,9 +18447,18 @@ 'type': 'object', 'properties': { 'day': { '$ref': 'WeekDay' }, - 'start_time': { '$ref': 'Time' }, - 'end_time': { '$ref': 'Time' }, - 'charge_start_time': { '$ref': 'Time' } + 'start_time': { + 'description': '''Time when the device will start running from the battery, interpreted in the device's local time zone.''', + '$ref': 'Time' + }, + 'end_time': { + 'description': '''Time when the device will run from alternating current, interpreted in the device's local time zone.''', + '$ref': 'Time' + }, + 'charge_start_time': { + 'description': '''Time when the device will use alternating current to charge battery, interpreted in the device's local time zone.''', + '$ref': 'Time' + } } } } @@ -20566,6 +20548,7 @@ 'example_value': True, 'id': 683, 'supported_on': ['chrome.*:81-84', 'chrome_os:81-84', 'android:81-84', 'webview_android:81-84'], + 'deprecated': True, 'features': { 'dynamic_refresh': False, 'per_profile': True,
diff --git a/components/policy/resources/webui/policy_base.js b/components/policy/resources/webui/policy_base.js index c0cbb30..552e47421 100644 --- a/components/policy/resources/webui/policy_base.js +++ b/components/policy/resources/webui/policy_base.js
@@ -173,10 +173,9 @@ if (scope !== 'updater') { this.setLabelAndShow_( - '.time-since-last-refresh', status.timeSinceLastRefresh, false); - this.setLabelAndShow_( - '.refresh-interval', status.refreshInterval, false); - this.setLabelAndShow_('.status', status.status, false); + '.time-since-last-refresh', status.timeSinceLastRefresh); + this.setLabelAndShow_('.refresh-interval', status.refreshInterval); + this.setLabelAndShow_('.status', status.status); this.setLabelAndShow_( '.policy-push', loadTimeData.getString(
diff --git a/components/printing/common/BUILD.gn b/components/printing/common/BUILD.gn index ce878a58..386f3770 100644 --- a/components/printing/common/BUILD.gn +++ b/components/printing/common/BUILD.gn
@@ -15,6 +15,7 @@ ] deps = [ + ":mojo_interfaces", "//base", "//components/cloud_devices/common:common", "//ipc",
diff --git a/components/printing/common/print.mojom b/components/printing/common/print.mojom index a270415..eb84dd0 100644 --- a/components/printing/common/print.mojom +++ b/components/printing/common/print.mojom
@@ -29,6 +29,21 @@ DuplexMode duplex; }; +// Parameters to describe the to-be-rendered preview document. +struct DidStartPreviewParams { + // Total page count for the rendered preview. (Not the number of pages the + // user selected to print.) + int32 page_count; + // The list of 0-based page numbers that will be rendered. + array<int32> pages_to_render; + // number of pages per sheet and should be greater or equal to 1. + int32 pages_per_sheet; + // Physical size of the page, including non-printable margins. + gfx.mojom.Size page_size; + // Scaling % to fit to page + int32 fit_to_page_scaling; +}; + // Interface implemented by a class that desires to render print documents for // Chrome print preview. interface PrintRenderer {
diff --git a/components/printing/common/print_messages.h b/components/printing/common/print_messages.h index 8f44ed0b..e72d76b 100644 --- a/components/printing/common/print_messages.h +++ b/components/printing/common/print_messages.h
@@ -14,6 +14,7 @@ #include "base/memory/read_only_shared_memory_region.h" #include "base/values.h" #include "build/build_config.h" +#include "components/printing/common/print.mojom.h" #include "components/printing/common/printing_param_traits_macros.h" #include "ipc/ipc_message_macros.h" #include "printing/buildflags/buildflags.h" @@ -244,23 +245,23 @@ #if BUILDFLAG(ENABLE_PRINT_PREVIEW) // Parameters to describe the to-be-rendered preview document. -IPC_STRUCT_BEGIN(PrintHostMsg_DidStartPreview_Params) +IPC_STRUCT_TRAITS_BEGIN(printing::mojom::DidStartPreviewParams) // Total page count for the rendered preview. (Not the number of pages the // user selected to print.) - IPC_STRUCT_MEMBER(int, page_count) + IPC_STRUCT_TRAITS_MEMBER(page_count) // The list of 0-based page numbers that will be rendered. - IPC_STRUCT_MEMBER(std::vector<int>, pages_to_render) + IPC_STRUCT_TRAITS_MEMBER(pages_to_render) // number of pages per sheet and should be greater or equal to 1. - IPC_STRUCT_MEMBER(int, pages_per_sheet) + IPC_STRUCT_TRAITS_MEMBER(pages_per_sheet) // Physical size of the page, including non-printable margins. - IPC_STRUCT_MEMBER(gfx::Size, page_size) + IPC_STRUCT_TRAITS_MEMBER(page_size) // Scaling % to fit to page - IPC_STRUCT_MEMBER(int, fit_to_page_scaling) -IPC_STRUCT_END() + IPC_STRUCT_TRAITS_MEMBER(fit_to_page_scaling) +IPC_STRUCT_TRAITS_END() // Parameters to describe a rendered preview page. IPC_STRUCT_BEGIN(PrintHostMsg_DidPreviewPage_Params) @@ -384,7 +385,7 @@ // Notify the browser the about the to-be-rendered print preview document. IPC_MESSAGE_ROUTED2(PrintHostMsg_DidStartPreview, - PrintHostMsg_DidStartPreview_Params /* params */, + printing::mojom::DidStartPreviewParams /* params */, PrintHostMsg_PreviewIds /* ids */) // Notify the browser of the default page layout according to the currently
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc index b4decb9..2bbacae 100644 --- a/components/printing/renderer/print_render_frame_helper.cc +++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -31,6 +31,7 @@ #include "base/trace_event/trace_event.h" #include "build/build_config.h" #include "components/grit/components_resources.h" +#include "components/printing/common/print.mojom.h" #include "components/printing/common/print_messages.h" #include "content/public/common/web_preferences.h" #include "content/public/renderer/render_frame.h" @@ -1506,14 +1507,15 @@ routing_id(), default_page_layout, printable_area_in_points, has_page_size_style, ids)); - PrintHostMsg_DidStartPreview_Params params; - params.page_count = print_preview_context_.total_page_count(); - params.pages_to_render = print_preview_context_.pages_to_render(); - params.pages_per_sheet = print_params.pages_per_sheet; - params.page_size = GetPdfPageSize(print_params.page_size, dpi); - params.fit_to_page_scaling = - GetFitToPageScaleFactor(printable_area_in_points); - Send(new PrintHostMsg_DidStartPreview(routing_id(), params, ids)); + Send(new PrintHostMsg_DidStartPreview( + routing_id(), + mojom::DidStartPreviewParams( + print_preview_context_.total_page_count(), + print_preview_context_.pages_to_render(), + print_params.pages_per_sheet, + GetPdfPageSize(print_params.page_size, dpi), + GetFitToPageScaleFactor(printable_area_in_points)), + ids)); if (CheckForCancel()) return CREATE_FAIL;
diff --git a/components/printing/test/BUILD.gn b/components/printing/test/BUILD.gn index 0e30276..8f65aa0f 100644 --- a/components/printing/test/BUILD.gn +++ b/components/printing/test/BUILD.gn
@@ -17,6 +17,7 @@ public_deps = [ "//base", "//components/printing/common", + "//components/printing/common:mojo_interfaces", "//components/printing/renderer", "//content/public/common", "//content/public/renderer",
diff --git a/components/printing/test/print_mock_render_thread.cc b/components/printing/test/print_mock_render_thread.cc index 1f8001f..1fd46af8 100644 --- a/components/printing/test/print_mock_render_thread.cc +++ b/components/printing/test/print_mock_render_thread.cc
@@ -8,6 +8,7 @@ #include "base/values.h" #include "build/build_config.h" +#include "components/printing/common/print.mojom.h" #include "components/printing/test/mock_printer.h" #include "ipc/ipc_sync_message.h" #include "printing/buildflags/buildflags.h" @@ -98,7 +99,7 @@ #if BUILDFLAG(ENABLE_PRINT_PREVIEW) void PrintMockRenderThread::OnDidStartPreview( - const PrintHostMsg_DidStartPreview_Params& params, + const printing::mojom::DidStartPreviewParams& params, const PrintHostMsg_PreviewIds& ids) { print_preview_pages_remaining_ = params.page_count; }
diff --git a/components/printing/test/print_mock_render_thread.h b/components/printing/test/print_mock_render_thread.h index 7e175b8..30204f8 100644 --- a/components/printing/test/print_mock_render_thread.h +++ b/components/printing/test/print_mock_render_thread.h
@@ -16,6 +16,7 @@ #include "base/macros.h" #include "base/single_thread_task_runner.h" #include "build/build_config.h" +#include "components/printing/common/print.mojom-forward.h" #include "content/public/test/mock_render_thread.h" #include "printing/buildflags/buildflags.h" @@ -24,7 +25,6 @@ } class MockPrinter; -struct PrintHostMsg_DidStartPreview_Params; struct PrintHostMsg_DidPreviewPage_Params; struct PrintHostMsg_DidPrintDocument_Params; struct PrintHostMsg_PreviewIds; @@ -81,7 +81,7 @@ void OnDidPrintDocument(const PrintHostMsg_DidPrintDocument_Params& params, IPC::Message* reply_msg); #if BUILDFLAG(ENABLE_PRINT_PREVIEW) - void OnDidStartPreview(const PrintHostMsg_DidStartPreview_Params& params, + void OnDidStartPreview(const printing::mojom::DidStartPreviewParams& params, const PrintHostMsg_PreviewIds& ids); void OnDidPreviewPage(const PrintHostMsg_DidPreviewPage_Params& params, const PrintHostMsg_PreviewIds& ids);
diff --git a/components/signin/core/browser/android/BUILD.gn b/components/signin/core/browser/android/BUILD.gn index de11afb7..08e5e4ce 100644 --- a/components/signin/core/browser/android/BUILD.gn +++ b/components/signin/core/browser/android/BUILD.gn
@@ -66,8 +66,15 @@ "//base:base_java", "//base:base_java_test_support", "//base:base_junit_test_support", + "//testing/android/junit:junit_test_support", "//third_party/android_deps:androidx_annotation_annotation_java", + "//third_party/android_sdk:android_test_base_java", + "//third_party/android_support_test_runner:rules_java", + "//third_party/android_support_test_runner:runner_java", + "//third_party/guava:guava_android_java", "//third_party/junit", + "//third_party/mockito:mockito_java", + "//third_party/robolectric:robolectric_all_java", ] }
diff --git a/components/speech/BUILD.gn b/components/speech/BUILD.gn new file mode 100644 index 0000000..30148e5c --- /dev/null +++ b/components/speech/BUILD.gn
@@ -0,0 +1,22 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("speech") { + sources = [ + "downstream_loader.cc", + "downstream_loader.h", + "downstream_loader_client.h", + "upstream_loader.cc", + "upstream_loader.h", + "upstream_loader_client.h", + ] + + deps = [ + "//mojo/public/cpp/bindings", + "//mojo/public/cpp/platform", + "//mojo/public/cpp/system", + "//services/network/public/cpp", + "//services/network/public/mojom", + ] +}
diff --git a/components/speech/DEPS b/components/speech/DEPS new file mode 100644 index 0000000..38ed60b --- /dev/null +++ b/components/speech/DEPS
@@ -0,0 +1,4 @@ +include_rules = [ + "+mojo/public/cpp", + "+services/network/public", +]
diff --git a/components/speech/downstream_loader.cc b/components/speech/downstream_loader.cc new file mode 100644 index 0000000..14ca749 --- /dev/null +++ b/components/speech/downstream_loader.cc
@@ -0,0 +1,48 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/speech/downstream_loader.h" + +#include "base/callback.h" +#include "components/speech/downstream_loader_client.h" + +namespace speech { + +DownstreamLoader::DownstreamLoader( + std::unique_ptr<network::ResourceRequest> resource_request, + net::NetworkTrafficAnnotationTag upstream_traffic_annotation, + network::mojom::URLLoaderFactory* url_loader_factory, + DownstreamLoaderClient* downstream_loader_client) + : downstream_loader_client_(downstream_loader_client) { + DCHECK(downstream_loader_client_); + simple_url_loader_ = network::SimpleURLLoader::Create( + std::move(resource_request), upstream_traffic_annotation); + simple_url_loader_->DownloadAsStream(url_loader_factory, this); +} + +DownstreamLoader::~DownstreamLoader() = default; + +void DownstreamLoader::OnDataReceived(base::StringPiece string_piece, + base::OnceClosure resume) { + downstream_loader_client_->OnDownstreamDataReceived(string_piece); + std::move(resume).Run(); +} + +void DownstreamLoader::OnComplete(bool success) { + int response_code = -1; + if (simple_url_loader_->ResponseInfo() && + simple_url_loader_->ResponseInfo()->headers) { + response_code = + simple_url_loader_->ResponseInfo()->headers->response_code(); + } + + downstream_loader_client_->OnDownstreamDataComplete(success, response_code); +} + +void DownstreamLoader::OnRetry(base::OnceClosure start_retry) { + // Retries are not enabled for these requests. + NOTREACHED(); +} + +} // namespace speech
diff --git a/components/speech/downstream_loader.h b/components/speech/downstream_loader.h new file mode 100644 index 0000000..f6682a7 --- /dev/null +++ b/components/speech/downstream_loader.h
@@ -0,0 +1,46 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SPEECH_DOWNSTREAM_LOADER_H_ +#define COMPONENTS_SPEECH_DOWNSTREAM_LOADER_H_ + +#include <memory> + +#include "base/callback_forward.h" +#include "base/strings/string_piece.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/simple_url_loader.h" +#include "services/network/public/cpp/simple_url_loader_stream_consumer.h" + +namespace speech { + +class DownstreamLoaderClient; + +// Streams response data from the server to the DownstreamLoaderClient. +class DownstreamLoader : public network::SimpleURLLoaderStreamConsumer { + public: + DownstreamLoader(std::unique_ptr<network::ResourceRequest> resource_request, + net::NetworkTrafficAnnotationTag upstream_traffic_annotation, + network::mojom::URLLoaderFactory* url_loader_factory, + DownstreamLoaderClient* downstream_loader_client); + DownstreamLoader(const DownstreamLoader&) = delete; + DownstreamLoader& operator=(const DownstreamLoader&) = delete; + ~DownstreamLoader() override; + + // SimpleURLLoaderStreamConsumer implementation: + void OnDataReceived(base::StringPiece string_piece, + base::OnceClosure resume) override; + void OnComplete(bool success) override; + void OnRetry(base::OnceClosure start_retry) override; + + private: + // The DownstreamLoaderClient must outlive the DownstreamLoader. + DownstreamLoaderClient* const downstream_loader_client_; + + std::unique_ptr<network::SimpleURLLoader> simple_url_loader_; +}; + +} // namespace speech + +#endif // COMPONENTS_SPEECH_DOWNSTREAM_LOADER_H_
diff --git a/components/speech/downstream_loader_client.h b/components/speech/downstream_loader_client.h new file mode 100644 index 0000000..3b0e078 --- /dev/null +++ b/components/speech/downstream_loader_client.h
@@ -0,0 +1,40 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SPEECH_DOWNSTREAM_LOADER_CLIENT_H_ +#define COMPONENTS_SPEECH_DOWNSTREAM_LOADER_CLIENT_H_ + +#include "base/strings/string_piece.h" + +namespace speech { + +// An interface containing the callback functions required by consumers +// of the DownstreamLoader. The class that implements this client +// interface must outlive the DownstreamLoader. +class DownstreamLoaderClient { + public: + DownstreamLoaderClient(const DownstreamLoaderClient&) = delete; + DownstreamLoaderClient& operator=(const DownstreamLoaderClient&) = delete; + + protected: + DownstreamLoaderClient() = default; + virtual ~DownstreamLoaderClient() = default; + + private: + friend class DownstreamLoader; + + // Executed when downstream data is received. + virtual void OnDownstreamDataReceived( + base::StringPiece new_response_data) = 0; + + // Executed when downstream data is completed. + // success: True on 2xx responses where the entire body was successfully + // received. response_code: The HTTP response code if available, or -1 on + // network errors. + virtual void OnDownstreamDataComplete(bool success, int response_code) = 0; +}; + +} // namespace speech + +#endif // COMPONENTS_SPEECH_DOWNSTREAM_LOADER_CLIENT_H_
diff --git a/components/speech/upstream_loader.cc b/components/speech/upstream_loader.cc new file mode 100644 index 0000000..9a88c14b --- /dev/null +++ b/components/speech/upstream_loader.cc
@@ -0,0 +1,129 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/speech/upstream_loader.h" + +#include "base/callback_forward.h" +#include "components/speech/upstream_loader_client.h" + +namespace speech { + +UpstreamLoader::UpstreamLoader( + std::unique_ptr<network::ResourceRequest> resource_request, + net::NetworkTrafficAnnotationTag upstream_traffic_annotation, + network::mojom::URLLoaderFactory* url_loader_factory, + UpstreamLoaderClient* upstream_loader_client) + : upstream_loader_client_(upstream_loader_client) { + DCHECK(upstream_loader_client_); + // Attach a chunked upload body. + mojo::PendingRemote<network::mojom::ChunkedDataPipeGetter> data_remote; + receiver_set_.Add(this, data_remote.InitWithNewPipeAndPassReceiver()); + resource_request->request_body = new network::ResourceRequestBody(); + resource_request->request_body->SetToChunkedDataPipe(std::move(data_remote)); + simple_url_loader_ = network::SimpleURLLoader::Create( + std::move(resource_request), upstream_traffic_annotation); + simple_url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + url_loader_factory, + base::BindOnce(&UpstreamLoader::OnComplete, base::Unretained(this))); +} + +UpstreamLoader::~UpstreamLoader() = default; + +// Attempts to send more of the upload body, if more data is available, and +// |upload_pipe_| is valid. +void UpstreamLoader::SendData() { + DCHECK_LE(upload_position_, upload_body_.size()); + + if (!upload_pipe_.is_valid()) + return; + + // Nothing more to write yet, or done writing everything. + if (upload_position_ == upload_body_.size()) + return; + + // Since kMaxUploadWrite is a uint32_t, no overflow occurs in this downcast. + uint32_t write_bytes = std::min(upload_body_.length() - upload_position_, + static_cast<size_t>(kMaxUploadWrite)); + MojoResult result = + upload_pipe_->WriteData(upload_body_.data() + upload_position_, + &write_bytes, MOJO_WRITE_DATA_FLAG_NONE); + + // Wait for the pipe to have more capacity available, if needed. + if (result == MOJO_RESULT_SHOULD_WAIT) { + upload_pipe_watcher_->ArmOrNotify(); + return; + } + + // Do nothing on pipe closure - depend on the SimpleURLLoader to notice the + // other pipes being closed on error. Can reach this point if there's a + // retry, for instance, so cannot draw any conclusions here. + if (result != MOJO_RESULT_OK) + return; + + upload_position_ += write_bytes; + // If more data is available, arm the watcher again. Don't write again in a + // loop, even if WriteData would allow it, to avoid blocking the current + // thread. + if (upload_position_ < upload_body_.size()) + upload_pipe_watcher_->ArmOrNotify(); +} + +void UpstreamLoader::AppendChunkToUpload(const std::string& data, + bool is_last_chunk) { + DCHECK(!has_last_chunk_); + + upload_body_ += data; + if (is_last_chunk) { + // Send size before the rest of the body. While it doesn't matter much, if + // the other side receives the size before the last chunk, which Mojo does + // not guarantee, some protocols can merge the data and the last chunk + // itself into a single frame. + has_last_chunk_ = is_last_chunk; + if (get_size_callback_) + std::move(get_size_callback_).Run(net::OK, upload_body_.size()); + } + + SendData(); +} + +void UpstreamLoader::OnUploadPipeWriteable(MojoResult unused) { + SendData(); +} + +void UpstreamLoader::OnComplete(std::unique_ptr<std::string> response_body) { + int response_code = -1; + if (simple_url_loader_->ResponseInfo() && + simple_url_loader_->ResponseInfo()->headers) { + response_code = + simple_url_loader_->ResponseInfo()->headers->response_code(); + } + upstream_loader_client_->OnUpstreamDataComplete(response_body != nullptr, + response_code); +} + +void UpstreamLoader::GetSize(GetSizeCallback get_size_callback) { + if (has_last_chunk_) { + std::move(get_size_callback).Run(net::OK, upload_body_.size()); + } else { + get_size_callback_ = std::move(get_size_callback); + } +} + +void UpstreamLoader::StartReading(mojo::ScopedDataPipeProducerHandle pipe) { + // Delete any existing pipe, if any. + upload_pipe_watcher_.reset(); + upload_pipe_ = std::move(pipe); + upload_pipe_watcher_ = std::make_unique<mojo::SimpleWatcher>( + FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL); + upload_pipe_watcher_->Watch( + upload_pipe_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, + base::BindRepeating(&UpstreamLoader::OnUploadPipeWriteable, + base::Unretained(this))); + upload_position_ = 0; + + // Will attempt to start sending the request body, if any data is available. + SendData(); +} + +} // namespace speech
diff --git a/components/speech/upstream_loader.h b/components/speech/upstream_loader.h new file mode 100644 index 0000000..7f80e04 --- /dev/null +++ b/components/speech/upstream_loader.h
@@ -0,0 +1,77 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SPEECH_UPSTREAM_LOADER_H_ +#define COMPONENTS_SPEECH_UPSTREAM_LOADER_H_ + +#include <memory> +#include <string> + +#include "mojo/public/cpp/bindings/receiver_set.h" +#include "mojo/public/cpp/system/data_pipe.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/simple_url_loader.h" +#include "services/network/public/mojom/chunked_data_pipe_getter.mojom.h" + +namespace speech { + +class UpstreamLoaderClient; + +// Maximum amount of data written per Mojo write. +const uint32_t kMaxUploadWrite = 128 * 1024; + +// Streams sound data up to the server. Buffers entire request body into memory, +// so it can be replayed in the case of redirects or retries. +class UpstreamLoader : public network::mojom::ChunkedDataPipeGetter { + public: + UpstreamLoader(std::unique_ptr<network::ResourceRequest> resource_request, + net::NetworkTrafficAnnotationTag upstream_traffic_annotation, + network::mojom::URLLoaderFactory* url_loader_factory, + UpstreamLoaderClient* upstream_loader_client); + UpstreamLoader(const UpstreamLoader&) = delete; + UpstreamLoader& operator=(const UpstreamLoader&) = delete; + ~UpstreamLoader() override; + + void SendData(); + + void AppendChunkToUpload(const std::string& data, bool is_last_chunk); + + private: + void OnUploadPipeWriteable(MojoResult unused); + void OnComplete(std::unique_ptr<std::string> response_body); + + // mojom::ChunkedDataPipeGetter implementation: + void GetSize(GetSizeCallback get_size_callback) override; + void StartReading(mojo::ScopedDataPipeProducerHandle pipe) override; + + // Partial upload body. Have to cache the entire thing in memory, in case have + // to replay it. + std::string upload_body_; + + // Current position in |upload_body_|. All bytes before this point have been + // written to |upload_pipe_|. + size_t upload_position_ = 0; + + // Whether |upload_body_| is complete. + bool has_last_chunk_ = false; + + // Current pipe being used to send the |upload_body_| to the URLLoader. + mojo::ScopedDataPipeProducerHandle upload_pipe_; + + // Watches |upload_pipe_| for writeability. + std::unique_ptr<mojo::SimpleWatcher> upload_pipe_watcher_; + + // If non-null, invoked once the size of the upload is known. + network::mojom::ChunkedDataPipeGetter::GetSizeCallback get_size_callback_; + + // The UpstreamLoaderClient must outlive the UpstreamLoader. + UpstreamLoaderClient* const upstream_loader_client_; + + std::unique_ptr<network::SimpleURLLoader> simple_url_loader_; + mojo::ReceiverSet<network::mojom::ChunkedDataPipeGetter> receiver_set_; +}; + +} // namespace speech + +#endif // COMPONENTS_SPEECH_UPSTREAM_LOADER_H_
diff --git a/components/speech/upstream_loader_client.h b/components/speech/upstream_loader_client.h new file mode 100644 index 0000000..dcc51f7 --- /dev/null +++ b/components/speech/upstream_loader_client.h
@@ -0,0 +1,34 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SPEECH_UPSTREAM_LOADER_CLIENT_H_ +#define COMPONENTS_SPEECH_UPSTREAM_LOADER_CLIENT_H_ + +namespace speech { + +// An interface containing the callback functions required by consumers +// of the UpstreamLoader. The class that implements this client +// interface must outlive the UpstreamLoader. +class UpstreamLoaderClient { + public: + UpstreamLoaderClient(const UpstreamLoaderClient&) = delete; + UpstreamLoaderClient& operator=(const UpstreamLoaderClient&) = delete; + + protected: + UpstreamLoaderClient() = default; + virtual ~UpstreamLoaderClient() = default; + + private: + friend class UpstreamLoader; + + // Executed when upstream data is completed. + // success: True on 2xx responses. + // response_code: The HTTP response code if available, or -1 on + // network errors. + virtual void OnUpstreamDataComplete(bool success, int response_code) = 0; +}; + +} // namespace speech + +#endif // COMPONENTS_SPEECH_UPSTREAM_LOADER_CLIENT_H_
diff --git a/components/sync/engine_impl/model_type_registry.cc b/components/sync/engine_impl/model_type_registry.cc index 6b6a9e0..c061d6db 100644 --- a/components/sync/engine_impl/model_type_registry.cc +++ b/components/sync/engine_impl/model_type_registry.cc
@@ -145,22 +145,11 @@ int migrated_entity_count = 0; if (uss_migrator_.Run(type, user_share_, worker_ptr, &migrated_entity_count)) { - UMA_HISTOGRAM_ENUMERATION("Sync.USSMigrationSuccess", - ModelTypeHistogramValue(type)); // If we succesfully migrated, purge the directory of data for the type. // Purging removes the directory's local copy of the data only. directory()->PurgeEntriesWithTypeIn(ModelTypeSet(type), ModelTypeSet(), ModelTypeSet()); - } else { - UMA_HISTOGRAM_ENUMERATION("Sync.USSMigrationFailure", - ModelTypeHistogramValue(type)); } - - // Note that a partial failure may still contribute to the counts histogram. - base::UmaHistogramCounts100000( - std::string("Sync.USSMigrationEntityCount.") + - ModelTypeToHistogramSuffix(type), - migrated_entity_count); } // We want to check that we haven't accidentally enabled both the non-blocking
diff --git a/components/variations/android/BUILD.gn b/components/variations/android/BUILD.gn index 287ad61..ea87506 100644 --- a/components/variations/android/BUILD.gn +++ b/components/variations/android/BUILD.gn
@@ -29,5 +29,8 @@ "//base:base_java_test_support", "//base:base_junit_test_support", "//third_party/hamcrest:hamcrest_java", + "//third_party/junit", + "//third_party/mockito:mockito_java", + "//third_party/robolectric:robolectric_all_java", ] }
diff --git a/components/viz/client/client_resource_provider.cc b/components/viz/client/client_resource_provider.cc index 68fa873..c789f40 100644 --- a/components/viz/client/client_resource_provider.cc +++ b/components/viz/client/client_resource_provider.cc
@@ -383,7 +383,7 @@ ClientResourceProvider::ScopedSkSurface::~ScopedSkSurface() { if (surface_) - surface_->flush(); + surface_->flushAndSubmit(); } SkSurfaceProps ClientResourceProvider::ScopedSkSurface::ComputeSurfaceProps(
diff --git a/components/viz/common/gpu/context_cache_controller_unittest.cc b/components/viz/common/gpu/context_cache_controller_unittest.cc index c380ea6..03696829 100644 --- a/components/viz/common/gpu/context_cache_controller_unittest.cc +++ b/components/viz/common/gpu/context_cache_controller_unittest.cc
@@ -177,7 +177,7 @@ SkPixmap pixmap(image_info, image_data.data(), image_info.minRowBytes()); auto image = SkImage::MakeRasterCopy(pixmap); auto image_gpu = image->makeTextureImage(gr_context); - gr_context->flush(); + gr_context->flushAndSubmit(); } // Ensure we see size taken up for the image (now released, but cached for
diff --git a/components/viz/service/display_embedder/skia_output_device_buffer_queue.cc b/components/viz/service/display_embedder/skia_output_device_buffer_queue.cc index 1ba33bf..f6be3ec1 100644 --- a/components/viz/service/display_embedder/skia_output_device_buffer_queue.cc +++ b/components/viz/service/display_embedder/skia_output_device_buffer_queue.cc
@@ -140,6 +140,8 @@ }; scoped_skia_write_access_->surface()->flush( SkSurface::BackendSurfaceAccess::kNoAccess, flush_info); + DCHECK(scoped_skia_write_access_->surface()->getContext()); + scoped_skia_write_access_->surface()->getContext()->submit(); } scoped_skia_write_access_.reset(); end_semaphores_.clear();
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index 1c27142..c026eee 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -833,7 +833,7 @@ gl::ScopedProgressReporter scoped_progress_reporter( context_state_->progress_reporter()); // This ensures any outstanding callbacks for promise images are performed. - gr_context()->flush(); + gr_context()->flushAndSubmit(); release_current_last_.emplace(gl_surface_, context_state_); } @@ -969,6 +969,8 @@ context_state_->progress_reporter()); result = output_sk_surface()->flush( SkSurface::BackendSurfaceAccess::kPresent, flush_info); + DCHECK(output_sk_surface()->getContext()); + output_sk_surface()->getContext()->submit(); } if (result != GrSemaphoresSubmitted::kYes && @@ -1111,6 +1113,8 @@ &flush_info); auto result = offscreen.surface()->flush( SkSurface::BackendSurfaceAccess::kNoAccess, flush_info); + DCHECK(offscreen.surface()->getContext()); + offscreen.surface()->getContext()->submit(); if (result != GrSemaphoresSubmitted::kYes && !(scoped_promise_image_access.begin_semaphores().empty() && scoped_promise_image_access.end_semaphores().empty())) { @@ -1227,11 +1231,11 @@ surface->getCanvas()->drawPaint(paint); gl::ScopedProgressReporter scoped_progress_reporter( context_state_->progress_reporter()); - surface->flush(); + surface->flushAndSubmit(); } if (use_gl_renderer_copier_) { - surface->flush(); + surface->flushAndSubmit(); GLuint gl_id = 0; GLenum internal_format = supports_alpha_ ? GL_RGBA : GL_RGB;
diff --git a/components/viz/test/fake_skia_output_surface.cc b/components/viz/test/fake_skia_output_surface.cc index 7265a00f..eddec23 100644 --- a/components/viz/test/fake_skia_output_surface.cc +++ b/components/viz/test/fake_skia_output_surface.cc
@@ -213,7 +213,7 @@ gpu::SyncToken FakeSkiaOutputSurface::SubmitPaint( base::OnceClosure on_finished) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - sk_surfaces_[current_render_pass_id_]->flush(); + sk_surfaces_[current_render_pass_id_]->flushAndSubmit(); current_render_pass_id_ = 0; if (on_finished)
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc index 501eb980..474f742a 100644 --- a/content/app/content_main_runner_impl.cc +++ b/content/app/content_main_runner_impl.cc
@@ -60,6 +60,7 @@ #include "content/browser/tracing/memory_instrumentation_util.h" #include "content/browser/utility_process_host.h" #include "content/child/field_trial.h" +#include "content/common/android/cpu_time_metrics.h" #include "content/common/content_constants_internal.h" #include "content/common/url_schemes.h" #include "content/gpu/in_process_gpu_thread.h" @@ -898,6 +899,10 @@ tracing::InitTracingPostThreadPoolStartAndFeatureList(); +#if defined(OS_ANDROID) + SetupCpuTimeMetrics(); +#endif + if (should_start_service_manager_only) ForceInProcessNetworkService(true);
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index d18ea00..df0d6dda 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -2564,7 +2564,10 @@ "webauth/virtual_fido_discovery_factory.h", ] - deps += [ "//third_party/flac" ] + deps += [ + "//components/speech", + "//third_party/flac", + ] } if (is_mac) {
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc index 64000eb..47258ec 100644 --- a/content/browser/accessibility/browser_accessibility.cc +++ b/content/browser/accessibility/browser_accessibility.cc
@@ -1748,7 +1748,7 @@ std::vector<int32_t> BrowserAccessibility::GetColHeaderNodeIds() const { std::vector<int32_t> result; - node()->GetTableCellColHeaderNodeIds(&result); + node()->GetTableColHeaderNodeIds(&result); return result; }
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm index d6e194d..df49119 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.mm +++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -1030,13 +1030,7 @@ NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease]; if (is_table_like) { // If this is a table, return all column headers. - std::set<int32_t> headerIds; - for (int i = 0; i < *_owner->GetTableColCount(); i++) { - std::vector<int32_t> colHeaderIds = table->GetColHeaderNodeIds(i); - std::copy(colHeaderIds.begin(), colHeaderIds.end(), - std::inserter(headerIds, headerIds.end())); - } - for (int32_t id : headerIds) { + for (int32_t id : table->GetColHeaderNodeIds()) { BrowserAccessibility* cell = _owner->manager()->GetFromID(id); if (cell) [ret addObject:ToBrowserAccessibilityCocoa(cell)];
diff --git a/content/browser/cache_storage/cache_storage.proto b/content/browser/cache_storage/cache_storage.proto index bdec6e5..24b8b6c 100644 --- a/content/browser/cache_storage/cache_storage.proto +++ b/content/browser/cache_storage/cache_storage.proto
@@ -50,6 +50,10 @@ repeated string cors_exposed_header_names = 7; repeated string url_list = 8; optional bool loaded_with_credentials = 9; + // Mapped to net::HttpResponseInfo::ConnectionInfo via static casting. + optional int32 connection_info = 10; + optional string alpn_negotiated_protocol = 11; + optional bool was_fetched_via_spdy = 12; } message CacheMetadata {
diff --git a/content/browser/cache_storage/cache_storage_cache_unittest.cc b/content/browser/cache_storage/cache_storage_cache_unittest.cc index 3a346bd..bbf7439 100644 --- a/content/browser/cache_storage/cache_storage_cache_unittest.cc +++ b/content/browser/cache_storage/cache_storage_cache_unittest.cc
@@ -677,7 +677,9 @@ nullptr /* side_data_blob */, nullptr /* side_data_blob_for_cache_put */, network::mojom::ParsedHeaders::New(), - false /* loaded_with_credentials */); + net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN, + "unknown" /* alpn_negotiated_protocol */, + false /* loaded_with_credentials */, false /* was_fetched_via_spdy */); } void CopySideDataToResponse(const std::string& uuid,
diff --git a/content/browser/cache_storage/cache_storage_manager_unittest.cc b/content/browser/cache_storage/cache_storage_manager_unittest.cc index fb58ce9..db20ba9 100644 --- a/content/browser/cache_storage/cache_storage_manager_unittest.cc +++ b/content/browser/cache_storage/cache_storage_manager_unittest.cc
@@ -669,7 +669,9 @@ nullptr /* side_data_blob */, nullptr /* side_data_blob_for_cache_put */, network::mojom::ParsedHeaders::New(), - false /* loaded_with_credentials */); + net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN, + "unknown" /* alpn_negotiated_protocol */, + false /* loaded_with_credentials */, false /* was_fetched_via_spdy */); blink::mojom::BatchOperationPtr operation = blink::mojom::BatchOperation::New();
diff --git a/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc b/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc index 55296ad..8c312d7 100644 --- a/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc +++ b/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc
@@ -130,6 +130,83 @@ return proto::CacheResponse::OPAQUE_TYPE; } +// Assert that ConnectionInfo does not change since we cast it to +// an integer in order to serialize it to disk. +static_assert(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN == 0, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_HTTP1_1 == 1, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_DEPRECATED_SPDY2 == 2, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_DEPRECATED_SPDY3 == 3, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_HTTP2 == 4, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_UNKNOWN_VERSION == 5, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_DEPRECATED_HTTP2_14 == 6, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_DEPRECATED_HTTP2_15 == 7, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_HTTP0_9 == 8, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_HTTP1_0 == 9, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_32 == 10, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_33 == 11, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_34 == 12, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35 == 13, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_36 == 14, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_37 == 15, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_38 == 16, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_39 == 17, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_40 == 18, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_41 == 19, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_42 == 20, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_43 == 21, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_Q099 == 22, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_44 == 23, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_45 == 24, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_46 == 25, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_47 == 26, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_999 == 27, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_Q048 == 28, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_Q049 == 29, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_Q050 == 30, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_T048 == 31, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_T049 == 32, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_T050 == 33, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_T099 == 34, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_DRAFT_25 == 35, + "ConnectionInfo enum is stable"); +static_assert(net::HttpResponseInfo::CONNECTION_INFO_QUIC_DRAFT_27 == 36, + "ConnectionInfo enum is stable"); + // Copy headers out of a cache entry and into a protobuf. The callback is // guaranteed to be run. void ReadMetadata(disk_cache::Entry* entry, MetadataCallback callback); @@ -339,6 +416,11 @@ headers.insert(std::make_pair(header.name(), header.value())); } + std::string alpn_negotiated_protocol = + metadata.response().has_alpn_negotiated_protocol() + ? metadata.response().alpn_negotiated_protocol() + : "unknown"; + return blink::mojom::FetchAPIResponse::New( url_list, metadata.response().status_code(), metadata.response().status_text(), @@ -352,7 +434,11 @@ metadata.response().cors_exposed_header_names().end()), nullptr /* side_data_blob */, nullptr /* side_data_blob_for_cache_put */, network::mojom::ParsedHeaders::New(), - metadata.response().loaded_with_credentials()); + // Default proto value of 0 maps to CONNECTION_INFO_UNKNOWN. + static_cast<net::HttpResponseInfo::ConnectionInfo>( + metadata.response().connection_info()), + alpn_negotiated_protocol, metadata.response().loaded_with_credentials(), + metadata.response().was_fetched_via_spdy()); } // The size of opaque (non-cors) resource responses are padded in order @@ -1703,6 +1789,12 @@ response_metadata->add_url_list(url.spec()); response_metadata->set_loaded_with_credentials( put_context->response->loaded_with_credentials); + response_metadata->set_connection_info( + put_context->response->connection_info); + response_metadata->set_alpn_negotiated_protocol( + put_context->response->alpn_negotiated_protocol); + response_metadata->set_was_fetched_via_spdy( + put_context->response->was_fetched_via_spdy); response_metadata->set_response_time( put_context->response->response_time.ToInternalValue()); for (ResponseHeaderMap::const_iterator it =
diff --git a/content/browser/frame_host/cookie_utils.cc b/content/browser/frame_host/cookie_utils.cc index e951953..6896e4c 100644 --- a/content/browser/frame_host/cookie_utils.cc +++ b/content/browser/frame_host/cookie_utils.cc
@@ -129,7 +129,8 @@ breaking_context_downgrade = breaking_context_downgrade || excluded_cookie.status.HasDowngradeWarning(); - if (excluded_cookie.status.ShouldRecordDowngradeMetrics()) { + if (excluded_cookie.status.HasDowngradeWarning()) { + // Unlike with UMA, do not record cookies that have no downgrade warning. RecordContextDowngradeUKM(rfh, cookie_details->type, excluded_cookie.status, cookie_details->url); }
diff --git a/content/browser/frame_host/mixed_content_navigation_throttle.cc b/content/browser/frame_host/mixed_content_navigation_throttle.cc index f58fda0b..b647b00 100644 --- a/content/browser/frame_host/mixed_content_navigation_throttle.cc +++ b/content/browser/frame_host/mixed_content_navigation_throttle.cc
@@ -77,6 +77,8 @@ params.request_context_type = navigation_request->request_context_type(); params.request_destination = navigation_request->request_destination(); params.was_allowed = was_allowed; + DCHECK(!navigation_request->GetRedirectChain().empty()); + params.url_before_redirects = navigation_request->GetRedirectChain()[0]; params.had_redirect = for_redirect; params.source_location = *(navigation_request->common_params().source_location.get());
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index c8dcce4c..aaef0eb6 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1419,17 +1419,6 @@ } } -mojo::Remote<blink::mojom::PauseSubresourceLoadingHandle> -RenderFrameHostImpl::PauseSubresourceLoading() { - DCHECK(frame_); - mojo::Remote<blink::mojom::PauseSubresourceLoadingHandle> - pause_subresource_loading_handle; - GetRemoteInterfaces()->GetInterface( - pause_subresource_loading_handle.BindNewPipeAndPassReceiver()); - - return pause_subresource_loading_handle; -} - void RenderFrameHostImpl::ExecuteMediaPlayerActionAtLocation( const gfx::Point& location, const blink::mojom::MediaPlayerAction& action) { @@ -5578,9 +5567,10 @@ GetSiteInstance(), frame_tree_node_); } - int opener_routing_id = - frame_tree_node_->render_manager()->GetOpenerRoutingID(GetSiteInstance()); - Send(new FrameMsg_UpdateOpener(GetRoutingID(), opener_routing_id)); + auto opener_frame_token = + frame_tree_node_->render_manager()->GetOpenerFrameToken( + GetSiteInstance()); + GetAssociatedLocalFrame()->UpdateOpener(opener_frame_token); } void RenderFrameHostImpl::SetFocusedFrame() {
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index e53229b..1041444 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -344,8 +344,6 @@ bool IsFeatureEnabled(blink::mojom::DocumentPolicyFeature feature, blink::PolicyValue threshold_value) override; void ViewSource() override; - mojo::Remote<blink::mojom::PauseSubresourceLoadingHandle> - PauseSubresourceLoading() override; void ExecuteMediaPlayerActionAtLocation( const gfx::Point&, const blink::mojom::MediaPlayerAction& action) override;
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc index 3b000d6..2a94795 100644 --- a/content/browser/frame_host/render_frame_host_manager.cc +++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -3020,11 +3020,10 @@ if (!proxy) continue; - int opener_routing_id = - node->render_manager()->GetOpenerRoutingID(instance); - DCHECK_NE(opener_routing_id, MSG_ROUTING_NONE); - proxy->Send( - new FrameMsg_UpdateOpener(proxy->GetRoutingID(), opener_routing_id)); + auto opener_frame_token = + node->render_manager()->GetOpenerFrameToken(instance); + DCHECK(opener_frame_token); + proxy->GetAssociatedRemoteFrame()->UpdateOpener(opener_frame_token); } } @@ -3055,6 +3054,16 @@ ->GetRoutingIdForSiteInstance(instance); } +base::Optional<base::UnguessableToken> +RenderFrameHostManager::GetOpenerFrameToken(SiteInstance* instance) { + if (!frame_tree_node_->opener()) + return base::nullopt; + + return frame_tree_node_->opener() + ->render_manager() + ->GetFrameTokenForSiteInstance(instance); +} + void RenderFrameHostManager::SendPageMessage(IPC::Message* msg, SiteInstance* instance_to_skip) { DCHECK(IPC_MESSAGE_CLASS(*msg) == PageMsgStart);
diff --git a/content/browser/frame_host/render_frame_host_manager.h b/content/browser/frame_host/render_frame_host_manager.h index 2b96d746..2f699112c 100644 --- a/content/browser/frame_host/render_frame_host_manager.h +++ b/content/browser/frame_host/render_frame_host_manager.h
@@ -409,6 +409,15 @@ // if the opener node doesn't have a proxy for |instance|. int GetOpenerRoutingID(SiteInstance* instance); + // Returns a base::UnguessableToken for the current FrameTreeNode's opener + // node in the given SiteInstance. May return a frame token of either a + // RenderFrameHost (if opener's current or pending RFH has SiteInstance + // |instance|) or a RenderFrameProxyHost. Returns an empty frame token if + // there is no opener, or if the opener node doesn't have a proxy for + // |instance|. + base::Optional<base::UnguessableToken> GetOpenerFrameToken( + SiteInstance* instance); + // Called on the RFHM of the inner WebContents to create a // RenderFrameProxyHost in its outer WebContents's SiteInstance, // |outer_contents_site_instance|. The frame in outer WebContents that is
diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc index 3068b28..8bca3631 100644 --- a/content/browser/frame_host/render_frame_host_manager_unittest.cc +++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -2092,9 +2092,55 @@ EXPECT_FALSE(bar_rfh->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI); } +// This class intercepts RenderFrameProxyHost creations, and overrides their +// respective blink::mojom::RemoteFrame instances, so that it can watch the +// updates of opener frames. +class UpdateOpenerProxyObserver { + public: + UpdateOpenerProxyObserver() { + RenderFrameProxyHost::SetCreatedCallbackForTesting(base::BindRepeating( + &UpdateOpenerProxyObserver::RenderFrameProxyHostCreatedCallback, + base::Unretained(this))); + } + ~UpdateOpenerProxyObserver() { + RenderFrameProxyHost::SetCreatedCallbackForTesting( + RenderFrameProxyHost::CreatedCallback()); + } + base::Optional<base::UnguessableToken> OpenerFrameToken( + RenderFrameProxyHost* proxy) { + return remote_frames_[proxy]->opener_frame_token(); + } + + private: + class Remote : public content::FakeRemoteFrame { + public: + explicit Remote(RenderFrameProxyHost* proxy) { + Init(proxy->GetRemoteAssociatedInterfacesTesting()); + } + void UpdateOpener( + const base::Optional<base::UnguessableToken>& frame_token) override { + frame_token_ = frame_token; + } + base::Optional<base::UnguessableToken> opener_frame_token() { + return frame_token_; + } + + private: + base::Optional<base::UnguessableToken> frame_token_; + }; + + void RenderFrameProxyHostCreatedCallback(RenderFrameProxyHost* proxy_host) { + remote_frames_[proxy_host] = std::make_unique<Remote>(proxy_host); + } + + std::map<RenderFrameProxyHost*, std::unique_ptr<Remote>> remote_frames_; +}; + // Test that opener proxies are created properly with a cycle on the opener // chain. TEST_P(RenderFrameHostManagerTest, CreateOpenerProxiesWithCycleOnOpenerChain) { + UpdateOpenerProxyObserver proxy_observers; + const GURL kUrl1("http://www.google.com/"); const GURL kUrl2 = isolated_cross_site_url(); @@ -2138,28 +2184,26 @@ EXPECT_TRUE(tab2_proxy); // Verify that the proxies' openers point to each other. - int tab1_opener_routing_id = - tab1_manager->GetOpenerRoutingID(rfh2->GetSiteInstance()); - int tab2_opener_routing_id = - tab2_manager->GetOpenerRoutingID(rfh2->GetSiteInstance()); - EXPECT_EQ(tab2_proxy->GetRoutingID(), tab1_opener_routing_id); - EXPECT_EQ(tab1_proxy->GetRoutingID(), tab2_opener_routing_id); + auto tab1_opener_frame_token = + tab1_manager->GetOpenerFrameToken(rfh2->GetSiteInstance()); + auto tab2_opener_frame_token = + tab2_manager->GetOpenerFrameToken(rfh2->GetSiteInstance()); + EXPECT_EQ(tab2_proxy->GetFrameToken(), tab1_opener_frame_token); + EXPECT_EQ(tab1_proxy->GetFrameToken(), tab2_opener_frame_token); // Setting tab2_proxy's opener required an extra IPC message to be set, since - // the opener's routing ID wasn't available when tab2_proxy was created. - // Verify that this IPC was sent and that it passed correct routing ID. - const IPC::Message* message = - rfh2->GetProcess()->sink().GetUniqueMessageMatching( - FrameMsg_UpdateOpener::ID); - EXPECT_TRUE(message); - FrameMsg_UpdateOpener::Param params; - EXPECT_TRUE(FrameMsg_UpdateOpener::Read(message, ¶ms)); - EXPECT_EQ(tab2_opener_routing_id, std::get<0>(params)); + // the opener's frame token wasn't available when tab2_proxy was created. + // Verify that this IPC was sent and that it passed correct frame token. + base::RunLoop().RunUntilIdle(); + DCHECK(proxy_observers.OpenerFrameToken(tab2_proxy) == + tab2_manager->GetOpenerFrameToken(rfh2->GetSiteInstance())); } // Test that opener proxies are created properly when the opener points // to itself. TEST_P(RenderFrameHostManagerTest, CreateOpenerProxiesWhenOpenerPointsToSelf) { + UpdateOpenerProxyObserver proxy_observers; + const GURL kUrl1("http://www.google.com/"); const GURL kUrl2 = isolated_cross_site_url(); @@ -2190,20 +2234,16 @@ EXPECT_TRUE(opener_proxy); // Verify that the proxy's opener points to itself. - int opener_routing_id = - opener_manager->GetOpenerRoutingID(rfh2->GetSiteInstance()); - EXPECT_EQ(opener_proxy->GetRoutingID(), opener_routing_id); + auto opener_frame_token = + opener_manager->GetOpenerFrameToken(rfh2->GetSiteInstance()); + EXPECT_EQ(opener_proxy->GetFrameToken(), opener_frame_token); // Setting the opener in opener_proxy required an extra IPC message, since - // the opener's routing ID wasn't available when opener_proxy was created. - // Verify that this IPC was sent and that it passed correct routing ID. - const IPC::Message* message = - rfh2->GetProcess()->sink().GetUniqueMessageMatching( - FrameMsg_UpdateOpener::ID); - EXPECT_TRUE(message); - FrameMsg_UpdateOpener::Param params; - EXPECT_TRUE(FrameMsg_UpdateOpener::Read(message, ¶ms)); - EXPECT_EQ(opener_routing_id, std::get<0>(params)); + // the opener's frame_token wasn't available when opener_proxy was created. + // Verify that this IPC was sent and that it passed correct frame token. + base::RunLoop().RunUntilIdle(); + DCHECK(proxy_observers.OpenerFrameToken(opener_proxy) == + opener_manager->GetOpenerFrameToken(rfh2->GetSiteInstance())); } // Build the following frame opener graph and see that it can be properly
diff --git a/content/browser/frame_host/render_frame_proxy_host.cc b/content/browser/frame_host/render_frame_proxy_host.cc index b755844..bb4468f 100644 --- a/content/browser/frame_host/render_frame_proxy_host.cc +++ b/content/browser/frame_host/render_frame_proxy_host.cc
@@ -200,7 +200,6 @@ IPC_MESSAGE_HANDLER(FrameHostMsg_Detach, OnDetach) IPC_MESSAGE_HANDLER(FrameHostMsg_OpenURL, OnOpenURL) IPC_MESSAGE_HANDLER(FrameHostMsg_RouteMessageEvent, OnRouteMessageEvent) - IPC_MESSAGE_HANDLER(FrameHostMsg_AdvanceFocus, OnAdvanceFocus) IPC_MESSAGE_HANDLER(FrameHostMsg_PrintCrossProcessSubframe, OnPrintCrossProcessSubframe) IPC_MESSAGE_UNHANDLED(handled = false) @@ -376,9 +375,10 @@ GetSiteInstance(), frame_tree_node_); } - int opener_routing_id = - frame_tree_node_->render_manager()->GetOpenerRoutingID(GetSiteInstance()); - Send(new FrameMsg_UpdateOpener(GetRoutingID(), opener_routing_id)); + auto opener_frame_token = + frame_tree_node_->render_manager()->GetOpenerFrameToken( + GetSiteInstance()); + GetAssociatedRemoteFrame()->UpdateOpener(opener_frame_token); } void RenderFrameProxyHost::SetFocusedFrame() { @@ -626,33 +626,6 @@ target_origin, std::move(message)); } -void RenderFrameProxyHost::OnAdvanceFocus(blink::mojom::FocusType type, - int32_t source_routing_id) { - RenderFrameHostImpl* target_rfh = - frame_tree_node_->render_manager()->current_frame_host(); - if (target_rfh->InsidePortal()) { - bad_message::ReceivedBadMessage( - GetProcess(), bad_message::RFPH_ADVANCE_FOCUS_INTO_PORTAL); - return; - } - - // Translate the source RenderFrameHost in this process to its equivalent - // RenderFrameProxyHost in the target process. This is needed for continuing - // the focus traversal from correct place in a parent frame after one of its - // child frames finishes its traversal. - RenderFrameHostImpl* source_rfh = - RenderFrameHostImpl::FromID(GetProcess()->GetID(), source_routing_id); - RenderFrameProxyHost* source_proxy = - source_rfh ? source_rfh->frame_tree_node() - ->render_manager() - ->GetRenderFrameProxyHost(target_rfh->GetSiteInstance()) - : nullptr; - - target_rfh->AdvanceFocus(type, source_proxy); - frame_tree_node_->current_frame_host()->delegate()->OnAdvanceFocus( - source_rfh); -} - void RenderFrameProxyHost::DidFocusFrame() { RenderFrameHostImpl* render_frame_host = frame_tree_node_->current_frame_host(); @@ -686,6 +659,33 @@ opener_frame_token.value_or(base::UnguessableToken()), GetSiteInstance()); } +void RenderFrameProxyHost::AdvanceFocus( + blink::mojom::FocusType focus_type, + const base::UnguessableToken& source_frame_token) { + RenderFrameHostImpl* target_rfh = frame_tree_node_->current_frame_host(); + if (target_rfh->InsidePortal()) { + bad_message::ReceivedBadMessage( + GetProcess(), bad_message::RFPH_ADVANCE_FOCUS_INTO_PORTAL); + return; + } + + // Translate the source RenderFrameHost in this process to its equivalent + // RenderFrameProxyHost in the target process. This is needed for continuing + // the focus traversal from correct place in a parent frame after one of its + // child frames finishes its traversal. + RenderFrameHostImpl* source_rfh = RenderFrameHostImpl::FromFrameToken( + GetProcess()->GetID(), source_frame_token); + RenderFrameProxyHost* source_proxy = + source_rfh ? source_rfh->frame_tree_node() + ->render_manager() + ->GetRenderFrameProxyHost(target_rfh->GetSiteInstance()) + : nullptr; + + target_rfh->AdvanceFocus(focus_type, source_proxy); + frame_tree_node_->current_frame_host()->delegate()->OnAdvanceFocus( + source_rfh); +} + bool RenderFrameProxyHost::IsInertForTesting() { return cross_process_frame_connector_->IsInert(); }
diff --git a/content/browser/frame_host/render_frame_proxy_host.h b/content/browser/frame_host/render_frame_proxy_host.h index 8063a3f..708d418 100644 --- a/content/browser/frame_host/render_frame_proxy_host.h +++ b/content/browser/frame_host/render_frame_proxy_host.h
@@ -162,6 +162,8 @@ void SetIsInert(bool inert) override; void DidChangeOpener(const base::Optional<base::UnguessableToken>& opener_frame_token) override; + void AdvanceFocus(blink::mojom::FocusType focus_type, + const base::UnguessableToken& source_frame_token) override; // Returns associated remote for the content::mojom::RenderFrameProxy Mojo // interface. @@ -186,7 +188,6 @@ void OnDetach(); void OnOpenURL(const FrameHostMsg_OpenURL_Params& params); void OnRouteMessageEvent(const FrameMsg_PostMessage_Params& params); - void OnAdvanceFocus(blink::mojom::FocusType type, int32_t source_routing_id); void OnPrintCrossProcessSubframe(const gfx::Rect& rect, int document_cookie); // IPC::Listener
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 9a0feaad..ae8f3b6 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -1121,6 +1121,27 @@ cmd_line->AppendSwitch(service_manager::switches::kDisableGpuSandbox); cmd_line->AppendSwitchASCII(switches::kUseGL, gl::kGLImplementationDisabledName); + + // Pass the current device info to the info-collection GPU process for + // crash key logging. + const gpu::GPUInfo::GPUDevice device_info = GetGPUInfo().active_gpu(); + cmd_line->AppendSwitchASCII( + switches::kGpuVendorId, + base::StringPrintf("%u", device_info.vendor_id)); + cmd_line->AppendSwitchASCII( + switches::kGpuDeviceId, + base::StringPrintf("%u", device_info.device_id)); +#if defined(OS_WIN) + cmd_line->AppendSwitchASCII( + switches::kGpuSubSystemId, + base::StringPrintf("%u", device_info.sub_sys_id)); + cmd_line->AppendSwitchASCII(switches::kGpuRevision, + base::StringPrintf("%u", device_info.revision)); +#endif + if (device_info.driver_version.length()) { + cmd_line->AppendSwitchASCII(switches::kGpuDriverVersion, + device_info.driver_version); + } } // TODO(penghuang): Replace all GPU related switches with GpuPreferences.
diff --git a/content/browser/media/media_service.cc b/content/browser/media/media_service.cc index 2b3ebca..f1c9e2f 100644 --- a/content/browser/media/media_service.cc +++ b/content/browser/media/media_service.cc
@@ -72,7 +72,6 @@ std::move(receiver), ServiceProcessHost::Options() .WithDisplayName("Media Service") - .WithSandboxType(service_manager::SANDBOX_TYPE_UTILITY) .Pass()); remote.reset_on_idle_timeout(kIdleTimeout); #endif
diff --git a/content/browser/portal/portal_browsertest.cc b/content/browser/portal/portal_browsertest.cc index 03886cfb..a0ae89cc 100644 --- a/content/browser/portal/portal_browsertest.cc +++ b/content/browser/portal/portal_browsertest.cc
@@ -1678,9 +1678,8 @@ ->GetProxyToOuterDelegate(); RenderProcessHostBadIpcMessageWaiter rph_kill_waiter( main_frame->GetProcess()); - outer_delegate_proxy->OnMessageReceived(FrameHostMsg_AdvanceFocus( - outer_delegate_proxy->GetRoutingID(), blink::mojom::FocusType::kNone, - main_frame->GetRoutingID())); + outer_delegate_proxy->AdvanceFocus(blink::mojom::FocusType::kNone, + main_frame->frame_token()); base::Optional<bad_message::BadMessageReason> result = rph_kill_waiter.Wait(); EXPECT_TRUE(result.has_value()); EXPECT_EQ(result.value(), bad_message::RFPH_ADVANCE_FOCUS_INTO_PORTAL);
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index e753093..0124d497 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -3356,7 +3356,6 @@ switches::kTraceToConsole, switches::kUseFakeCodecForPeerConnection, switches::kUseFakeUIForMediaStream, - switches::kUseLegacyFormControls, switches::kUseMobileUserAgent, switches::kV, switches::kVideoCaptureUseGpuMemoryBuffer,
diff --git a/content/browser/speech/DEPS b/content/browser/speech/DEPS index d3ee893e..365fc46 100644 --- a/content/browser/speech/DEPS +++ b/content/browser/speech/DEPS
@@ -1,3 +1,4 @@ include_rules = [ + "+components/speech", "+google_apis", # Exception to general rule, see content/DEPS for details. ]
diff --git a/content/browser/speech/speech_recognition_engine.cc b/content/browser/speech/speech_recognition_engine.cc index e55a430..a7a6113 100644 --- a/content/browser/speech/speech_recognition_engine.cc +++ b/content/browser/speech/speech_recognition_engine.cc
@@ -23,8 +23,6 @@ #include "net/base/load_flags.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "services/network/public/cpp/shared_url_loader_factory.h" -#include "services/network/public/cpp/simple_url_loader.h" -#include "services/network/public/mojom/chunked_data_pipe_getter.mojom.h" #include "third_party/blink/public/mojom/speech/speech_recognition_error.mojom.h" #include "third_party/blink/public/mojom/speech/speech_recognition_result.mojom.h" @@ -42,9 +40,6 @@ // This matches the maximum maxAlternatives value supported by the server. const uint32_t kMaxMaxAlternatives = 30; -// Maximum amount of data written per Mojo write. -const uint32_t kMaxUploadWrite = 128 * 1024; - // TODO(hans): Remove this and other logging when we don't need it anymore. void DumpResponse(const std::string& response) { DVLOG(1) << "------------"; @@ -81,198 +76,6 @@ } // namespace -// Streams sound data up to the server. -class SpeechRecognitionEngine::UpstreamLoader - : public network::mojom::ChunkedDataPipeGetter { - public: - UpstreamLoader(std::unique_ptr<network::ResourceRequest> resource_request, - net::NetworkTrafficAnnotationTag upstream_traffic_annotation, - network::mojom::URLLoaderFactory* url_loader_factory, - SpeechRecognitionEngine* speech_recognition_engine) - : speech_recognition_engine_(speech_recognition_engine) { - // Attach a chunked upload body. - mojo::PendingRemote<network::mojom::ChunkedDataPipeGetter> data_remote; - receiver_set_.Add(this, data_remote.InitWithNewPipeAndPassReceiver()); - resource_request->request_body = new network::ResourceRequestBody(); - resource_request->request_body->SetToChunkedDataPipe( - std::move(data_remote)); - simple_url_loader_ = network::SimpleURLLoader::Create( - std::move(resource_request), upstream_traffic_annotation); - simple_url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie( - url_loader_factory, - base::BindOnce(&UpstreamLoader::OnComplete, base::Unretained(this))); - } - - ~UpstreamLoader() override = default; - - void OnComplete(std::unique_ptr<std::string> response_body) { - int response_code = -1; - if (simple_url_loader_->ResponseInfo() && - simple_url_loader_->ResponseInfo()->headers) { - response_code = - simple_url_loader_->ResponseInfo()->headers->response_code(); - } - speech_recognition_engine_->OnUpstreamDataComplete(response_body != nullptr, - response_code); - } - - void AppendChunkToUpload(const std::string& data, bool is_last_chunk) { - DCHECK(!has_last_chunk_); - - upload_body_ += data; - if (is_last_chunk) { - // Send size before the rest of the body. While it doesn't matter much, if - // the other side receives the size before the last chunk, which Mojo does - // not gaurantee, some protocols can merge the data and the last chunk - // itself into a single frame. - has_last_chunk_ = is_last_chunk; - if (get_size_callback_) - std::move(get_size_callback_).Run(net::OK, upload_body_.size()); - } - - SendData(); - } - - private: - void OnUploadPipeWriteable(MojoResult unused) { SendData(); } - - // Attempts to send more of the upload body, if more data is available, and - // |upload_pipe_| is valid. - void SendData() { - DCHECK_LE(upload_position_, upload_body_.size()); - - if (!upload_pipe_.is_valid()) - return; - - // Nothing more to write yet, or done writing everything. - if (upload_position_ == upload_body_.size()) - return; - - // Since kMaxUploadWrite is a uint32_t, no overflow occurs in this downcast. - uint32_t write_bytes = std::min(upload_body_.length() - upload_position_, - static_cast<size_t>(kMaxUploadWrite)); - MojoResult result = - upload_pipe_->WriteData(upload_body_.data() + upload_position_, - &write_bytes, MOJO_WRITE_DATA_FLAG_NONE); - - // Wait for the pipe to have more capacity available, if needed. - if (result == MOJO_RESULT_SHOULD_WAIT) { - upload_pipe_watcher_->ArmOrNotify(); - return; - } - - // Do nothing on pipe closure - depend on the SimpleURLLoader to notice the - // other pipes being closed on error. Can reach this point if there's a - // retry, for instance, so cannot draw any conclusions here. - if (result != MOJO_RESULT_OK) - return; - - upload_position_ += write_bytes; - // If more data is available, arm the watcher again. Don't write again in a - // loop, even if WriteData would allow it, to avoid blocking the current - // thread. - if (upload_position_ < upload_body_.size()) - upload_pipe_watcher_->ArmOrNotify(); - } - - // mojom::ChunkedDataPipeGetter implementation: - - void GetSize(GetSizeCallback get_size_callback) override { - if (has_last_chunk_) { - std::move(get_size_callback).Run(net::OK, upload_body_.size()); - } else { - get_size_callback_ = std::move(get_size_callback); - } - } - - void StartReading(mojo::ScopedDataPipeProducerHandle pipe) override { - // Delete any existing pipe, if any. - upload_pipe_watcher_.reset(); - upload_pipe_ = std::move(pipe); - upload_pipe_watcher_ = std::make_unique<mojo::SimpleWatcher>( - FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL); - upload_pipe_watcher_->Watch( - upload_pipe_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, - base::BindRepeating(&UpstreamLoader::OnUploadPipeWriteable, - base::Unretained(this))); - upload_position_ = 0; - - // Will attempt to start sending the request body, if any data is available. - SendData(); - } - - // Partial upload body. Have to cache the entire thing in memory, in case have - // to replay it. - std::string upload_body_; - // Current position in |upload_body_|. All bytes before this point have been - // written to |upload_pipe_|. - size_t upload_position_ = 0; - // Whether |upload_body_| is complete. - bool has_last_chunk_ = false; - - // Current pipe being used to send the |upload_body_| to the URLLoader. - mojo::ScopedDataPipeProducerHandle upload_pipe_; - // Watches |upload_pipe_| for writeability. - std::unique_ptr<mojo::SimpleWatcher> upload_pipe_watcher_; - - // If non-null, invoked once the size of the upload is known. - network::mojom::ChunkedDataPipeGetter::GetSizeCallback get_size_callback_; - - SpeechRecognitionEngine* const speech_recognition_engine_; - std::unique_ptr<network::SimpleURLLoader> simple_url_loader_; - mojo::ReceiverSet<network::mojom::ChunkedDataPipeGetter> receiver_set_; - - DISALLOW_COPY_AND_ASSIGN(UpstreamLoader); -}; - -// Streams response data from the server to the SpeechRecognitionEngine. -class SpeechRecognitionEngine::DownstreamLoader - : public network::SimpleURLLoaderStreamConsumer { - public: - DownstreamLoader(std::unique_ptr<network::ResourceRequest> resource_request, - net::NetworkTrafficAnnotationTag upstream_traffic_annotation, - network::mojom::URLLoaderFactory* url_loader_factory, - SpeechRecognitionEngine* speech_recognition_engine) - : speech_recognition_engine_(speech_recognition_engine) { - simple_url_loader_ = network::SimpleURLLoader::Create( - std::move(resource_request), upstream_traffic_annotation); - simple_url_loader_->DownloadAsStream(url_loader_factory, this); - } - - ~DownstreamLoader() override = default; - - // SimpleURLLoaderStreamConsumer implementation: - - void OnDataReceived(base::StringPiece string_piece, - base::OnceClosure resume) override { - speech_recognition_engine_->OnDownstreamDataReceived(string_piece); - std::move(resume).Run(); - } - - void OnComplete(bool success) override { - int response_code = -1; - if (simple_url_loader_->ResponseInfo() && - simple_url_loader_->ResponseInfo()->headers) { - response_code = - simple_url_loader_->ResponseInfo()->headers->response_code(); - } - - speech_recognition_engine_->OnDownstreamDataComplete(success, - response_code); - } - - void OnRetry(base::OnceClosure start_retry) override { - // Retries are not enabled for these requests. - NOTREACHED(); - } - - private: - SpeechRecognitionEngine* const speech_recognition_engine_; - std::unique_ptr<network::SimpleURLLoader> simple_url_loader_; - - DISALLOW_COPY_AND_ASSIGN(DownstreamLoader); -}; - SpeechRecognitionEngine::Config::Config() : filter_profanities(false), continuous(true), @@ -562,7 +365,7 @@ auto downstream_request = std::make_unique<network::ResourceRequest>(); downstream_request->credentials_mode = network::mojom::CredentialsMode::kOmit; downstream_request->url = downstream_url; - downstream_loader_ = std::make_unique<DownstreamLoader>( + downstream_loader_ = std::make_unique<speech::DownstreamLoader>( std::move(downstream_request), downstream_traffic_annotation, shared_url_loader_factory_.get(), this); @@ -667,7 +470,7 @@ encoder_->GetMimeType()); } - upstream_loader_ = std::make_unique<UpstreamLoader>( + upstream_loader_ = std::make_unique<speech::UpstreamLoader>( std::move(upstream_request), upstream_traffic_annotation, shared_url_loader_factory_.get(), this);
diff --git a/content/browser/speech/speech_recognition_engine.h b/content/browser/speech/speech_recognition_engine.h index 1f35012..d1e99750 100644 --- a/content/browser/speech/speech_recognition_engine.h +++ b/content/browser/speech/speech_recognition_engine.h
@@ -14,6 +14,10 @@ #include "base/memory/ref_counted.h" #include "base/sequence_checker.h" #include "base/strings/string_piece.h" +#include "components/speech/downstream_loader.h" +#include "components/speech/downstream_loader_client.h" +#include "components/speech/upstream_loader.h" +#include "components/speech/upstream_loader_client.h" #include "content/browser/speech/audio_encoder.h" #include "content/browser/speech/chunked_byte_buffer.h" #include "content/common/content_export.h" @@ -59,7 +63,9 @@ // EndRecognition. If a recognition was started, the caller can free the // SpeechRecognitionEngine only after calling EndRecognition. -class CONTENT_EXPORT SpeechRecognitionEngine { +class CONTENT_EXPORT SpeechRecognitionEngine + : public speech::UpstreamLoaderClient, + public speech::DownstreamLoaderClient { public: class Delegate { public: @@ -104,7 +110,7 @@ SpeechRecognitionEngine( scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory, const std::string& accept_language); - ~SpeechRecognitionEngine(); + ~SpeechRecognitionEngine() override; // Sets the URL requests are sent to for tests. static void set_web_service_base_url_for_tests( @@ -119,8 +125,8 @@ int GetDesiredAudioChunkDurationMs() const; private: - class UpstreamLoader; - class DownstreamLoader; + friend class speech::UpstreamLoaderClient; + friend class speech::DownstreamLoader; Delegate* delegate_; @@ -171,10 +177,12 @@ DISALLOW_COPY_AND_ASSIGN(FSMEventArgs); }; - void OnUpstreamDataComplete(bool success, int response_code); + // speech::UpstreamLoaderClient + void OnUpstreamDataComplete(bool success, int response_code) override; - void OnDownstreamDataReceived(base::StringPiece new_response_data); - void OnDownstreamDataComplete(bool success, int response_code); + // speech::DownstreamLoaderClient + void OnDownstreamDataReceived(base::StringPiece new_response_data) override; + void OnDownstreamDataComplete(bool success, int response_code) override; // Entry point for pushing any new external event into the recognizer FSM. void DispatchEvent(const FSMEventArgs& event_args); @@ -204,8 +212,8 @@ void UploadAudioChunk(const std::string& data, FrameType type, bool is_final); Config config_; - std::unique_ptr<UpstreamLoader> upstream_loader_; - std::unique_ptr<DownstreamLoader> downstream_loader_; + std::unique_ptr<speech::UpstreamLoader> upstream_loader_; + std::unique_ptr<speech::DownstreamLoader> downstream_loader_; scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_; const std::string accept_language_; std::unique_ptr<AudioEncoder> encoder_;
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 378f6d38..5a8008b 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1760,7 +1760,7 @@ } bool WebContentsImpl::NeedToFireBeforeUnloadOrUnload() { - if (!WillNotifyDisconnection()) + if (!notify_disconnection_) return false; // Don't fire if the main frame's RenderViewHost indicates that beforeunload @@ -3589,18 +3589,6 @@ focused_frame->Reload(); } -std::vector<mojo::Remote<blink::mojom::PauseSubresourceLoadingHandle>> -WebContentsImpl::PauseSubresourceLoading() { - std::vector<mojo::Remote<blink::mojom::PauseSubresourceLoadingHandle>> - handles; - for (RenderFrameHost* rfh : GetAllFrames()) { - if (!rfh->IsRenderFrameLive()) - continue; - handles.push_back(rfh->PauseSubresourceLoading()); - } - return handles; -} - void WebContentsImpl::Undo() { auto* input_handler = GetFocusedFrameInputHandler(); if (!input_handler) @@ -3942,10 +3930,6 @@ return contents_mime_type_; } -bool WebContentsImpl::WillNotifyDisconnection() { - return notify_disconnection_; -} - blink::mojom::RendererPreferences* WebContentsImpl::GetMutableRendererPrefs() { return &renderer_preferences_; }
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 333cba86..823efc87 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -429,8 +429,6 @@ void ReplaceMisspelling(const base::string16& word) override; void NotifyContextMenuClosed( const CustomContextMenuContext& context) override; - std::vector<mojo::Remote<blink::mojom::PauseSubresourceLoadingHandle>> - PauseSubresourceLoading() override; void ExecuteCustomContextMenuCommand( int action, const CustomContextMenuContext& context) override; @@ -465,10 +463,8 @@ base::OnceCallback<void(uint64_t, data_decoder::mojom::WebBundlerError)> callback) override; const std::string& GetContentsMimeType() override; - bool WillNotifyDisconnection() override; blink::mojom::RendererPreferences* GetMutableRendererPrefs() override; void Close() override; - void SystemDragEnded(RenderWidgetHost* source_rwh) override; void SetClosedByUserGesture(bool value) override; bool GetClosedByUserGesture() override; int GetMinimumZoomPercent() override; @@ -1196,6 +1192,10 @@ // Returns the focused frame's input handler. mojom::FrameInputHandler* GetFocusedFrameInputHandler(); + // A render view-originated drag has ended. Informs the render view host and + // WebContentsDelegate. + void SystemDragEnded(RenderWidgetHost* source_rwh); + private: friend class WebContentsObserver; friend class WebContents; // To implement factory methods.
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc index 26cfcad..b940450 100644 --- a/content/browser/web_contents/web_contents_impl_unittest.cc +++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -837,12 +837,12 @@ // If swapped out is forbidden, a new proxy should be created for the opener // in |instance|, and we should ensure that its routing ID is returned here. // Otherwise, we should find the pending RFH and not create a new proxy. - int opener_frame_routing_id = - popup->GetRenderManager()->GetOpenerRoutingID(instance); + auto opener_frame_token = + popup->GetRenderManager()->GetOpenerFrameToken(instance); RenderFrameProxyHost* proxy = contents()->GetRenderManager()->GetRenderFrameProxyHost(instance); EXPECT_TRUE(proxy); - EXPECT_EQ(proxy->GetRoutingID(), opener_frame_routing_id); + EXPECT_EQ(proxy->GetFrameToken(), opener_frame_token); // Ensure that committing the navigation removes the proxy. navigation->Commit();
diff --git a/content/child/child_process.cc b/content/child/child_process.cc index 04b8f40e..cbaaf5d2 100644 --- a/content/child/child_process.cc +++ b/content/child/child_process.cc
@@ -16,6 +16,7 @@ #include "base/threading/thread_local.h" #include "build/build_config.h" #include "content/child/child_thread_impl.h" +#include "content/common/android/cpu_time_metrics.h" #include "services/tracing/public/cpp/trace_startup.h" #include "third_party/blink/public/common/features.h" @@ -52,8 +53,13 @@ DCHECK(base::ThreadPoolInstance::Get()); initialized_thread_pool_ = true; } + tracing::InitTracingPostThreadPoolStartAndFeatureList(); +#if defined(OS_ANDROID) + SetupCpuTimeMetrics(); +#endif + // We can't recover from failing to start the IO thread. base::Thread::Options thread_options(base::MessagePumpType::IO, 0); thread_options.priority = io_thread_priority;
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index cdce633..dc68cc6 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -40,6 +40,8 @@ sources = [ "all_messages.h", + "android/cpu_time_metrics.cc", + "android/cpu_time_metrics.h", "android/gin_java_bridge_errors.cc", "android/gin_java_bridge_errors.h", "android/gin_java_bridge_value.cc",
diff --git a/content/common/android/cpu_time_metrics.cc b/content/common/android/cpu_time_metrics.cc new file mode 100644 index 0000000..5d8f9db --- /dev/null +++ b/content/common/android/cpu_time_metrics.cc
@@ -0,0 +1,120 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/common/android/cpu_time_metrics.h" + +#include "base/command_line.h" +#include "base/lazy_instance.h" +#include "base/message_loop/message_loop_current.h" +#include "base/metrics/histogram_macros.h" +#include "base/no_destructor.h" +#include "base/process/process_metrics.h" +#include "base/task/task_observer.h" +#include "content/public/common/content_switches.h" +#include "content/public/common/process_type.h" + +#include <memory> + +namespace content { +namespace { + +// Histogram macros expect an enum class with kMaxValue. Because +// content::ProcessType cannot be migrated to this style at the moment, we +// specify a separate version here. Keep in sync with content::ProcessType. +// TODO(eseckler): Replace with content::ProcessType after its migration. +enum class ProcessTypeForUma { + kUnknown = 1, + kBrowser, + kRenderer, + kPluginDeprecated, + kWorkerDeprecated, + kUtility, + kZygote, + kSandboxHelper, + kGpu, + kPpapiPlugin, + kPpapiBroker, + kMaxValue = kPpapiBroker, +}; + +static_assert(static_cast<int>(ProcessTypeForUma::kMaxValue) == + PROCESS_TYPE_PPAPI_BROKER, + "ProcessTypeForUma and CurrentProcessType() require updating"); + +ProcessTypeForUma CurrentProcessType() { + std::string process_type = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kProcessType); + if (process_type.empty()) + return ProcessTypeForUma::kBrowser; + if (process_type == switches::kRendererProcess) + return ProcessTypeForUma::kRenderer; + if (process_type == switches::kUtilityProcess) + return ProcessTypeForUma::kUtility; + if (process_type == switches::kSandboxIPCProcess) + return ProcessTypeForUma::kSandboxHelper; + if (process_type == switches::kGpuProcess) + return ProcessTypeForUma::kGpu; + if (process_type == switches::kPpapiPluginProcess) + return ProcessTypeForUma::kPpapiPlugin; + if (process_type == switches::kPpapiBrokerProcess) + return ProcessTypeForUma::kPpapiBroker; + NOTREACHED() << "Unexpected process type: " << process_type; + return ProcessTypeForUma::kUnknown; +} + +// Samples the process's CPU time after a specific number of task were executed +// on the current thread (process main). The number of tasks is a crude proxy +// for CPU activity within this process. We sample more frequently when the +// process is more active, thus ensuring we lose little CPU time attribution +// when the process is terminated, even after it was very active. +class ProcessCpuTimeTaskObserver : public base::TaskObserver { + public: + ProcessCpuTimeTaskObserver() + : process_metrics_(base::ProcessMetrics::CreateCurrentProcessMetrics()), + process_type_(CurrentProcessType()) {} + + void WillProcessTask(const base::PendingTask& pending_task, + bool was_blocked_or_low_priority) override {} + + void DidProcessTask(const base::PendingTask& pending_task) override { + task_counter_++; + if (task_counter_ == kReportAfterEveryNTasks) { + CollectAndReportProcessCpuTime(); + task_counter_ = 0; + } + } + + void CollectAndReportProcessCpuTime() { + // GetCumulativeCPUUsage() may return a negative value if sampling failed. + base::TimeDelta cumulative_cpu_time = + process_metrics_->GetCumulativeCPUUsage(); + base::TimeDelta cpu_time_delta = cumulative_cpu_time - reported_cpu_time_; + if (cpu_time_delta > base::TimeDelta()) { + UMA_HISTOGRAM_SCALED_ENUMERATION( + "Power.CpuTimeSecondsPerProcessType", process_type_, + cpu_time_delta.InMicroseconds(), base::Time::kMicrosecondsPerSecond); + reported_cpu_time_ = cumulative_cpu_time; + } + } + + private: + // Sample CPU time after every 100th task to balance overhead of sampling and + // loss at process termination. + static constexpr int kReportAfterEveryNTasks = 100; + + int task_counter_ = 0; + std::unique_ptr<base::ProcessMetrics> process_metrics_; + ProcessTypeForUma process_type_; + base::TimeDelta reported_cpu_time_; +}; + +} // namespace + +void SetupCpuTimeMetrics() { + static base::NoDestructor<ProcessCpuTimeTaskObserver> task_observer; + base::MessageLoopCurrent::Get()->AddTaskObserver(task_observer.get()); +} + +} // namespace content
diff --git a/content/common/android/cpu_time_metrics.h b/content/common/android/cpu_time_metrics.h new file mode 100644 index 0000000..35b3b75 --- /dev/null +++ b/content/common/android/cpu_time_metrics.h
@@ -0,0 +1,21 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_COMMON_ANDROID_CPU_TIME_METRICS_H_ +#define CONTENT_COMMON_ANDROID_CPU_TIME_METRICS_H_ + +namespace content { + +// Sets up periodic collection/reporting of the process's CPU time. Should be +// called on the process's main thread. +// +// The current process's CPU time usage is recorded periodically and reported it +// into UMA histograms. The histogram data can later be used to approximate the +// power consumption / efficiency of the app. Currently only supports Android, +// where the sandbox allows isolated processes to read from /proc/self/stats. +void SetupCpuTimeMetrics(); + +} // namespace content + +#endif // CONTENT_COMMON_ANDROID_CPU_TIME_METRICS_H_
diff --git a/content/common/background_fetch/background_fetch_types.cc b/content/common/background_fetch/background_fetch_types.cc index baa4868..e7ea923 100644 --- a/content/common/background_fetch/background_fetch_types.cc +++ b/content/common/background_fetch/background_fetch_types.cc
@@ -37,8 +37,9 @@ response->cors_exposed_header_names, CloneSerializedBlob(response->side_data_blob), CloneSerializedBlob(response->side_data_blob_for_cache_put), - mojo::Clone(response->parsed_headers), - response->loaded_with_credentials); + mojo::Clone(response->parsed_headers), response->connection_info, + response->alpn_negotiated_protocol, response->loaded_with_credentials, + response->was_fetched_via_spdy); } // static
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 15dfbab..a7ed181 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -66,7 +66,6 @@ #include "third_party/blink/public/mojom/frame/lifecycle.mojom.h" #include "third_party/blink/public/mojom/frame/tree_scope_type.mojom.h" #include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" -#include "third_party/blink/public/mojom/input/focus_type.mojom.h" #include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h" #include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom.h" #include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom.h" @@ -111,8 +110,6 @@ blink::ContextMenuDataMediaType::kLast) IPC_ENUM_TRAITS_MAX_VALUE(blink::ContextMenuDataInputFieldType, blink::ContextMenuDataInputFieldType::kMaxValue) -IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::FocusType, - blink::mojom::FocusType::kMaxValue) IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::ScrollbarMode, blink::mojom::ScrollbarMode::kMaxValue) IPC_ENUM_TRAITS_MAX_VALUE(content::StopFindAction, @@ -457,6 +454,7 @@ IPC_STRUCT_MEMBER(blink::mojom::RequestContextType, request_context_type) IPC_STRUCT_MEMBER(network::mojom::RequestDestination, request_destination) IPC_STRUCT_MEMBER(bool, was_allowed) + IPC_STRUCT_MEMBER(GURL, url_before_redirects) IPC_STRUCT_MEMBER(bool, had_redirect) IPC_STRUCT_MEMBER(network::mojom::SourceLocation, source_location) IPC_STRUCT_END() @@ -484,11 +482,6 @@ content::CustomContextMenuContext /* custom_context */, unsigned /* action */) -// Requests that the RenderFrame or RenderFrameProxy updates its opener to the -// specified frame. The routing ID may be MSG_ROUTING_NONE if the opener was -// disowned. -IPC_MESSAGE_ROUTED1(FrameMsg_UpdateOpener, int /* opener_routing_id */) - // Requests that the RenderFrame send back a response after waiting for the // commit, activation and frame swap of the current DOM tree in blink. IPC_MESSAGE_ROUTED1(FrameMsg_VisualStateRequest, uint64_t /* id */) @@ -795,15 +788,6 @@ std::string /* data buffer */, bool /* end of data? */) -// This message is sent from a RenderFrameProxy when sequential focus -// navigation needs to advance into its actual frame. |source_routing_id| -// identifies the frame that issued this request. This is used when pressing -// <tab> or <shift-tab> hits an out-of-process iframe when searching for the -// next focusable element. -IPC_MESSAGE_ROUTED2(FrameHostMsg_AdvanceFocus, - blink::mojom::FocusType /* type */, - int32_t /* source_routing_id */) - // A message from HTML-based UI. When (trusted) Javascript calls // send(message, args), this message is sent to the browser. IPC_MESSAGE_ROUTED2(FrameHostMsg_WebUISend,
diff --git a/content/common/service_worker/service_worker_loader_helpers.cc b/content/common/service_worker/service_worker_loader_helpers.cc index 8f2ac0a..e1192265 100644 --- a/content/common/service_worker/service_worker_loader_helpers.cc +++ b/content/common/service_worker/service_worker_loader_helpers.cc
@@ -107,6 +107,9 @@ out_head->cors_exposed_header_names = response.cors_exposed_header_names; out_head->did_service_worker_navigation_preload = false; out_head->parsed_headers = mojo::Clone(response.parsed_headers); + out_head->connection_info = response.connection_info; + out_head->alpn_negotiated_protocol = response.alpn_negotiated_protocol; + out_head->was_fetched_via_spdy = response.was_fetched_via_spdy; } // static
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index fedef32..961b0f0 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -571,7 +571,10 @@ "//content/public/test/android:content_java_test_support", "//media/mojo/mojom:mojom_java", "//mojo/public/java:bindings_java", + "//mojo/public/mojom/base:base_java", + "//third_party/android_deps:androidx_test_core_java", "//third_party/blink/public/mojom:android_mojo_bindings_java", + "//third_party/hamcrest:hamcrest_java", "//ui/android:ui_java", "//ui/gfx/geometry/mojom:mojom_java", ]
diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h index 94ba0f61..a5769d6a 100644 --- a/content/public/browser/render_frame_host.h +++ b/content/public/browser/render_frame_host.h
@@ -430,13 +430,6 @@ // RenderFrameHost. virtual void ViewSource() = 0; - // Starts pausing subresource loading on this frame and returns - // PauseSubresourceLoadingHandle that controls the pausing behavior. As long - // as this handle is live, pausing will continue until an internal - // navigation happens in the frame. - virtual mojo::Remote<blink::mojom::PauseSubresourceLoadingHandle> - PauseSubresourceLoading() = 0; - // Run the given action on the media player location at the given point. virtual void ExecuteMediaPlayerActionAtLocation( const gfx::Point& location,
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h index 53b2215..5677c0c 100644 --- a/content/public/browser/web_contents.h +++ b/content/public/browser/web_contents.h
@@ -82,7 +82,6 @@ class BrowserPluginGuestDelegate; class RenderFrameHost; class RenderViewHost; -class RenderWidgetHost; class RenderWidgetHostView; class WebContentsDelegate; class WebUI; @@ -684,13 +683,6 @@ // Reloads the focused frame. virtual void ReloadFocusedFrame() = 0; - // Attains PauseSubresourceLoadingHandles for each frame in the web contents. - // As long as these handles are not deleted, subresources will continue to be - // deferred until an internal navigation happens in the frame. Holding handles - // for deleted or re-navigated frames has no effect. - virtual std::vector<mojo::Remote<blink::mojom::PauseSubresourceLoadingHandle>> - PauseSubresourceLoading() = 0; - // Editing commands ---------------------------------------------------------- virtual void Undo() = 0; @@ -827,9 +819,6 @@ // Returns the contents MIME type after a navigation. virtual const std::string& GetContentsMimeType() = 0; - // Returns true if this WebContents will notify about disconnection. - virtual bool WillNotifyDisconnection() = 0; - // Returns the settings which get passed to the renderer. virtual blink::mojom::RendererPreferences* GetMutableRendererPrefs() = 0; @@ -837,10 +826,6 @@ // out of nested run loops. virtual void Close() = 0; - // A render view-originated drag has ended. Informs the render view host and - // WebContentsDelegate. - virtual void SystemDragEnded(RenderWidgetHost* source_rwh) = 0; - // Indicates if this tab was explicitly closed by the user (control-w, close // tab menu item...). This is false for actions that indirectly close the tab, // such as closing the window. The setter is maintained by TabStripModel, and
diff --git a/content/public/common/content_switch_dependent_feature_overrides.cc b/content/public/common/content_switch_dependent_feature_overrides.cc index c3f1d16..7f92bb46 100644 --- a/content/public/common/content_switch_dependent_feature_overrides.cc +++ b/content/public/common/content_switch_dependent_feature_overrides.cc
@@ -9,7 +9,6 @@ #include "net/base/features.h" #include "services/network/public/cpp/features.h" #include "third_party/blink/public/common/features.h" -#include "ui/base/ui_base_features.h" namespace content { @@ -57,11 +56,6 @@ std::cref(features::kOriginIsolationHeader), base::FeatureList::OVERRIDE_ENABLE_FEATURE}, - // Overrides for --use-legacy-form-controls. - {switches::kUseLegacyFormControls, - std::cref(features::kFormControlsRefresh), - base::FeatureList::OVERRIDE_DISABLE_FEATURE}, - // Overrides for --enable-experimental-cookie-features. {switches::kEnableExperimentalCookieFeatures, std::cref(features::kCookieDeprecationMessages),
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index f005975..e24f681 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -967,11 +967,6 @@ const char kWebXrRuntimeOpenXr[] = "openxr"; const char kWebXrRuntimeWMR[] = "windows-mixed-reality"; -// This switch allows the FormControlsRefresh feature to be disabled temporarily -// from M81 through M84. -// TODO(1034611): Remove this after M84. -const char kUseLegacyFormControls[] = "use-legacy-form-controls"; - // This switch disables the ScrollToTextFragment feature. const char kDisableScrollToTextFragment[] = "disable-scroll-to-text-fragment";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index cc57a77..bf31ae0 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -258,7 +258,6 @@ extern const char kWebRtcMaxCpuConsumptionPercentage[]; CONTENT_EXPORT extern const char kWebRtcStunProbeTrialParameter[]; CONTENT_EXPORT extern const char kWebRtcLocalEventLogging[]; -CONTENT_EXPORT extern const char kUseLegacyFormControls[]; CONTENT_EXPORT extern const char kDisableScrollToTextFragment[]; CONTENT_EXPORT extern const char kWebXrForceRuntime[];
diff --git a/content/public/test/fake_local_frame.cc b/content/public/test/fake_local_frame.cc index ffca2c92..fa42b84e5 100644 --- a/content/public/test/fake_local_frame.cc +++ b/content/public/test/fake_local_frame.cc
@@ -107,6 +107,9 @@ void FakeLocalFrame::BindReportingObserver( mojo::PendingReceiver<blink::mojom::ReportingObserver> receiver) {} +void FakeLocalFrame::UpdateOpener( + const base::Optional<base::UnguessableToken>& opener_frame_token) {} + void FakeLocalFrame::BindFrameHostReceiver( mojo::ScopedInterfaceEndpointHandle handle) { receiver_.Bind(mojo::PendingAssociatedReceiver<blink::mojom::LocalFrame>(
diff --git a/content/public/test/fake_local_frame.h b/content/public/test/fake_local_frame.h index dd64f00..bdf0297 100644 --- a/content/public/test/fake_local_frame.h +++ b/content/public/test/fake_local_frame.h
@@ -85,6 +85,8 @@ #endif void BindReportingObserver( mojo::PendingReceiver<blink::mojom::ReportingObserver> receiver) override; + void UpdateOpener(const base::Optional<base::UnguessableToken>& + opener_frame_token) override; private: void BindFrameHostReceiver(mojo::ScopedInterfaceEndpointHandle handle);
diff --git a/content/public/test/fake_remote_frame.cc b/content/public/test/fake_remote_frame.cc index 0e51675..42958de 100644 --- a/content/public/test/fake_remote_frame.cc +++ b/content/public/test/fake_remote_frame.cc
@@ -80,6 +80,9 @@ void FakeRemoteFrame::IntrinsicSizingInfoOfChildChanged( blink::mojom::IntrinsicSizingInfoPtr sizing_info) {} +void FakeRemoteFrame::UpdateOpener( + const base::Optional<base::UnguessableToken>& opener_frame_token) {} + void FakeRemoteFrame::FakeRemoteFrame::BindFrameHostReceiver( mojo::ScopedInterfaceEndpointHandle handle) { receiver_.Bind(mojo::PendingAssociatedReceiver<blink::mojom::RemoteFrame>(
diff --git a/content/public/test/fake_remote_frame.h b/content/public/test/fake_remote_frame.h index 44b0cdf..e89a20d 100644 --- a/content/public/test/fake_remote_frame.h +++ b/content/public/test/fake_remote_frame.h
@@ -81,6 +81,8 @@ const std::vector<blink::ParsedFeaturePolicyDeclaration>& parsed_feature_policy) override {} void DidUpdateFramePolicy(const blink::FramePolicy& frame_policy) override {} + void UpdateOpener(const base::Optional<base::UnguessableToken>& + opener_frame_token) override; private: void BindFrameHostReceiver(mojo::ScopedInterfaceEndpointHandle handle);
diff --git a/content/renderer/media/android/media_player_renderer_client.cc b/content/renderer/media/android/media_player_renderer_client.cc index bf79b30..c567550 100644 --- a/content/renderer/media/android/media_player_renderer_client.cc +++ b/content/renderer/media/android/media_player_renderer_client.cc
@@ -55,17 +55,13 @@ client_ = client; init_cb_ = std::move(init_cb); - // Initialize the StreamTexture using a 1x1 texture because we do not have - // any size information from the MediaPlayer yet. - // The size will be automatically updated in OnVideoNaturalSizeChange() once - // we parse the media's metadata. // Unretained is safe here because |stream_texture_wrapper_| resets the // Closure it has before destroying itself on |compositor_task_runner_|, // and |this| is garanteed to live until the Closure has been reset. stream_texture_wrapper_->Initialize( base::BindRepeating(&MediaPlayerRendererClient::OnFrameAvailable, base::Unretained(this)), - gfx::Size(1, 1), compositor_task_runner_, + compositor_task_runner_, base::BindOnce( &MediaPlayerRendererClient::OnStreamTextureWrapperInitialized, weak_factory_.GetWeakPtr(), media_resource));
diff --git a/content/renderer/media/android/stream_texture_wrapper_impl.cc b/content/renderer/media/android/stream_texture_wrapper_impl.cc index 7bd4fa9..a02c70a 100644 --- a/content/renderer/media/android/stream_texture_wrapper_impl.cc +++ b/content/renderer/media/android/stream_texture_wrapper_impl.cc
@@ -126,13 +126,11 @@ void StreamTextureWrapperImpl::Initialize( const base::RepeatingClosure& received_frame_cb, - const gfx::Size& rotated_visible_size, scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner, StreamTextureWrapperInitCB init_cb) { DVLOG(2) << __func__; compositor_task_runner_ = compositor_task_runner; - rotated_visible_size_ = rotated_visible_size; main_task_runner_->PostTask( FROM_HERE, @@ -160,8 +158,6 @@ return; } - stream_texture_proxy_->UpdateRotatedVisibleSize(rotated_visible_size_); - // Unretained is safe here since |stream_texture_proxy_| is a scoped member of // the this StreamTextureWrapperImpl class which clears/resets this callback // before |this| is destroyed.
diff --git a/content/renderer/media/android/stream_texture_wrapper_impl.h b/content/renderer/media/android/stream_texture_wrapper_impl.h index 98b63d0..87735ab 100644 --- a/content/renderer/media/android/stream_texture_wrapper_impl.h +++ b/content/renderer/media/android/stream_texture_wrapper_impl.h
@@ -63,7 +63,6 @@ // DidReceiveFrame() method. void Initialize( const base::RepeatingClosure& received_frame_cb, - const gfx::Size& rotated_visible_size, scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner, StreamTextureWrapperInitCB init_cb) override;
diff --git a/content/renderer/media/android/stream_texture_wrapper_impl_unittest.cc b/content/renderer/media/android/stream_texture_wrapper_impl_unittest.cc index c3d7b32c..398974fd 100644 --- a/content/renderer/media/android/stream_texture_wrapper_impl_unittest.cc +++ b/content/renderer/media/android/stream_texture_wrapper_impl_unittest.cc
@@ -35,7 +35,7 @@ // we try to initialize it. int result = 0; stream_texture_wrapper->Initialize( - base::DoNothing(), gfx::Size(0, 0), + base::DoNothing(), blink::scheduler::GetSingleThreadTaskRunnerForTesting(), base::BindOnce( [](int* result_out, bool result) { *result_out = result ? 1 : 2; },
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 3ae145d..02afc49 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -2191,7 +2191,6 @@ IPC_MESSAGE_HANDLER(FrameMsg_VisualStateRequest, OnVisualStateRequest) IPC_MESSAGE_HANDLER(FrameMsg_Reload, OnReload) - IPC_MESSAGE_HANDLER(FrameMsg_UpdateOpener, OnUpdateOpener) IPC_MESSAGE_HANDLER(FrameMsg_GetSavableResourceLinks, OnGetSavableResourceLinks) IPC_MESSAGE_HANDLER(FrameMsg_GetSerializedHtmlWithLocalLinks, @@ -2678,11 +2677,6 @@ } #endif // defined(OS_ANDROID) -void RenderFrameImpl::OnUpdateOpener(int opener_routing_id) { - WebFrame* opener = ResolveWebFrame(opener_routing_id); - frame_->SetOpener(opener); -} - void RenderFrameImpl::OnReload() { frame_->StartReload(WebFrameLoadType::kReload); } @@ -5781,7 +5775,8 @@ params.request_context_type); frame_->MixedContentFound(params.main_resource_url, params.mixed_content_url, request_context, params.was_allowed, - params.had_redirect, source_location); + params.url_before_redirects, params.had_redirect, + source_location); } void RenderFrameImpl::RequestOverlayRoutingToken(
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index e884349..392a1969 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -1038,7 +1038,6 @@ void OnVisualStateRequest(uint64_t key); // TODO(https://crbug.com/995428): Deprecated. void OnReload(); - void OnUpdateOpener(int opener_routing_id); void OnGetSavableResourceLinks(); void OnGetSerializedHtmlWithLocalLinks( const std::map<GURL, base::FilePath>& url_to_local_path,
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index 3afac3e6..1cd7178 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc
@@ -387,7 +387,6 @@ bool handled = true; IPC_BEGIN_MESSAGE_MAP(RenderFrameProxy, msg) - IPC_MESSAGE_HANDLER(FrameMsg_UpdateOpener, OnUpdateOpener) IPC_MESSAGE_HANDLER(FrameMsg_DidUpdateName, OnDidUpdateName) IPC_MESSAGE_HANDLER(FrameMsg_TransferUserActivationFrom, OnTransferUserActivationFrom) @@ -426,11 +425,6 @@ screen_info().device_scale_factor); } -void RenderFrameProxy::OnUpdateOpener(int opener_routing_id) { - blink::WebFrame* opener = RenderFrameImpl::ResolveWebFrame(opener_routing_id); - web_frame_->SetOpener(opener); -} - void RenderFrameProxy::DidStartLoading() { web_frame_->DidStartLoading(); } @@ -716,12 +710,6 @@ intersection_state)); } -void RenderFrameProxy::AdvanceFocus(blink::mojom::FocusType type, - blink::WebLocalFrame* source) { - int source_routing_id = RenderFrameImpl::FromWebFrame(source)->GetRoutingID(); - Send(new FrameHostMsg_AdvanceFocus(routing_id_, type, source_routing_id)); -} - base::UnguessableToken RenderFrameProxy::GetDevToolsFrameToken() { return devtools_frame_token_; }
diff --git a/content/renderer/render_frame_proxy.h b/content/renderer/render_frame_proxy.h index 2849a24..c7dcebd 100644 --- a/content/renderer/render_frame_proxy.h +++ b/content/renderer/render_frame_proxy.h
@@ -195,8 +195,6 @@ const blink::WebRect& screen_space_rect) override; void UpdateRemoteViewportIntersection( const blink::ViewportIntersectionState& intersection_state) override; - void AdvanceFocus(blink::mojom::FocusType type, - blink::WebLocalFrame* source) override; base::UnguessableToken GetDevToolsFrameToken() override; uint32_t Print(const blink::WebRect& rect, cc::PaintCanvas* canvas) override; @@ -227,7 +225,6 @@ // IPC handlers void OnDeleteProxy(); void OnCompositorFrameSwapped(const IPC::Message& message); - void OnUpdateOpener(int opener_routing_id); void OnDidUpdateName(const std::string& name, const std::string& unique_name); void OnEnforceInsecureRequestPolicy( blink::mojom::InsecureRequestPolicy policy);
diff --git a/content/shell/android/BUILD.gn b/content/shell/android/BUILD.gn index ab9633d6..3902a89 100644 --- a/content/shell/android/BUILD.gn +++ b/content/shell/android/BUILD.gn
@@ -248,6 +248,7 @@ "//mojo/public/java/system:test_support_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", + "//third_party/hamcrest:hamcrest_java", "//third_party/junit:junit", "//ui/android:ui_java", ]
diff --git a/content/test/data/media/getusermedia.html b/content/test/data/media/getusermedia.html index 093f051..9ae5ef4 100644 --- a/content/test/data/media/getusermedia.html +++ b/content/test/data/media/getusermedia.html
@@ -6,6 +6,18 @@ return document.getElementById(id); }; + // The modal permission dialog requires a user gesture to trigger. + // Hook up a click event listener to run a specified method (which + // may be changed by the test). + var functionToRun; + function runFunctionOnClick() { + eval(functionToRun); + } + + window.addEventListener('load', () => { + window.addEventListener('click', runFunctionOnClick); + }); + function getSources() { navigator.mediaDevices.enumerateDevices().then(function(devices) { document.title = 'Media devices available'; @@ -31,13 +43,17 @@ JSON.stringify(constraints)); navigator.mediaDevices.getUserMedia(constraints) .then(stream => { + window.document.title = 'Granted:1'; detectVideoInLocalView1(stream).then(() => { stream.getVideoTracks()[0].stop(); detectVideoStopped('local-view-1') .then(reportTestSuccess); }); }) - .catch(failTest); + .catch(() => { + window.document.title = 'Denied:1'; + failTest(); + }); } // Requests getusermedia and expects it to succeed.
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt index 05b37e11..58e3fe1 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -296,7 +296,7 @@ #################### crbug.com/angleproject/4242 [ mac ] conformance2/glsl3/matrix-row-major-dynamic-indexing.html [ Failure ] -crbug.com/angleproject/4417 [ mac intel no-passthrough ] conformance2/rendering/framebuffer-render-to-layer.html [ Failure ] +crbug.com/angleproject/4417 [ mac no-passthrough ] conformance2/rendering/framebuffer-render-to-layer.html [ Failure ] # Flakes heavily on many OpenGL configurations crbug.com/832238 [ mac no-angle ] conformance2/transform_feedback/too-small-buffers.html [ Failure ] @@ -725,6 +725,7 @@ crbug.com/696345 [ no-angle linux amd-0x6613 ] conformance2/transform_feedback/switching-objects.html [ Failure ] crbug.com/913301 [ linux amd-0x6613 ] conformance2/textures/misc/generate-mipmap-with-large-base-level.html [ Failure ] crbug.com/809237 [ linux amd-0x6613 ] conformance2/uniforms/incompatible-texture-type-for-sampler.html [ Skip ] +crbug.com/1018028 [ linux amd-0x6613 ] conformance/rendering/bind-framebuffer-flush-bug.html [ Failure ] #################### # Android failures #
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt index 8488bcf9..78173c2 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -520,6 +520,10 @@ crbug.com/611945 [ qualcomm-adreno-(tm)-430 android ] conformance/glsl/bugs/sampler-struct-function-arg.html [ Failure ] crbug.com/951628 [ android qualcomm-adreno-(tm)-420 no-passthrough ] conformance/rendering/blending.html [ Failure ] crbug.com/1002997 [ android qualcomm-adreno-(tm)-430 no-passthrough ] conformance/rendering/blending.html [ Failure ] +crbug.com/1083320 [ android qualcomm-adreno-(tm)-420 ] conformance/misc/uninitialized-test.html [ Skip ] +crbug.com/1056830 [ android qualcomm-adreno-(tm)-420 ] conformance/extensions/webgl-compressed-texture-astc.html [ Failure ] +crbug.com/1083320 [ android qualcomm-adreno-(tm)-430 ] conformance/misc/uninitialized-test.html [ Skip ] +crbug.com/1056830 [ android qualcomm-adreno-(tm)-430 ] conformance/extensions/webgl-compressed-texture-astc.html [ Failure ] # This test is skipped because running it causes a future test to fail. # The list of tests which may be that future test is very long. It is
diff --git a/content/test/test_web_contents.cc b/content/test/test_web_contents.cc index e0ea97b..59be9fb 100644 --- a/content/test/test_web_contents.cc +++ b/content/test/test_web_contents.cc
@@ -425,13 +425,6 @@ suggested_filename_ = suggested_filename; } -std::vector<mojo::Remote<blink::mojom::PauseSubresourceLoadingHandle>> -TestWebContents::PauseSubresourceLoading() { - pause_subresource_loading_called_ = true; - return std::vector< - mojo::Remote<blink::mojom::PauseSubresourceLoadingHandle>>(); -} - bool TestWebContents::GetPauseSubresourceLoadingCalled() { return pause_subresource_loading_called_; }
diff --git a/content/test/test_web_contents.h b/content/test/test_web_contents.h index 603ad208..0d4fd05 100644 --- a/content/test/test_web_contents.h +++ b/content/test/test_web_contents.h
@@ -151,10 +151,6 @@ void SetHistoryOffsetAndLength(int history_offset, int history_length) override; - // Records that this was called and returns and empty vector. - std::vector<mojo::Remote<blink::mojom::PauseSubresourceLoadingHandle>> - PauseSubresourceLoading() override; - bool GetPauseSubresourceLoadingCalled() override; void ResetPauseSubresourceLoadingCalled() override;
diff --git a/device/fido/cable/fido_ble_connection.cc b/device/fido/cable/fido_ble_connection.cc index 0abe9d9d..6b94db1 100644 --- a/device/fido/cable/fido_ble_connection.cc +++ b/device/fido/cable/fido_ble_connection.cc
@@ -253,22 +253,20 @@ return; } -#if defined(OS_MACOSX) // Attempt a write without response for performance reasons. Fall back to a - // confirmed write in case of failure, e.g. when the characteristic does not - // provide the required property. - if (control_point->WriteWithoutResponse(data)) { - FIDO_LOG(DEBUG) << "Write without response succeeded."; - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), true)); - return; - } -#endif // defined(OS_MACOSX) + // confirmed write when the characteristic does not provide the required + // property. + BluetoothRemoteGattCharacteristic::WriteType write_type = + (control_point->GetProperties() & + BluetoothRemoteGattCharacteristic::PROPERTY_WRITE_WITHOUT_RESPONSE) + ? BluetoothRemoteGattCharacteristic::WriteType::kWithoutResponse + : BluetoothRemoteGattCharacteristic::WriteType::kWithResponse; FIDO_LOG(DEBUG) << "Wrote Control Point."; auto copyable_callback = base::AdaptCallbackForRepeating(std::move(callback)); - control_point->DeprecatedWriteRemoteCharacteristic( - data, base::BindOnce(OnWriteRemoteCharacteristic, copyable_callback), + control_point->WriteRemoteCharacteristic( + data, write_type, + base::BindOnce(OnWriteRemoteCharacteristic, copyable_callback), base::BindOnce(OnWriteRemoteCharacteristicError, copyable_callback)); } @@ -416,8 +414,9 @@ auto copyable_callback = base::AdaptCallbackForRepeating(std::move(callback)); DCHECK(service_revision_bitfield_id_); fido_service->GetCharacteristic(*service_revision_bitfield_id_) - ->DeprecatedWriteRemoteCharacteristic( + ->WriteRemoteCharacteristic( {static_cast<uint8_t>(service_revision)}, + BluetoothRemoteGattCharacteristic::WriteType::kWithResponse, base::BindOnce(OnWriteRemoteCharacteristic, copyable_callback), base::BindOnce(OnWriteRemoteCharacteristicError, copyable_callback)); }
diff --git a/device/fido/cable/fido_ble_connection_unittest.cc b/device/fido/cable/fido_ble_connection_unittest.cc index 37811ee..49f25b9 100644 --- a/device/fido/cable/fido_ble_connection_unittest.cc +++ b/device/fido/cable/fido_ble_connection_unittest.cc
@@ -165,10 +165,10 @@ {kDefaultServiceRevision}))); })); - ON_CALL(*fido_service_revision_bitfield_, - DeprecatedWriteRemoteCharacteristic_) + ON_CALL(*fido_service_revision_bitfield_, WriteRemoteCharacteristic_) .WillByDefault(Invoke( - [=](auto&, base::OnceClosure& callback, + [=](auto&, BluetoothRemoteGattCharacteristic::WriteType, + base::OnceClosure& callback, const BluetoothRemoteGattCharacteristic::ErrorCallback&) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, std::move(callback)); @@ -284,20 +284,15 @@ } void SetNextWriteControlPointResponse(bool success) { -// For performance reasons we try writes without responses first on macOS. -#if defined(OS_MACOSX) - EXPECT_CALL(*fido_control_point_, WriteWithoutResponse) - .WillOnce(Return(success)); - if (success) - return; -#else - EXPECT_CALL(*fido_control_point_, WriteWithoutResponse).Times(0); -#endif // defined(OS_MACOSX) - - EXPECT_CALL(*fido_control_point_, - DeprecatedWriteRemoteCharacteristic_(_, _, _)) + EXPECT_CALL( + *fido_control_point_, + WriteRemoteCharacteristic_( + _, BluetoothRemoteGattCharacteristic::WriteType::kWithoutResponse, + _, _)) .WillOnce(Invoke([success]( - const auto& data, base::OnceClosure& callback, + const auto& data, + BluetoothRemoteGattCharacteristic::WriteType, + base::OnceClosure& callback, BluetoothRemoteGattCharacteristic::ErrorCallback& error_callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( @@ -311,10 +306,15 @@ void SetNextWriteServiceRevisionResponse(std::vector<uint8_t> expected_data, bool success) { - EXPECT_CALL(*fido_service_revision_bitfield_, - DeprecatedWriteRemoteCharacteristic_(expected_data, _, _)) + EXPECT_CALL( + *fido_service_revision_bitfield_, + WriteRemoteCharacteristic_( + expected_data, + BluetoothRemoteGattCharacteristic::WriteType::kWithResponse, _, _)) .WillOnce(Invoke([success]( - const auto& data, base::OnceClosure& callback, + const auto& data, + BluetoothRemoteGattCharacteristic::WriteType, + base::OnceClosure& callback, BluetoothRemoteGattCharacteristic::ErrorCallback& error_callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( @@ -339,7 +339,7 @@ std::make_unique<NiceMockBluetoothGattCharacteristic>( fido_service_, "fido_control_point", BluetoothUUID(kFidoControlPointUUID), kIsLocal, - BluetoothGattCharacteristic::PROPERTY_WRITE, + BluetoothGattCharacteristic::PROPERTY_WRITE_WITHOUT_RESPONSE, BluetoothGattCharacteristic::PERMISSION_NONE); fido_control_point_ = fido_control_point.get(); fido_service_->AddMockCharacteristic(std::move(fido_control_point));
diff --git a/device/fido/fido_request_handler_base.cc b/device/fido/fido_request_handler_base.cc index 32106956..896cecd 100644 --- a/device/fido/fido_request_handler_base.cc +++ b/device/fido/fido_request_handler_base.cc
@@ -166,11 +166,7 @@ void FidoRequestHandlerBase::StartAuthenticatorRequest( const std::string& authenticator_id) { - auto authenticator_it = active_authenticators_.find(authenticator_id); - if (authenticator_it == active_authenticators_.end()) - return; - - InitializeAuthenticatorAndDispatchRequest(authenticator_it->second.get()); + InitializeAuthenticatorAndDispatchRequest(authenticator_id); } void FidoRequestHandlerBase::CancelActiveAuthenticators( @@ -279,13 +275,17 @@ void FidoRequestHandlerBase::AuthenticatorAdded( FidoDiscoveryBase* discovery, FidoAuthenticator* authenticator) { - DCHECK(authenticator && - !base::Contains(active_authenticators(), authenticator->GetId())); - auto authenticator_state = - std::make_unique<AuthenticatorState>(authenticator); - auto* weak_authenticator_state = authenticator_state.get(); - active_authenticators_.emplace(authenticator->GetId(), - std::move(authenticator_state)); + DCHECK(!authenticator->GetId().empty()); + bool was_inserted; + std::tie(std::ignore, was_inserted) = active_authenticators_.insert( + {authenticator->GetId(), + std::make_unique<AuthenticatorState>(authenticator)}); + if (!was_inserted) { + NOTREACHED(); + FIDO_LOG(ERROR) << "Authenticator with duplicate ID " + << authenticator->GetId(); + return; + } // If |observer_| exists, dispatching request to |authenticator| is // delegated to |observer_|. Else, dispatch request to |authenticator| @@ -307,7 +307,7 @@ FROM_HERE, base::BindOnce( &FidoRequestHandlerBase::InitializeAuthenticatorAndDispatchRequest, - GetWeakPtr(), weak_authenticator_state)); + GetWeakPtr(), authenticator->GetId())); } else { VLOG(2) << "Embedder controls the dispatch."; } @@ -336,7 +336,12 @@ } void FidoRequestHandlerBase::InitializeAuthenticatorAndDispatchRequest( - AuthenticatorState* authenticator_state) { + const std::string& authenticator_id) { + auto authenticator_it = active_authenticators_.find(authenticator_id); + if (authenticator_it == active_authenticators_.end()) { + return; + } + AuthenticatorState* authenticator_state = authenticator_it->second.get(); authenticator_state->timer = std::make_unique<base::ElapsedTimer>(); authenticator_state->authenticator->InitializeAuthenticator(base::BindOnce( &FidoRequestHandlerBase::DispatchRequest, weak_factory_.GetWeakPtr(),
diff --git a/device/fido/fido_request_handler_base.h b/device/fido/fido_request_handler_base.h index 9b11535..55b06436 100644 --- a/device/fido/fido_request_handler_base.h +++ b/device/fido/fido_request_handler_base.h
@@ -289,7 +289,7 @@ // to FidoDeviceAuthenticator instances in order to determine their protocol // versions before a request can be dispatched. void InitializeAuthenticatorAndDispatchRequest( - AuthenticatorState* authenticator_state); + const std::string& authenticator_id); void ConstructBleAdapterPowerManager(); AuthenticatorMap active_authenticators_;
diff --git a/device/fido/virtual_fido_device.cc b/device/fido/virtual_fido_device.cc index 4596d26..ef4b6a54 100644 --- a/device/fido/virtual_fido_device.cc +++ b/device/fido/virtual_fido_device.cc
@@ -9,6 +9,7 @@ #include <utility> #include "base/bind.h" +#include "base/rand_util.h" #include "components/cbor/values.h" #include "components/cbor/writer.h" #include "crypto/ec_private_key.h" @@ -384,9 +385,10 @@ /*icon_url=*/base::nullopt)); } +// VirtualFidoDevice ---------------------------------------------------------- + VirtualFidoDevice::VirtualFidoDevice() = default; -// VirtualFidoDevice ---------------------------------------------------------- VirtualFidoDevice::VirtualFidoDevice(scoped_refptr<State> state) : state_(std::move(state)) {} @@ -515,12 +517,16 @@ } std::string VirtualFidoDevice::GetId() const { - // Use our heap address to get a unique-ish number. (0xffe1 is a prime). - return "VirtualFidoDevice-" + std::to_string((size_t)this % 0xffe1); + return id_; } FidoTransportProtocol VirtualFidoDevice::DeviceTransport() const { return state_->transport; } +// static +std::string VirtualFidoDevice::MakeVirtualFidoDeviceId() { + return "VirtualFidoDevice-" + base::RandBytesAsString(32); +} + } // namespace device
diff --git a/device/fido/virtual_fido_device.h b/device/fido/virtual_fido_device.h index 1aba4ff..045dd37 100644 --- a/device/fido/virtual_fido_device.h +++ b/device/fido/virtual_fido_device.h
@@ -297,6 +297,9 @@ FidoTransportProtocol DeviceTransport() const override; private: + static std::string MakeVirtualFidoDeviceId(); + + const std::string id_ = MakeVirtualFidoDeviceId(); scoped_refptr<State> state_ = base::MakeRefCounted<State>(); DISALLOW_COPY_AND_ASSIGN(VirtualFidoDevice);
diff --git a/docs/security/compromised-renderers.md b/docs/security/compromised-renderers.md index 6733e138..8114b6c 100644 --- a/docs/security/compromised-renderers.md +++ b/docs/security/compromised-renderers.md
@@ -245,9 +245,13 @@ used by scripts executed in cross-site execution contexts. Protection techniques: -- Partitioning the code cache by Network Isolation Key (NIK). -- Using `CanAccessDataForOrigin` in +- Validating origins sent in IPCs from a renderer process by using + `CanAccessDataForOrigin` in `CodeCacheHostImpl::DidGenerateCacheableMetadataInCacheStorage`. +- Using trustworthy, browser-side origin lock while writing to and fetching from + the code cache by using `ChildProcessSecurityPolicyImpl::GetOriginLock` in + `GetSecondaryKeyForCodeCache` in + `//content/browser/renderer_host/code_cache_host_impl.cc` ## Cross-Origin-Resource-Policy response header
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc index 901ba97..0f077fe0 100644 --- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc +++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc
@@ -21,6 +21,7 @@ #include "components/guest_view/browser/test_guest_view_manager.h" #include "components/javascript_dialogs/app_modal_dialog_controller.h" #include "components/javascript_dialogs/app_modal_dialog_view.h" +#include "components/printing/common/print.mojom.h" #include "components/printing/common/print_messages.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_handle.h" @@ -194,7 +195,7 @@ return false; } - void OnDidStartPreview(const PrintHostMsg_DidStartPreview_Params& params, + void OnDidStartPreview(const printing::mojom::DidStartPreviewParams& params, const PrintHostMsg_PreviewIds& ids) { // Expect that there is at least one page. did_load_ = true;
diff --git a/fuchsia/runners/BUILD.gn b/fuchsia/runners/BUILD.gn index 72d0436..9384feb53 100644 --- a/fuchsia/runners/BUILD.gn +++ b/fuchsia/runners/BUILD.gn
@@ -63,12 +63,15 @@ "cast/cast_component.h", "cast/cast_runner.cc", "cast/cast_runner.h", + "cast/cast_streaming.cc", + "cast/cast_streaming.h", "cast/named_message_port_connector.cc", "cast/named_message_port_connector.h", "cast/pending_cast_component.cc", "cast/pending_cast_component.h", ] data_deps = [ "//chromecast/bindings:named_message_port_connector_resources" ] + data = [ "cast/data" ] deps = [ "//base", "//fuchsia/base",
diff --git a/fuchsia/runners/cast/api_bindings_client.h b/fuchsia/runners/cast/api_bindings_client.h index 8cb11926..652a672 100644 --- a/fuchsia/runners/cast/api_bindings_client.h +++ b/fuchsia/runners/cast/api_bindings_client.h
@@ -27,9 +27,9 @@ ~ApiBindingsClient(); // Injects APIs and handles channel connections on |frame|. - // |on_error_closure|: Invoked in the event of an unrecoverable error (e.g. - // lost connection to the Agent). The callback must - // remain valid for the entire lifetime of |this|. + // |on_error_callback| is invoked in the event of an unrecoverable error (e.g. + // lost connection to the Agent). The callback must remain valid for the + // entire lifetime of |this|. void AttachToFrame(fuchsia::web::Frame* frame, NamedMessagePortConnector* connector, base::OnceClosure on_error_callback); @@ -38,13 +38,16 @@ // |bindings_service_|. bool HasBindings() const; + // TODO(crbug.com/1082821): Move this method back to private once the Cast + // Streaming Receiver component has been implemented. + // Called when |connector_| has connected a port. + void OnPortConnected(base::StringPiece port_name, + fidl::InterfaceHandle<fuchsia::web::MessagePort> port); + private: // Called when ApiBindings::GetAll() has responded. void OnBindingsReceived(std::vector<chromium::cast::ApiBinding> bindings); - // Called when |connector_| has connected a port. - void OnPortConnected(base::StringPiece port_name, - fidl::InterfaceHandle<fuchsia::web::MessagePort> port); base::Optional<std::vector<chromium::cast::ApiBinding>> bindings_; fuchsia::web::Frame* frame_ = nullptr;
diff --git a/fuchsia/runners/cast/cast_component.cc b/fuchsia/runners/cast/cast_component.cc index 8a3c24c..b8e8cff 100644 --- a/fuchsia/runners/cast/cast_component.cc +++ b/fuchsia/runners/cast/cast_component.cc
@@ -18,6 +18,7 @@ #include "fuchsia/base/mem_buffer_util.h" #include "fuchsia/fidl/chromium/cast/cpp/fidl.h" #include "fuchsia/runners/cast/cast_runner.h" +#include "fuchsia/runners/cast/cast_streaming.h" #include "fuchsia/runners/common/web_component.h" namespace { @@ -91,6 +92,33 @@ fuchsia::web::AllowInputState::DENY); frame()->SetNavigationEventListener( navigation_listener_binding_.NewBinding()); + + if (IsAppConfigForCastStreaming(application_config_)) { + // TODO(crbug.com/1082821): Remove this once the Cast Streaming Receiver + // component has been implemented. + + // Register the MessagePort for the Cast Streaming Receiver. + fidl::InterfaceHandle<fuchsia::web::MessagePort> message_port; + fuchsia::web::WebMessage message; + message.set_data(cr_fuchsia::MemBufferFromString("", "empty_message")); + fuchsia::web::OutgoingTransferable outgoing_transferable; + outgoing_transferable.set_message_port(message_port.NewRequest()); + std::vector<fuchsia::web::OutgoingTransferable> outgoing_transferables; + outgoing_transferables.push_back(std::move(outgoing_transferable)); + message.set_outgoing_transfer(std::move(outgoing_transferables)); + + frame()->PostMessage( + kCastStreamingMessagePortOrigin, std::move(message), + [this](fuchsia::web::Frame_PostMessage_Result result) { + if (result.is_err()) { + DestroyComponent(kBindingsFailureExitCode, + fuchsia::sys::TerminationReason::INTERNAL_ERROR); + } + }); + api_bindings_client_->OnPortConnected(kCastStreamingMessagePortName, + std::move(message_port)); + } + api_bindings_client_->AttachToFrame( frame(), connector_.get(), base::BindOnce(&CastComponent::DestroyComponent, base::Unretained(this), @@ -112,8 +140,8 @@ application_config_.agent_url())); // Pass application permissions to the frame. - std::string origin = GURL(application_config_.web_url()).GetOrigin().spec(); if (application_config_.has_permissions()) { + std::string origin = GURL(application_config_.web_url()).GetOrigin().spec(); for (auto& permission : application_config_.permissions()) { fuchsia::web::PermissionDescriptor permission_clone; zx_status_t status = permission.Clone(&permission_clone);
diff --git a/fuchsia/runners/cast/cast_runner.cc b/fuchsia/runners/cast/cast_runner.cc index 26f30af..cb84276 100644 --- a/fuchsia/runners/cast/cast_runner.cc +++ b/fuchsia/runners/cast/cast_runner.cc
@@ -17,6 +17,7 @@ #include "base/fuchsia/fuchsia_logging.h" #include "base/logging.h" #include "fuchsia/base/agent_manager.h" +#include "fuchsia/runners/cast/cast_streaming.h" #include "fuchsia/runners/cast/pending_cast_component.h" #include "fuchsia/runners/common/web_content_runner.h" #include "url/gurl.h" @@ -132,40 +133,38 @@ void CastRunner::LaunchPendingComponent(PendingCastComponent* pending_component, CastComponent::Params params) { - WebContentRunner* component_owner = main_context_.get(); - // Save the list of CORS exemptions so that they can be used in Context // creation parameters. cors_exempt_headers_ = pending_component->TakeCorsExemptHeaders(); - const bool is_isolated = - params.application_config - .has_content_directories_for_isolated_application(); - if (is_isolated) { - // Create an isolated context which will own the CastComponent. - auto context = - std::make_unique<WebContentRunner>(GetIsolatedContextParams(std::move( - *params.application_config - .mutable_content_directories_for_isolated_application()))); - context->SetOnEmptyCallback(base::BindOnce( - &CastRunner::OnIsolatedContextEmpty, base::Unretained(this), - base::Unretained(context.get()))); - component_owner = context.get(); - isolated_contexts_.insert(std::move(context)); + // TODO(crbug.com/1082821): Remove |web_content_url| once the Cast Streaming + // Receiver component has been implemented. + GURL web_content_url(params.application_config.web_url()); + if (IsAppConfigForCastStreaming(params.application_config)) + web_content_url = GURL(kCastStreamingWebUrl); + + base::Optional<fuchsia::web::CreateContextParams> create_context_params = + GetContextParamsForAppConfig(¶ms.application_config); + + WebContentRunner* component_owner = main_context_.get(); + if (create_context_params) { + component_owner = CreateIsolatedContextForParams( + std::move(create_context_params.value())); } - // Launch the URL specified in the component |params|. - GURL app_url = GURL(params.application_config.web_url()); auto cast_component = std::make_unique<CastComponent>( component_owner, std::move(params), is_headless_); + + // Start the component, which creates and configures the web.Frame, and load + // the specified web content into it. cast_component->SetOnDestroyedCallback( base::BindOnce(&CastRunner::OnComponentDestroyed, base::Unretained(this), base::Unretained(cast_component.get()))); cast_component->StartComponent(); - cast_component->LoadUrl(std::move(app_url), + cast_component->LoadUrl(std::move(web_content_url), std::vector<fuchsia::net::http::Header>()); - if (!is_isolated) { + if (component_owner == main_context_.get()) { // If this component has the microphone permission then use it to route // Audio service requests through. if (IsPermissionGrantedInAppConfig( @@ -205,6 +204,7 @@ LOG(WARNING) << "Running in headless mode."; *params.mutable_features() |= fuchsia::web::ContextFeatureFlags::HEADLESS; } else { + // TODO(crbug.com/1078227): Remove HARDWARE_VIDEO_DECODER_ONLY. *params.mutable_features() |= fuchsia::web::ContextFeatureFlags::HARDWARE_VIDEO_DECODER | fuchsia::web::ContextFeatureFlags::HARDWARE_VIDEO_DECODER_ONLY | @@ -252,7 +252,8 @@ return params; } -fuchsia::web::CreateContextParams CastRunner::GetIsolatedContextParams( +fuchsia::web::CreateContextParams +CastRunner::GetIsolatedContextParamsWithFuchsiaDirs( std::vector<fuchsia::web::ContentDirectoryProvider> content_directories) { fuchsia::web::CreateContextParams params = GetCommonContextParams(); params.set_content_directories(std::move(content_directories)); @@ -261,6 +262,54 @@ return params; } +fuchsia::web::CreateContextParams +CastRunner::GetIsolatedContextParamsForCastStreaming() { + fuchsia::web::CreateContextParams params = GetCommonContextParams(); + ApplyCastStreamingContextParams(¶ms); + // TODO(crbug.com/1069746): Use a different FilteredServiceDirectory for Cast + // Streaming Contexts. + main_services_->ConnectClient( + params.mutable_service_directory()->NewRequest()); + return params; +} + +base::Optional<fuchsia::web::CreateContextParams> +CastRunner::GetContextParamsForAppConfig( + chromium::cast::ApplicationConfig* app_config) { + base::Optional<fuchsia::web::CreateContextParams> params; + + if (IsAppConfigForCastStreaming(*app_config)) { + // TODO(crbug.com/1082821): Remove this once the CastStreamingReceiver + // Component has been implemented. + return base::make_optional(GetIsolatedContextParamsForCastStreaming()); + } + + const bool is_isolated_app = + app_config->has_content_directories_for_isolated_application(); + if (is_isolated_app) { + return base::make_optional( + GetIsolatedContextParamsWithFuchsiaDirs(std::move( + *app_config + ->mutable_content_directories_for_isolated_application()))); + } + + // No need to create an isolated context in other cases. + return base::nullopt; +} + +WebContentRunner* CastRunner::CreateIsolatedContextForParams( + fuchsia::web::CreateContextParams create_context_params) { + // Create an isolated context which will own the CastComponent. + auto context = + std::make_unique<WebContentRunner>(std::move(create_context_params)); + context->SetOnEmptyCallback( + base::BindOnce(&CastRunner::OnIsolatedContextEmpty, + base::Unretained(this), base::Unretained(context.get()))); + WebContentRunner* raw_context = context.get(); + isolated_contexts_.insert(std::move(context)); + return raw_context; +} + void CastRunner::OnIsolatedContextEmpty(WebContentRunner* context) { auto it = isolated_contexts_.find(context); DCHECK(it != isolated_contexts_.end()); @@ -279,7 +328,7 @@ } // Otherwise use the Runner's fuchsia.media.Audio service. fuchsia.media.Audio - // may be used by frames without MICRIPHONE permission to create AudioRenderer + // may be used by frames without MICROPHONE permission to create AudioRenderer // instance. base::fuchsia::ComponentContextForCurrentProcess()->svc()->Connect( std::move(request));
diff --git a/fuchsia/runners/cast/cast_runner.h b/fuchsia/runners/cast/cast_runner.h index dfd77efa..d1b5d5e 100644 --- a/fuchsia/runners/cast/cast_runner.h +++ b/fuchsia/runners/cast/cast_runner.h
@@ -70,13 +70,21 @@ // Handlers used to provide parameters for main & isolated Contexts. fuchsia::web::CreateContextParams GetCommonContextParams(); fuchsia::web::CreateContextParams GetMainContextParams(); - fuchsia::web::CreateContextParams GetIsolatedContextParams( + fuchsia::web::CreateContextParams GetIsolatedContextParamsWithFuchsiaDirs( std::vector<fuchsia::web::ContentDirectoryProvider> content_directories); + // TODO(crbug.com/1082821): Remove this once the CastStreamingReceiver + // Component has been implemented. + fuchsia::web::CreateContextParams GetIsolatedContextParamsForCastStreaming(); - // Creates a CastRunner configured to serve data from content directories in - // |component_params|. + // Returns CreateContextParams for |app_config|. Returns nullopt if there is + // no need to create an isolated context. + base::Optional<fuchsia::web::CreateContextParams> + GetContextParamsForAppConfig(chromium::cast::ApplicationConfig* app_config); + + // Launches an isolated Context with the given |create_context_params| and + // returns the newly created WebContentRunner. WebContentRunner* CreateIsolatedContextForParams( - CastComponent::Params* component_params); + fuchsia::web::CreateContextParams create_context_params); // Called when an isolated component terminates, to allow the Context hosting // it to be torn down. @@ -99,9 +107,10 @@ const std::unique_ptr<base::fuchsia::FilteredServiceDirectory> main_services_; const std::unique_ptr<WebContentRunner> main_context_; - // Holds fuchsia.web.Contexts used to host isolated components. const std::unique_ptr<base::fuchsia::FilteredServiceDirectory> isolated_services_; + + // Holds fuchsia.web.Contexts used to host isolated components. base::flat_set<std::unique_ptr<WebContentRunner>, base::UniquePtrComparator> isolated_contexts_;
diff --git a/fuchsia/runners/cast/cast_streaming.cc b/fuchsia/runners/cast/cast_streaming.cc new file mode 100644 index 0000000..88754ed --- /dev/null +++ b/fuchsia/runners/cast/cast_streaming.cc
@@ -0,0 +1,66 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "fuchsia/runners/cast/cast_streaming.h" + +#include "base/fuchsia/file_utils.h" +#include "base/path_service.h" + +namespace { + +constexpr char kCastStreamingAppUrl[] = "cast-streaming:receiver"; +constexpr char kCastDataDirectory[] = "fuchsia/runners/cast/data"; +constexpr char kCastStreamingContentDirectoryName[] = "cast-streaming"; + +// Returns the content directories for the Cast Streaming application. +std::vector<fuchsia::web::ContentDirectoryProvider> +GetCastStreamingContentDirectories() { + base::FilePath pkg_path; + bool success = base::PathService::Get(base::DIR_ASSETS, &pkg_path); + DCHECK(success); + + fuchsia::web::ContentDirectoryProvider content_directory; + content_directory.set_directory( + base::fuchsia::OpenDirectory(pkg_path.AppendASCII(kCastDataDirectory))); + content_directory.set_name(kCastStreamingContentDirectoryName); + std::vector<fuchsia::web::ContentDirectoryProvider> content_directories; + content_directories.emplace_back(std::move(content_directory)); + + return content_directories; +} + +} // namespace + +const char kCastStreamingWebUrl[] = + "fuchsia-dir://cast-streaming/receiver.html"; + +const char kCastStreamingMessagePortOrigin[] = "cast-streaming:receiver"; + +const char kCastStreamingMessagePortName[] = "cast.__platform__.cast_transport"; + +bool IsAppConfigForCastStreaming( + const chromium::cast::ApplicationConfig& application_config) { + return application_config.web_url() == kCastStreamingAppUrl; +} + +void ApplyCastStreamingContextParams( + fuchsia::web::CreateContextParams* params) { + // Disable the HARDWARE_VIDEO_DECODER_ONLY tag. + // TODO(crbug.com/1078227): Remove HARDWARE_VIDEO_DECODER_ONLY once it is + // no longer set in CastRunner::CommonContextParams(). For now, this is + // required to enable software decoders. + *params->mutable_features() &= + ~fuchsia::web::ContextFeatureFlags::HARDWARE_VIDEO_DECODER_ONLY; + + // Disable the WIDEVINE_CDM tag. + // TODO(crbug.com/1069746): Remove this once WIDEVINE_CDM is no longer set in + // CastRunner::CommonContextParams(). + *params->mutable_features() &= + ~fuchsia::web::ContextFeatureFlags::WIDEVINE_CDM; + + *params->mutable_features() |= fuchsia::web::ContextFeatureFlags::NETWORK; + + // Set the content directory with the streaming app. + params->set_content_directories(GetCastStreamingContentDirectories()); +}
diff --git a/fuchsia/runners/cast/cast_streaming.h b/fuchsia/runners/cast/cast_streaming.h new file mode 100644 index 0000000..0bc7f65 --- /dev/null +++ b/fuchsia/runners/cast/cast_streaming.h
@@ -0,0 +1,33 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FUCHSIA_RUNNERS_CAST_CAST_STREAMING_H_ +#define FUCHSIA_RUNNERS_CAST_CAST_STREAMING_H_ + +#include <fuchsia/web/cpp/fidl.h> + +#include "base/callback.h" +#include "base/strings/string_piece.h" +#include "fuchsia/fidl/chromium/cast/cpp/fidl.h" + +// TODO(crbug.com/1082821): Remove unused methods here once the +// Cast Streaming Receiver component has been implemented. + +// URL for the Cast Streaming application. +extern const char kCastStreamingWebUrl[]; + +// Origin value for the Cast Streaming MessagePort. +extern const char kCastStreamingMessagePortOrigin[]; + +// Name of the Cast Streaming MessagePort. +extern const char kCastStreamingMessagePortName[]; + +// Returns true if |application_config| is a cast streaming application. +bool IsAppConfigForCastStreaming( + const chromium::cast::ApplicationConfig& application_config); + +// Modifies |params| to apply Cast Streaming-specific Context Params. +void ApplyCastStreamingContextParams(fuchsia::web::CreateContextParams* params); + +#endif // FUCHSIA_RUNNERS_CAST_CAST_STREAMING_H_
diff --git a/fuchsia/runners/cast/data/receiver.html b/fuchsia/runners/cast/data/receiver.html new file mode 100644 index 0000000..7aabb6bb --- /dev/null +++ b/fuchsia/runners/cast/data/receiver.html
@@ -0,0 +1,29 @@ +<!DOCTYPE html> +<!-- +Copyright 2020 The Chromium Authors. All rights reserved. +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> +<html> +<head> + <meta charset="utf-8"> + <style> + video { + background-color: black; + max-width: 100%; + height: auto; + } + </style> +</head> + +<body> + <video src="data:cast_streaming_receiver" autoplay> + + <!-- TODO(crbug.com/1042501): This should not be necessary. Figure out why + autoplay is not enough here. --> + <script> + var video = document.querySelector('video'); + video.play(); + </script> +</body> +</html>
diff --git a/gin/public/v8_platform.h b/gin/public/v8_platform.h index 8a3d3035..da2aeb2 100644 --- a/gin/public/v8_platform.h +++ b/gin/public/v8_platform.h
@@ -34,6 +34,9 @@ std::unique_ptr<v8::Task> task) override; void CallDelayedOnWorkerThread(std::unique_ptr<v8::Task> task, double delay_in_seconds) override; + std::unique_ptr<v8::JobHandle> PostJob( + v8::TaskPriority priority, + std::unique_ptr<v8::JobTask> job_task) override; bool IdleTasksEnabled(v8::Isolate* isolate) override; double MonotonicallyIncreasingTime() override; double CurrentClockTimeMillis() override;
diff --git a/gin/v8_platform.cc b/gin/v8_platform.cc index a81289ba..bf6a1c9 100644 --- a/gin/v8_platform.cc +++ b/gin/v8_platform.cc
@@ -17,6 +17,7 @@ #include "base/location.h" #include "base/rand_util.h" #include "base/system/sys_info.h" +#include "base/task/post_job.h" #include "base/task/post_task.h" #include "base/task/task_traits.h" #include "base/task/thread_pool/thread_pool_instance.h" @@ -269,6 +270,47 @@ #endif // BUILDFLAG(USE_PARTITION_ALLOC) +class JobDelegateImpl : public v8::JobDelegate { + public: + explicit JobDelegateImpl(base::JobDelegate* delegate) : delegate_(delegate) {} + JobDelegateImpl() = default; + + JobDelegateImpl(const JobDelegateImpl&) = delete; + JobDelegateImpl& operator=(const JobDelegateImpl&) = delete; + + // v8::JobDelegate: + bool ShouldYield() override { return delegate_->ShouldYield(); } + void NotifyConcurrencyIncrease() override { + delegate_->NotifyConcurrencyIncrease(); + } + + private: + base::JobDelegate* delegate_; +}; + +class JobHandleImpl : public v8::JobHandle { + public: + JobHandleImpl(base::JobHandle handle, std::unique_ptr<v8::JobTask> job_task) + : handle_(std::move(handle)), job_task_(std::move(job_task)) {} + ~JobHandleImpl() override = default; + + JobHandleImpl(const JobHandleImpl&) = delete; + JobHandleImpl& operator=(const JobHandleImpl&) = delete; + + // v8::JobHandle: + void NotifyConcurrencyIncrease() override { + handle_.NotifyConcurrencyIncrease(); + } + void Join() override { handle_.Join(); } + void Cancel() override { handle_.Cancel(); } + + bool IsRunning() override { return !!handle_; } + + private: + base::JobHandle handle_; + std::unique_ptr<v8::JobTask> job_task_; +}; + } // namespace } // namespace gin @@ -441,6 +483,37 @@ base::TimeDelta::FromSecondsD(delay_in_seconds)); } +std::unique_ptr<v8::JobHandle> V8Platform::PostJob( + v8::TaskPriority priority, + std::unique_ptr<v8::JobTask> job_task) { + base::TaskTraits task_traits; + switch (priority) { + case v8::TaskPriority::kBestEffort: + task_traits = kLowPriorityTaskTraits; + break; + case v8::TaskPriority::kUserVisible: + task_traits = kDefaultTaskTraits; + break; + case v8::TaskPriority::kUserBlocking: + task_traits = kBlockingTaskTraits; + break; + } + auto handle = base::PostJob( + FROM_HERE, task_traits, + base::BindRepeating( + [](v8::JobTask* job_task, base::JobDelegate* delegate) { + JobDelegateImpl delegate_impl(delegate); + job_task->Run(&delegate_impl); + }, + base::Unretained(job_task.get())), + base::BindRepeating( + [](v8::JobTask* job_task) { return job_task->GetMaxConcurrency(); }, + base::Unretained(job_task.get()))); + + return std::make_unique<JobHandleImpl>(std::move(handle), + std::move(job_task)); +} + bool V8Platform::IdleTasksEnabled(v8::Isolate* isolate) { return PerIsolateData::From(isolate)->task_runner()->IdleTasksEnabled(); }
diff --git a/gin/v8_platform_unittest.cc b/gin/v8_platform_unittest.cc index 5409e89..d2ea2b7 100644 --- a/gin/v8_platform_unittest.cc +++ b/gin/v8_platform_unittest.cc
@@ -4,6 +4,9 @@ #include "gin/public/v8_platform.h" +#include <atomic> + +#include "base/test/task_environment.h" #include "base/trace_event/trace_event.h" #include "testing/gtest/include/gtest/gtest.h" @@ -62,4 +65,26 @@ ASSERT_EQ(0, test_observer.Disabled()); } +// Tests that PostJob runs a task and is done after Join. +TEST(V8PlatformTest, PostJobSimple) { + base::test::TaskEnvironment task_environment; + std::atomic_size_t num_tasks_to_run(4); + class Task : public v8::JobTask { + public: + explicit Task(std::atomic_size_t* num_tasks_to_run) + : num_tasks_to_run(num_tasks_to_run) {} + void Run(v8::JobDelegate* delegate) override { --(*num_tasks_to_run); } + size_t GetMaxConcurrency() const override { return *num_tasks_to_run; } + + std::atomic_size_t* num_tasks_to_run; + }; + auto handle = + V8Platform::Get()->PostJob(v8::TaskPriority::kUserVisible, + std::make_unique<Task>(&num_tasks_to_run)); + EXPECT_TRUE(handle->IsRunning()); + handle->Join(); + EXPECT_FALSE(handle->IsRunning()); + DCHECK_EQ(num_tasks_to_run, 0U); +} + } // namespace gin
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc index 77e694f4..23719a2b 100644 --- a/gpu/command_buffer/service/raster_decoder.cc +++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -401,7 +401,7 @@ if (!flush_workaround_disabled_for_test_) { TRACE_EVENT0("gpu", "RasterDecoderImpl::FlushToWorkAroundMacCrashes"); if (gr_context()) - gr_context()->flush(); + gr_context()->flushAndSubmit(); api()->glFlushFn(); // Flushes can be expensive, yield to allow interruption after each flush. @@ -851,6 +851,8 @@ shared_context_state_->vk_context_provider(), &flush_info); auto result = sk_surface_->flush( SkSurface::BackendSurfaceAccess::kPresent, flush_info); + DCHECK(gr_context()); + gr_context()->submit(); DCHECK(result == GrSemaphoresSubmitted::kYes || end_semaphores_.empty()); end_semaphores_.clear(); sk_surface_ = nullptr; @@ -862,7 +864,7 @@ } } if (gr_context()) { - gr_context()->flush(); + gr_context()->flushAndSubmit(); } } @@ -2257,6 +2259,8 @@ shared_context_state_->vk_context_provider(), &flush_info); dest_scoped_access->surface()->flush( SkSurface::BackendSurfaceAccess::kNoAccess, flush_info); + DCHECK(dest_scoped_access->surface()->getContext()); + dest_scoped_access->surface()->getContext()->submit(); if (!dest_shared_image->IsCleared()) { dest_shared_image->SetClearedRect(new_cleared_rect); @@ -2370,6 +2374,8 @@ shared_context_state_->vk_context_provider(), &flush_info); dest_scoped_access->surface()->flush( SkSurface::BackendSurfaceAccess::kNoAccess, flush_info); + DCHECK(dest_scoped_access->surface()->getContext()); + dest_scoped_access->surface()->getContext()->submit(); if (!dest_shared_image->IsCleared()) { dest_shared_image->SetClearedRect( @@ -2560,6 +2566,8 @@ shared_context_state_->vk_context_provider(), &flush_info); dest_scoped_access->surface()->flush( SkSurface::BackendSurfaceAccess::kNoAccess, flush_info); + DCHECK(dest_scoped_access->surface()->getContext()); + dest_scoped_access->surface()->getContext()->submit(); if (!images[YUVConversionMailboxIndex::kDestIndex]->IsCleared() && drew_image) { @@ -2896,6 +2904,10 @@ shared_context_state_->vk_context_provider(), &flush_info); auto result = sk_surface_->flush(SkSurface::BackendSurfaceAccess::kPresent, flush_info); + if (sk_surface_->getContext()) { + sk_surface_->getContext()->submit(); + } + DCHECK(result == GrSemaphoresSubmitted::kYes || end_semaphores_.empty()); end_semaphores_.clear();
diff --git a/gpu/ipc/service/stream_texture_android.cc b/gpu/ipc/service/stream_texture_android.cc index 7b4c168..74faadd 100644 --- a/gpu/ipc/service/stream_texture_android.cc +++ b/gpu/ipc/service/stream_texture_android.cc
@@ -227,6 +227,11 @@ if (!has_listener_ || !channel_) return; + // We haven't received size for first time yet from the MediaPlayer we will + // defer this sending OnFrameAvailable till then. + if (rotated_visible_size_.IsEmpty()) + return; + UpdateTexImage(BindingsMode::kEnsureTexImageBound); gfx::Rect visible_rect; @@ -324,7 +329,14 @@ void StreamTexture::OnUpdateRotatedVisibleSize( const gfx::Size& rotated_visible_size) { DCHECK(channel_); + bool was_empty = rotated_visible_size_.IsEmpty(); rotated_visible_size_ = rotated_visible_size; + + // It's possible that first OnUpdateRotatedVisibleSize will come after first + // OnFrameAvailable. We delay sending OnFrameWithInfoAvailable if it comes + // first so now it's time to send it. + if (was_empty && has_pending_frame_) + OnFrameAvailable(); } void StreamTexture::OnDestroy() {
diff --git a/gpu/vulkan/demo/vulkan_demo.cc b/gpu/vulkan/demo/vulkan_demo.cc index e46d726..b8dc416 100644 --- a/gpu/vulkan/demo/vulkan_demo.cc +++ b/gpu/vulkan/demo/vulkan_demo.cc
@@ -204,6 +204,7 @@ .fSignalSemaphores = &semaphore, }; sk_surface_->flush(SkSurface::BackendSurfaceAccess::kPresent, flush_info); + sk_surface_->getContext()->submit(); auto backend = sk_surface_->getBackendRenderTarget( SkSurface::kFlushRead_BackendHandleAccess); GrVkImageInfo vk_image_info;
diff --git a/gpu/vulkan/vulkan_fence_helper.cc b/gpu/vulkan/vulkan_fence_helper.cc index d7d902a..42671b0 100644 --- a/gpu/vulkan/vulkan_fence_helper.cc +++ b/gpu/vulkan/vulkan_fence_helper.cc
@@ -75,32 +75,38 @@ tasks_pending_fence_.emplace_back(std::move(task)); } -void VulkanFenceHelper::ProcessCleanupTasks() { +void VulkanFenceHelper::ProcessCleanupTasks(uint64_t retired_generation_id) { VkDevice device = device_queue_->GetVulkanDevice(); + if (!retired_generation_id) + retired_generation_id = current_generation_; + // Iterate over our pending cleanup fences / tasks, advancing // |current_generation_| as far as possible. for (const auto& tasks_for_fence : cleanup_tasks_) { - // If we're already ahead of this task (callback modified |generation_id_|), - // continue. - if (tasks_for_fence.generation_id <= current_generation_) - continue; - // Callback based tasks have no actual fence to wait on, keep checking // future fences, as a callback may be delayed. if (tasks_for_fence.UsingCallback()) continue; VkResult result = vkGetFenceStatus(device, tasks_for_fence.fence); - if (result == VK_NOT_READY) + if (result == VK_NOT_READY) { + retired_generation_id = + std::min(retired_generation_id, tasks_for_fence.generation_id - 1); break; - if (result != VK_SUCCESS) { - PerformImmediateCleanup(); - return; } - current_generation_ = tasks_for_fence.generation_id; + if (result == VK_SUCCESS) { + retired_generation_id = + std::max(tasks_for_fence.generation_id, retired_generation_id); + continue; + } + DLOG(ERROR) << "vkGetFenceStatus() failed: " << result; + PerformImmediateCleanup(); + return; } + current_generation_ = retired_generation_id; + // Runs any cleanup tasks for generations that have passed. Create a temporary // vector of tasks to run to avoid reentrancy issues. std::vector<CleanupTask> tasks_to_run; @@ -161,8 +167,7 @@ // If |current_generation_| is ahead of the callback's // |generation_id|, the callback came late. Ignore it. if (generation_id > fence_helper->current_generation_) { - fence_helper->current_generation_ = generation_id; - fence_helper->ProcessCleanupTasks(); + fence_helper->ProcessCleanupTasks(generation_id); } }, weak_factory_.GetWeakPtr(), generation_id);
diff --git a/gpu/vulkan/vulkan_fence_helper.h b/gpu/vulkan/vulkan_fence_helper.h index 1b6e586a..571fc97c 100644 --- a/gpu/vulkan/vulkan_fence_helper.h +++ b/gpu/vulkan/vulkan_fence_helper.h
@@ -101,7 +101,7 @@ // executed in order they are enqueued. void EnqueueCleanupTaskForSubmittedWork(CleanupTask task); // Processes CleanupTasks for which a fence has passed. - void ProcessCleanupTasks(); + void ProcessCleanupTasks(uint64_t retired_generation_id = 0); // Helpers for common types: void EnqueueSemaphoreCleanupForSubmittedWork(VkSemaphore semaphore); void EnqueueSemaphoresCleanupForSubmittedWork(
diff --git a/ios/build/bots/tests/eg2_tests.json b/ios/build/bots/tests/eg2_tests.json index 45aab59..e10cc49 100644 --- a/ios/build/bots/tests/eg2_tests.json +++ b/ios/build/bots/tests/eg2_tests.json
@@ -3,25 +3,5 @@ "EG2 tests to run on the waterfall." ], "tests": [ - { - "app": "ios_chrome_bookmarks_eg2tests_module", - "host": "ios_chrome_eg2tests" - }, - { - "app": "ios_chrome_smoke_eg2tests_module", - "host": "ios_chrome_eg2tests" - }, - { - "app": "ios_chrome_settings_eg2tests_module", - "host": "ios_chrome_eg2tests" - }, - { - "app": "ios_chrome_web_eg2tests_module", - "host": "ios_chrome_eg2tests" - }, - { - "app":"ios_showcase_eg2tests_module", - "host":"ios_showcase_eg2tests" - } ] }
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 5bde0322..4d7a716 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -434,12 +434,6 @@ {"send-uma-cellular", flag_descriptions::kSendUmaOverAnyNetwork, flag_descriptions::kSendUmaOverAnyNetworkDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(kUmaCellular)}, - {"autofill-no-local-save-on-unmask-success", - flag_descriptions::kAutofillNoLocalSaveOnUnmaskSuccessName, - flag_descriptions::kAutofillNoLocalSaveOnUnmaskSuccessDescription, - flags_ui::kOsIos, - FEATURE_VALUE_TYPE( - autofill::features::kAutofillNoLocalSaveOnUnmaskSuccess)}, {"omnibox-preserve-default-match-against-async-update", flag_descriptions::kOmniboxPreserveDefaultMatchAgainstAsyncUpdateName, flag_descriptions:: @@ -467,14 +461,6 @@ flag_descriptions::kCollectionsCardPresentationStyleName, flag_descriptions::kCollectionsCardPresentationStyleDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(kCollectionsCardPresentationStyle)}, - {"enable-autofill-credit-card-upload-editable-expiration-date", - flag_descriptions:: - kEnableAutofillCreditCardUploadEditableExpirationDateName, - flag_descriptions:: - kEnableAutofillCreditCardUploadEditableExpirationDateDescription, - flags_ui::kOsIos, - FEATURE_VALUE_TYPE( - autofill::features::kAutofillUpstreamEditableExpirationDate)}, {"credit-card-scanner", flag_descriptions::kCreditCardScannerName, flag_descriptions::kCreditCardScannerDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(kCreditCardScanner)},
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index 3e54a19..a3121c85 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -69,12 +69,6 @@ "Delay between the different fields of a form being autofilled. In " "milliseconds."; -const char kAutofillNoLocalSaveOnUnmaskSuccessName[] = - "Remove the option to save local copies of unmasked server cards"; -const char kAutofillNoLocalSaveOnUnmaskSuccessDescription[] = - "When enabled, the server card unmask prompt will not include the checkbox " - "to also save the card locally on the current device upon success."; - const char kAutofillPruneSuggestionsName[] = "Autofill Prune Suggestions"; const char kAutofillPruneSuggestionsDescription[] = "Further limits the number of suggestions in the Autofill dropdown."; @@ -206,13 +200,6 @@ "If enabled, when a server card is unmasked, its info will be cached until " "page navigation to simplify consecutive fills on the same page."; -const char kEnableAutofillCreditCardUploadEditableExpirationDateName[] = - "Make expiration date editable in dialog during credit card upload"; -const char kEnableAutofillCreditCardUploadEditableExpirationDateDescription[] = - "If enabled, if a credit card's expiration date was not detected when " - "offering card upload to Google Payments, the offer-to-save dialog " - "displays an expiration date selector."; - const char kEnableClipboardProviderImageSuggestionsName[] = "Enable copied image provider"; const char kEnableClipboardProviderImageSuggestionsDescription[] =
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index ce589210..2f2020c 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -48,11 +48,6 @@ extern const char kAutofillIOSDelayBetweenFieldsName[]; extern const char kAutofillIOSDelayBetweenFieldsDescription[]; -// Title and description for the flag to control offering to save unmasked -// server cards locally as FULL_SERVER_CARDs upon success of credit card unmask. -extern const char kAutofillNoLocalSaveOnUnmaskSuccessName[]; -extern const char kAutofillNoLocalSaveOnUnmaskSuccessDescription[]; - // Title and description for the flag that controls whether the maximum number // of Autofill suggestions shown is pruned. extern const char kAutofillPruneSuggestionsName[]; @@ -175,12 +170,6 @@ extern const char kEnableAutofillCacheServerCardInfoName[]; extern const char kEnableAutofillCacheServerCardInfoDescription[]; -// Title and description for the flag to control if credit card upload can -// display an expiration date fix flow. -extern const char kEnableAutofillCreditCardUploadEditableExpirationDateName[]; -extern const char - kEnableAutofillCreditCardUploadEditableExpirationDateDescription[]; - // Title and description for the flag to enable the clipboard provider to // suggest searchihng for copied images. extern const char kEnableClipboardProviderImageSuggestionsName[];
diff --git a/ios/chrome/browser/ui/autofill/card_unmask_prompt_view_bridge.mm b/ios/chrome/browser/ui/autofill/card_unmask_prompt_view_bridge.mm index 9e24d199..8736689 100644 --- a/ios/chrome/browser/ui/autofill/card_unmask_prompt_view_bridge.mm +++ b/ios/chrome/browser/ui/autofill/card_unmask_prompt_view_bridge.mm
@@ -213,18 +213,7 @@ _CVCItem.instructionsText = instructions; _CVCItem.CVCImageResourceID = CVCImageResourceID; [model addItem:_CVCItem toSectionWithIdentifier:SectionIdentifierMain]; - - if (controller->CanStoreLocally()) { - _storageSwitchItem = - [[CollectionViewSwitchItem alloc] initWithType:ItemTypeStorageSwitch]; - _storageSwitchItem.text = l10n_util::GetNSString( - IDS_AUTOFILL_CARD_UNMASK_PROMPT_STORAGE_CHECKBOX); - _storageSwitchItem.on = controller->GetStoreLocallyStartState(); - [model addItem:_storageSwitchItem - toSectionWithIdentifier:SectionIdentifierMain]; - } else { - _storageSwitchItem = nil; - } + _storageSwitchItem = nil; // No status item when loading the model. _statusItem = nil;
diff --git a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm index e4ee409e..a99cc2f 100644 --- a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm +++ b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
@@ -116,8 +116,7 @@ GetApplicationContext()->GetApplicationLocale())), infobar_manager_(infobar_manager), password_manager_(password_manager), - unmask_controller_(browser_state->GetPrefs(), - browser_state->IsOffTheRecord()), + unmask_controller_(browser_state->GetPrefs()), // TODO(crbug.com/928595): Replace the closure with a callback to the // renderer that indicates if log messages should be sent from the // renderer.
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/full_card_requester.mm b/ios/chrome/browser/ui/autofill/manual_fill/full_card_requester.mm index 902842f..9abec8a 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/full_card_requester.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/full_card_requester.mm
@@ -26,8 +26,7 @@ FullCardRequester::FullCardRequester(UIViewController* base_view_controller, ChromeBrowserState* browser_state) : base_view_controller_(base_view_controller), - unmask_controller_(browser_state->GetPrefs(), - browser_state->IsOffTheRecord()) {} + unmask_controller_(browser_state->GetPrefs()) {} void FullCardRequester::GetFullCard( const autofill::CreditCard& card,
diff --git a/ios/third_party/material_components_ios/BUILD.gn b/ios/third_party/material_components_ios/BUILD.gn index ea02c76..b408324 100644 --- a/ios/third_party/material_components_ios/BUILD.gn +++ b/ios/third_party/material_components_ios/BUILD.gn
@@ -269,6 +269,8 @@ "src/components/NavigationDrawer/src/MDCBottomDrawerViewController.h", "src/components/NavigationDrawer/src/MDCBottomDrawerViewControllerDelegate.h", "src/components/NavigationDrawer/src/MaterialNavigationDrawer.h", + "src/components/NavigationDrawer/src/Theming/MDCBottomDrawerViewController+MaterialTheming.h", + "src/components/NavigationDrawer/src/Theming/MaterialNavigationDrawer+MaterialTheming.h", "src/components/NavigationDrawer/src/private/MDCBottomDrawerContainerViewController.h", "src/components/NavigationDrawer/src/private/MDCBottomDrawerContainerViewControllerDelegate.h", "src/components/NavigationDrawer/src/private/MDCBottomDrawerHeaderMask.h", @@ -615,6 +617,7 @@ "src/components/NavigationBar/src/TypographyThemer", "src/components/NavigationDrawer/src", "src/components/NavigationDrawer/src/ColorThemer", + "src/components/NavigationDrawer/src/Theming", "src/components/NavigationDrawer/src/private", "src/components/OverlayWindow/src", "src/components/PageControl/src", @@ -1087,6 +1090,9 @@ "src/components/NavigationDrawer/src/MDCBottomDrawerViewController.m", "src/components/NavigationDrawer/src/MDCBottomDrawerViewControllerDelegate.h", "src/components/NavigationDrawer/src/MaterialNavigationDrawer.h", + "src/components/NavigationDrawer/src/Theming/MDCBottomDrawerViewController+MaterialTheming.h", + "src/components/NavigationDrawer/src/Theming/MDCBottomDrawerViewController+MaterialTheming.m", + "src/components/NavigationDrawer/src/Theming/MaterialNavigationDrawer+MaterialTheming.h", "src/components/NavigationDrawer/src/private/MDCBottomDrawerContainerViewController.h", "src/components/NavigationDrawer/src/private/MDCBottomDrawerContainerViewController.m", "src/components/NavigationDrawer/src/private/MDCBottomDrawerContainerViewControllerDelegate.h",
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn index 554dfea9..64bc565f 100644 --- a/ios/web/BUILD.gn +++ b/ios/web/BUILD.gn
@@ -224,6 +224,7 @@ "//components/url_formatter", "//ios/net", "//ios/testing:ocmock_support", + "//ios/web/navigation", "//ios/web/public", "//ios/web/public/session", "//ios/web/public/test",
diff --git a/ios/web/crw_navigation_item_storage.mm b/ios/web/crw_navigation_item_storage.mm index 1838ff6..2cb1cd3 100644 --- a/ios/web/crw_navigation_item_storage.mm +++ b/ios/web/crw_navigation_item_storage.mm
@@ -138,8 +138,12 @@ - (void)encodeWithCoder:(NSCoder*)aCoder { // Desktop Chrome doesn't persist |url_| or |originalUrl_|, only // |virtualUrl_|. Chrome on iOS is persisting |url_|. - web::nscoder_util::EncodeString( - aCoder, web::kNavigationItemStorageVirtualURLKey, _virtualURL.spec()); + if (_virtualURL != _URL) { + // In most cases _virtualURL is the same as URL. Not storing virtual URL + // will save memory during unarchiving. + web::nscoder_util::EncodeString( + aCoder, web::kNavigationItemStorageVirtualURLKey, _virtualURL.spec()); + } web::nscoder_util::EncodeString(aCoder, web::kNavigationItemStorageURLKey, _URL.spec()); web::nscoder_util::EncodeString( @@ -163,4 +167,11 @@ forKey:web::kNavigationItemStorageHTTPRequestHeadersKey]; } +- (GURL)virtualURL { + // virtualURL is not stored (see -encodeWithCoder:) if it's the same as URL. + // This logic repeats NavigationItemImpl::GetURL to store virtualURL only when + // different from URL. + return _virtualURL.is_empty() ? _URL : _virtualURL; +} + @end
diff --git a/ios/web/crw_navigation_item_storage_unittest.mm b/ios/web/crw_navigation_item_storage_unittest.mm index f4187618..bcb5e3d 100644 --- a/ios/web/crw_navigation_item_storage_unittest.mm +++ b/ios/web/crw_navigation_item_storage_unittest.mm
@@ -11,6 +11,7 @@ #include "base/strings/sys_string_conversions.h" #import "ios/web/navigation/navigation_item_impl.h" +#import "ios/web/navigation/navigation_item_storage_builder.h" #import "ios/web/navigation/navigation_item_storage_test_util.h" #include "ios/web/public/navigation/referrer.h" #include "testing/gtest/include/gtest/gtest.h" @@ -88,3 +89,38 @@ EXPECT_EQ(item_storage().virtualURL, decoded.URL); EXPECT_EQ(item_storage().virtualURL, decoded.virtualURL); } + +// CRWNavigationItemStorage does not store "virtualURL" if the it's the same +// as "URL" to save memory. This test verifies that virtualURL actually gets +// restored correctly. +TEST_F(CRWNavigationItemStorageTest, EncodeDecodeSameVirtualURL) { + web::NavigationItemStorageBuilder builder; + + web::NavigationItemImpl item_to_store; + item_to_store.SetURL(GURL("http://url.test")); + item_to_store.SetVirtualURL(item_to_store.GetURL()); + + // Serialize and deserialize navigation item. + NSData* data = [NSKeyedArchiver + archivedDataWithRootObject:builder.BuildStorage(&item_to_store) + requiringSecureCoding:NO + error:nil]; + NSKeyedUnarchiver* unarchiver = + [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:nil]; + unarchiver.requiresSecureCoding = NO; + std::unique_ptr<web::NavigationItemImpl> restored_item = + builder.BuildNavigationItemImpl( + [unarchiver decodeObjectForKey:NSKeyedArchiveRootObjectKey]); + + EXPECT_EQ(item_to_store.GetURL(), restored_item->GetURL()); + EXPECT_EQ(item_to_store.GetVirtualURL(), restored_item->GetVirtualURL()); +} + +// Tests that virtualURL will be the same as URL, if virtualURL is not +// overridden. This logic allows to store only one URL when virtualURL and URL +// are the same. +TEST_F(CRWNavigationItemStorageTest, VirtualURL) { + CRWNavigationItemStorage* storage = [[CRWNavigationItemStorage alloc] init]; + storage.URL = GURL("https://foo.test/"); + EXPECT_EQ(storage.URL, storage.virtualURL); +}
diff --git a/ios/web_view/internal/autofill/cwv_credit_card_verifier.mm b/ios/web_view/internal/autofill/cwv_credit_card_verifier.mm index 58a7b793..26615e1 100644 --- a/ios/web_view/internal/autofill/cwv_credit_card_verifier.mm +++ b/ios/web_view/internal/autofill/cwv_credit_card_verifier.mm
@@ -107,8 +107,7 @@ _unmaskingView = std::make_unique<ios_web_view::WebViewCardUnmaskPromptView>(self); _unmaskingController = - std::make_unique<autofill::CardUnmaskPromptControllerImpl>( - prefs, isOffTheRecord); + std::make_unique<autofill::CardUnmaskPromptControllerImpl>(prefs); _unmaskingController->ShowPrompt( base::BindOnce(^autofill::CardUnmaskPromptView*() { return _unmaskingView.get();
diff --git a/ios/web_view/internal/web_view_web_main_parts.mm b/ios/web_view/internal/web_view_web_main_parts.mm index f477ee7..b3ae73a5 100644 --- a/ios/web_view/internal/web_view_web_main_parts.mm +++ b/ios/web_view/internal/web_view_web_main_parts.mm
@@ -55,7 +55,6 @@ std::string enable_features = base::JoinString( { autofill::features::kAutofillUpstream.name, - autofill::features::kAutofillNoLocalSaveOnUnmaskSuccess.name, autofill::features::kAutofillEnableAccountWalletStorage.name, password_manager::features::kEnablePasswordsAccountStorage.name, switches::kSyncDeviceInfoInTransportMode.name,
diff --git a/media/base/android/stream_texture_wrapper.h b/media/base/android/stream_texture_wrapper.h index 69a388e..4900adf 100644 --- a/media/base/android/stream_texture_wrapper.h +++ b/media/base/android/stream_texture_wrapper.h
@@ -23,7 +23,6 @@ // See StreamTextureWrapperImpl. virtual void Initialize( const base::RepeatingClosure& received_frame_cb, - const gfx::Size& natural_size, scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner, StreamTextureWrapperInitCB init_cb) = 0;
diff --git a/media/renderers/paint_canvas_video_renderer.cc b/media/renderers/paint_canvas_video_renderer.cc index 5eaa952..e605538 100644 --- a/media/renderers/paint_canvas_video_renderer.cc +++ b/media/renderers/paint_canvas_video_renderer.cc
@@ -1453,7 +1453,7 @@ gr_context, video_frame.ColorSpace(), video_frame.format(), yuv_textures, result_texture); - gr_context->flush(); + gr_context->flushAndSubmit(); source_ri->EndSharedImageAccessDirectCHROMIUM(yuv_cache_.texture); source_ri->GenUnverifiedSyncTokenCHROMIUM( @@ -1601,7 +1601,7 @@ return false; // Flush any pending GPU work using this texture. - sk_image->flush(raster_context_provider->GrContext()); + sk_image->flushAndSubmit(raster_context_provider->GrContext()); // We need a new texture ID because skia will destroy the previous one with // the SkImage. @@ -1681,7 +1681,7 @@ ConvertFromVideoFrameYUV(video_frame.get(), raster_context_provider, dest_holder); } - raster_context_provider->GrContext()->flush(); + raster_context_provider->GrContext()->flushAndSubmit(); } // TODO(jochin): Don't always generate SkImage here.
diff --git a/media/renderers/yuv_util.cc b/media/renderers/yuv_util.cc index 3a66d63..3f5f539 100644 --- a/media/renderers/yuv_util.cc +++ b/media/renderers/yuv_util.cc
@@ -188,7 +188,7 @@ sk_sp<SkImage> img = YUVGrBackendTexturesToSkImage( gr_context, video_frame->ColorSpace(), video_frame->format(), yuv_textures, result_texture); - gr_context->flush(); + gr_context->flushAndSubmit(); DeleteYUVTextures(video_frame, raster_context_provider, yuv_textures_info);
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl index 1093c7f..9ffd65d 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl
@@ -20,13 +20,8 @@ {{ kythe_annotation(full_enum_name) }} enum class {{enum_name}} : int32_t { {%- for field in enum.fields %} -{%- if field.value %} {{ kythe_annotation("%s.%s"|format(full_enum_name, field.name)) }} - {{field.name}} = {{field.value|expression_to_text}}, -{%- else %} - {{ kythe_annotation("%s.%s"|format(full_enum_name, field.name)) }} - {{field.name}}, -{%- endif %} + {{field.name}} = {{field.numeric_value}}, {%- endfor %} {%- if enum.min_value is not none %} kMinValue = {{enum.min_value}},
diff --git a/mojo/public/tools/bindings/generators/java_templates/enum_definition.tmpl b/mojo/public/tools/bindings/generators/java_templates/enum_definition.tmpl index 0daf77b3..e09f00aa 100644 --- a/mojo/public/tools/bindings/generators/java_templates/enum_definition.tmpl +++ b/mojo/public/tools/bindings/generators/java_templates/enum_definition.tmpl
@@ -1,18 +1,8 @@ -{%- macro enum_value(enum, field, index) -%} -{%- if field.value -%} -{{field.value|expression_to_text('i32')}}; -{%- elif index == 0 -%} -{{field.numeric_value}}; -{%- else -%} -{{field.numeric_value}}; // {{enum.fields[index - 1]|name}} + 1 -{%- endif -%} -{%- endmacro -%} - {%- macro enum_def(enum, top_level) -%} public {{ 'static ' if not top_level }}final class {{enum|name}} { private static final boolean IS_EXTENSIBLE = {% if enum.extensible %}true{% else %}false{% endif %}; {% for field in enum.fields %} - public static final int {{field|name}} = {{enum_value(enum, field, loop.index0)}} + public static final int {{field|name}} = {{field.numeric_value}}; {%- endfor %} {%- if enum|covers_continuous_range %}
diff --git a/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl b/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl index 26961956..50341269 100644 --- a/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl +++ b/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl
@@ -2,13 +2,7 @@ {{enum_name}} = {}; {%- set prev_enum = 0 %} {%- for field in enum.fields %} -{%- if field.value %} - {{enum_name}}.{{field.name}} = {{field.value|expression_to_text}}; -{%- elif loop.first %} - {{enum_name}}.{{field.name}} = 0; -{%- else %} - {{enum_name}}.{{field.name}} = {{enum_name}}.{{enum.fields[loop.index0 - 1].name}} + 1; -{%- endif %} + {{enum_name}}.{{field.name}} = {{field.numeric_value}}; {%- endfor %} {%- if enum.min_value is not none %} {{enum_name}}.MIN_VALUE = {{enum.min_value}},
diff --git a/mojo/public/tools/bindings/generators/js_templates/lite/enum_definition.tmpl b/mojo/public/tools/bindings/generators/js_templates/lite/enum_definition.tmpl index affa4d09..d6561f3b 100644 --- a/mojo/public/tools/bindings/generators/js_templates/lite/enum_definition.tmpl +++ b/mojo/public/tools/bindings/generators/js_templates/lite/enum_definition.tmpl
@@ -21,7 +21,7 @@ {{enum_name}} = { {# Set up the enum here, but fill out the values later. #} {%- for field in enum.fields %} - {{field.name}}: 0, + {{field.name}}: {{field.numeric_value}}, {%- endfor %} {%- if enum.min_value is not none %} MIN_VALUE: {{enum.min_value}}, @@ -30,16 +30,5 @@ MAX_VALUE: {{enum.max_value}}, {%- endif %} }; -{%- for field in enum.fields %} -{# Suppress type checks since we're assigning number into an enum. #} -/** @suppress {checkTypes} */ -{%- if field.value %} -{{enum_name}}.{{field.name}} = {{field.value|expression_to_text_lite}}; -{%- elif loop.first %} -{{enum_name}}.{{field.name}} = 0; -{%- else %} -{{enum_name}}.{{field.name}} = {{enum_name}}.{{enum.fields[loop.index0 - 1].name}} + 1; -{%- endif %} -{%- endfor %} {%- endmacro %}
diff --git a/mojo/public/tools/bindings/generators/ts_templates/module_definition.tmpl b/mojo/public/tools/bindings/generators/ts_templates/module_definition.tmpl index dc6d54d..d219a88 100644 --- a/mojo/public/tools/bindings/generators/ts_templates/module_definition.tmpl +++ b/mojo/public/tools/bindings/generators/ts_templates/module_definition.tmpl
@@ -11,11 +11,7 @@ {% for enum in enums %} export enum {{enum.name}} { {%- for field in enum.fields %} -{%- if field.value %} - {{field.name}} = {{field.value}}, -{%- else %} - {{field.name}}, -{%- endif %} + {{field.name}} = {{field.numeric_value}}, {%- endfor %} {%- if enum.min_value is not none %} MIN_VALUE = {{enum.min_value}},
diff --git a/mojo/public/tools/mojom/const_unittest.py b/mojo/public/tools/mojom/const_unittest.py new file mode 100755 index 0000000..7ba67d1 --- /dev/null +++ b/mojo/public/tools/mojom/const_unittest.py
@@ -0,0 +1,91 @@ +#!/usr/bin/env python +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +from mojom_parser_test_case import MojomParserTestCase +from mojom.generate import module as mojom + + +class ConstTest(MojomParserTestCase): + """Tests constant parsing behavior.""" + + def testLiteralInt(self): + a_mojom = 'a.mojom' + self.WriteFile(a_mojom, 'const int32 k = 42;') + self.ParseMojoms([a_mojom]) + a = self.LoadModule(a_mojom) + self.assertEqual(1, len(a.constants)) + self.assertEqual('k', a.constants[0].mojom_name) + self.assertEqual('42', a.constants[0].value) + + def testLiteralFloat(self): + a_mojom = 'a.mojom' + self.WriteFile(a_mojom, 'const float k = 42.5;') + self.ParseMojoms([a_mojom]) + a = self.LoadModule(a_mojom) + self.assertEqual(1, len(a.constants)) + self.assertEqual('k', a.constants[0].mojom_name) + self.assertEqual('42.5', a.constants[0].value) + + def testLiteralString(self): + a_mojom = 'a.mojom' + self.WriteFile(a_mojom, 'const string k = "woot";') + self.ParseMojoms([a_mojom]) + a = self.LoadModule(a_mojom) + self.assertEqual(1, len(a.constants)) + self.assertEqual('k', a.constants[0].mojom_name) + self.assertEqual('"woot"', a.constants[0].value) + + def testEnumConstant(self): + a_mojom = 'a.mojom' + self.WriteFile(a_mojom, 'module a; enum E { kA = 41, kB };') + b_mojom = 'b.mojom' + self.WriteFile( + b_mojom, """\ + import "a.mojom"; + const a.E kE1 = a.E.kB; + + // We also allow value names to be unqualified, implying scope from the + // constant's type. + const a.E kE2 = kB; + """) + self.ParseMojoms([a_mojom, b_mojom]) + a = self.LoadModule(a_mojom) + b = self.LoadModule(b_mojom) + self.assertEqual(1, len(a.enums)) + self.assertEqual('E', a.enums[0].mojom_name) + self.assertEqual(2, len(b.constants)) + self.assertEqual('kE1', b.constants[0].mojom_name) + self.assertEqual(a.enums[0], b.constants[0].kind) + self.assertEqual(a.enums[0].fields[1], b.constants[0].value.field) + self.assertEqual(42, b.constants[0].value.field.numeric_value) + self.assertEqual('kE2', b.constants[1].mojom_name) + self.assertEqual(a.enums[0].fields[1], b.constants[1].value.field) + self.assertEqual(42, b.constants[1].value.field.numeric_value) + + def testConstantReference(self): + a_mojom = 'a.mojom' + self.WriteFile(a_mojom, 'const int32 kA = 42; const int32 kB = kA;') + self.ParseMojoms([a_mojom]) + a = self.LoadModule(a_mojom) + self.assertEqual(2, len(a.constants)) + self.assertEqual('kA', a.constants[0].mojom_name) + self.assertEqual('42', a.constants[0].value) + self.assertEqual('kB', a.constants[1].mojom_name) + self.assertEqual('42', a.constants[1].value) + + def testImportedConstantReference(self): + a_mojom = 'a.mojom' + self.WriteFile(a_mojom, 'const int32 kA = 42;') + b_mojom = 'b.mojom' + self.WriteFile(b_mojom, 'import "a.mojom"; const int32 kB = kA;') + self.ParseMojoms([a_mojom, b_mojom]) + a = self.LoadModule(a_mojom) + b = self.LoadModule(b_mojom) + self.assertEqual(1, len(a.constants)) + self.assertEqual(1, len(b.constants)) + self.assertEqual('kA', a.constants[0].mojom_name) + self.assertEqual('42', a.constants[0].value) + self.assertEqual('kB', b.constants[0].mojom_name) + self.assertEqual('42', b.constants[0].value)
diff --git a/mojo/public/tools/mojom/enum_unittest.py b/mojo/public/tools/mojom/enum_unittest.py new file mode 100755 index 0000000..4b273e0d --- /dev/null +++ b/mojo/public/tools/mojom/enum_unittest.py
@@ -0,0 +1,93 @@ +#!/usr/bin/env python +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +from mojom_parser_test_case import MojomParserTestCase + + +class EnumTest(MojomParserTestCase): + """Tests enum parsing behavior.""" + + def testExplicitValues(self): + """Verifies basic parsing of assigned integral values.""" + types = self.ExtractTypes('enum E { kFoo=0, kBar=2, kBaz };') + self.assertEqual('kFoo', types['E'].fields[0].mojom_name) + self.assertEqual(0, types['E'].fields[0].numeric_value) + self.assertEqual('kBar', types['E'].fields[1].mojom_name) + self.assertEqual(2, types['E'].fields[1].numeric_value) + self.assertEqual('kBaz', types['E'].fields[2].mojom_name) + self.assertEqual(3, types['E'].fields[2].numeric_value) + + def testImplicitValues(self): + """Verifies basic automatic assignment of integral values at parse time.""" + types = self.ExtractTypes('enum E { kFoo, kBar, kBaz };') + self.assertEqual('kFoo', types['E'].fields[0].mojom_name) + self.assertEqual(0, types['E'].fields[0].numeric_value) + self.assertEqual('kBar', types['E'].fields[1].mojom_name) + self.assertEqual(1, types['E'].fields[1].numeric_value) + self.assertEqual('kBaz', types['E'].fields[2].mojom_name) + self.assertEqual(2, types['E'].fields[2].numeric_value) + + def testSameEnumReference(self): + """Verifies that an enum value can be assigned from the value of another + field within the same enum.""" + types = self.ExtractTypes('enum E { kA, kB, kFirst=kA };') + self.assertEqual('kA', types['E'].fields[0].mojom_name) + self.assertEqual(0, types['E'].fields[0].numeric_value) + self.assertEqual('kB', types['E'].fields[1].mojom_name) + self.assertEqual(1, types['E'].fields[1].numeric_value) + self.assertEqual('kFirst', types['E'].fields[2].mojom_name) + self.assertEqual(0, types['E'].fields[2].numeric_value) + + def testSameModuleOtherEnumReference(self): + """Verifies that an enum value can be assigned from the value of a field + in another enum within the same module.""" + types = self.ExtractTypes('enum E { kA, kB }; enum F { kA = E.kB };') + self.assertEqual(1, types['F'].fields[0].numeric_value) + + def testImportedEnumReference(self): + """Verifies that an enum value can be assigned from the value of a field + in another enum within a different module.""" + a_mojom = 'a.mojom' + self.WriteFile(a_mojom, 'module a; enum E { kFoo=42, kBar };') + b_mojom = 'b.mojom' + self.WriteFile(b_mojom, + 'module b; import "a.mojom"; enum F { kFoo = a.E.kBar };') + self.ParseMojoms([a_mojom, b_mojom]) + b = self.LoadModule(b_mojom) + + self.assertEqual('F', b.enums[0].mojom_name) + self.assertEqual('kFoo', b.enums[0].fields[0].mojom_name) + self.assertEqual(43, b.enums[0].fields[0].numeric_value) + + def testConstantReference(self): + """Verifies that an enum value can be assigned from the value of an + integral constant within the same module.""" + types = self.ExtractTypes('const int32 kFoo = 42; enum E { kA = kFoo };') + self.assertEqual(42, types['E'].fields[0].numeric_value) + + def testInvalidConstantReference(self): + """Verifies that enum values cannot be assigned from the value of + non-integral constants.""" + with self.assertRaisesRegexp(ValueError, 'not an integer'): + self.ExtractTypes('const float kFoo = 1.0; enum E { kA = kFoo };') + with self.assertRaisesRegexp(ValueError, 'not an integer'): + self.ExtractTypes('const double kFoo = 1.0; enum E { kA = kFoo };') + with self.assertRaisesRegexp(ValueError, 'not an integer'): + self.ExtractTypes('const string kFoo = "lol"; enum E { kA = kFoo };') + + def testImportedConstantReference(self): + """Verifies that an enum value can be assigned from the value of an integral + constant within an imported module.""" + a_mojom = 'a.mojom' + self.WriteFile(a_mojom, 'module a; const int32 kFoo = 37;') + b_mojom = 'b.mojom' + self.WriteFile(b_mojom, + 'module b; import "a.mojom"; enum F { kFoo = a.kFoo };') + self.ParseMojoms([a_mojom, b_mojom]) + b = self.LoadModule(b_mojom) + + self.assertEqual('F', b.enums[0].mojom_name) + self.assertEqual('kFoo', b.enums[0].fields[0].mojom_name) + self.assertEqual(37, b.enums[0].fields[0].numeric_value)
diff --git a/mojo/public/tools/mojom/mojom/generate/module.py b/mojo/public/tools/mojom/mojom/generate/module.py index f77cbe227..addb308b 100644 --- a/mojo/public/tools/mojom/mojom/generate/module.py +++ b/mojo/public/tools/mojom/mojom/generate/module.py
@@ -264,7 +264,7 @@ self.mojom_name = mojom_name def GetSpec(self): - return (self.module.mojom_namespace + '.' + + return (self.module.GetNamespacePrefix() + (self.parent_kind and (self.parent_kind.mojom_name + '.') or "") + self.mojom_name) @@ -299,9 +299,9 @@ self.enum = enum def GetSpec(self): - return (self.module.mojom_namespace + '.' + - (self.parent_kind and (self.parent_kind.mojom_name + '.') - or "") + self.enum.mojom_name + '.' + self.mojom_name) + return (self.module.GetNamespacePrefix() + + (self.parent_kind and (self.parent_kind.mojom_name + '.') or "") + + self.enum.mojom_name + '.' + self.mojom_name) @property def name(self): @@ -1017,6 +1017,9 @@ 'unions': False }) + def GetNamespacePrefix(self): + return '%s.' % self.mojom_namespace if self.mojom_namespace else '' + def AddInterface(self, mojom_name, attributes=None): interface = Interface(mojom_name, self, attributes) self.interfaces.append(interface)
diff --git a/mojo/public/tools/mojom/mojom/generate/translate.py b/mojo/public/tools/mojom/mojom/generate/translate.py index 6854b8b..7219b023 100644 --- a/mojo/public/tools/mojom/mojom/generate/translate.py +++ b/mojo/public/tools/mojom/mojom/generate/translate.py
@@ -50,6 +50,23 @@ return result +def _ProcessElements(scope, elements, operations_by_type): + """Iterates over the given elements, running a function from + operations_by_type for any element that matches a key in that dict. The scope + is the name of the surrounding scope, such as a filename or struct name, used + only in error messages.""" + names_in_this_scope = set() + for element in elements: + # pylint: disable=unidiomatic-typecheck + element_type = type(element) + if element_type in operations_by_type: + if element.mojom_name in names_in_this_scope: + raise Exception('Names must be unique within a scope. The name "%s" is ' + 'used more than once within the scope "%s".' % + (duplicate_name, scope)) + operations_by_type[element_type](element) + + def _MapKind(kind): map_to_kind = { 'bool': 'b', @@ -153,39 +170,62 @@ return kinds.get(spec) -def _LookupValue(values, mojom_name, scope, kind): - """Like LookupKind, but for constant values.""" - # If the type is an enum, the value can be specified as a qualified name, in - # which case the form EnumName.ENUM_VALUE must be used. We use the presence - # of a '.' in the requested name to identify this. Otherwise, we prepend the - # enum name. - if isinstance(kind, mojom.Enum) and '.' not in mojom_name: - mojom_name = '%s.%s' % (kind.spec.split(':', 1)[1], mojom_name) +def _GetScopeForKind(module, kind): + """For a given kind, returns a tuple of progressively more specific names + used to qualify the kind. For example if kind is an enum named Bar nested in a + struct Foo within module 'foo', this would return ('foo', 'Foo', 'Bar')""" + if isinstance(kind, mojom.Enum) and kind.parent_kind: + # Enums may be nested in other kinds. + return _GetScopeForKind(module, kind.parent_kind) + (kind.mojom_name, ) + + module_fragment = (module.mojom_namespace, ) if module.mojom_namespace else () + kind_fragment = (kind.mojom_name, ) if kind else () + return module_fragment + kind_fragment + + +def _LookupValueInScope(module, kind, identifier): + """Given a kind and an identifier, this attempts to resolve the given + identifier to a concrete NamedValue within the scope of the given kind.""" + scope = _GetScopeForKind(module, kind) for i in reversed(range(len(scope) + 1)): - test_spec = '.'.join(scope[:i]) - if test_spec: - test_spec += '.' - test_spec += mojom_name - value = values.get(test_spec) + qualified_name = '.'.join(scope[:i] + (identifier, )) + value = module.values.get(qualified_name) if value: return value - - return values.get(mojom_name) + return None -def _FixupExpression(module, value, scope, kind): - """Translates an IDENTIFIER into a built-in value or structured NamedValue - object.""" - if isinstance(value, tuple) and value[0] == 'IDENTIFIER': - # Allow user defined values to shadow builtins. - result = _LookupValue(module.values, value[1], scope, kind) - if result: - if isinstance(result, tuple): - raise Exception('Unable to resolve expression: %r' % value[1]) - return result - if _IsBuiltinValue(value[1]): - return mojom.BuiltinValue(value[1]) - return value +def _LookupValue(module, parent_kind, implied_kind, ast_leaf_node): + """Resolves a leaf node in the form ('IDENTIFIER', 'x') to a constant value + identified by 'x' in some mojom definition. parent_kind is used as context + when resolving the identifier. If the given leaf node is not an IDENTIFIER + (e.g. already a constant value), it is returned as-is. + + If implied_kind is provided, the parsed identifier may also be resolved within + its scope as fallback. This can be useful for more concise value references + when assigning enum-typed constants or field values.""" + if not isinstance(ast_leaf_node, tuple) or ast_leaf_node[0] != 'IDENTIFIER': + return ast_leaf_node + + # First look for a known user-defined identifier to resolve this within the + # enclosing scope. + identifier = ast_leaf_node[1] + + value = _LookupValueInScope(module, parent_kind, identifier) + if value: + return value + + # Next look in the scope of implied_kind, if provided. + value = (implied_kind and implied_kind.module and _LookupValueInScope( + implied_kind.module, implied_kind, identifier)) + if value: + return value + + # Fall back on defined builtin symbols + if _IsBuiltinValue(identifier): + return mojom.BuiltinValue(identifier) + + raise ValueError('Unknown identifier %s' % identifier) def _Kind(kinds, spec, scope): @@ -280,26 +320,22 @@ struct = mojom.Struct(module=module) struct.mojom_name = parsed_struct.mojom_name struct.native_only = parsed_struct.body is None - struct.spec = 'x:' + module.mojom_namespace + '.' + struct.mojom_name + struct.spec = 'x:' + module.GetNamespacePrefix() + struct.mojom_name module.kinds[struct.spec] = struct - if struct.native_only: - struct.enums = [] - struct.constants = [] - struct.fields_data = [] - else: - struct.enums = list( - map( - lambda enum: _Enum(module, enum, struct), - _ElemsOfType(parsed_struct.body, ast.Enum, - parsed_struct.mojom_name))) - struct.constants = list( - map( - lambda constant: _Constant(module, constant, struct), - _ElemsOfType(parsed_struct.body, ast.Const, - parsed_struct.mojom_name))) - # Stash fields parsed_struct here temporarily. - struct.fields_data = _ElemsOfType(parsed_struct.body, ast.StructField, - parsed_struct.mojom_name) + struct.enums = [] + struct.constants = [] + struct.fields_data = [] + if not struct.native_only: + _ProcessElements( + parsed_struct.mojom_name, parsed_struct.body, { + ast.Enum: + lambda enum: struct.enums.append(_Enum(module, enum, struct)), + ast.Const: + lambda const: struct.constants.append( + _Constant(module, const, struct)), + ast.StructField: + struct.fields_data.append, + }) struct.attributes = _AttributeListToDict(parsed_struct.attribute_list) @@ -327,11 +363,12 @@ """ union = mojom.Union(module=module) union.mojom_name = parsed_union.mojom_name - union.spec = 'x:' + module.mojom_namespace + '.' + union.mojom_name + union.spec = 'x:' + module.GetNamespacePrefix() + union.mojom_name module.kinds[union.spec] = union # Stash fields parsed_union here temporarily. - union.fields_data = _ElemsOfType(parsed_union.body, ast.UnionField, - parsed_union.mojom_name) + union.fields_data = [] + _ProcessElements(parsed_union.mojom_name, parsed_union.body, + {ast.UnionField: union.fields_data.append}) union.attributes = _AttributeListToDict(parsed_union.attribute_list) return union @@ -351,9 +388,8 @@ field.kind = _Kind(module.kinds, _MapKind(parsed_field.typename), (module.mojom_namespace, struct.mojom_name)) field.ordinal = parsed_field.ordinal.value if parsed_field.ordinal else None - field.default = _FixupExpression(module, parsed_field.default_value, - (module.mojom_namespace, struct.mojom_name), - field.kind) + field.default = _LookupValue(module, struct, field.kind, + parsed_field.default_value) field.attributes = _AttributeListToDict(parsed_field.attribute_list) return field @@ -373,8 +409,7 @@ field.kind = _Kind(module.kinds, _MapKind(parsed_field.typename), (module.mojom_namespace, union.mojom_name)) field.ordinal = parsed_field.ordinal.value if parsed_field.ordinal else None - field.default = _FixupExpression( - module, None, (module.mojom_namespace, union.mojom_name), field.kind) + field.default = None field.attributes = _AttributeListToDict(parsed_field.attribute_list) return field @@ -444,67 +479,55 @@ """ interface = mojom.Interface(module=module) interface.mojom_name = parsed_iface.mojom_name - interface.spec = 'x:' + module.mojom_namespace + '.' + interface.mojom_name + interface.spec = 'x:' + module.GetNamespacePrefix() + interface.mojom_name module.kinds[interface.spec] = interface - interface.enums = list( - map(lambda enum: _Enum(module, enum, interface), - _ElemsOfType(parsed_iface.body, ast.Enum, parsed_iface.mojom_name))) - interface.constants = list( - map(lambda constant: _Constant(module, constant, interface), - _ElemsOfType(parsed_iface.body, ast.Const, parsed_iface.mojom_name))) - # Stash methods parsed_iface here temporarily. - interface.methods_data = _ElemsOfType(parsed_iface.body, ast.Method, - parsed_iface.mojom_name) interface.attributes = _AttributeListToDict(parsed_iface.attribute_list) + interface.enums = [] + interface.constants = [] + interface.methods_data = [] + _ProcessElements( + parsed_iface.mojom_name, parsed_iface.body, { + ast.Enum: + lambda enum: interface.enums.append(_Enum(module, enum, interface)), + ast.Const: + lambda const: interface.constants.append( + _Constant(module, const, interface)), + ast.Method: + interface.methods_data.append, + }) return interface -def _EnumField(module, enum, parsed_field, parent_kind): +def _EnumField(module, enum, parsed_field): """ Args: module: {mojom.Module} Module currently being constructed. enum: {mojom.Enum} Enum this field belongs to. parsed_field: {ast.EnumValue} Parsed enum value. - parent_kind: {mojom.Kind} The enclosing type. Returns: {mojom.EnumField} AST enum field. """ field = mojom.EnumField() field.mojom_name = parsed_field.mojom_name - # TODO(mpcomplete): FixupExpression should be done in the second pass, - # so constants and enums can refer to each other. - # TODO(mpcomplete): But then, what if constants are initialized to an enum? Or - # vice versa? - if parent_kind: - field.value = _FixupExpression( - module, parsed_field.value, - (module.mojom_namespace, parent_kind.mojom_name), enum) - else: - field.value = _FixupExpression(module, parsed_field.value, - (module.mojom_namespace, ), enum) + field.value = _LookupValue(module, enum, None, parsed_field.value) field.attributes = _AttributeListToDict(parsed_field.attribute_list) value = mojom.EnumValue(module, enum, field) module.values[value.GetSpec()] = value return field -def _ResolveNumericEnumValues(enum_fields): +def _ResolveNumericEnumValues(enum): """ - Given a reference to a list of mojom.EnumField, resolves and assigns their - values to EnumField.numeric_value. - - Returns: - A tuple of the lowest and highest assigned enumerator value or None, None - if no enumerator values were assigned. + Given a reference to a mojom.Enum, resolves and assigns the numeric value of + each field, and also computes the min_value and max_value of the enum. """ # map of <mojom_name> -> integral value - resolved_enum_values = {} prev_value = -1 min_value = None max_value = None - for field in enum_fields: + for field in enum.fields: # This enum value is +1 the previous enum value (e.g: BEGIN). if field.value is None: prev_value += 1 @@ -515,18 +538,26 @@ # Reference to a previous enum value (e.g: INIT = BEGIN). elif isinstance(field.value, mojom.EnumValue): - prev_value = resolved_enum_values[field.value.mojom_name] + prev_value = field.value.field.numeric_value + elif isinstance(field.value, mojom.ConstantValue): + constant = field.value.constant + kind = constant.kind + if not mojom.IsIntegralKind(kind) or mojom.IsBoolKind(kind): + raise ValueError('Enum values must be integers. %s is not an integer.' % + constant.mojom_name) + prev_value = int(constant.value, 0) else: - raise Exception("Unresolved enum value.") + raise Exception('Unresolved enum value for %s' % field.value.GetSpec()) - resolved_enum_values[field.mojom_name] = prev_value + #resolved_enum_values[field.mojom_name] = prev_value field.numeric_value = prev_value if min_value is None or prev_value < min_value: min_value = prev_value if max_value is None or prev_value > max_value: max_value = prev_value - return min_value, max_value + enum.min_value = min_value + enum.max_value = max_value def _Enum(module, parsed_enum, parent_kind): @@ -547,11 +578,12 @@ enum.spec = 'x:%s.%s' % (module.mojom_namespace, mojom_name) enum.parent_kind = parent_kind enum.attributes = _AttributeListToDict(parsed_enum.attribute_list) + if not enum.native_only: enum.fields = list( - map(lambda field: _EnumField(module, enum, field, parent_kind), + map(lambda field: _EnumField(module, enum, field), parsed_enum.enum_value_list)) - enum.min_value, enum.max_value = _ResolveNumericEnumValues(enum.fields) + _ResolveNumericEnumValues(enum) module.kinds[enum.spec] = enum @@ -583,7 +615,12 @@ # TODO(mpcomplete): maybe we should only support POD kinds. constant.kind = _Kind(module.kinds, _MapKind(parsed_const.typename), scope) constant.parent_kind = parent_kind - constant.value = _FixupExpression(module, parsed_const.value, scope, None) + constant.value = _LookupValue(module, parent_kind, constant.kind, + parsed_const.value) + + # Iteratively resolve this constant reference to a concrete value + while isinstance(constant.value, mojom.ConstantValue): + constant.value = constant.value.constant.value value = mojom.ConstantValue(module, parent_kind, constant) module.values[value.GetSpec()] = value @@ -675,21 +712,25 @@ filename = os.path.basename(path) # First pass collects kinds. - module.enums = list( - map(lambda enum: _Enum(module, enum, None), - _ElemsOfType(tree.definition_list, ast.Enum, filename))) - module.structs = list( - map(lambda struct: _Struct(module, struct), - _ElemsOfType(tree.definition_list, ast.Struct, filename))) - module.unions = list( - map(lambda union: _Union(module, union), - _ElemsOfType(tree.definition_list, ast.Union, filename))) - module.interfaces = list( - map(lambda interface: _Interface(module, interface), - _ElemsOfType(tree.definition_list, ast.Interface, filename))) - module.constants = list( - map(lambda constant: _Constant(module, constant, None), - _ElemsOfType(tree.definition_list, ast.Const, filename))) + module.constants = [] + module.enums = [] + module.structs = [] + module.unions = [] + module.interfaces = [] + _ProcessElements( + filename, tree.definition_list, { + ast.Const: + lambda const: module.constants.append(_Constant(module, const, None)), + ast.Enum: + lambda enum: module.enums.append(_Enum(module, enum, None)), + ast.Struct: + lambda struct: module.structs.append(_Struct(module, struct)), + ast.Union: + lambda union: module.unions.append(_Union(module, union)), + ast.Interface: + lambda interface: module.interfaces.append( + _Interface(module, interface)), + }) # Second pass expands fields and methods. This allows fields and parameters # to refer to kinds defined anywhere in the mojom.
diff --git a/mojo/public/tools/mojom/mojom_parser_test_case.py b/mojo/public/tools/mojom/mojom_parser_test_case.py new file mode 100644 index 0000000..e213fbfa7 --- /dev/null +++ b/mojo/public/tools/mojom/mojom_parser_test_case.py
@@ -0,0 +1,73 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import json +import os +import os.path +import shutil +import tempfile +import unittest + +import mojom_parser + +from mojom.generate import module + + +class MojomParserTestCase(unittest.TestCase): + """Tests covering the behavior defined by the main mojom_parser.py script. + This includes behavior around input and output path manipulation, dependency + resolution, and module serialization and deserialization.""" + + def __init__(self, method_name): + super(MojomParserTestCase, self).__init__(method_name) + self._temp_dir = None + + def setUp(self): + self._temp_dir = tempfile.mkdtemp() + + def tearDown(self): + shutil.rmtree(self._temp_dir) + self._temp_dir = None + + def GetPath(self, path): + assert not os.path.isabs(path) + return os.path.join(self._temp_dir, path) + + def GetModulePath(self, path): + assert not os.path.isabs(path) + return os.path.join(self.GetPath('out'), path) + '-module' + + def WriteFile(self, path, contents): + full_path = self.GetPath(path) + dirname = os.path.dirname(full_path) + if not os.path.exists(dirname): + os.makedirs(dirname) + with open(full_path, 'w') as f: + f.write(contents) + + def LoadModule(self, mojom_path): + with open(self.GetModulePath(mojom_path), 'rb') as f: + return module.Module.Load(f) + + def ParseMojoms(self, mojoms, metadata=None): + """Parse all input mojoms relative the temp dir.""" + out_dir = self.GetPath('out') + args = [ + '--input-root', self._temp_dir, '--input-root', out_dir, + '--output-root', out_dir, '--mojoms' + ] + list(map(lambda mojom: os.path.join(self._temp_dir, mojom), mojoms)) + if metadata: + args.extend(['--check-imports', self.GetPath(metadata)]) + mojom_parser.Run(args) + + def ExtractTypes(self, mojom): + filename = 'test.mojom' + self.WriteFile(filename, mojom) + self.ParseMojoms([filename]) + m = self.LoadModule(filename) + definitions = {} + for kinds in (m.enums, m.structs, m.unions, m.interfaces): + for kind in kinds: + definitions[kind.mojom_name] = kind + return definitions
diff --git a/mojo/public/tools/mojom/mojom_parser_unittest.py b/mojo/public/tools/mojom/mojom_parser_unittest.py index 9aa655d..bdb7f8f 100755 --- a/mojo/public/tools/mojom/mojom_parser_unittest.py +++ b/mojo/public/tools/mojom/mojom_parser_unittest.py
@@ -3,65 +3,14 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import json -import os -import os.path -import shutil -import tempfile -import unittest - -import mojom_parser - -from mojom.generate import module +from mojom_parser_test_case import MojomParserTestCase -class MojomParserTest(unittest.TestCase): +class MojomParserTest(MojomParserTestCase): """Tests covering the behavior defined by the main mojom_parser.py script. This includes behavior around input and output path manipulation, dependency resolution, and module serialization and deserialization.""" - def __init__(self, method_name): - super(MojomParserTest, self).__init__(method_name) - self._temp_dir = None - - def setUp(self): - self._temp_dir = tempfile.mkdtemp() - - def tearDown(self): - shutil.rmtree(self._temp_dir) - self._temp_dir = None - - def GetPath(self, path): - assert not os.path.isabs(path) - return os.path.join(self._temp_dir, path) - - def GetModulePath(self, path): - assert not os.path.isabs(path) - return os.path.join(self.GetPath('out'), path) + '-module' - - def WriteFile(self, path, contents): - full_path = self.GetPath(path) - dirname = os.path.dirname(full_path) - if not os.path.exists(dirname): - os.makedirs(dirname) - with open(full_path, 'w') as f: - f.write(contents) - - def LoadModule(self, mojom_path): - with open(self.GetModulePath(mojom_path), 'rb') as f: - return module.Module.Load(f) - - def ParseMojoms(self, mojoms, metadata=None): - """Parse all input mojoms relative the temp dir.""" - out_dir = self.GetPath('out') - args = [ - '--input-root', self._temp_dir, '--input-root', out_dir, - '--output-root', out_dir, '--mojoms' - ] + list(map(lambda mojom: os.path.join(self._temp_dir, mojom), mojoms)) - if metadata: - args.extend(['--check-imports', self.GetPath(metadata)]) - mojom_parser.Run(args) - def testBasicParse(self): """Basic test to verify that we can parse a mojom file and get a module.""" mojom = 'foo/bar.mojom'
diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc index 553a587b..13cac26 100644 --- a/net/http/transport_security_state.cc +++ b/net/http/transport_security_state.cc
@@ -658,72 +658,21 @@ const base::Time& expiry, bool include_subdomains) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + const std::string canonicalized_host = CanonicalizeHost(host); + if (canonicalized_host.empty()) + return; STSState sts_state; + // No need to store |sts_state.domain| since it is redundant. + // (|canonicalized_host| is the map key.) sts_state.last_observed = base::Time::Now(); sts_state.include_subdomains = include_subdomains; sts_state.expiry = expiry; sts_state.upgrade_mode = upgrade_mode; - EnableSTSHost(host, sts_state); -} - -void TransportSecurityState::AddHPKPInternal(const std::string& host, - const base::Time& last_observed, - const base::Time& expiry, - bool include_subdomains, - const HashValueVector& hashes, - const GURL& report_uri) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - - PKPState pkp_state; - pkp_state.last_observed = last_observed; - pkp_state.expiry = expiry; - pkp_state.include_subdomains = include_subdomains; - pkp_state.spki_hashes = hashes; - pkp_state.report_uri = report_uri; - - EnablePKPHost(host, pkp_state); -} - -void TransportSecurityState::AddExpectCTInternal( - const std::string& host, - const base::Time& last_observed, - const base::Time& expiry, - bool enforce, - const GURL& report_uri) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - - ExpectCTState expect_ct_state; - expect_ct_state.last_observed = last_observed; - expect_ct_state.expiry = expiry; - expect_ct_state.enforce = enforce; - expect_ct_state.report_uri = report_uri; - - EnableExpectCTHost(host, expect_ct_state); -} - -void TransportSecurityState:: - SetEnablePublicKeyPinningBypassForLocalTrustAnchors(bool value) { - enable_pkp_bypass_for_local_trust_anchors_ = value; -} - -void TransportSecurityState::EnableSTSHost(const std::string& host, - const STSState& state) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - - const std::string canonicalized_host = CanonicalizeHost(host); - if (canonicalized_host.empty()) - return; - // Only store new state when HSTS is explicitly enabled. If it is // disabled, remove the state from the enabled hosts. - if (state.ShouldUpgradeToSSL()) { - STSState sts_state(state); - // No need to store this value since it is redundant. (|canonicalized_host| - // is the map key.) - sts_state.domain.clear(); - + if (sts_state.ShouldUpgradeToSSL()) { enabled_sts_hosts_[HashHost(canonicalized_host)] = sts_state; } else { const std::string hashed_host = HashHost(canonicalized_host); @@ -733,22 +682,29 @@ DirtyNotify(); } -void TransportSecurityState::EnablePKPHost(const std::string& host, - const PKPState& state) { +void TransportSecurityState::AddHPKPInternal(const std::string& host, + const base::Time& last_observed, + const base::Time& expiry, + bool include_subdomains, + const HashValueVector& hashes, + const GURL& report_uri) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - const std::string canonicalized_host = CanonicalizeHost(host); if (canonicalized_host.empty()) return; + PKPState pkp_state; + // No need to store |pkp_state.domain| since it is redundant. + // (|canonicalized_host| is the map key.) + pkp_state.last_observed = last_observed; + pkp_state.expiry = expiry; + pkp_state.include_subdomains = include_subdomains; + pkp_state.spki_hashes = hashes; + pkp_state.report_uri = report_uri; + // Only store new state when HPKP is explicitly enabled. If it is // disabled, remove the state from the enabled hosts. - if (state.HasPublicKeyPins()) { - PKPState pkp_state(state); - // No need to store this value since it is redundant. (|canonicalized_host| - // is the map key.) - pkp_state.domain.clear(); - + if (pkp_state.HasPublicKeyPins()) { enabled_pkp_hosts_[HashHost(canonicalized_host)] = pkp_state; } else { const std::string hashed_host = HashHost(canonicalized_host); @@ -758,8 +714,12 @@ DirtyNotify(); } -void TransportSecurityState::EnableExpectCTHost(const std::string& host, - const ExpectCTState& state) { +void TransportSecurityState::AddExpectCTInternal( + const std::string& host, + const base::Time& last_observed, + const base::Time& expiry, + bool enforce, + const GURL& report_uri) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (!IsDynamicExpectCTEnabled()) return; @@ -768,14 +728,17 @@ if (canonicalized_host.empty()) return; + ExpectCTState expect_ct_state; + // No need to store |expect_ct_state.domain| since it is redundant. + // (|canonicalized_host| is the map key.) + expect_ct_state.last_observed = last_observed; + expect_ct_state.expiry = expiry; + expect_ct_state.enforce = enforce; + expect_ct_state.report_uri = report_uri; + // Only store new state when Expect-CT is explicitly enabled. If it is // disabled, remove the state from the enabled hosts. - if (state.enforce || !state.report_uri.is_empty()) { - ExpectCTState expect_ct_state(state); - // No need to store this value since it is redundant. (|canonicalized_host| - // is the map key.) - expect_ct_state.domain.clear(); - + if (expect_ct_state.enforce || !expect_ct_state.report_uri.is_empty()) { enabled_expect_ct_hosts_[HashHost(canonicalized_host)] = expect_ct_state; } else { const std::string hashed_host = HashHost(canonicalized_host); @@ -785,6 +748,11 @@ DirtyNotify(); } +void TransportSecurityState:: + SetEnablePublicKeyPinningBypassForLocalTrustAnchors(bool value) { + enable_pkp_bypass_for_local_trust_anchors_ = value; +} + TransportSecurityState::PKPStatus TransportSecurityState::CheckPinsAndMaybeSendReport( const HostPortPair& host_port_pair,
diff --git a/net/http/transport_security_state.h b/net/http/transport_security_state.h index b54581d4..4e077d1 100644 --- a/net/http/transport_security_state.h +++ b/net/http/transport_security_state.h
@@ -579,35 +579,26 @@ // changed. void DirtyNotify(); - // Adds HSTS state to |host|. + // Adds HSTS, HPKP, and Expect-CT state for |host|. The new state supercedes + // any previous state for the |host|, including static entries. + // + // The new state for |host| is persisted using the Delegate (if any). void AddHSTSInternal(const std::string& host, STSState::UpgradeMode upgrade_mode, const base::Time& expiry, bool include_subdomains); - - // Adds HPKP state to |host|. void AddHPKPInternal(const std::string& host, const base::Time& last_observed, const base::Time& expiry, bool include_subdomains, const HashValueVector& hashes, const GURL& report_uri); - - // Adds Expect-CT state to |host|. void AddExpectCTInternal(const std::string& host, const base::Time& last_observed, const base::Time& expiry, bool enforce, const GURL& report_uri); - // Enable TransportSecurity for |host|. |state| supercedes any previous - // state for the |host|, including static entries. - // - // The new state for |host| is persisted using the Delegate (if any). - void EnableSTSHost(const std::string& host, const STSState& state); - void EnablePKPHost(const std::string& host, const PKPState& state); - void EnableExpectCTHost(const std::string& host, const ExpectCTState& state); - // Returns true if a request to |host_port_pair| with the given // SubjectPublicKeyInfo |hashes| satisfies the pins in |pkp_state|, // and false otherwise. If a violation is found and reporting is
diff --git a/net/quic/quic_flags_list.h b/net/quic/quic_flags_list.h index 75090827..70a3ef7 100644 --- a/net/quic/quic_flags_list.h +++ b/net/quic/quic_flags_list.h
@@ -311,12 +311,6 @@ FLAGS_quic_reloadable_flag_quic_remove_android_conformance_test_workaround, true) -// If true, lower the CWND gain in BBRv2 STARTUP to 2 when BBQ2 is in connection -// options. -QUIC_FLAG(bool, - FLAGS_quic_reloadable_flag_quic_bbr2_lower_startup_cwnd_gain, - true) - // The divisor that controls how often MAX_STREAMS frames are sent. QUIC_FLAG(int32_t, FLAGS_quic_max_streams_window_divisor, 2)
diff --git a/net/reporting/reporting_delivery_agent.cc b/net/reporting/reporting_delivery_agent.cc index fca2421..80a7a8c 100644 --- a/net/reporting/reporting_delivery_agent.cc +++ b/net/reporting/reporting_delivery_agent.cc
@@ -4,9 +4,10 @@ #include "net/reporting/reporting_delivery_agent.h" +#include <algorithm> #include <map> +#include <set> #include <string> -#include <unordered_set> #include <utility> #include <vector> @@ -17,6 +18,7 @@ #include "base/timer/timer.h" #include "base/values.h" #include "net/base/network_isolation_key.h" +#include "net/base/url_util.h" #include "net/reporting/reporting_cache.h" #include "net/reporting/reporting_cache_observer.h" #include "net/reporting/reporting_context.h" @@ -31,9 +33,9 @@ namespace { -void SerializeReports(const std::vector<const ReportingReport*>& reports, - base::TimeTicks now, - std::string* json_out) { +using ReportList = std::vector<const ReportingReport*>; + +std::string SerializeReports(const ReportList& reports, base::TimeTicks now) { base::ListValue reports_value; for (const ReportingReport* report : reports) { @@ -49,10 +51,112 @@ reports_value.Append(std::move(report_value)); } - bool json_written = base::JSONWriter::Write(reports_value, json_out); + std::string json_out; + bool json_written = base::JSONWriter::Write(reports_value, &json_out); DCHECK(json_written); + return json_out; } +bool CompareReportGroupKeys(const ReportingReport* lhs, + const ReportingReport* rhs) { + return lhs->GetGroupKey() < rhs->GetGroupKey(); +} + +// Each Delivery corresponds to one upload URLRequest. +class Delivery { + public: + // The target of a delivery. All reports uploaded together must share the + // same values for these parameters. + // Note that |origin| here (which matches the report's |origin|) is not + // necessarily the same as the |origin| of the ReportingEndpoint's group key + // (if the endpoint is configured to include subdomains). Reports with + // different group keys can be in the same delivery, as long as the NIK and + // report origin are the same, and they all get assigned to the same endpoint + // URL. + struct Target { + Target(const NetworkIsolationKey& network_isolation_key, + const url::Origin& origin, + const GURL& endpoint_url) + : network_isolation_key(network_isolation_key), + origin(origin), + endpoint_url(endpoint_url) {} + + ~Target() = default; + + bool operator<(const Target& other) const { + return std::tie(network_isolation_key, origin, endpoint_url) < + std::tie(other.network_isolation_key, other.origin, + other.endpoint_url); + } + + NetworkIsolationKey network_isolation_key; + url::Origin origin; + GURL endpoint_url; + }; + + explicit Delivery(const Target& target) : target_(target) {} + + ~Delivery() = default; + + // Add the reports in [reports_begin, reports_end) into this delivery. + // Modify the report counter for the |endpoint| to which this delivery is + // destined. + void AddReports(const ReportingEndpoint& endpoint, + const ReportList::const_iterator reports_begin, + const ReportList::const_iterator reports_end) { + DCHECK(reports_begin != reports_end); + DCHECK_EQ(endpoint.group_key.network_isolation_key, + network_isolation_key()); + DCHECK(IsSubdomainOf(target_.origin.host() /* subdomain */, + endpoint.group_key.origin.host() /* superdomain */)); + for (auto it = reports_begin; it != reports_end; ++it) { + DCHECK_EQ((*reports_begin)->GetGroupKey(), (*it)->GetGroupKey()); + DCHECK_EQ((*it)->network_isolation_key, network_isolation_key()); + DCHECK_EQ(url::Origin::Create((*it)->url), target_.origin); + DCHECK_EQ((*it)->group, endpoint.group_key.group_name); + // Report origin is equal to, or a subdomain of, the endpoint + // configuration's origin. + DCHECK(IsSubdomainOf((*it)->url.host_piece() /* subdomain */, + endpoint.group_key.origin.host() /* superdomain */)); + } + + reports_per_group_[endpoint.group_key] += + std::distance(reports_begin, reports_end); + reports_.insert(reports_.end(), reports_begin, reports_end); + } + + // Records statistics for reports after an upload has completed. + // Either removes successfully delivered reports, or increments the failure + // counter if delivery was unsuccessful. + void ProcessOutcome(ReportingCache* cache, bool success) { + for (const auto& group_name_and_count : reports_per_group_) { + cache->IncrementEndpointDeliveries(group_name_and_count.first, + target_.endpoint_url, + group_name_and_count.second, success); + } + if (success) { + cache->RemoveReports(reports_, ReportingReport::Outcome::DELIVERED); + } else { + cache->IncrementReportsAttempts(reports_); + } + } + + const NetworkIsolationKey& network_isolation_key() const { + return target_.network_isolation_key; + } + const GURL& endpoint_url() const { return target_.endpoint_url; } + const ReportList& reports() const { return reports_; } + + private: + const Target target_; + ReportList reports_; + + // Used to track statistics for each ReportingEndpoint. + // The endpoint is uniquely identified by the key in conjunction with + // |target_.endpoint_url|. See ProcessOutcome(). + std::map<ReportingEndpointGroupKey, int> reports_per_group_; +}; + class ReportingDeliveryAgentImpl : public ReportingDeliveryAgent, public ReportingCacheObserver { public: @@ -89,33 +193,8 @@ } private: - // TODO(chlily): Add NIK. - using OriginEndpoint = std::pair<url::Origin, GURL>; - using GroupEndpoint = std::pair<ReportingEndpointGroupKey, GURL>; - - class Delivery { - public: - explicit Delivery(const OriginEndpoint& report_origin_endpoint) - : report_origin(report_origin_endpoint.first), - endpoint(report_origin_endpoint.second) {} - - ~Delivery() = default; - - void AddReports(const ReportingEndpoint& endpoint, - const std::vector<const ReportingReport*>& to_add) { - GroupEndpoint key = std::make_pair(endpoint.group_key, endpoint.info.url); - reports_per_endpoint[key] += to_add.size(); - reports.insert(reports.end(), to_add.begin(), to_add.end()); - } - - const url::Origin report_origin; - const GURL endpoint; - std::vector<const ReportingReport*> reports; - std::map<GroupEndpoint, int> reports_per_endpoint; - }; - bool CacheHasReports() { - std::vector<const ReportingReport*> reports; + ReportList reports; context_->cache()->GetReports(&reports); return !reports.empty(); } @@ -134,8 +213,9 @@ } void SendReports() { - std::vector<const ReportingReport*> reports = - cache()->GetReportsToDeliver(); + ReportList reports = cache()->GetReportsToDeliver(); + if (reports.empty()) + return; // First determine which origins we're allowed to upload reports about. std::set<url::Origin> report_origins; @@ -148,84 +228,79 @@ weak_factory_.GetWeakPtr(), std::move(reports))); } - void OnSendPermissionsChecked(std::vector<const ReportingReport*> reports, + void OnSendPermissionsChecked(ReportList reports, std::set<url::Origin> allowed_report_origins) { - // Sort reports into buckets by endpoint group. - std::map<ReportingEndpointGroupKey, std::vector<const ReportingReport*>> - origin_group_reports; - for (const ReportingReport* report : reports) { - url::Origin report_origin = url::Origin::Create(report->url); - if (allowed_report_origins.find(report_origin) == - allowed_report_origins.end()) { - continue; - } - // TODO(chlily): Use proper NIK once reports are double-keyed. - ReportingEndpointGroupKey group_key(NetworkIsolationKey::Todo(), - report_origin, report->group); - origin_group_reports[group_key].push_back(report); - } + DCHECK(!reports.empty()); + std::map<Delivery::Target, std::unique_ptr<Delivery>> deliveries; - // Find an endpoint for each (origin, group) bucket and sort reports into - // endpoint buckets. Don't allow concurrent deliveries to the same (origin, - // group) bucket. - std::map<OriginEndpoint, std::unique_ptr<Delivery>> deliveries; - for (auto& it : origin_group_reports) { - const ReportingEndpointGroupKey& group_key = it.first; + // Sort by group key + std::sort(reports.begin(), reports.end(), &CompareReportGroupKeys); - if (base::Contains(pending_groups_, group_key)) + // Iterate over "buckets" of reports with the same group key. + for (auto bucket_it = reports.begin(); bucket_it != reports.end();) { + auto bucket_start = bucket_it; + // Set the iterator to the beginning of the next group bucket. + bucket_it = std::upper_bound(bucket_it, reports.end(), *bucket_it, + &CompareReportGroupKeys); + + // Skip this group if we don't have origin permissions for this origin. + const ReportingEndpointGroupKey& report_group_key = + (*bucket_start)->GetGroupKey(); + if (!base::Contains(allowed_report_origins, report_group_key.origin)) continue; + // Skip this group if there is already a pending upload for it. + // We don't allow multiple concurrent uploads for the same group. + if (base::Contains(pending_groups_, report_group_key)) + continue; + + // Find an endpoint to deliver these reports to. const ReportingEndpoint endpoint = - endpoint_manager_->FindEndpointForDelivery(group_key); - - if (!endpoint) { - // TODO(chlily): Remove reports for which there are no valid - // delivery endpoints. + endpoint_manager_->FindEndpointForDelivery(report_group_key); + // TODO(chlily): Remove reports for which there are no valid delivery + // endpoints. + if (!endpoint) continue; - } - OriginEndpoint report_origin_endpoint(group_key.origin, - endpoint.info.url); - Delivery* delivery; - auto delivery_it = deliveries.find(report_origin_endpoint); + pending_groups_.insert(report_group_key); + + // Add the reports to the appropriate delivery. + Delivery::Target target(report_group_key.network_isolation_key, + report_group_key.origin, endpoint.info.url); + auto delivery_it = deliveries.find(target); if (delivery_it == deliveries.end()) { - auto new_delivery = std::make_unique<Delivery>(report_origin_endpoint); - delivery = new_delivery.get(); - deliveries[report_origin_endpoint] = std::move(new_delivery); - } else { - delivery = delivery_it->second.get(); + bool inserted; + auto new_delivery = std::make_unique<Delivery>(target); + std::tie(delivery_it, inserted) = deliveries.insert( + std::make_pair(std::move(target), std::move(new_delivery))); + DCHECK(inserted); } - - delivery->AddReports(endpoint, it.second); - pending_groups_.insert(group_key); + delivery_it->second->AddReports(endpoint, bucket_start, bucket_it); } // Keep track of which of these reports we don't queue for delivery; we'll // need to mark them as not-pending. - std::unordered_set<const ReportingReport*> undelivered_reports( - reports.begin(), reports.end()); + std::set<const ReportingReport*> undelivered_reports(reports.begin(), + reports.end()); // Start an upload for each delivery. - for (auto& it : deliveries) { - const OriginEndpoint& report_origin_endpoint = it.first; - const url::Origin& report_origin = report_origin_endpoint.first; - const GURL& endpoint = report_origin_endpoint.second; - std::unique_ptr<Delivery>& delivery = it.second; - - std::string json; - SerializeReports(delivery->reports, tick_clock().NowTicks(), &json); + for (auto& target_and_delivery : deliveries) { + const Delivery::Target& target = target_and_delivery.first; + std::unique_ptr<Delivery>& delivery = target_and_delivery.second; int max_depth = 0; - for (const ReportingReport* report : delivery->reports) { + for (const ReportingReport* report : delivery->reports()) { undelivered_reports.erase(report); - if (report->depth > max_depth) - max_depth = report->depth; + max_depth = std::max(report->depth, max_depth); } + std::string upload_data = + SerializeReports(delivery->reports(), tick_clock().NowTicks()); + // TODO: Calculate actual max depth. - // TODO(mmenke): Populate NetworkIsolationKey. uploader()->StartUpload( - report_origin, endpoint, NetworkIsolationKey::Todo(), json, max_depth, + target.origin, target.endpoint_url, target.network_isolation_key, + upload_data, max_depth, base::BindOnce(&ReportingDeliveryAgentImpl::OnUploadComplete, weak_factory_.GetWeakPtr(), std::move(delivery))); } @@ -236,39 +311,24 @@ void OnUploadComplete(std::unique_ptr<Delivery> delivery, ReportingUploader::Outcome outcome) { - for (const auto& endpoint_and_count : delivery->reports_per_endpoint) { - const ReportingEndpointGroupKey& group_key = - endpoint_and_count.first.first; - const GURL& endpoint = endpoint_and_count.first.second; - int report_count = endpoint_and_count.second; - cache()->IncrementEndpointDeliveries( - group_key, endpoint, report_count, - outcome == ReportingUploader::Outcome::SUCCESS); - } + bool success = outcome == ReportingUploader::Outcome::SUCCESS; + delivery->ProcessOutcome(cache(), success); - if (outcome == ReportingUploader::Outcome::SUCCESS) { - cache()->RemoveReports(delivery->reports, - ReportingReport::Outcome::DELIVERED); - // TODO(mmenke): Populate NetworkIsolationKey argument. - endpoint_manager_->InformOfEndpointRequest(NetworkIsolationKey::Todo(), - delivery->endpoint, true); - } else { - cache()->IncrementReportsAttempts(delivery->reports); - // TODO(mmenke): Populate NetworkIsolationKey argument. - endpoint_manager_->InformOfEndpointRequest(NetworkIsolationKey::Todo(), - delivery->endpoint, false); - } + endpoint_manager_->InformOfEndpointRequest( + delivery->network_isolation_key(), delivery->endpoint_url(), success); + // TODO(chlily): This leaks information across NIKs. If the endpoint URL is + // configured for both NIK1 and NIK2, and it responds with a 410 on a NIK1 + // connection, then the change in configuration will be detectable on a NIK2 + // connection. if (outcome == ReportingUploader::Outcome::REMOVE_ENDPOINT) - cache()->RemoveEndpointsForUrl(delivery->endpoint); + cache()->RemoveEndpointsForUrl(delivery->endpoint_url()); - for (const ReportingReport* report : delivery->reports) { - ReportingEndpointGroupKey group_key( - NetworkIsolationKey::Todo(), delivery->report_origin, report->group); - pending_groups_.erase(group_key); + for (const ReportingReport* report : delivery->reports()) { + pending_groups_.erase(report->GetGroupKey()); } - cache()->ClearReportsPending(delivery->reports); + cache()->ClearReportsPending(delivery->reports()); } const ReportingPolicy& policy() const { return context_->policy(); }
diff --git a/net/reporting/reporting_delivery_agent.h b/net/reporting/reporting_delivery_agent.h index b857fd1..08cb97f 100644 --- a/net/reporting/reporting_delivery_agent.h +++ b/net/reporting/reporting_delivery_agent.h
@@ -19,32 +19,27 @@ class ReportingContext; -// Takes reports from the ReportingCache, assembles reports into deliveries to -// endpoints, and sends those deliveries using ReportingUploader. +// Batches reports fetched from the ReportingCache and uploads them using the +// ReportingUploader. // -// Since the Reporting spec is completely silent on issues of concurrency, the -// delivery agent handles it as so: +// Reports are only considered for delivery if all of the following are true: +// - The report is not already part of a pending upload request. +// - Uploads are allowed for the report's origin (i.e. the origin of the URL +// associated with the reported event). +// - There is not already a pending upload for any reports sharing the same +// (NIK, origin, group) key. // -// 1. An individual report can only be included in one delivery at once -- if -// SendReports is called again while a report is being delivered, it won't -// be included in another delivery during that call to SendReports. (This is, -// in fact, made redundant by rule 3, but it's included anyway in case rule 3 -// changes.) +// Reports are batched for upload to an endpoint URL such that: +// - The available reports with the same (NIK, origin, group) are always +// uploaded together. +// - All reports uploaded together must share a NIK and origin. +// - Reports for the same (NIK, origin) can be uploaded separately if they are +// for different groups. +// - Reports for different groups can be batched together, if they are assigned +// to ReportingEndpoints sharing a URL (that is, the upload URL). // -// 2. An endpoint can only be the target of one delivery at once -- if -// SendReports is called again with reports that could be delivered to that -// endpoint, they won't be delivered to that endpoint. -// -// 3. Reports for an (origin, group) tuple can only be included in one delivery -// at once -- if SendReports is called again with reports in that (origin, -// group), they won't be included in any delivery during that call to -// SendReports. (This prevents the agent from getting around rule 2 by using -// other endpoints in the same group.) -// -// 4. Reports for the same origin *can* be included in multiple parallel -// deliveries if they are in different groups within that origin. -// -// (Note that a single delivery can contain an infinite number of reports.) +// There is no limit to the number of reports that can be uploaded together. +// (Aside from the global cap on total reports.) // // TODO(juliatuttle): Consider capping the maximum number of reports per // delivery attempt.
diff --git a/net/reporting/reporting_delivery_agent_unittest.cc b/net/reporting/reporting_delivery_agent_unittest.cc index 893cdd6..7812de9 100644 --- a/net/reporting/reporting_delivery_agent_unittest.cc +++ b/net/reporting/reporting_delivery_agent_unittest.cc
@@ -37,12 +37,47 @@ policy.endpoint_backoff_policy.entry_lifetime_ms = 0; policy.endpoint_backoff_policy.always_use_initial_delay = false; UsePolicy(policy); + report_body_.SetStringKey("key", "value"); } - const NetworkIsolationKey kNik_ = NetworkIsolationKey::Todo(); + void AddReport(const NetworkIsolationKey& network_isolation_key, + const GURL& url, + const std::string& group) { + cache()->AddReport(network_isolation_key, url, kUserAgent_, group, kType_, + std::make_unique<base::Value>(report_body_.Clone()), + 0 /* depth */, tick_clock()->NowTicks() /* queued */, + 0 /* attempts */); + } + + // The first report added to the cache is uploaded immediately, and a timer is + // started for all subsequent reports (which may then be batched). To test + // behavior involving batching multiple reports, we need to add, upload, and + // immediately resolve a dummy report to prime the delivery timer. + void UploadFirstReportAndStartTimer() { + ReportingEndpointGroupKey dummy_group( + NetworkIsolationKey(), url::Origin::Create(GURL("https://dummy.test")), + "dummy"); + ASSERT_TRUE(SetEndpointInCache( + dummy_group, GURL("https://dummy.test/upload"), kExpires_)); + AddReport(dummy_group.network_isolation_key, dummy_group.origin.GetURL(), + dummy_group.group_name); + + ASSERT_EQ(1u, pending_uploads().size()); + pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); + EXPECT_EQ(0u, pending_uploads().size()); + EXPECT_TRUE(delivery_timer()->IsRunning()); + } + + base::Value report_body_{base::Value::Type::DICTIONARY}; const GURL kUrl_ = GURL("https://origin/path"); + const GURL kOtherUrl_ = GURL("https://other-origin/path"); const GURL kSubdomainUrl_ = GURL("https://sub.origin/path"); const url::Origin kOrigin_ = url::Origin::Create(GURL("https://origin/")); + const url::Origin kOtherOrigin_ = + url::Origin::Create(GURL("https://other-origin/")); + const NetworkIsolationKey kNik_; + const NetworkIsolationKey kOtherNik_ = + NetworkIsolationKey(kOrigin_, kOtherOrigin_); const GURL kEndpoint_ = GURL("https://endpoint/"); const std::string kUserAgent_ = "Mozilla/1.0"; const std::string kGroup_ = "group"; @@ -53,12 +88,8 @@ }; TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateUpload) { - base::DictionaryValue body; - body.SetString("key", "value"); - ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); - cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_, - body.CreateDeepCopy(), 0, tick_clock()->NowTicks(), 0); + AddReport(kNik_, kUrl_, kGroup_); // Upload is automatically started when cache is modified. @@ -79,7 +110,8 @@ ExpectDictStringValue(kType_, *report, "type"); ExpectDictStringValue(kUrl_.spec(), *report, "url"); ExpectDictStringValue(kUserAgent_, *report, "user_agent"); - ExpectDictDictionaryValue(body, *report, "body"); + base::Value* body = report->FindDictKey("body"); + EXPECT_EQ("value", *body->FindStringKey("key")); } pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); @@ -89,7 +121,7 @@ EXPECT_TRUE(reports.empty()); { - const ReportingEndpoint::Statistics stats = + ReportingEndpoint::Statistics stats = GetEndpointStatistics(kGroupKey_, kEndpoint_); EXPECT_EQ(1, stats.attempted_uploads); EXPECT_EQ(1, stats.successful_uploads); @@ -101,13 +133,9 @@ } TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateSubdomainUpload) { - base::DictionaryValue body; - body.SetString("key", "value"); - ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_, OriginSubdomains::INCLUDE)); - cache()->AddReport(kNik_, kSubdomainUrl_, kUserAgent_, kGroup_, kType_, - body.CreateDeepCopy(), 0, tick_clock()->NowTicks(), 0); + AddReport(kNik_, kSubdomainUrl_, kGroup_); // Upload is automatically started when cache is modified. @@ -128,7 +156,8 @@ ExpectDictStringValue(kType_, *report, "type"); ExpectDictStringValue(kSubdomainUrl_.spec(), *report, "url"); ExpectDictStringValue(kUserAgent_, *report, "user_agent"); - ExpectDictDictionaryValue(body, *report, "body"); + base::Value* body = report->FindDictKey("body"); + EXPECT_EQ("value", *body->FindStringKey("key")); } pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); @@ -138,7 +167,7 @@ EXPECT_TRUE(reports.empty()); { - const ReportingEndpoint::Statistics stats = + ReportingEndpoint::Statistics stats = GetEndpointStatistics(kGroupKey_, kEndpoint_); EXPECT_EQ(1, stats.attempted_uploads); EXPECT_EQ(1, stats.successful_uploads); @@ -151,13 +180,9 @@ TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateSubdomainUploadWithOverwrittenEndpoint) { - base::DictionaryValue body; - body.SetString("key", "value"); - ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_, OriginSubdomains::INCLUDE)); - cache()->AddReport(kNik_, kSubdomainUrl_, kUserAgent_, kGroup_, kType_, - body.CreateDeepCopy(), 0, tick_clock()->NowTicks(), 0); + AddReport(kNik_, kSubdomainUrl_, kGroup_); // Upload is automatically started when cache is modified. @@ -168,7 +193,7 @@ pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); { - const ReportingEndpoint::Statistics stats = + ReportingEndpoint::Statistics stats = GetEndpointStatistics(kGroupKey_, kEndpoint_); EXPECT_EQ(1, stats.attempted_uploads); EXPECT_EQ(1, stats.successful_uploads); @@ -183,18 +208,13 @@ } TEST_F(ReportingDeliveryAgentTest, SuccessfulDelayedUpload) { - base::DictionaryValue body; - body.SetString("key", "value"); - // Trigger and complete an upload to start the delivery timer. ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); - cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_, - body.CreateDeepCopy(), 0, tick_clock()->NowTicks(), 0); + AddReport(kNik_, kUrl_, kGroup_); pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); // Add another report to upload after a delay. - cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_, - body.CreateDeepCopy(), 0, tick_clock()->NowTicks(), 0); + AddReport(kNik_, kUrl_, kGroup_); EXPECT_TRUE(delivery_timer()->IsRunning()); delivery_timer()->Fire(); @@ -216,12 +236,13 @@ ExpectDictStringValue(kType_, *report, "type"); ExpectDictStringValue(kUrl_.spec(), *report, "url"); ExpectDictStringValue(kUserAgent_, *report, "user_agent"); - ExpectDictDictionaryValue(body, *report, "body"); + base::Value* body = report->FindDictKey("body"); + EXPECT_EQ("value", *body->FindStringKey("key")); } pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); { - const ReportingEndpoint::Statistics stats = + ReportingEndpoint::Statistics stats = GetEndpointStatistics(kGroupKey_, kEndpoint_); EXPECT_EQ(2, stats.attempted_uploads); EXPECT_EQ(2, stats.successful_uploads); @@ -239,9 +260,7 @@ TEST_F(ReportingDeliveryAgentTest, FailedUpload) { ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); - cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_, - std::make_unique<base::DictionaryValue>(), 0, - tick_clock()->NowTicks(), 0); + AddReport(kNik_, kUrl_, kGroup_); EXPECT_TRUE(delivery_timer()->IsRunning()); delivery_timer()->Fire(); @@ -250,7 +269,7 @@ pending_uploads()[0]->Complete(ReportingUploader::Outcome::FAILURE); { - const ReportingEndpoint::Statistics stats = + ReportingEndpoint::Statistics stats = GetEndpointStatistics(kGroupKey_, kEndpoint_); EXPECT_EQ(1, stats.attempted_uploads); EXPECT_EQ(0, stats.successful_uploads); @@ -272,7 +291,7 @@ EXPECT_TRUE(pending_uploads().empty()); { - const ReportingEndpoint::Statistics stats = + ReportingEndpoint::Statistics stats = GetEndpointStatistics(kGroupKey_, kEndpoint_); EXPECT_EQ(1, stats.attempted_uploads); EXPECT_EQ(0, stats.successful_uploads); @@ -292,8 +311,7 @@ body.SetString("key", "value"); ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); - cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_, - body.CreateDeepCopy(), 0, tick_clock()->NowTicks(), 0); + AddReport(kNik_, kUrl_, kGroup_); tick_clock()->Advance(base::TimeDelta::FromMilliseconds(kAgeMillis)); @@ -305,7 +323,7 @@ EXPECT_TRUE(pending_uploads().empty()); { - const ReportingEndpoint::Statistics stats = + ReportingEndpoint::Statistics stats = GetEndpointStatistics(kGroupKey_, kEndpoint_); EXPECT_EQ(0, stats.attempted_uploads); EXPECT_EQ(0, stats.successful_uploads); @@ -320,17 +338,13 @@ } TEST_F(ReportingDeliveryAgentTest, RemoveEndpointUpload) { - static const url::Origin kDifferentOrigin = - url::Origin::Create(GURL("https://origin2/")); - static const ReportingEndpointGroupKey kOtherGroupKey( - NetworkIsolationKey(), kDifferentOrigin, kGroup_); + static const ReportingEndpointGroupKey kOtherGroupKey(kNik_, kOtherOrigin_, + kGroup_); ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); ASSERT_TRUE(SetEndpointInCache(kOtherGroupKey, kEndpoint_, kExpires_)); - cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_, - std::make_unique<base::DictionaryValue>(), 0, - tick_clock()->NowTicks(), 0); + AddReport(kNik_, kUrl_, kGroup_); EXPECT_TRUE(delivery_timer()->IsRunning()); delivery_timer()->Fire(); @@ -357,9 +371,7 @@ TEST_F(ReportingDeliveryAgentTest, ConcurrentRemove) { ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); - cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_, - std::make_unique<base::DictionaryValue>(), 0, - tick_clock()->NowTicks(), 0); + AddReport(kNik_, kUrl_, kGroup_); EXPECT_TRUE(delivery_timer()->IsRunning()); delivery_timer()->Fire(); @@ -393,9 +405,7 @@ context()->test_delegate()->set_pause_permissions_check(true); ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); - cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_, - std::make_unique<base::DictionaryValue>(), 0, - tick_clock()->NowTicks(), 0); + AddReport(kNik_, kUrl_, kGroup_); ASSERT_TRUE(context()->test_delegate()->PermissionsCheckPaused()); @@ -421,134 +431,126 @@ EXPECT_TRUE(reports.empty()); } -// Test that the agent will combine reports destined for the same endpoint, even -// if the reports are from different origins. -TEST_F(ReportingDeliveryAgentTest, - BatchReportsFromDifferentOriginsToSameEndpoint) { - static const GURL kDifferentUrl("https://origin2/path"); - static const url::Origin kDifferentOrigin = - url::Origin::Create(kDifferentUrl); - const ReportingEndpointGroupKey kDifferentGroupKey(NetworkIsolationKey(), - kDifferentOrigin, kGroup_); - - ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); - ASSERT_TRUE(SetEndpointInCache(kDifferentGroupKey, kEndpoint_, kExpires_)); +// Reports uploaded together must share a NIK and origin. +// Test that the agent will not combine reports destined for the same endpoint +// if the reports are from different origins or NIKs, but does combine all +// reports for the same (NIK, origin). +TEST_F(ReportingDeliveryAgentTest, OnlyBatchSameNikAndOrigin) { + const ReportingEndpointGroupKey kGroupKeys[] = { + ReportingEndpointGroupKey(kNik_, kOrigin_, kGroup_), + ReportingEndpointGroupKey(kNik_, kOtherOrigin_, kGroup_), + ReportingEndpointGroupKey(kOtherNik_, kOrigin_, kGroup_), + ReportingEndpointGroupKey(kOtherNik_, kOtherOrigin_, kGroup_), + }; + for (const ReportingEndpointGroupKey& group_key : kGroupKeys) { + ASSERT_TRUE(SetEndpointInCache(group_key, kEndpoint_, kExpires_)); + } // Trigger and complete an upload to start the delivery timer. - cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_, - std::make_unique<base::DictionaryValue>(), 0, - tick_clock()->NowTicks(), 0); - pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); + UploadFirstReportAndStartTimer(); // Now that the delivery timer is running, these reports won't be immediately // uploaded. - cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_, - std::make_unique<base::DictionaryValue>(), 0, - tick_clock()->NowTicks(), 0); - cache()->AddReport(kNik_, kDifferentUrl, kUserAgent_, kGroup_, kType_, - std::make_unique<base::DictionaryValue>(), 0, - tick_clock()->NowTicks(), 0); + AddReport(kNik_, kUrl_, kGroup_); + AddReport(kNik_, kOtherUrl_, kGroup_); + AddReport(kNik_, kOtherUrl_, kGroup_); + AddReport(kOtherNik_, kUrl_, kGroup_); + AddReport(kOtherNik_, kUrl_, kGroup_); + AddReport(kOtherNik_, kUrl_, kGroup_); + AddReport(kOtherNik_, kOtherUrl_, kGroup_); + AddReport(kOtherNik_, kOtherUrl_, kGroup_); + AddReport(kOtherNik_, kOtherUrl_, kGroup_); + AddReport(kOtherNik_, kOtherUrl_, kGroup_); EXPECT_EQ(0u, pending_uploads().size()); - // When we fire the delivery timer, we should NOT batch these two reports into - // a single upload, since each upload must only contain reports about a single - // origin. + // There should be one upload per (NIK, origin). EXPECT_TRUE(delivery_timer()->IsRunning()); delivery_timer()->Fire(); - ASSERT_EQ(2u, pending_uploads().size()); + ASSERT_EQ(4u, pending_uploads().size()); pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); + pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); + pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); EXPECT_EQ(0u, pending_uploads().size()); + + for (int i = 0; i < 4; ++i) { + ReportingEndpoint::Statistics stats = + GetEndpointStatistics(kGroupKeys[i], kEndpoint_); + EXPECT_EQ(1, stats.attempted_uploads); + EXPECT_EQ(1, stats.successful_uploads); + EXPECT_EQ(i + 1, stats.attempted_reports); + EXPECT_EQ(i + 1, stats.successful_reports); + } } -// Test that the agent won't start a second upload to the same endpoint for a -// particular origin while one is pending, but will once it is no longer -// pending. -TEST_F(ReportingDeliveryAgentTest, SerializeUploadsToEndpoint) { - ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); - - cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_, - std::make_unique<base::DictionaryValue>(), 0, - tick_clock()->NowTicks(), 0); - - EXPECT_TRUE(delivery_timer()->IsRunning()); - delivery_timer()->Fire(); - EXPECT_EQ(1u, pending_uploads().size()); - - cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_, - std::make_unique<base::DictionaryValue>(), 0, - tick_clock()->NowTicks(), 0); - - EXPECT_TRUE(delivery_timer()->IsRunning()); - delivery_timer()->Fire(); - ASSERT_EQ(1u, pending_uploads().size()); - - pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); - EXPECT_EQ(0u, pending_uploads().size()); - - EXPECT_TRUE(delivery_timer()->IsRunning()); - delivery_timer()->Fire(); - ASSERT_EQ(1u, pending_uploads().size()); - - pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); - EXPECT_EQ(0u, pending_uploads().size()); -} - -// Test that the agent won't start a second upload for an (origin, group) while -// one is pending, even if a different endpoint is available, but will once the -// original delivery is complete and the (origin, group) is no longer pending. +// Test that the agent won't start a second upload for a (NIK, origin, group) +// while one is pending, even if a different endpoint is available, but will +// once the original delivery is complete and the (NIK, origin, group) is no +// longer pending. TEST_F(ReportingDeliveryAgentTest, SerializeUploadsToGroup) { static const GURL kDifferentEndpoint("https://endpoint2/"); ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kDifferentEndpoint, kExpires_)); - cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_, - std::make_unique<base::DictionaryValue>(), 0, - tick_clock()->NowTicks(), 0); + // Trigger and complete an upload to start the delivery timer. + UploadFirstReportAndStartTimer(); + // First upload causes this group key to become pending. + AddReport(kNik_, kUrl_, kGroup_); + EXPECT_EQ(0u, pending_uploads().size()); EXPECT_TRUE(delivery_timer()->IsRunning()); delivery_timer()->Fire(); EXPECT_EQ(1u, pending_uploads().size()); - cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_, - std::make_unique<base::DictionaryValue>(), 0, - tick_clock()->NowTicks(), 0); - + // Second upload isn't started because the group is pending. + AddReport(kNik_, kUrl_, kGroup_); EXPECT_TRUE(delivery_timer()->IsRunning()); delivery_timer()->Fire(); ASSERT_EQ(1u, pending_uploads().size()); + // Resolve the first upload. pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); EXPECT_EQ(0u, pending_uploads().size()); + // Now the other upload can happen. EXPECT_TRUE(delivery_timer()->IsRunning()); delivery_timer()->Fire(); ASSERT_EQ(1u, pending_uploads().size()); - pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); EXPECT_EQ(0u, pending_uploads().size()); + + // A total of 2 reports were uploaded. + { + ReportingEndpoint::Statistics stats = + GetEndpointStatistics(kGroupKey_, kEndpoint_); + ReportingEndpoint::Statistics different_stats = + GetEndpointStatistics(kGroupKey_, kDifferentEndpoint); + EXPECT_EQ(2, stats.attempted_uploads + different_stats.attempted_uploads); + EXPECT_EQ(2, stats.successful_uploads + different_stats.successful_uploads); + EXPECT_EQ(2, stats.attempted_reports + different_stats.attempted_reports); + EXPECT_EQ(2, stats.successful_reports + different_stats.successful_reports); + } } // Tests that the agent will start parallel uploads to different groups within -// the same origin. +// the same (NIK, origin) to endpoints with different URLs. TEST_F(ReportingDeliveryAgentTest, ParallelizeUploadsAcrossGroups) { static const GURL kDifferentEndpoint("https://endpoint2/"); static const std::string kDifferentGroup("group2"); - const ReportingEndpointGroupKey kDifferentGroupKey(NetworkIsolationKey(), - kOrigin_, kDifferentGroup); + const ReportingEndpointGroupKey kDifferentGroupKey(kNik_, kOrigin_, + kDifferentGroup); ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); ASSERT_TRUE( SetEndpointInCache(kDifferentGroupKey, kDifferentEndpoint, kExpires_)); - cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_, - std::make_unique<base::DictionaryValue>(), 0, - tick_clock()->NowTicks(), 0); - cache()->AddReport(kNik_, kUrl_, kUserAgent_, kDifferentGroup, kType_, - std::make_unique<base::DictionaryValue>(), 0, - tick_clock()->NowTicks(), 0); + // Trigger and complete an upload to start the delivery timer. + UploadFirstReportAndStartTimer(); + + AddReport(kNik_, kUrl_, kGroup_); + AddReport(kNik_, kUrl_, kDifferentGroup); EXPECT_TRUE(delivery_timer()->IsRunning()); delivery_timer()->Fire(); @@ -557,6 +559,63 @@ pending_uploads()[1]->Complete(ReportingUploader::Outcome::SUCCESS); pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); EXPECT_EQ(0u, pending_uploads().size()); + + { + ReportingEndpoint::Statistics stats = + GetEndpointStatistics(kGroupKey_, kEndpoint_); + EXPECT_EQ(1, stats.attempted_uploads); + EXPECT_EQ(1, stats.successful_uploads); + EXPECT_EQ(1, stats.attempted_reports); + EXPECT_EQ(1, stats.successful_reports); + } + { + ReportingEndpoint::Statistics stats = + GetEndpointStatistics(kDifferentGroupKey, kDifferentEndpoint); + EXPECT_EQ(1, stats.attempted_uploads); + EXPECT_EQ(1, stats.successful_uploads); + EXPECT_EQ(1, stats.attempted_reports); + EXPECT_EQ(1, stats.successful_reports); + } +} + +// Tests that the agent will include reports for different groups for the same +// (NIK, origin) in the same upload if they are destined for the same endpoint +// URL. +TEST_F(ReportingDeliveryAgentTest, BatchReportsAcrossGroups) { + static const std::string kDifferentGroup("group2"); + const ReportingEndpointGroupKey kDifferentGroupKey(kNik_, kOrigin_, + kDifferentGroup); + + ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); + ASSERT_TRUE(SetEndpointInCache(kDifferentGroupKey, kEndpoint_, kExpires_)); + + UploadFirstReportAndStartTimer(); + + AddReport(kNik_, kUrl_, kGroup_); + AddReport(kNik_, kUrl_, kDifferentGroup); + + EXPECT_TRUE(delivery_timer()->IsRunning()); + delivery_timer()->Fire(); + ASSERT_EQ(1u, pending_uploads().size()); + pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); + EXPECT_EQ(0u, pending_uploads().size()); + + { + ReportingEndpoint::Statistics stats = + GetEndpointStatistics(kGroupKey_, kEndpoint_); + EXPECT_EQ(1, stats.attempted_uploads); + EXPECT_EQ(1, stats.successful_uploads); + EXPECT_EQ(1, stats.attempted_reports); + EXPECT_EQ(1, stats.successful_reports); + } + { + ReportingEndpoint::Statistics stats = + GetEndpointStatistics(kDifferentGroupKey, kEndpoint_); + EXPECT_EQ(1, stats.attempted_uploads); + EXPECT_EQ(1, stats.successful_uploads); + EXPECT_EQ(1, stats.attempted_reports); + EXPECT_EQ(1, stats.successful_reports); + } } } // namespace
diff --git a/net/reporting/reporting_report.cc b/net/reporting/reporting_report.cc index 63648cff..c2a841a 100644 --- a/net/reporting/reporting_report.cc +++ b/net/reporting/reporting_report.cc
@@ -55,6 +55,11 @@ RecordReportOutcome(outcome); } +ReportingEndpointGroupKey ReportingReport::GetGroupKey() const { + return ReportingEndpointGroupKey(network_isolation_key, + url::Origin::Create(url), group); +} + // static void ReportingReport::RecordReportDiscardedForNoURLRequestContext() { RecordReportOutcome(Outcome::DISCARDED_NO_URL_REQUEST_CONTEXT);
diff --git a/net/reporting/reporting_report.h b/net/reporting/reporting_report.h index 02018ad..8384566 100644 --- a/net/reporting/reporting_report.h +++ b/net/reporting/reporting_report.h
@@ -12,6 +12,7 @@ #include "base/time/time.h" #include "net/base/net_export.h" #include "net/base/network_isolation_key.h" +#include "net/reporting/reporting_endpoint.h" #include "url/gurl.h" namespace base { @@ -65,6 +66,13 @@ // Records metrics about report outcome. ~ReportingReport(); + // Bundles together the NIK, origin of the report URL, and group name. + // This is not exactly the same as the group key of the endpoint that the + // report will be delivered to. The origin may differ if the endpoint is + // configured for a superdomain of the report's origin. The NIK and group name + // will be the same. + ReportingEndpointGroupKey GetGroupKey() const; + static void RecordReportDiscardedForNoURLRequestContext(); static void RecordReportDiscardedForNoReportingService();
diff --git a/services/BUILD.gn b/services/BUILD.gn index c64868ed..cab26e2e 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn
@@ -105,11 +105,13 @@ deps = [ "$google_play_services_package:google_play_services_base_java", "$google_play_services_package:google_play_services_basement_java", + "$google_play_services_package:google_play_services_location_java", "$google_play_services_package:google_play_services_vision_common_java", "$google_play_services_package:google_play_services_vision_java", "//base:base_java", "//base:base_java_test_support", "//base:base_junit_test_support", + "//mojo/public/java:base_java", "//mojo/public/java:bindings_java", "//mojo/public/java:system_java", "//services/device/generic_sensor:java",
diff --git a/services/device/usb/usb_service_win.cc b/services/device/usb/usb_service_win.cc index d194a99..39fe05bb 100644 --- a/services/device/usb/usb_service_win.cc +++ b/services/device/usb/usb_service_win.cc
@@ -24,6 +24,7 @@ #include "base/strings/string_util.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/scoped_thread_priority.h" #include "base/threading/thread_task_runner_handle.h" #include "base/win/registry.h" #include "base/win/scoped_devinfo.h" @@ -305,6 +306,10 @@ if (!base::EqualsCaseInsensitiveASCII(info.driver, L"winusb")) return info; + // Boost priority while potentially loading Advapi32.dll on a background + // thread for the registry functions used below. + SCOPED_MAY_LOAD_LIBRARY_AT_BACKGROUND_PRIORITY(); + // There is no standard device interface GUID for USB functions and so we // must discover the set of GUIDs that have been set in the registry by // the INF file or Microsoft OS Compatibility descriptors before @@ -327,6 +332,10 @@ } for (const auto& guid_string : device_interface_guids) { + // Boost priority while potentially loading Ole32.dll on a background + // thread for CLSIDFromString(). + SCOPED_MAY_LOAD_LIBRARY_AT_BACKGROUND_PRIORITY(); + GUID guid; if (FAILED(CLSIDFromString(guid_string.c_str(), &guid))) { USB_LOG(ERROR) << "Failed to parse device interface GUID: " @@ -352,6 +361,10 @@ ~BlockingTaskRunnerHelper() {} void EnumerateDevices() { + // Boost priority while potentially loading SetupAPI.dll for the following + // functions on a background thread. + SCOPED_MAY_LOAD_LIBRARY_AT_BACKGROUND_PRIORITY(); + base::win::ScopedDevInfo dev_info( SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, nullptr, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT)); @@ -379,6 +392,10 @@ } void OnDeviceAdded(const GUID& guid, const base::string16& device_path) { + // Boost priority while potentially loading SetupAPI.dll and Ole32.dll on a + // background thread for the following functions. + SCOPED_MAY_LOAD_LIBRARY_AT_BACKGROUND_PRIORITY(); + base::win::ScopedDevInfo dev_info(SetupDiGetClassDevs( &guid, nullptr, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT)); if (!dev_info.is_valid()) { @@ -402,6 +419,7 @@ } } + private: void EnumerateDevice(HDEVINFO dev_info, SP_DEVICE_INTERFACE_DATA* device_interface_data, const base::Optional<base::string16>& opt_device_path) { @@ -494,7 +512,6 @@ std::move(parent_path), interface_number, info)); } - private: std::unordered_map<base::string16, base::string16> hub_paths_; // Calls back to |service_| must be posted to |service_task_runner_|, which
diff --git a/services/network/public/mojom/BUILD.gn b/services/network/public/mojom/BUILD.gn index cbf1505..74462f6 100644 --- a/services/network/public/mojom/BUILD.gn +++ b/services/network/public/mojom/BUILD.gn
@@ -49,6 +49,22 @@ "//services/network/public/cpp:cpp_base", ] }, + { + types = [ + { + mojom = "network.mojom.ConnectionInfo" + cpp = "::net::HttpResponseInfo::ConnectionInfo" + }, + ] + traits_headers = [ + "//net/http/http_response_info.h", + "//services/network/public/cpp/network_ipc_param_traits.h", + ] + traits_public_deps = [ + "//net", + "//services/network/public/cpp:cpp_base", + ] + }, ] cpp_typemaps = [ @@ -661,10 +677,6 @@ cpp = "::net::ct::CTPolicyCompliance" }, { - mojom = "network.mojom.ConnectionInfo" - cpp = "::net::HttpResponseInfo::ConnectionInfo" - }, - { mojom = "network.mojom.CorsErrorStatus" cpp = "::network::CorsErrorStatus" },
diff --git a/testing/buildbot/chromium.ci.json b/testing/buildbot/chromium.ci.json index 7b08bcb..97a802f 100644 --- a/testing/buildbot/chromium.ci.json +++ b/testing/buildbot/chromium.ci.json
@@ -194875,6 +194875,93 @@ }, { "args": [ + "context_lost", + "--show-stdout", + "--browser=web-engine-shell", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" + ], + "isolate_name": "fuchsia_telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "context_lost_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-16.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://content/test:fuchsia_telemetry_gpu_integration_test/context_lost_tests/" + }, + { + "args": [ + "depth_capture", + "--show-stdout", + "--browser=web-engine-shell", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" + ], + "isolate_name": "fuchsia_telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "depth_capture_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-16.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://content/test:fuchsia_telemetry_gpu_integration_test/depth_capture_tests/" + }, + { + "args": [ + "gpu_process", + "--show-stdout", + "--browser=web-engine-shell", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" + ], + "isolate_name": "fuchsia_telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "gpu_process_launch_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-16.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://content/test:fuchsia_telemetry_gpu_integration_test/gpu_process_launch_tests/" + }, + { + "args": [ "hardware_accelerated_feature", "--show-stdout", "--browser=web-engine-shell", @@ -199471,7 +199558,8 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, @@ -199513,7 +199601,8 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, @@ -199555,7 +199644,8 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, @@ -199597,7 +199687,8 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, @@ -203237,12 +203328,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_bookmarks_egtests", + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_bookmarks_egtests_iPad Air 2 12.4", + "name": "ios_chrome_bookmarks_eg2tests_module_iPad Air 2 12.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -203265,7 +203356,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" }, { "args": [ @@ -203278,12 +203369,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_bookmarks_egtests", + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_bookmarks_egtests_iPad Air 2 13.4", + "name": "ios_chrome_bookmarks_eg2tests_module_iPad Air 2 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -203306,7 +203397,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" }, { "args": [ @@ -203319,12 +203410,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_bookmarks_egtests", + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_bookmarks_egtests_iPhone 7 13.4", + "name": "ios_chrome_bookmarks_eg2tests_module_iPhone 7 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -203347,7 +203438,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" }, { "args": [ @@ -203360,12 +203451,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_bookmarks_egtests", + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_bookmarks_egtests_iPhone X 12.4", + "name": "ios_chrome_bookmarks_eg2tests_module_iPhone X 12.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -203388,7 +203479,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" }, { "args": [ @@ -203401,12 +203492,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_bookmarks_egtests", + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_bookmarks_egtests_iPhone X 13.4", + "name": "ios_chrome_bookmarks_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -203429,7 +203520,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" }, { "args": [ @@ -203568,12 +203659,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_reading_list_egtests", + "isolate_name": "ios_chrome_settings_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_reading_list_egtests_iPad Air 2 12.4", + "name": "ios_chrome_settings_eg2tests_module_iPad Air 2 12.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -203594,9 +203685,10 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, { "args": [ @@ -203609,12 +203701,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_reading_list_egtests", + "isolate_name": "ios_chrome_settings_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_reading_list_egtests_iPad Air 2 13.4", + "name": "ios_chrome_settings_eg2tests_module_iPad Air 2 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -203635,9 +203727,10 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, { "args": [ @@ -203650,12 +203743,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_reading_list_egtests", + "isolate_name": "ios_chrome_settings_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_reading_list_egtests_iPhone 7 13.4", + "name": "ios_chrome_settings_eg2tests_module_iPhone 7 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -203676,9 +203769,10 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, { "args": [ @@ -203691,12 +203785,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_reading_list_egtests", + "isolate_name": "ios_chrome_settings_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_reading_list_egtests_iPhone X 12.4", + "name": "ios_chrome_settings_eg2tests_module_iPhone X 12.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -203717,9 +203811,10 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, { "args": [ @@ -203732,53 +203827,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_reading_list_egtests", + "isolate_name": "ios_chrome_settings_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_reading_list_egtests_iPhone X 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPad Air 2 12.4", + "name": "ios_chrome_settings_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -203802,175 +203856,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 3 }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPad Air 2 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPhone 7 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPhone X 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, { "args": [ @@ -204106,12 +203992,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_translate_egtests", + "isolate_name": "ios_chrome_smoke_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_translate_egtests_iPad Air 2 12.4", + "name": "ios_chrome_smoke_eg2tests_module_iPad Air 2 12.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -204134,7 +204020,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" }, { "args": [ @@ -204147,12 +204033,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_translate_egtests", + "isolate_name": "ios_chrome_smoke_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_translate_egtests_iPad Air 2 13.4", + "name": "ios_chrome_smoke_eg2tests_module_iPad Air 2 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -204175,7 +204061,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" }, { "args": [ @@ -204188,12 +204074,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_translate_egtests", + "isolate_name": "ios_chrome_smoke_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_translate_egtests_iPhone 7 13.4", + "name": "ios_chrome_smoke_eg2tests_module_iPhone 7 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -204216,7 +204102,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" }, { "args": [ @@ -204229,12 +204115,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_translate_egtests", + "isolate_name": "ios_chrome_smoke_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_translate_egtests_iPhone X 12.4", + "name": "ios_chrome_smoke_eg2tests_module_iPhone X 12.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -204257,7 +204143,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" }, { "args": [ @@ -204270,12 +204156,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_translate_egtests", + "isolate_name": "ios_chrome_smoke_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_translate_egtests_iPhone X 13.4", + "name": "ios_chrome_smoke_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -204298,7 +204184,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" }, { "args": [ @@ -204437,12 +204323,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_web_egtests", + "isolate_name": "ios_chrome_web_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_web_egtests_iPad Air 2 12.4", + "name": "ios_chrome_web_eg2tests_module_iPad Air 2 12.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -204465,7 +204351,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" }, { "args": [ @@ -204478,12 +204364,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_web_egtests", + "isolate_name": "ios_chrome_web_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_web_egtests_iPad Air 2 13.4", + "name": "ios_chrome_web_eg2tests_module_iPad Air 2 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -204506,7 +204392,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" }, { "args": [ @@ -204519,12 +204405,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_web_egtests", + "isolate_name": "ios_chrome_web_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_web_egtests_iPhone 7 13.4", + "name": "ios_chrome_web_eg2tests_module_iPhone 7 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -204547,7 +204433,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" }, { "args": [ @@ -204560,12 +204446,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_web_egtests", + "isolate_name": "ios_chrome_web_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_web_egtests_iPhone X 12.4", + "name": "ios_chrome_web_eg2tests_module_iPhone X 12.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -204588,7 +204474,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" }, { "args": [ @@ -204601,12 +204487,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_web_egtests", + "isolate_name": "ios_chrome_web_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_web_egtests_iPhone X 13.4", + "name": "ios_chrome_web_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -204629,7 +204515,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" }, { "args": [ @@ -204642,12 +204528,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_showcase_egtests", + "isolate_name": "ios_showcase_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_showcase_egtests_iPad Air 2 12.4", + "name": "ios_showcase_eg2tests_module_iPad Air 2 12.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -204670,7 +204556,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" }, { "args": [ @@ -204683,12 +204569,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_showcase_egtests", + "isolate_name": "ios_showcase_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_showcase_egtests_iPad Air 2 13.4", + "name": "ios_showcase_eg2tests_module_iPad Air 2 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -204711,7 +204597,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" }, { "args": [ @@ -204724,12 +204610,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_showcase_egtests", + "isolate_name": "ios_showcase_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_showcase_egtests_iPhone 7 13.4", + "name": "ios_showcase_eg2tests_module_iPhone 7 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -204752,7 +204638,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" }, { "args": [ @@ -204765,12 +204651,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_showcase_egtests", + "isolate_name": "ios_showcase_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_showcase_egtests_iPhone X 12.4", + "name": "ios_showcase_eg2tests_module_iPhone X 12.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -204793,7 +204679,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" }, { "args": [ @@ -204806,12 +204692,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_showcase_egtests", + "isolate_name": "ios_showcase_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_showcase_egtests_iPhone X 13.4", + "name": "ios_showcase_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -204834,7 +204720,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" }, { "args": [ @@ -205302,6 +205188,48 @@ "--xcode-build-version", "11e146" ], + "isolate_name": "ios_chrome_integration_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_integration_eg2tests_module_iPad Air 2 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_integration_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], "isolate_name": "ios_chrome_settings_eg2tests_module", "merge": { "args": [], @@ -205328,7 +205256,8 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, @@ -205343,6 +205272,47 @@ "--xcode-build-version", "11e146" ], + "isolate_name": "ios_chrome_signin_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_signin_eg2tests_module_iPad Air 2 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], "isolate_name": "ios_chrome_smoke_eg2tests_module", "merge": { "args": [], @@ -205384,6 +205354,48 @@ "--xcode-build-version", "11e146" ], + "isolate_name": "ios_chrome_ui_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_ui_eg2tests_module_iPad Air 2 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 5 + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], "isolate_name": "ios_chrome_unittests", "merge": { "args": [], @@ -205712,6 +205724,47 @@ "--xcode-build-version", "11e146" ], + "isolate_name": "ios_web_shell_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_shell_eg2tests_module_iPad Air 2 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web/shell/test:ios_web_shell_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], "isolate_name": "ios_web_unittests", "merge": { "args": [], @@ -206689,12 +206742,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_bookmarks_egtests", + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_bookmarks_egtests_iPad Air 2 13.4", + "name": "ios_chrome_bookmarks_eg2tests_module_iPad Air 2 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -206717,7 +206770,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" }, { "args": [ @@ -206732,12 +206785,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_bookmarks_egtests", + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_bookmarks_egtests_iPhone X 13.4", + "name": "ios_chrome_bookmarks_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -206760,7 +206813,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" }, { "args": [ @@ -206863,98 +206916,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_reading_list_egtests", + "isolate_name": "ios_chrome_settings_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_reading_list_egtests_iPad Air 2 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "13.4", - "--args-json", - "{\"test_args\": [\"--run-with-custom-webkit\"]}", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_reading_list_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_reading_list_egtests_iPhone X 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "13.4", - "--args-json", - "{\"test_args\": [\"--run-with-custom-webkit\"]}", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPad Air 2 13.4", + "name": "ios_chrome_settings_eg2tests_module_iPad Air 2 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -206978,7 +206945,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 3 }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, { "args": [ @@ -206993,12 +206960,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_settings_egtests", + "isolate_name": "ios_chrome_settings_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_settings_egtests_iPhone X 13.4", + "name": "ios_chrome_settings_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -207022,7 +206989,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 3 }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, { "args": [ @@ -207123,12 +207090,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_translate_egtests", + "isolate_name": "ios_chrome_smoke_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_translate_egtests_iPad Air 2 13.4", + "name": "ios_chrome_smoke_eg2tests_module_iPad Air 2 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -207151,7 +207118,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" }, { "args": [ @@ -207166,12 +207133,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_translate_egtests", + "isolate_name": "ios_chrome_smoke_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_translate_egtests_iPhone X 13.4", + "name": "ios_chrome_smoke_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -207194,7 +207161,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" }, { "args": [ @@ -207383,12 +207350,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_web_egtests", + "isolate_name": "ios_chrome_web_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_web_egtests_iPad Air 2 13.4", + "name": "ios_chrome_web_eg2tests_module_iPad Air 2 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -207411,7 +207378,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" }, { "args": [ @@ -207426,12 +207393,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_web_egtests", + "isolate_name": "ios_chrome_web_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_web_egtests_iPhone X 13.4", + "name": "ios_chrome_web_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -207454,7 +207421,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" }, { "args": [ @@ -207727,12 +207694,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_showcase_egtests", + "isolate_name": "ios_showcase_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_showcase_egtests_iPad Air 2 13.4", + "name": "ios_showcase_eg2tests_module_iPad Air 2 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -207755,7 +207722,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" }, { "args": [ @@ -207770,12 +207737,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_showcase_egtests", + "isolate_name": "ios_showcase_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_showcase_egtests_iPhone X 13.4", + "name": "ios_showcase_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -207798,7 +207765,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" }, { "args": [ @@ -209990,6 +209957,88 @@ { "args": [ "--platform", + "iPad Air (3rd generation)", + "--version", + "12.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_bookmarks_eg2tests_module_iPad Air (3rd generation) 12.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air (3rd generation)", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_bookmarks_eg2tests_module_iPad Air (3rd generation) 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" + }, + { + "args": [ + "--platform", "iPhone 7", "--version", "13.4", @@ -210113,170 +210162,6 @@ { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_bookmarks_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air (3rd generation)", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_bookmarks_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_egtests_iPad Air (3rd generation) 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_bookmarks_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_bookmarks_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_egtests_iPhone X 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" - }, - { - "args": [ - "--platform", "iPad (6th generation)", "--version", "12.4", @@ -210571,170 +210456,6 @@ { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_reading_list_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_reading_list_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air (3rd generation)", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_reading_list_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_reading_list_egtests_iPad Air (3rd generation) 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_reading_list_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_reading_list_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_reading_list_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_reading_list_egtests_iPhone X 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", "iPad (6th generation)", "--version", "12.4", @@ -210769,7 +210490,8 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, @@ -210810,7 +210532,92 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air (3rd generation)", + "--version", + "12.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_settings_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_settings_eg2tests_module_iPad Air (3rd generation) 12.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air (3rd generation)", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_settings_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_settings_eg2tests_module_iPad Air (3rd generation) 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, @@ -210851,7 +210658,8 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, @@ -210892,7 +210700,8 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, @@ -210933,181 +210742,14 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air (3rd generation)", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPad Air (3rd generation) 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPhone X 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", "iPad (6th generation)", "--version", "12.4", @@ -211477,6 +211119,88 @@ { "args": [ "--platform", + "iPad Air (3rd generation)", + "--version", + "12.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_smoke_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_smoke_eg2tests_module_iPad Air (3rd generation) 12.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air (3rd generation)", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_smoke_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_smoke_eg2tests_module_iPad Air (3rd generation) 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" + }, + { + "args": [ + "--platform", "iPhone 7", "--version", "13.4", @@ -211600,170 +211324,6 @@ { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_translate_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_translate_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air (3rd generation)", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_translate_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_translate_egtests_iPad Air (3rd generation) 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_translate_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_translate_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_translate_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_translate_egtests_iPhone X 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" - }, - { - "args": [ - "--platform", "iPad (6th generation)", "--version", "12.4", @@ -212386,6 +211946,88 @@ { "args": [ "--platform", + "iPad Air (3rd generation)", + "--version", + "12.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_web_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_web_eg2tests_module_iPad Air (3rd generation) 12.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air (3rd generation)", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_web_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_web_eg2tests_module_iPad Air (3rd generation) 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" + }, + { + "args": [ + "--platform", "iPhone 7", "--version", "13.4", @@ -212509,170 +212151,6 @@ { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_web_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air (3rd generation)", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_web_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_egtests_iPad Air (3rd generation) 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_web_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_web_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_egtests_iPhone X 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" - }, - { - "args": [ - "--platform", "iPhone X", "--version", "12.4", @@ -213001,6 +212479,88 @@ { "args": [ "--platform", + "iPad Air (3rd generation)", + "--version", + "12.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_showcase_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_showcase_eg2tests_module_iPad Air (3rd generation) 12.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air (3rd generation)", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_showcase_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_showcase_eg2tests_module_iPad Air (3rd generation) 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" + }, + { + "args": [ + "--platform", "iPhone 7", "--version", "13.4", @@ -213124,170 +212684,6 @@ { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_showcase_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air (3rd generation)", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_showcase_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_egtests_iPad Air (3rd generation) 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_showcase_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_showcase_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_egtests_iPhone X 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" - }, - { - "args": [ - "--platform", "iPhone X", "--version", "12.4", @@ -216457,6 +215853,129 @@ { "args": [ "--platform", + "iPad Air (3rd generation)", + "--version", + "12.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_bookmarks_eg2tests_module_iPad Air (3rd generation) 12.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_bookmarks_eg2tests_module_iPad Air 2 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPhone 7", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_bookmarks_eg2tests_module_iPhone 7 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" + }, + { + "args": [ + "--platform", "iPhone X", "--version", "12.4", @@ -216498,170 +216017,6 @@ { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_bookmarks_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_bookmarks_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_egtests_iPad Air 2 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_bookmarks_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_egtests_iPhone 7 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_bookmarks_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" - }, - { - "args": [ - "--platform", "iPhone X", "--version", "13.4", @@ -216670,12 +216025,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_bookmarks_egtests", + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_bookmarks_egtests_iPhone X 13.4", + "name": "ios_chrome_bookmarks_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -216698,7 +216053,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" }, { "args": [ @@ -216913,211 +216268,6 @@ { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_reading_list_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_reading_list_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_reading_list_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_reading_list_egtests_iPad Air 2 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_reading_list_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_reading_list_egtests_iPhone 7 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_reading_list_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_reading_list_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_reading_list_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_reading_list_egtests_iPhone X 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", "iPad (6th generation)", "--version", "12.4", @@ -217152,7 +216302,134 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air (3rd generation)", + "--version", + "12.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_settings_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_settings_eg2tests_module_iPad Air (3rd generation) 12.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_settings_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_settings_eg2tests_module_iPad Air 2 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPhone 7", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_settings_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_settings_eg2tests_module_iPhone 7 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, @@ -217193,181 +216470,14 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPad Air 2 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPhone 7 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", "iPhone X", "--version", "13.4", @@ -217376,12 +216486,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_settings_egtests", + "isolate_name": "ios_chrome_settings_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_settings_egtests_iPhone X 13.4", + "name": "ios_chrome_settings_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -217405,7 +216515,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 3 }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, { "args": [ @@ -217656,6 +216766,129 @@ { "args": [ "--platform", + "iPad Air (3rd generation)", + "--version", + "12.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_smoke_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_smoke_eg2tests_module_iPad Air (3rd generation) 12.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_smoke_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_smoke_eg2tests_module_iPad Air 2 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPhone 7", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_smoke_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_smoke_eg2tests_module_iPhone 7 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" + }, + { + "args": [ + "--platform", "iPhone X", "--version", "12.4", @@ -217697,170 +216930,6 @@ { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_translate_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_translate_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_translate_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_translate_egtests_iPad Air 2 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_translate_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_translate_egtests_iPhone 7 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_translate_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_translate_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" - }, - { - "args": [ - "--platform", "iPhone X", "--version", "13.4", @@ -217869,12 +216938,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_translate_egtests", + "isolate_name": "ios_chrome_smoke_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_translate_egtests_iPhone X 13.4", + "name": "ios_chrome_smoke_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -217897,7 +216966,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" }, { "args": [ @@ -218358,6 +217427,129 @@ { "args": [ "--platform", + "iPad Air (3rd generation)", + "--version", + "12.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_web_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_web_eg2tests_module_iPad Air (3rd generation) 12.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_web_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_web_eg2tests_module_iPad Air 2 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPhone 7", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_web_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_web_eg2tests_module_iPhone 7 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" + }, + { + "args": [ + "--platform", "iPhone X", "--version", "12.4", @@ -218399,170 +217591,6 @@ { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_web_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_web_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_egtests_iPad Air 2 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_web_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_egtests_iPhone 7 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_web_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" - }, - { - "args": [ - "--platform", "iPhone X", "--version", "13.4", @@ -218571,12 +217599,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_web_egtests", + "isolate_name": "ios_chrome_web_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_web_egtests_iPhone X 13.4", + "name": "ios_chrome_web_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -218599,7 +217627,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" }, { "args": [ @@ -218891,6 +217919,129 @@ { "args": [ "--platform", + "iPad Air (3rd generation)", + "--version", + "12.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_showcase_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_showcase_eg2tests_module_iPad Air (3rd generation) 12.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_showcase_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_showcase_eg2tests_module_iPad Air 2 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPhone 7", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_showcase_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_showcase_eg2tests_module_iPhone 7 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" + }, + { + "args": [ + "--platform", "iPhone X", "--version", "12.4", @@ -218932,170 +218083,6 @@ { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_showcase_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_showcase_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_egtests_iPad Air 2 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_showcase_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_egtests_iPhone 7 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_showcase_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" - }, - { - "args": [ - "--platform", "iPhone X", "--version", "13.4", @@ -219104,12 +218091,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_showcase_egtests", + "isolate_name": "ios_showcase_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_showcase_egtests_iPhone X 13.4", + "name": "ios_showcase_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -219132,7 +218119,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" }, { "args": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 6960bfb..72db4f8b 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -15024,6 +15024,93 @@ }, { "args": [ + "context_lost", + "--show-stdout", + "--browser=web-engine-shell", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" + ], + "isolate_name": "fuchsia_telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "context_lost_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-16.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://content/test:fuchsia_telemetry_gpu_integration_test/context_lost_tests/" + }, + { + "args": [ + "depth_capture", + "--show-stdout", + "--browser=web-engine-shell", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" + ], + "isolate_name": "fuchsia_telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "depth_capture_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-16.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://content/test:fuchsia_telemetry_gpu_integration_test/depth_capture_tests/" + }, + { + "args": [ + "gpu_process", + "--show-stdout", + "--browser=web-engine-shell", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" + ], + "isolate_name": "fuchsia_telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "gpu_process_launch_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-16.04" + } + ], + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://content/test:fuchsia_telemetry_gpu_integration_test/gpu_process_launch_tests/" + }, + { + "args": [ "hardware_accelerated_feature", "--show-stdout", "--browser=web-engine-shell", @@ -16642,7 +16729,8 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, @@ -16684,7 +16772,8 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, @@ -16726,7 +16815,8 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, @@ -16768,7 +16858,8 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, @@ -20733,6 +20824,48 @@ "--xcode-build-version", "11e146" ], + "isolate_name": "ios_chrome_integration_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_integration_eg2tests_module_iPad Air 2 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_integration_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], "isolate_name": "ios_chrome_settings_eg2tests_module", "merge": { "args": [], @@ -20759,7 +20892,8 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, @@ -20774,6 +20908,47 @@ "--xcode-build-version", "11e146" ], + "isolate_name": "ios_chrome_signin_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_signin_eg2tests_module_iPad Air 2 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], "isolate_name": "ios_chrome_smoke_eg2tests_module", "merge": { "args": [], @@ -20815,6 +20990,48 @@ "--xcode-build-version", "11e146" ], + "isolate_name": "ios_chrome_ui_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_ui_eg2tests_module_iPad Air 2 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 5 + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], "isolate_name": "ios_chrome_unittests", "merge": { "args": [], @@ -21143,6 +21360,47 @@ "--xcode-build-version", "11e146" ], + "isolate_name": "ios_web_shell_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_web_shell_eg2tests_module_iPad Air 2 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/web/shell/test:ios_web_shell_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], "isolate_name": "ios_web_unittests", "merge": { "args": [], @@ -22120,12 +22378,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_bookmarks_egtests", + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_bookmarks_egtests_iPad Air 2 13.4", + "name": "ios_chrome_bookmarks_eg2tests_module_iPad Air 2 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -22148,7 +22406,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" }, { "args": [ @@ -22163,12 +22421,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_bookmarks_egtests", + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_bookmarks_egtests_iPhone X 13.4", + "name": "ios_chrome_bookmarks_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -22191,7 +22449,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" }, { "args": [ @@ -22294,98 +22552,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_reading_list_egtests", + "isolate_name": "ios_chrome_settings_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_reading_list_egtests_iPad Air 2 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "13.4", - "--args-json", - "{\"test_args\": [\"--run-with-custom-webkit\"]}", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_reading_list_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_reading_list_egtests_iPhone X 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "13.4", - "--args-json", - "{\"test_args\": [\"--run-with-custom-webkit\"]}", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPad Air 2 13.4", + "name": "ios_chrome_settings_eg2tests_module_iPad Air 2 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -22409,7 +22581,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 3 }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, { "args": [ @@ -22424,12 +22596,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_settings_egtests", + "isolate_name": "ios_chrome_settings_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_settings_egtests_iPhone X 13.4", + "name": "ios_chrome_settings_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -22453,7 +22625,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 3 }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, { "args": [ @@ -22554,12 +22726,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_translate_egtests", + "isolate_name": "ios_chrome_smoke_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_translate_egtests_iPad Air 2 13.4", + "name": "ios_chrome_smoke_eg2tests_module_iPad Air 2 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -22582,7 +22754,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" }, { "args": [ @@ -22597,12 +22769,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_translate_egtests", + "isolate_name": "ios_chrome_smoke_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_translate_egtests_iPhone X 13.4", + "name": "ios_chrome_smoke_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -22625,7 +22797,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" }, { "args": [ @@ -22814,12 +22986,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_web_egtests", + "isolate_name": "ios_chrome_web_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_web_egtests_iPad Air 2 13.4", + "name": "ios_chrome_web_eg2tests_module_iPad Air 2 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -22842,7 +23014,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" }, { "args": [ @@ -22857,12 +23029,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_web_egtests", + "isolate_name": "ios_chrome_web_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_web_egtests_iPhone X 13.4", + "name": "ios_chrome_web_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -22885,7 +23057,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" }, { "args": [ @@ -23158,12 +23330,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_showcase_egtests", + "isolate_name": "ios_showcase_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_showcase_egtests_iPad Air 2 13.4", + "name": "ios_showcase_eg2tests_module_iPad Air 2 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -23186,7 +23358,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" }, { "args": [ @@ -23201,12 +23373,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_showcase_egtests", + "isolate_name": "ios_showcase_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_showcase_egtests_iPhone X 13.4", + "name": "ios_showcase_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -23229,7 +23401,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" }, { "args": [ @@ -25421,6 +25593,88 @@ { "args": [ "--platform", + "iPad Air (3rd generation)", + "--version", + "12.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_bookmarks_eg2tests_module_iPad Air (3rd generation) 12.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air (3rd generation)", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_bookmarks_eg2tests_module_iPad Air (3rd generation) 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" + }, + { + "args": [ + "--platform", "iPhone 7", "--version", "13.4", @@ -25544,170 +25798,6 @@ { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_bookmarks_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air (3rd generation)", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_bookmarks_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_egtests_iPad Air (3rd generation) 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_bookmarks_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_bookmarks_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_egtests_iPhone X 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" - }, - { - "args": [ - "--platform", "iPad (6th generation)", "--version", "12.4", @@ -26002,170 +26092,6 @@ { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_reading_list_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_reading_list_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air (3rd generation)", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_reading_list_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_reading_list_egtests_iPad Air (3rd generation) 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_reading_list_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_reading_list_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_reading_list_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_reading_list_egtests_iPhone X 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", "iPad (6th generation)", "--version", "12.4", @@ -26200,7 +26126,8 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, @@ -26241,7 +26168,92 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air (3rd generation)", + "--version", + "12.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_settings_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_settings_eg2tests_module_iPad Air (3rd generation) 12.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air (3rd generation)", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_settings_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_settings_eg2tests_module_iPad Air (3rd generation) 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, @@ -26282,7 +26294,8 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, @@ -26323,7 +26336,8 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, @@ -26364,181 +26378,14 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air (3rd generation)", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPad Air (3rd generation) 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPhone X 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", "iPad (6th generation)", "--version", "12.4", @@ -26908,6 +26755,88 @@ { "args": [ "--platform", + "iPad Air (3rd generation)", + "--version", + "12.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_smoke_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_smoke_eg2tests_module_iPad Air (3rd generation) 12.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air (3rd generation)", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_smoke_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_smoke_eg2tests_module_iPad Air (3rd generation) 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" + }, + { + "args": [ + "--platform", "iPhone 7", "--version", "13.4", @@ -27031,170 +26960,6 @@ { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_translate_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_translate_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air (3rd generation)", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_translate_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_translate_egtests_iPad Air (3rd generation) 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_translate_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_translate_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_translate_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_translate_egtests_iPhone X 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" - }, - { - "args": [ - "--platform", "iPad (6th generation)", "--version", "12.4", @@ -27817,6 +27582,88 @@ { "args": [ "--platform", + "iPad Air (3rd generation)", + "--version", + "12.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_web_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_web_eg2tests_module_iPad Air (3rd generation) 12.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air (3rd generation)", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_web_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_web_eg2tests_module_iPad Air (3rd generation) 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" + }, + { + "args": [ + "--platform", "iPhone 7", "--version", "13.4", @@ -27940,170 +27787,6 @@ { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_web_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air (3rd generation)", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_web_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_egtests_iPad Air (3rd generation) 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_web_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_web_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_egtests_iPhone X 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" - }, - { - "args": [ - "--platform", "iPhone X", "--version", "12.4", @@ -28432,6 +28115,88 @@ { "args": [ "--platform", + "iPad Air (3rd generation)", + "--version", + "12.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_showcase_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_showcase_eg2tests_module_iPad Air (3rd generation) 12.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air (3rd generation)", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_showcase_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_showcase_eg2tests_module_iPad Air (3rd generation) 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" + }, + { + "args": [ + "--platform", "iPhone 7", "--version", "13.4", @@ -28555,170 +28320,6 @@ { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_showcase_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air (3rd generation)", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_showcase_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_egtests_iPad Air (3rd generation) 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_showcase_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_showcase_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_egtests_iPhone X 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" - }, - { - "args": [ - "--platform", "iPhone X", "--version", "12.4", @@ -31888,6 +31489,129 @@ { "args": [ "--platform", + "iPad Air (3rd generation)", + "--version", + "12.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_bookmarks_eg2tests_module_iPad Air (3rd generation) 12.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_bookmarks_eg2tests_module_iPad Air 2 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPhone 7", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_bookmarks_eg2tests_module_iPhone 7 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" + }, + { + "args": [ + "--platform", "iPhone X", "--version", "12.4", @@ -31929,170 +31653,6 @@ { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_bookmarks_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_bookmarks_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_egtests_iPad Air 2 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_bookmarks_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_egtests_iPhone 7 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_bookmarks_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" - }, - { - "args": [ - "--platform", "iPhone X", "--version", "13.4", @@ -32101,12 +31661,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_bookmarks_egtests", + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_bookmarks_egtests_iPhone X 13.4", + "name": "ios_chrome_bookmarks_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -32129,7 +31689,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" }, { "args": [ @@ -32344,211 +31904,6 @@ { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_reading_list_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_reading_list_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_reading_list_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_reading_list_egtests_iPad Air 2 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_reading_list_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_reading_list_egtests_iPhone 7 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_reading_list_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_reading_list_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_reading_list_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_reading_list_egtests_iPhone X 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", "iPad (6th generation)", "--version", "12.4", @@ -32583,7 +31938,134 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air (3rd generation)", + "--version", + "12.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_settings_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_settings_eg2tests_module_iPad Air (3rd generation) 12.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_settings_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_settings_eg2tests_module_iPad Air 2 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPhone 7", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_settings_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_settings_eg2tests_module_iPhone 7 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, @@ -32624,181 +32106,14 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPad Air 2 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPhone 7 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", "iPhone X", "--version", "13.4", @@ -32807,12 +32122,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_settings_egtests", + "isolate_name": "ios_chrome_settings_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_settings_egtests_iPhone X 13.4", + "name": "ios_chrome_settings_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -32836,7 +32151,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 3 }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, { "args": [ @@ -33087,6 +32402,129 @@ { "args": [ "--platform", + "iPad Air (3rd generation)", + "--version", + "12.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_smoke_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_smoke_eg2tests_module_iPad Air (3rd generation) 12.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_smoke_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_smoke_eg2tests_module_iPad Air 2 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPhone 7", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_smoke_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_smoke_eg2tests_module_iPhone 7 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" + }, + { + "args": [ + "--platform", "iPhone X", "--version", "12.4", @@ -33128,170 +32566,6 @@ { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_translate_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_translate_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_translate_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_translate_egtests_iPad Air 2 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_translate_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_translate_egtests_iPhone 7 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_translate_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_translate_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" - }, - { - "args": [ - "--platform", "iPhone X", "--version", "13.4", @@ -33300,12 +32574,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_translate_egtests", + "isolate_name": "ios_chrome_smoke_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_translate_egtests_iPhone X 13.4", + "name": "ios_chrome_smoke_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -33328,7 +32602,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" }, { "args": [ @@ -33789,6 +33063,129 @@ { "args": [ "--platform", + "iPad Air (3rd generation)", + "--version", + "12.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_web_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_web_eg2tests_module_iPad Air (3rd generation) 12.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_web_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_web_eg2tests_module_iPad Air 2 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPhone 7", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_chrome_web_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_chrome_web_eg2tests_module_iPhone 7 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" + }, + { + "args": [ + "--platform", "iPhone X", "--version", "12.4", @@ -33830,170 +33227,6 @@ { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_web_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_web_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_egtests_iPad Air 2 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_web_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_egtests_iPhone 7 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_web_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" - }, - { - "args": [ - "--platform", "iPhone X", "--version", "13.4", @@ -34002,12 +33235,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_web_egtests", + "isolate_name": "ios_chrome_web_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_web_egtests_iPhone X 13.4", + "name": "ios_chrome_web_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -34030,7 +33263,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" }, { "args": [ @@ -34322,6 +33555,129 @@ { "args": [ "--platform", + "iPad Air (3rd generation)", + "--version", + "12.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_showcase_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_showcase_eg2tests_module_iPad Air (3rd generation) 12.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPad Air 2", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_showcase_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_showcase_eg2tests_module_iPad Air 2 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" + }, + { + "args": [ + "--platform", + "iPhone 7", + "--version", + "13.4", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "11e146" + ], + "isolate_name": "ios_showcase_eg2tests_module", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "ios_showcase_eg2tests_module_iPhone 7 13.4", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" + } + ], + "dimension_sets": [ + { + "os": "Mac-10.15" + } + ], + "named_caches": [ + { + "name": "xcode_ios_11e146", + "path": "Xcode.app" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" + }, + { + "args": [ + "--platform", "iPhone X", "--version", "12.4", @@ -34363,170 +33719,6 @@ { "args": [ "--platform", - "iPad Air (3rd generation)", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_showcase_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_egtests_iPad Air (3rd generation) 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_showcase_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_egtests_iPad Air 2 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_showcase_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_egtests_iPhone 7 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_showcase_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" - }, - { - "args": [ - "--platform", "iPhone X", "--version", "13.4", @@ -34535,12 +33727,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_showcase_egtests", + "isolate_name": "ios_showcase_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_showcase_egtests_iPhone X 13.4", + "name": "ios_showcase_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -34563,7 +33755,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" }, { "args": [
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json index 40543f6..b20db24 100644 --- a/testing/buildbot/chromium.mac.json +++ b/testing/buildbot/chromium.mac.json
@@ -15025,12 +15025,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_bookmarks_egtests", + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_bookmarks_egtests_iPad Air 2 12.4", + "name": "ios_chrome_bookmarks_eg2tests_module_iPad Air 2 12.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -15053,7 +15053,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" }, { "args": [ @@ -15066,12 +15066,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_bookmarks_egtests", + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_bookmarks_egtests_iPad Air 2 13.4", + "name": "ios_chrome_bookmarks_eg2tests_module_iPad Air 2 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -15094,7 +15094,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" }, { "args": [ @@ -15107,12 +15107,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_bookmarks_egtests", + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_bookmarks_egtests_iPhone 7 13.4", + "name": "ios_chrome_bookmarks_eg2tests_module_iPhone 7 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -15135,7 +15135,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" }, { "args": [ @@ -15148,12 +15148,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_bookmarks_egtests", + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_bookmarks_egtests_iPhone X 12.4", + "name": "ios_chrome_bookmarks_eg2tests_module_iPhone X 12.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -15176,7 +15176,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" }, { "args": [ @@ -15189,12 +15189,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_bookmarks_egtests", + "isolate_name": "ios_chrome_bookmarks_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_bookmarks_egtests_iPhone X 13.4", + "name": "ios_chrome_bookmarks_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -15217,7 +15217,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_bookmarks_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" }, { "args": [ @@ -15356,12 +15356,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_reading_list_egtests", + "isolate_name": "ios_chrome_settings_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_reading_list_egtests_iPad Air 2 12.4", + "name": "ios_chrome_settings_eg2tests_module_iPad Air 2 12.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -15382,9 +15382,10 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, { "args": [ @@ -15397,12 +15398,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_reading_list_egtests", + "isolate_name": "ios_chrome_settings_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_reading_list_egtests_iPad Air 2 13.4", + "name": "ios_chrome_settings_eg2tests_module_iPad Air 2 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -15423,9 +15424,10 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, { "args": [ @@ -15438,12 +15440,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_reading_list_egtests", + "isolate_name": "ios_chrome_settings_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_reading_list_egtests_iPhone 7 13.4", + "name": "ios_chrome_settings_eg2tests_module_iPhone 7 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -15464,9 +15466,10 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, { "args": [ @@ -15479,12 +15482,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_reading_list_egtests", + "isolate_name": "ios_chrome_settings_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_reading_list_egtests_iPhone X 12.4", + "name": "ios_chrome_settings_eg2tests_module_iPhone X 12.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -15505,9 +15508,10 @@ "path": "Xcode.app" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, { "args": [ @@ -15520,53 +15524,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_reading_list_egtests", + "isolate_name": "ios_chrome_settings_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_reading_list_egtests_iPhone X 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPad Air 2 12.4", + "name": "ios_chrome_settings_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -15590,175 +15553,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 3 }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPad Air 2 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPhone 7 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "12.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPhone X 12.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", - "13.4", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "11e146" - ], - "isolate_name": "ios_chrome_settings_egtests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_egtests_iPhone X 13.4", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a" - } - ], - "dimension_sets": [ - { - "os": "Mac-10.15" - } - ], - "named_caches": [ - { - "name": "xcode_ios_11e146", - "path": "Xcode.app" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_settings_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" }, { "args": [ @@ -15894,12 +15689,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_translate_egtests", + "isolate_name": "ios_chrome_smoke_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_translate_egtests_iPad Air 2 12.4", + "name": "ios_chrome_smoke_eg2tests_module_iPad Air 2 12.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -15922,7 +15717,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" }, { "args": [ @@ -15935,12 +15730,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_translate_egtests", + "isolate_name": "ios_chrome_smoke_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_translate_egtests_iPad Air 2 13.4", + "name": "ios_chrome_smoke_eg2tests_module_iPad Air 2 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -15963,7 +15758,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" }, { "args": [ @@ -15976,12 +15771,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_translate_egtests", + "isolate_name": "ios_chrome_smoke_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_translate_egtests_iPhone 7 13.4", + "name": "ios_chrome_smoke_eg2tests_module_iPhone 7 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -16004,7 +15799,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" }, { "args": [ @@ -16017,12 +15812,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_translate_egtests", + "isolate_name": "ios_chrome_smoke_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_translate_egtests_iPhone X 12.4", + "name": "ios_chrome_smoke_eg2tests_module_iPhone X 12.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -16045,7 +15840,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" }, { "args": [ @@ -16058,12 +15853,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_translate_egtests", + "isolate_name": "ios_chrome_smoke_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_translate_egtests_iPhone X 13.4", + "name": "ios_chrome_smoke_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -16086,7 +15881,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_translate_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" }, { "args": [ @@ -16225,12 +16020,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_web_egtests", + "isolate_name": "ios_chrome_web_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_web_egtests_iPad Air 2 12.4", + "name": "ios_chrome_web_eg2tests_module_iPad Air 2 12.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -16253,7 +16048,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" }, { "args": [ @@ -16266,12 +16061,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_web_egtests", + "isolate_name": "ios_chrome_web_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_web_egtests_iPad Air 2 13.4", + "name": "ios_chrome_web_eg2tests_module_iPad Air 2 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -16294,7 +16089,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" }, { "args": [ @@ -16307,12 +16102,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_web_egtests", + "isolate_name": "ios_chrome_web_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_web_egtests_iPhone 7 13.4", + "name": "ios_chrome_web_eg2tests_module_iPhone 7 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -16335,7 +16130,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" }, { "args": [ @@ -16348,12 +16143,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_web_egtests", + "isolate_name": "ios_chrome_web_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_web_egtests_iPhone X 12.4", + "name": "ios_chrome_web_eg2tests_module_iPhone X 12.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -16376,7 +16171,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" }, { "args": [ @@ -16389,12 +16184,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_chrome_web_egtests", + "isolate_name": "ios_chrome_web_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_chrome_web_egtests_iPhone X 13.4", + "name": "ios_chrome_web_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -16417,7 +16212,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey:ios_chrome_web_egtests/" + "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" }, { "args": [ @@ -16430,12 +16225,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_showcase_egtests", + "isolate_name": "ios_showcase_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_showcase_egtests_iPad Air 2 12.4", + "name": "ios_showcase_eg2tests_module_iPad Air 2 12.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -16458,7 +16253,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" }, { "args": [ @@ -16471,12 +16266,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_showcase_egtests", + "isolate_name": "ios_showcase_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_showcase_egtests_iPad Air 2 13.4", + "name": "ios_showcase_eg2tests_module_iPad Air 2 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -16499,7 +16294,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" }, { "args": [ @@ -16512,12 +16307,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_showcase_egtests", + "isolate_name": "ios_showcase_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_showcase_egtests_iPhone 7 13.4", + "name": "ios_showcase_eg2tests_module_iPhone 7 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -16540,7 +16335,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" }, { "args": [ @@ -16553,12 +16348,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_showcase_egtests", + "isolate_name": "ios_showcase_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_showcase_egtests_iPhone X 12.4", + "name": "ios_showcase_eg2tests_module_iPhone X 12.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -16581,7 +16376,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" }, { "args": [ @@ -16594,12 +16389,12 @@ "--xcode-build-version", "11e146" ], - "isolate_name": "ios_showcase_egtests", + "isolate_name": "ios_showcase_eg2tests_module", "merge": { "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "ios_showcase_egtests_iPhone X 13.4", + "name": "ios_showcase_eg2tests_module_iPhone X 13.4", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ @@ -16622,7 +16417,7 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_egtests/" + "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" }, { "args": [
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 18331231..e1db6f0 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -940,6 +940,7 @@ # exception once there is enough capacity to run these tests. 'remove_from': [ 'Android FYI Release (Pixel 2)', + 'Fuchsia x64' # https://crbug.com/1058255 ], 'modifications': { 'Mac FYI GPU ASAN Release': { @@ -992,6 +993,7 @@ # exception once there is enough capacity to run these tests. 'remove_from': [ 'Android FYI Release (Pixel 2)', + 'Fuchsia x64' # https://crbug.com/1058255 ], 'modifications': { 'Win10 x64 Debug (NVIDIA)': { @@ -1157,6 +1159,7 @@ # exception once there is enough capacity to run these tests. 'remove_from': [ 'Android FYI Release (Pixel 2)', + 'Fuchsia x64', # https://crbug.com/1075803 ], 'modifications': { 'Win10 x64 Debug (NVIDIA)': {
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index a7a3157..995a318 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -1241,6 +1241,16 @@ }, 'fuchsia_gpu_telemetry_tests': { + 'context_lost': { + 'isolate_name': 'fuchsia_telemetry_gpu_integration_test', + }, + 'depth_capture': { + 'isolate_name': 'fuchsia_telemetry_gpu_integration_test', + }, + 'gpu_process': { + 'name': 'gpu_process_launch_tests', + 'isolate_name': 'fuchsia_telemetry_gpu_integration_test', + }, 'hardware_accelerated_feature': { 'isolate_name': 'fuchsia_telemetry_gpu_integration_test', }, @@ -2772,23 +2782,14 @@ 'ios_eg2_tests': { 'ios_chrome_bookmarks_eg2tests_module': {}, - 'ios_chrome_settings_eg2tests_module': {}, - 'ios_chrome_smoke_eg2tests_module': {}, - 'ios_chrome_web_eg2tests_module': {}, - 'ios_showcase_eg2tests_module': {}, - }, - - 'ios_eg_tests': { - 'ios_chrome_bookmarks_egtests': {}, - 'ios_chrome_reading_list_egtests': {}, - 'ios_chrome_settings_egtests': { + 'ios_chrome_settings_eg2tests_module': { 'swarming': { 'shards': 3, }, }, - 'ios_chrome_translate_egtests': {}, - 'ios_chrome_web_egtests': {}, - 'ios_showcase_egtests': {}, + 'ios_chrome_smoke_eg2tests_module': {}, + 'ios_chrome_web_eg2tests_module': {}, + 'ios_showcase_eg2tests_module': {}, }, 'ios_screen_size_dependent_tests': { @@ -4904,8 +4905,10 @@ 'variants': [ 'SIM_IPHONE_X_13_4', 'SIM_IPHONE_7_13_4', + 'SIM_IPAD_AIR_3RD_GEN_13_4', 'SIM_IPAD_6_GEN_13_4', 'SIM_IPHONE_X_12_4', + 'SIM_IPAD_AIR_3RD_GEN_12_4', 'SIM_IPAD_6_GEN_12_4', ] }, @@ -4920,14 +4923,6 @@ 'SIM_IPAD_6_GEN_12_4', ] }, - 'ios_eg_tests': { - 'variants': [ - 'SIM_IPHONE_X_13_4', - 'SIM_IPAD_AIR_3RD_GEN_13_4', - 'SIM_IPHONE_X_12_4', - 'SIM_IPAD_AIR_3RD_GEN_12_4', - ] - }, 'ios_screen_size_dependent_tests': { 'variants': [ 'SIM_IPHONE_6S_PLUS_13_4', @@ -4949,7 +4944,11 @@ }, 'ios_eg2_tests': { 'variants': [ + 'SIM_IPHONE_7_13_4', + 'SIM_IPAD_AIR_2_13_4', + 'SIM_IPHONE_X_13_4', 'SIM_IPHONE_X_12_4', + 'SIM_IPAD_AIR_3RD_GEN_12_4', 'SIM_IPAD_6_GEN_12_4', ] }, @@ -4962,15 +4961,6 @@ 'SIM_IPAD_6_GEN_12_4', ] }, - 'ios_eg_tests': { - 'variants': [ - 'SIM_IPHONE_7_13_4', - 'SIM_IPAD_AIR_2_13_4', - 'SIM_IPHONE_X_13_4', - 'SIM_IPHONE_X_12_4', - 'SIM_IPAD_AIR_3RD_GEN_12_4', - ] - }, 'ios_screen_size_dependent_tests': { 'variants': [ 'SIM_IPHONE_6S_PLUS_13_4', @@ -5043,7 +5033,7 @@ }, 'ios_simulator_full_configs_test': { - 'ios_eg_tests': { + 'ios_eg2_tests': { 'variants': [ 'SIM_IPAD_AIR_2_12_4', 'SIM_IPHONE_X_12_4', @@ -5067,6 +5057,11 @@ 'SIM_IPAD_AIR_2_13_4', ] }, + 'ios_eg2_cq_tests': { + 'variants': [ + 'SIM_IPAD_AIR_2_13_4', + ] + }, 'ios_eg2_tests': { 'variants': [ 'SIM_IPAD_AIR_2_13_4', @@ -5115,7 +5110,7 @@ 'SIM_IPAD_AIR_2_13_4', ] }, - 'ios_eg_tests': { + 'ios_eg2_tests': { 'variants': [ 'SIM_IPHONE_X_13_4', 'SIM_IPAD_AIR_2_13_4',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 1be2e61..2d1aa85e 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -879,27 +879,6 @@ ] } ], - "AutofillUpstreamEditableExpirationDate": [ - { - "platforms": [ - "android", - "android_weblayer", - "chromeos", - "ios", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "AutofillUpstreamEditableExpirationDate" - ] - } - ] - } - ], "AutofillUseImprovedLabelDisambiguation": [ { "platforms": [ @@ -2868,10 +2847,6 @@ "ImprovedCookieControls": [ { "platforms": [ - "chromeos", - "linux", - "mac", - "windows", "android" ], "experiments": [ @@ -4195,8 +4170,13 @@ ], "experiments": [ { - "name": "WithEnhancedExperiment", + "name": "WithEnhancedExperiment_20200519", + "params": { + "DefaultInIncognito": "true" + }, "enable_features": [ + "ImprovedCookieControls", + "ImprovedCookieControlsForThirdPartyCookieBlocking", "PasswordCheck", "PrivacySettingsRedesign", "SafeBrowsingEnhancedProtection", @@ -7161,6 +7141,21 @@ ] } ], + "iOSQRCodeGenerator": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "QRCodeGeneration" + ] + } + ] + } + ], "libvpx_for_vp8": [ { "platforms": [
diff --git a/third_party/android_deps/BUILD.gn b/third_party/android_deps/BUILD.gn index ba8765c..b076c7c 100644 --- a/third_party/android_deps/BUILD.gn +++ b/third_party/android_deps/BUILD.gn
@@ -141,6 +141,20 @@ } # This is generated, do not edit. Update BuildConfigGenerator.groovy instead. +android_aar_prebuilt("androidx_appcompat_appcompat_resources_java") { + aar_path = "libs/androidx_appcompat_appcompat_resources/appcompat-resources-1.2.0-beta01.aar" + info_path = "libs/androidx_appcompat_appcompat_resources/androidx_appcompat_appcompat_resources.info" + deps = [ + ":androidx_annotation_annotation_java", + ":androidx_collection_collection_java", + ":androidx_core_core_java", + ":androidx_vectordrawable_vectordrawable_animated_java", + ":androidx_vectordrawable_vectordrawable_java", + ] + skip_jetify = true +} + +# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. android_aar_prebuilt("androidx_asynclayoutinflater_asynclayoutinflater_java") { aar_path = "libs/androidx_asynclayoutinflater_asynclayoutinflater/asynclayoutinflater-1.0.0.aar" info_path = "libs/androidx_asynclayoutinflater_asynclayoutinflater/androidx_asynclayoutinflater_asynclayoutinflater.info" @@ -1558,24 +1572,6 @@ } # This is generated, do not edit. Update BuildConfigGenerator.groovy instead. -android_aar_prebuilt("androidx_appcompat_appcompat_resources_java") { - aar_path = "libs/androidx_appcompat_appcompat_resources/appcompat-resources-1.2.0-beta01.aar" - info_path = "libs/androidx_appcompat_appcompat_resources/androidx_appcompat_appcompat_resources.info" - - # To remove visibility constraint, add this dependency to - # //third_party/android_deps/build.gradle. - visibility = [ ":*" ] - deps = [ - ":androidx_annotation_annotation_java", - ":androidx_collection_collection_java", - ":androidx_core_core_java", - ":androidx_vectordrawable_vectordrawable_animated_java", - ":androidx_vectordrawable_vectordrawable_java", - ] - skip_jetify = true -} - -# This is generated, do not edit. Update BuildConfigGenerator.groovy instead. java_prebuilt("androidx_arch_core_core_common_java") { jar_path = "libs/androidx_arch_core_core_common/core-common-2.1.0.jar" output_name = "androidx_arch_core_core_common"
diff --git a/third_party/android_deps/build.gradle b/third_party/android_deps/build.gradle index 1038c06f..588df80 100644 --- a/third_party/android_deps/build.gradle +++ b/third_party/android_deps/build.gradle
@@ -30,6 +30,7 @@ compile "androidx.annotation:annotation:${androidXSupportLibVersion}" compile "androidx.appcompat:appcompat:1.2.0-beta01" + compile "androidx.appcompat:appcompat-resources:1.2.0-beta01" compile "androidx.asynclayoutinflater:asynclayoutinflater:${androidXSupportLibVersion}" compile "androidx.cardview:cardview:${androidXSupportLibVersion}" compile "androidx.concurrent:concurrent-futures:${androidXSupportLibVersion}"
diff --git a/third_party/android_platform/development/scripts/stack_core.py b/third_party/android_platform/development/scripts/stack_core.py index 35315831..d05a6593 100755 --- a/third_party/android_platform/development/scripts/stack_core.py +++ b/third_party/android_platform/development/scripts/stack_core.py
@@ -516,22 +516,26 @@ FILE_NAME_OFFSET = 30 soname = "" sosize = 0 - with zipfile.ZipFile(apkname, 'r') as apk: - for infoList in apk.infolist(): - _, file_extension = os.path.splitext(infoList.filename) - if (file_extension == '.so' and - infoList.file_size == infoList.compress_size): - with open(apkname, 'rb') as f: - f.seek(infoList.header_offset + FILE_NAME_LEN_OFFSET) - file_name_len = struct.unpack('H', f.read(2))[0] - extra_field_len = struct.unpack('H', f.read(2))[0] - file_offset = (infoList.header_offset + FILE_NAME_OFFSET + - file_name_len + extra_field_len) - f.seek(file_offset) - if offset == file_offset and f.read(4) == "\x7fELF": - soname = infoList.filename.replace('crazy.', '') - sosize = infoList.file_size - break + try: + with zipfile.ZipFile(apkname, 'r') as apk: + for infoList in apk.infolist(): + _, file_extension = os.path.splitext(infoList.filename) + if (file_extension == '.so' and + infoList.file_size == infoList.compress_size): + with open(apkname, 'rb') as f: + f.seek(infoList.header_offset + FILE_NAME_LEN_OFFSET) + file_name_len = struct.unpack('H', f.read(2))[0] + extra_field_len = struct.unpack('H', f.read(2))[0] + file_offset = (infoList.header_offset + FILE_NAME_OFFSET + + file_name_len + extra_field_len) + f.seek(file_offset) + if offset == file_offset and f.read(4) == "\x7fELF": + soname = infoList.filename.replace('crazy.', '') + sosize = infoList.file_size + break + except zipfile.BadZipfile: + logging.warning("Ignorning bad zip file %s", apkname) + return "", 0 return soname, sosize
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index 59eb599..97912f7f 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -157,7 +157,6 @@ "platform/scheduler/web_scoped_virtual_time_pauser.h", "platform/scheduler/web_thread_scheduler.h", "platform/scheduler/web_widget_scheduler.h", - "platform/shape_properties.h", "platform/task_type.h", "platform/url_conversion.h", "platform/user_metrics_action.h",
diff --git a/third_party/blink/public/mojom/fetch/fetch_api_response.mojom b/third_party/blink/public/mojom/fetch/fetch_api_response.mojom index 0f85ff3..2c9ed6cf 100644 --- a/third_party/blink/public/mojom/fetch/fetch_api_response.mojom +++ b/third_party/blink/public/mojom/fetch/fetch_api_response.mojom
@@ -7,6 +7,7 @@ import "mojo/public/mojom/base/time.mojom"; import "services/network/public/mojom/fetch_api.mojom"; import "services/network/public/mojom/parsed_headers.mojom"; +import "services/network/public/mojom/network_types.mojom"; import "third_party/blink/public/mojom/blob/serialized_blob.mojom"; import "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom"; import "url/mojom/url.mojom"; @@ -74,6 +75,13 @@ // output of blink::ParseHeaders(headers, url); network.mojom.ParsedHeaders? parsed_headers; + // Enumeration that describes the kind of connection originally used to + // fetch this request. + network.mojom.ConnectionInfo connection_info; + + // ALPN negotiated protocol of the socket which fetched this resource. + string alpn_negotiated_protocol = "unknown"; + // True if the response was loaded with a Request where the credentials mode // would potentially send cookies to the server: // @@ -86,4 +94,8 @@ // This field may be true even if there were no cookies actually available // to send. bool loaded_with_credentials = false; + + // True if the response was originally loaded via a request fetched over a + // SPDY channel. + bool was_fetched_via_spdy = false; };
diff --git a/third_party/blink/public/mojom/frame/frame.mojom b/third_party/blink/public/mojom/frame/frame.mojom index 5e69882..f2a6b69 100644 --- a/third_party/blink/public/mojom/frame/frame.mojom +++ b/third_party/blink/public/mojom/frame/frame.mojom
@@ -543,6 +543,10 @@ // Binds |receiver| to the document of this frame. BindReportingObserver( pending_receiver<blink.mojom.ReportingObserver> receiver); + + // Requests that the blink::LocalFrame updates its opener to the specified + // frame. The frame token may be "empty" if the opener was disowned. + UpdateOpener(mojo_base.mojom.UnguessableToken? opener_frame_token); }; // Implemented in Browser, this interface defines frame-specific methods that @@ -598,6 +602,14 @@ // frame identified by |opener_frame|, or, if |opener_frame| is "empty", // the frame disowns its opener for the lifetime of the window. DidChangeOpener(mojo_base.mojom.UnguessableToken? opener_frame); + + // This message is sent from a RemoteFrame when sequential focus navigation + // needs to advance into its actual frame. |source_frame_token| identifies the + // frame that issued this request. This is used when pressing <tab> or + // <shift-tab> hits an out-of-process iframe when searching for the next + // focusable element. + AdvanceFocus(blink.mojom.FocusType focus_type, + mojo_base.mojom.UnguessableToken source_frame_token); }; // Implemented in Blink, this interface defines frame-specific methods that will @@ -727,6 +739,10 @@ // Notifies the frame that its parent has changed the frame's sandbox flags or // container policy. DidUpdateFramePolicy(blink.mojom.FramePolicy frame_policy); + + // Requests that the blink::RemoteFrame updates its opener to the specified + // frame. The frame token may be "empty" if the opener was disowned. + UpdateOpener(mojo_base.mojom.UnguessableToken? opener_frame_token); }; // Implemented in Blink, this interface defines main-frame-specific methods that
diff --git a/third_party/blink/public/platform/shape_properties.h b/third_party/blink/public/platform/shape_properties.h deleted file mode 100644 index 8edf737f..0000000 --- a/third_party/blink/public/platform/shape_properties.h +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_SHAPE_PROPERTIES_H_ -#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_SHAPE_PROPERTIES_H_ - -namespace blink { - -// Bit field values indicating available display shapes. -enum DisplayShape { - kDisplayShapeRect = 1 << 0, - kDisplayShapeRound = 1 << 1, -}; - -} // namespace blink - -#endif
diff --git a/third_party/blink/public/platform/web_screen_info.h b/third_party/blink/public/platform/web_screen_info.h index 9ee3538..10ec99da 100644 --- a/third_party/blink/public/platform/web_screen_info.h +++ b/third_party/blink/public/platform/web_screen_info.h
@@ -32,7 +32,6 @@ #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_SCREEN_INFO_H_ #include "third_party/blink/public/common/screen_orientation/web_screen_orientation_type.h" -#include "third_party/blink/public/platform/shape_properties.h" #include "third_party/blink/public/platform/web_rect.h" #include "ui/gfx/color_space.h" @@ -83,9 +82,6 @@ // TODO(crbug.com/840189): we should use an enum rather than a number here. uint16_t orientation_angle = 0; - // This is the shape of display. - DisplayShape display_shape = kDisplayShapeRect; - WebScreenInfo() = default; bool operator==(const WebScreenInfo& other) const { @@ -97,8 +93,7 @@ this->rect == other.rect && this->available_rect == other.available_rect && this->orientation_type == other.orientation_type && - this->orientation_angle == other.orientation_angle && - this->display_shape == other.display_shape; + this->orientation_angle == other.orientation_angle; } bool operator!=(const WebScreenInfo& other) const {
diff --git a/third_party/blink/public/web/web_local_frame.h b/third_party/blink/public/web/web_local_frame.h index 8c64236..a5256ecf 100644 --- a/third_party/blink/public/web/web_local_frame.h +++ b/third_party/blink/public/web/web_local_frame.h
@@ -264,6 +264,7 @@ const WebURL& mixed_content_url, mojom::RequestContextType, bool was_allowed, + const WebURL& url_before_redirects, bool had_redirect, const WebSourceLocation&) = 0;
diff --git a/third_party/blink/public/web/web_remote_frame_client.h b/third_party/blink/public/web/web_remote_frame_client.h index 62cee3f..f1ce345ae 100644 --- a/third_party/blink/public/web/web_remote_frame_client.h +++ b/third_party/blink/public/web/web_remote_frame_client.h
@@ -52,11 +52,6 @@ virtual void UpdateRemoteViewportIntersection( const ViewportIntersectionState& intersection_state) {} - // Continue sequential focus navigation in this frame. This is called when - // the |source| frame is searching for the next focusable element (e.g., in - // response to <tab>) and encounters a remote frame. - virtual void AdvanceFocus(mojom::FocusType type, WebLocalFrame* source) {} - // Returns token to be used as a frame id in the devtools protocol. // It is derived from the content's devtools_frame_token, is // defined by the browser and passed into Blink upon frame creation.
diff --git a/third_party/blink/renderer/core/css/css_value_keywords.json5 b/third_party/blink/renderer/core/css/css_value_keywords.json5 index 66b6f04..9769267 100644 --- a/third_party/blink/renderer/core/css/css_value_keywords.json5 +++ b/third_party/blink/renderer/core/css/css_value_keywords.json5
@@ -1185,10 +1185,6 @@ "verso", "avoid-column", - // shape - // rect - // round - // color-gamut // srgb "p3",
diff --git a/third_party/blink/renderer/core/css/media_feature_names.json5 b/third_party/blink/renderer/core/css/media_feature_names.json5 index 388a588..b89d9f91 100644 --- a/third_party/blink/renderer/core/css/media_feature_names.json5 +++ b/third_party/blink/renderer/core/css/media_feature_names.json5
@@ -58,6 +58,5 @@ "-webkit-transform-3d", "scan", "screen-spanning", - "shape", ], }
diff --git a/third_party/blink/renderer/core/css/media_query_evaluator.cc b/third_party/blink/renderer/core/css/media_query_evaluator.cc index ba97661..7ec11c6 100644 --- a/third_party/blink/renderer/core/css/media_query_evaluator.cc +++ b/third_party/blink/renderer/core/css/media_query_evaluator.cc
@@ -35,7 +35,6 @@ #include "third_party/blink/public/common/css/screen_spanning.h" #include "third_party/blink/public/mojom/manifest/display_mode.mojom-shared.h" #include "third_party/blink/public/platform/pointer_properties.h" -#include "third_party/blink/public/platform/shape_properties.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_resolution_units.h" #include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h" @@ -737,28 +736,6 @@ media_values.PrefersReducedMotion(); } -static bool ShapeMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, - const MediaValues& media_values) { - if (!value.IsValid()) - return true; - - if (!value.is_id) - return false; - - DisplayShape shape = media_values.GetDisplayShape(); - - switch (value.id) { - case CSSValueID::kRect: - return shape == kDisplayShapeRect; - case CSSValueID::kRound: - return shape == kDisplayShapeRound; - default: - NOTREACHED(); - return false; - } -} - static bool AnyPointerMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& media_values) {
diff --git a/third_party/blink/renderer/core/css/media_query_evaluator_test.cc b/third_party/blink/renderer/core/css/media_query_evaluator_test.cc index bb2e9e00..700583c 100644 --- a/third_party/blink/renderer/core/css/media_query_evaluator_test.cc +++ b/third_party/blink/renderer/core/css/media_query_evaluator_test.cc
@@ -70,8 +70,6 @@ {"(display-mode: @browser)", 0}, {"(display-mode: 'browser')", 0}, {"(display-mode: @junk browser)", 0}, - {"(shape: rect)", 1}, - {"(shape: round)", 0}, {"(max-device-aspect-ratio: 4294967295/1)", 1}, {"(min-device-aspect-ratio: 1/4294967296)", 1}, {nullptr, 0} // Do not remove the terminator line. @@ -265,7 +263,6 @@ data.media_type = media_type_names::kScreen; data.strict_mode = true; data.display_mode = blink::mojom::DisplayMode::kBrowser; - data.display_shape = kDisplayShapeRect; data.immersive_mode = false; // Default values.
diff --git a/third_party/blink/renderer/core/css/media_query_exp.cc b/third_party/blink/renderer/core/css/media_query_exp.cc index e3ea6249..c1778ce3 100644 --- a/third_party/blink/renderer/core/css/media_query_exp.cc +++ b/third_party/blink/renderer/core/css/media_query_exp.cc
@@ -71,11 +71,6 @@ if (media_feature == media_feature_names::kScanMediaFeature) return ident == CSSValueID::kInterlace || ident == CSSValueID::kProgressive; - if (RuntimeEnabledFeatures::MediaQueryShapeEnabled()) { - if (media_feature == media_feature_names::kShapeMediaFeature) - return ident == CSSValueID::kRect || ident == CSSValueID::kRound; - } - if (media_feature == media_feature_names::kColorGamutMediaFeature) { return ident == CSSValueID::kSRGB || ident == CSSValueID::kP3 || ident == CSSValueID::kRec2020; @@ -217,8 +212,6 @@ media_feature == media_feature_names::kResolutionMediaFeature || media_feature == media_feature_names::kDisplayModeMediaFeature || media_feature == media_feature_names::kScanMediaFeature || - (media_feature == media_feature_names::kShapeMediaFeature && - RuntimeEnabledFeatures::MediaQueryShapeEnabled()) || media_feature == media_feature_names::kColorGamutMediaFeature || media_feature == media_feature_names::kImmersiveMediaFeature || media_feature == @@ -265,8 +258,7 @@ media_feature_ == media_feature_names::kMinDeviceHeightMediaFeature || media_feature_ == kMaxDeviceAspectRatioMediaFeature || media_feature_ == media_feature_names::kMaxDeviceWidthMediaFeature || - media_feature_ == media_feature_names::kMaxDeviceHeightMediaFeature || - media_feature_ == media_feature_names::kShapeMediaFeature; + media_feature_ == media_feature_names::kMaxDeviceHeightMediaFeature; } MediaQueryExp::MediaQueryExp(const MediaQueryExp& other)
diff --git a/third_party/blink/renderer/core/css/media_query_set_test.cc b/third_party/blink/renderer/core/css/media_query_set_test.cc index 1ccb196..6424fc3 100644 --- a/third_party/blink/renderer/core/css/media_query_set_test.cc +++ b/third_party/blink/renderer/core/css/media_query_set_test.cc
@@ -191,7 +191,6 @@ } TEST(MediaQuerySetTest, BehindRuntimeFlag) { - ScopedMediaQueryShapeForTest shape_flag(false); ScopedForcedColorsForTest forced_colors_flag(false); ScopedMediaQueryNavigationControlsForTest navigation_controls_flag(false); ScopedCSSFoldablesForTest foldables_flag(false); @@ -199,7 +198,6 @@ // The first string represents the input string, the second string represents // the output string. MediaQuerySetTestCase test_cases[] = { - {"(shape)", "not all"}, {"(forced-colors)", "not all"}, {"(navigation-controls)", "not all"}, {"(screen-spanning)", "not all"},
diff --git a/third_party/blink/renderer/core/css/media_values.cc b/third_party/blink/renderer/core/css/media_values.cc index b7ae26e..0e9bbb6 100644 --- a/third_party/blink/renderer/core/css/media_values.cc +++ b/third_party/blink/renderer/core/css/media_values.cc
@@ -174,15 +174,6 @@ return frame->GetSettings()->GetAvailableHoverTypes(); } -DisplayShape MediaValues::CalculateDisplayShape(LocalFrame* frame) { - DCHECK(frame); - DCHECK(frame->GetPage()); - return frame->GetPage() - ->GetChromeClient() - .GetScreenInfo(*frame) - .display_shape; -} - ColorSpaceGamut MediaValues::CalculateColorGamut(LocalFrame* frame) { DCHECK(frame); DCHECK(frame->GetPage());
diff --git a/third_party/blink/renderer/core/css/media_values.h b/third_party/blink/renderer/core/css/media_values.h index 00ee112..db573da2 100644 --- a/third_party/blink/renderer/core/css/media_values.h +++ b/third_party/blink/renderer/core/css/media_values.h
@@ -7,7 +7,6 @@ #include "third_party/blink/public/mojom/manifest/display_mode.mojom-shared.h" #include "third_party/blink/public/platform/pointer_properties.h" -#include "third_party/blink/public/platform/shape_properties.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -81,7 +80,6 @@ virtual bool HasValues() const = 0; virtual void OverrideViewportDimensions(double width, double height) = 0; - virtual DisplayShape GetDisplayShape() const = 0; virtual ColorSpaceGamut ColorGamut() const = 0; virtual PreferredColorScheme GetPreferredColorScheme() const = 0; virtual bool PrefersReducedMotion() const = 0; @@ -107,7 +105,6 @@ static int CalculateAvailablePointerTypes(LocalFrame*); static HoverType CalculatePrimaryHoverType(LocalFrame*); static int CalculateAvailableHoverTypes(LocalFrame*); - static DisplayShape CalculateDisplayShape(LocalFrame*); static ColorSpaceGamut CalculateColorGamut(LocalFrame*); static PreferredColorScheme CalculatePreferredColorScheme(LocalFrame*); static bool CalculatePrefersReducedMotion(LocalFrame*);
diff --git a/third_party/blink/renderer/core/css/media_values_cached.cc b/third_party/blink/renderer/core/css/media_values_cached.cc index 725271e..bdd6ecc 100644 --- a/third_party/blink/renderer/core/css/media_values_cached.cc +++ b/third_party/blink/renderer/core/css/media_values_cached.cc
@@ -33,7 +33,6 @@ immersive_mode(false), strict_mode(true), display_mode(blink::mojom::DisplayMode::kBrowser), - display_shape(kDisplayShapeRect), color_gamut(ColorSpaceGamut::kUnknown), preferred_color_scheme(PreferredColorScheme::kNoPreference), prefers_reduced_motion(false), @@ -76,7 +75,6 @@ strict_mode = MediaValues::CalculateStrictMode(frame); display_mode = MediaValues::CalculateDisplayMode(frame); media_type = MediaValues::CalculateMediaType(frame); - display_shape = MediaValues::CalculateDisplayShape(frame); color_gamut = MediaValues::CalculateColorGamut(frame); preferred_color_scheme = MediaValues::CalculatePreferredColorScheme(frame); prefers_reduced_motion = MediaValues::CalculatePrefersReducedMotion(frame); @@ -189,10 +187,6 @@ data_.viewport_height = height; } -DisplayShape MediaValuesCached::GetDisplayShape() const { - return data_.display_shape; -} - ColorSpaceGamut MediaValuesCached::ColorGamut() const { return data_.color_gamut; }
diff --git a/third_party/blink/renderer/core/css/media_values_cached.h b/third_party/blink/renderer/core/css/media_values_cached.h index cb0a896..ade5764 100644 --- a/third_party/blink/renderer/core/css/media_values_cached.h +++ b/third_party/blink/renderer/core/css/media_values_cached.h
@@ -34,7 +34,6 @@ bool strict_mode; String media_type; blink::mojom::DisplayMode display_mode; - DisplayShape display_shape; ColorSpaceGamut color_gamut; PreferredColorScheme preferred_color_scheme; bool prefers_reduced_motion; @@ -64,7 +63,6 @@ data.strict_mode = strict_mode; data.media_type = media_type.IsolatedCopy(); data.display_mode = display_mode; - data.display_shape = display_shape; data.color_gamut = color_gamut; data.preferred_color_scheme = preferred_color_scheme; data.prefers_reduced_motion = prefers_reduced_motion; @@ -105,7 +103,6 @@ bool HasValues() const override; const String MediaType() const override; blink::mojom::DisplayMode DisplayMode() const override; - DisplayShape GetDisplayShape() const override; ColorSpaceGamut ColorGamut() const override; PreferredColorScheme GetPreferredColorScheme() const override; bool PrefersReducedMotion() const override;
diff --git a/third_party/blink/renderer/core/css/media_values_dynamic.cc b/third_party/blink/renderer/core/css/media_values_dynamic.cc index 858f70a..67a9a9e 100644 --- a/third_party/blink/renderer/core/css/media_values_dynamic.cc +++ b/third_party/blink/renderer/core/css/media_values_dynamic.cc
@@ -136,10 +136,6 @@ return CalculateStrictMode(frame_); } -DisplayShape MediaValuesDynamic::GetDisplayShape() const { - return CalculateDisplayShape(frame_); -} - ColorSpaceGamut MediaValuesDynamic::ColorGamut() const { return CalculateColorGamut(frame_); }
diff --git a/third_party/blink/renderer/core/css/media_values_dynamic.h b/third_party/blink/renderer/core/css/media_values_dynamic.h index 577f6a4..0e9f515 100644 --- a/third_party/blink/renderer/core/css/media_values_dynamic.h +++ b/third_party/blink/renderer/core/css/media_values_dynamic.h
@@ -46,7 +46,6 @@ bool StrictMode() const override; const String MediaType() const override; blink::mojom::DisplayMode DisplayMode() const override; - DisplayShape GetDisplayShape() const override; ColorSpaceGamut ColorGamut() const override; PreferredColorScheme GetPreferredColorScheme() const override; bool PrefersReducedMotion() const override;
diff --git a/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.cc b/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.cc index c403f00..40f70b0d 100644 --- a/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.cc +++ b/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.cc
@@ -64,20 +64,20 @@ void IdleSpellCheckController::Trace(Visitor* visitor) const { visitor->Trace(cold_mode_requester_); + visitor->Trace(spell_check_requeseter_); ExecutionContextLifecycleObserver::Trace(visitor); } -IdleSpellCheckController::IdleSpellCheckController(LocalDOMWindow& window) +IdleSpellCheckController::IdleSpellCheckController( + LocalDOMWindow& window, + SpellCheckRequester& requester) : ExecutionContextLifecycleObserver(&window), state_(State::kInactive), idle_callback_handle_(kInvalidHandle), last_processed_undo_step_sequence_(0), cold_mode_requester_( - MakeGarbageCollected<ColdModeSpellCheckRequester>(window)) {} - -SpellCheckRequester& IdleSpellCheckController::GetSpellCheckRequester() const { - return GetWindow().GetSpellChecker().GetSpellCheckRequester(); -} + MakeGarbageCollected<ColdModeSpellCheckRequester>(window)), + spell_check_requeseter_(requester) {} LocalDOMWindow& IdleSpellCheckController::GetWindow() const { DCHECK(GetExecutionContext()); @@ -107,7 +107,7 @@ cold_mode_timer_.Cancel(); cold_mode_requester_->ClearProgress(); DisposeIdleCallback(); - GetSpellCheckRequester().Deactivate(); + spell_check_requeseter_->Deactivate(); } void IdleSpellCheckController::SetNeedsInvocation() { @@ -173,7 +173,7 @@ // TODO(xiaochengh): Figure out if this has any performance impact. GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing); - HotModeSpellCheckRequester requester(GetSpellCheckRequester()); + HotModeSpellCheckRequester requester(*spell_check_requeseter_); requester.CheckSpellingAt( GetWindow().GetFrame()->Selection().GetSelectionInDOMTree().Extent());
diff --git a/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h b/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h index ddedcaa..a5986a0 100644 --- a/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h +++ b/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h
@@ -34,7 +34,7 @@ USING_GARBAGE_COLLECTED_MIXIN(IdleSpellCheckController); public: - explicit IdleSpellCheckController(LocalDOMWindow&); + explicit IdleSpellCheckController(LocalDOMWindow&, SpellCheckRequester&); ~IdleSpellCheckController(); enum class State { @@ -97,6 +97,7 @@ int idle_callback_handle_; uint64_t last_processed_undo_step_sequence_; const Member<ColdModeSpellCheckRequester> cold_mode_requester_; + Member<SpellCheckRequester> spell_check_requeseter_; TaskHandle cold_mode_timer_; friend class IdleSpellCheckControllerTest;
diff --git a/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc b/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc index 5294f1b..b7180ef 100644 --- a/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc +++ b/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc
@@ -105,7 +105,9 @@ : window_(&window), spell_check_requester_(MakeGarbageCollected<SpellCheckRequester>(window)), idle_spell_check_controller_( - MakeGarbageCollected<IdleSpellCheckController>(window)) {} + MakeGarbageCollected<IdleSpellCheckController>( + window, + *spell_check_requester_)) {} LocalFrame& SpellChecker::GetFrame() const { DCHECK(window_->GetFrame());
diff --git a/third_party/blink/renderer/core/fetch/DEPS b/third_party/blink/renderer/core/fetch/DEPS index 82e8abc..d19aef1 100644 --- a/third_party/blink/renderer/core/fetch/DEPS +++ b/third_party/blink/renderer/core/fetch/DEPS
@@ -4,6 +4,7 @@ "+mojo/public/cpp/system/data_pipe_utils.h", "+mojo/public/cpp/system/simple_watcher.h", "+net/base/request_priority.h", + "+net/http/http_response_info.h", "+services/network/public/cpp", "+services/network/public/mojom", "+url/gurl.h",
diff --git a/third_party/blink/renderer/core/fetch/fetch_manager.cc b/third_party/blink/renderer/core/fetch/fetch_manager.cc index d3b1690..adcfd4f5 100644 --- a/third_party/blink/renderer/core/fetch/fetch_manager.cc +++ b/third_party/blink/renderer/core/fetch/fetch_manager.cc
@@ -535,7 +535,9 @@ // "- should fetching |request| be blocked as content security returns // blocked" if (!execution_context_->GetContentSecurityPolicyForWorld() - ->AllowConnectToSource(fetch_request_data_->Url())) { + ->AllowConnectToSource(fetch_request_data_->Url(), + fetch_request_data_->Url(), + RedirectStatus::kNoRedirect)) { // "A network error." PerformNetworkError( "Refused to connect to '" + fetch_request_data_->Url().ElidedString() +
diff --git a/third_party/blink/renderer/core/fetch/fetch_response_data.cc b/third_party/blink/renderer/core/fetch/fetch_response_data.cc index 2ec8683..4312fd6 100644 --- a/third_party/blink/renderer/core/fetch/fetch_response_data.cc +++ b/third_party/blink/renderer/core/fetch/fetch_response_data.cc
@@ -194,6 +194,10 @@ new_response->response_time_ = response_time_; new_response->cache_storage_cache_name_ = cache_storage_cache_name_; new_response->cors_exposed_header_names_ = cors_exposed_header_names_; + new_response->connection_info_ = connection_info_; + new_response->alpn_negotiated_protocol_ = alpn_negotiated_protocol_; + new_response->loaded_with_credentials_ = loaded_with_credentials_; + new_response->was_fetched_via_spdy_ = was_fetched_via_spdy_; switch (type_) { case Type::kBasic: @@ -261,7 +265,10 @@ response->cache_storage_cache_name = cache_storage_cache_name_; response->cors_exposed_header_names = HeaderSetToVector(cors_exposed_header_names_); + response->connection_info = connection_info_; + response->alpn_negotiated_protocol = alpn_negotiated_protocol_; response->loaded_with_credentials = loaded_with_credentials_; + response->was_fetched_via_spdy = was_fetched_via_spdy_; for (const auto& header : HeaderList()->List()) response->headers.insert(header.first, header.second); response->parsed_headers = ParseHeaders( @@ -308,6 +315,16 @@ SetResponseSource(network::mojom::FetchResponseSource::kNetwork); } + SetConnectionInfo(response.ConnectionInfo()); + + // Some non-http responses, like data: url responses, will have a null + // |alpn_negotiated_protocol|. In these cases we leave the default + // value of "unknown". + if (!response.AlpnNegotiatedProtocol().IsNull()) + SetAlpnNegotiatedProtocol(response.AlpnNegotiatedProtocol()); + + SetWasFetchedViaSpdy(response.WasFetchedViaSPDY()); + // TODO(wanderview): Remove |tainting| and use |response.GetType()| // instead once the OOR-CORS disabled path is removed. SetLoadedWithCredentials( @@ -326,7 +343,10 @@ status_message_(status_message), header_list_(MakeGarbageCollected<FetchHeaderList>()), response_time_(base::Time::Now()), - loaded_with_credentials_(false) {} + connection_info_(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN), + alpn_negotiated_protocol_("unknown"), + loaded_with_credentials_(false), + was_fetched_via_spdy_(false) {} void FetchResponseData::ReplaceBodyStreamBuffer(BodyStreamBuffer* buffer) { if (type_ == Type::kBasic || type_ == Type::kCors) {
diff --git a/third_party/blink/renderer/core/fetch/fetch_response_data.h b/third_party/blink/renderer/core/fetch/fetch_response_data.h index 85c3b4e..0c4bfcb 100644 --- a/third_party/blink/renderer/core/fetch/fetch_response_data.h +++ b/third_party/blink/renderer/core/fetch/fetch_response_data.h
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" +#include "net/http/http_response_info.h" #include "services/network/public/mojom/fetch_api.mojom-blink-forward.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h" #include "third_party/blink/public/mojom/fetch/fetch_api_response.mojom-blink-forward.h" @@ -103,10 +104,19 @@ void SetCorsExposedHeaderNames(const HTTPHeaderSet& header_names) { cors_exposed_header_names_ = header_names; } - bool LoadedWithCredentials() const { return loaded_with_credentials_; } + void SetConnectionInfo( + net::HttpResponseInfo::ConnectionInfo connection_info) { + connection_info_ = connection_info; + } + void SetAlpnNegotiatedProtocol(AtomicString alpn_negotiated_protocol) { + alpn_negotiated_protocol_ = alpn_negotiated_protocol; + } void SetLoadedWithCredentials(bool loaded_with_credentials) { loaded_with_credentials_ = loaded_with_credentials; } + void SetWasFetchedViaSpdy(bool was_fetched_via_spdy) { + was_fetched_via_spdy_ = was_fetched_via_spdy; + } // If the type is Default, replaces |buffer_|. // If the type is Basic or CORS, replaces |buffer_| and @@ -141,7 +151,10 @@ base::Time response_time_; String cache_storage_cache_name_; HTTPHeaderSet cors_exposed_header_names_; + net::HttpResponseInfo::ConnectionInfo connection_info_; + AtomicString alpn_negotiated_protocol_; bool loaded_with_credentials_; + bool was_fetched_via_spdy_; DISALLOW_COPY_AND_ASSIGN(FetchResponseData); };
diff --git a/third_party/blink/renderer/core/fetch/response.cc b/third_party/blink/renderer/core/fetch/response.cc index a2cab88..80758fc 100644 --- a/third_party/blink/renderer/core/fetch/response.cc +++ b/third_party/blink/renderer/core/fetch/response.cc
@@ -381,8 +381,12 @@ response->SetResponseTime(fetch_api_response.response_time); response->SetCacheStorageCacheName( fetch_api_response.cache_storage_cache_name); + response->SetConnectionInfo(fetch_api_response.connection_info); + response->SetAlpnNegotiatedProtocol( + WTF::AtomicString(fetch_api_response.alpn_negotiated_protocol)); response->SetLoadedWithCredentials( fetch_api_response.loaded_with_credentials); + response->SetWasFetchedViaSpdy(fetch_api_response.was_fetched_via_spdy); for (const auto& header : fetch_api_response.headers) response->HeaderList()->Append(header.key, header.value);
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc index b3aaf09..f21e3ea5 100644 --- a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc +++ b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc
@@ -715,6 +715,7 @@ const String& nonce, const IntegrityMetadataSet& integrity_metadata, ParserDisposition parser_disposition, + const KURL& url_before_redirects, RedirectStatus redirect_status, ReportingDisposition reporting_disposition, CheckHeaderType check_header_type) const { @@ -723,9 +724,9 @@ if (!type) return true; - return AllowFromSource(*type, url, redirect_status, reporting_disposition, - check_header_type, nonce, integrity_metadata, - parser_disposition); + return AllowFromSource(*type, url, url_before_redirects, redirect_status, + reporting_disposition, check_header_type, nonce, + integrity_metadata, parser_disposition); } void ContentSecurityPolicy::UsesScriptHashAlgorithms(uint8_t algorithms) { @@ -739,6 +740,7 @@ bool ContentSecurityPolicy::AllowFromSource( ContentSecurityPolicy::DirectiveType type, const KURL& url, + const KURL& url_before_redirects, RedirectStatus redirect_status, ReportingDisposition reporting_disposition, CheckHeaderType check_header_type, @@ -779,9 +781,9 @@ for (const auto& policy : policies_) { if (!CheckHeaderTypeMatches(check_header_type, policy->HeaderType())) continue; - is_allowed &= policy->AllowFromSource(type, url, redirect_status, - reporting_disposition, nonce, hashes, - parser_disposition); + is_allowed &= policy->AllowFromSource( + type, url, url_before_redirects, redirect_status, reporting_disposition, + nonce, hashes, parser_disposition); } return is_allowed; @@ -791,40 +793,45 @@ // `base-uri` isn't affected by 'upgrade-insecure-requests', so we use // CheckHeaderType::kCheckAll to check both report-only and enforce headers // here. - return AllowFromSource(ContentSecurityPolicy::DirectiveType::kBaseURI, url); + return AllowFromSource(ContentSecurityPolicy::DirectiveType::kBaseURI, url, + url, RedirectStatus::kNoRedirect); } bool ContentSecurityPolicy::AllowConnectToSource( const KURL& url, + const KURL& url_before_redirects, RedirectStatus redirect_status, ReportingDisposition reporting_disposition, CheckHeaderType check_header_type) const { return AllowFromSource(ContentSecurityPolicy::DirectiveType::kConnectSrc, url, - redirect_status, reporting_disposition, - check_header_type); + url_before_redirects, redirect_status, + reporting_disposition, check_header_type); } bool ContentSecurityPolicy::AllowFormAction(const KURL& url) const { - return AllowFromSource(ContentSecurityPolicy::DirectiveType::kFormAction, - url); + return AllowFromSource(ContentSecurityPolicy::DirectiveType::kFormAction, url, + url, RedirectStatus::kNoRedirect); } bool ContentSecurityPolicy::AllowImageFromSource( const KURL& url, + const KURL& url_before_redirects, RedirectStatus redirect_status, ReportingDisposition reporting_disposition, CheckHeaderType check_header_type) const { return AllowFromSource(ContentSecurityPolicy::DirectiveType::kImgSrc, url, - redirect_status, reporting_disposition, - check_header_type); + url_before_redirects, redirect_status, + reporting_disposition, check_header_type); } bool ContentSecurityPolicy::AllowMediaFromSource(const KURL& url) const { - return AllowFromSource(ContentSecurityPolicy::DirectiveType::kMediaSrc, url); + return AllowFromSource(ContentSecurityPolicy::DirectiveType::kMediaSrc, url, + url, RedirectStatus::kNoRedirect); } bool ContentSecurityPolicy::AllowObjectFromSource(const KURL& url) const { - return AllowFromSource(ContentSecurityPolicy::DirectiveType::kObjectSrc, url); + return AllowFromSource(ContentSecurityPolicy::DirectiveType::kObjectSrc, url, + url, RedirectStatus::kNoRedirect); } bool ContentSecurityPolicy::AllowScriptFromSource( @@ -832,17 +839,20 @@ const String& nonce, const IntegrityMetadataSet& hashes, ParserDisposition parser_disposition, + const KURL& url_before_redirects, RedirectStatus redirect_status, ReportingDisposition reporting_disposition, CheckHeaderType check_header_type) const { return AllowFromSource(ContentSecurityPolicy::DirectiveType::kScriptSrcElem, - url, redirect_status, reporting_disposition, - check_header_type, nonce, hashes, parser_disposition); + url, url_before_redirects, redirect_status, + reporting_disposition, check_header_type, nonce, + hashes, parser_disposition); } bool ContentSecurityPolicy::AllowWorkerContextFromSource( const KURL& url) const { - return AllowFromSource(ContentSecurityPolicy::DirectiveType::kWorkerSrc, url); + return AllowFromSource(ContentSecurityPolicy::DirectiveType::kWorkerSrc, url, + url, RedirectStatus::kNoRedirect); } bool ContentSecurityPolicy::AllowTrustedTypePolicy(const String& policy_name, @@ -991,9 +1001,13 @@ init->setBlockedURI("eval"); break; case ContentSecurityPolicy::kURLViolation: - init->setBlockedURI( - StripURLForUseInReport(delegate->GetSecurityOrigin(), blocked_url, - redirect_status, effective_type)); + // We pass RedirectStatus::kNoRedirect so that StripURLForUseInReport + // does not strip path and query from the URL. This is safe since + // blocked_url at this point is always the original url (before + // redirects). + init->setBlockedURI(StripURLForUseInReport( + delegate->GetSecurityOrigin(), blocked_url, + RedirectStatus::kNoRedirect, effective_type)); break; case ContentSecurityPolicy::kTrustedTypesSinkViolation: init->setBlockedURI("trusted-types-sink"); @@ -1215,10 +1229,10 @@ } void ContentSecurityPolicy::ReportMixedContent( - const KURL& mixed_url, + const KURL& blocked_url, RedirectStatus redirect_status) const { for (const auto& policy : policies_) - policy->ReportMixedContent(mixed_url, redirect_status); + policy->ReportMixedContent(blocked_url, redirect_status); } void ContentSecurityPolicy::ReportReportOnlyInMeta(const String& header) {
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy.h b/third_party/blink/renderer/core/frame/csp/content_security_policy.h index 39f7e01..f18fc9a 100644 --- a/third_party/blink/renderer/core/frame/csp/content_security_policy.h +++ b/third_party/blink/renderer/core/frame/csp/content_security_policy.h
@@ -270,13 +270,15 @@ bool AllowBaseURI(const KURL&) const; bool AllowConnectToSource( const KURL&, - RedirectStatus = RedirectStatus::kNoRedirect, + const KURL& url_before_redirects, + RedirectStatus, ReportingDisposition = ReportingDisposition::kReport, CheckHeaderType = CheckHeaderType::kCheckAll) const; bool AllowFormAction(const KURL&) const; bool AllowImageFromSource( const KURL&, - RedirectStatus = RedirectStatus::kNoRedirect, + const KURL& url_before_redirects, + RedirectStatus, ReportingDisposition = ReportingDisposition::kReport, CheckHeaderType = CheckHeaderType::kCheckAll) const; bool AllowMediaFromSource(const KURL&) const; @@ -286,7 +288,8 @@ const String& nonce, const IntegrityMetadataSet&, ParserDisposition, - RedirectStatus = RedirectStatus::kNoRedirect, + const KURL& url_before_redirects, + RedirectStatus, ReportingDisposition = ReportingDisposition::kReport, CheckHeaderType = CheckHeaderType::kCheckAll) const; bool AllowWorkerContextFromSource(const KURL&) const; @@ -333,7 +336,8 @@ mojom::RequestContextType, network::mojom::RequestDestination, const KURL&, - RedirectStatus = RedirectStatus::kNoRedirect, + const KURL& url_before_redirects, + RedirectStatus, ReportingDisposition = ReportingDisposition::kReport, CheckHeaderType = CheckHeaderType::kCheckAll) const; @@ -345,7 +349,8 @@ const String& nonce, const IntegrityMetadataSet&, ParserDisposition, - RedirectStatus = RedirectStatus::kNoRedirect, + const KURL& url_before_redirects, + RedirectStatus, ReportingDisposition = ReportingDisposition::kReport, CheckHeaderType = CheckHeaderType::kCheckAll) const; @@ -417,7 +422,7 @@ // Called when mixed content is detected on a page; will trigger a violation // report if the 'block-all-mixed-content' directive is specified for a // policy. - void ReportMixedContent(const KURL& mixed_url, RedirectStatus) const; + void ReportMixedContent(const KURL& blocked_url, RedirectStatus) const; void ReportBlockedScriptExecutionToInspector( const String& directive_text) const; @@ -544,7 +549,8 @@ bool AllowFromSource(ContentSecurityPolicy::DirectiveType, const KURL&, - RedirectStatus = RedirectStatus::kNoRedirect, + const KURL& url_before_redirects, + RedirectStatus, ReportingDisposition = ReportingDisposition::kReport, CheckHeaderType = CheckHeaderType::kCheckAll, const String& = String(),
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc index 30b7751..93a8666 100644 --- a/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc +++ b/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc
@@ -134,18 +134,19 @@ csp2->CopyStateFrom(csp.Get()); EXPECT_FALSE(csp2->AllowScriptFromSource( example_url, String(), IntegrityMetadataSet(), kParserInserted, - ResourceRequest::RedirectStatus::kNoRedirect, + example_url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting, ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly)); EXPECT_TRUE(csp2->AllowPluginType("application/x-type-1", "application/x-type-1", example_url, ReportingDisposition::kSuppressReporting)); EXPECT_TRUE(csp2->AllowImageFromSource( - example_url, ResourceRequest::RedirectStatus::kNoRedirect, + example_url, example_url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting, ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly)); EXPECT_FALSE(csp2->AllowImageFromSource( - not_example_url, ResourceRequest::RedirectStatus::kNoRedirect, + not_example_url, not_example_url, + ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting, ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly)); EXPECT_FALSE(csp2->AllowPluginType("application/x-type-2", @@ -168,17 +169,18 @@ csp2->CopyPluginTypesFrom(csp.Get()); EXPECT_TRUE(csp2->AllowScriptFromSource( example_url, String(), IntegrityMetadataSet(), kParserInserted, - ResourceRequest::RedirectStatus::kNoRedirect, + example_url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); EXPECT_TRUE(csp2->AllowPluginType("application/x-type-1", "application/x-type-1", example_url, ReportingDisposition::kSuppressReporting)); EXPECT_TRUE(csp2->AllowImageFromSource( - example_url, ResourceRequest::RedirectStatus::kNoRedirect, + example_url, example_url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); - EXPECT_TRUE(csp2->AllowImageFromSource( - not_example_url, ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting)); + EXPECT_TRUE( + csp2->AllowImageFromSource(not_example_url, not_example_url, + ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting)); EXPECT_FALSE(csp2->AllowPluginType("application/x-type-2", "application/x-type-2", example_url, ReportingDisposition::kSuppressReporting)); @@ -279,19 +281,19 @@ EXPECT_FALSE(csp->AllowRequest(mojom::RequestContextType::OBJECT, network::mojom::RequestDestination::kEmpty, url, String(), IntegrityMetadataSet(), - kParserInserted, + kParserInserted, url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); EXPECT_FALSE(csp->AllowRequest(mojom::RequestContextType::EMBED, network::mojom::RequestDestination::kEmbed, url, String(), IntegrityMetadataSet(), - kParserInserted, + kParserInserted, url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); EXPECT_TRUE(csp->AllowRequest(mojom::RequestContextType::PLUGIN, network::mojom::RequestDestination::kEmpty, url, String(), IntegrityMetadataSet(), - kParserInserted, + kParserInserted, url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); } @@ -305,31 +307,31 @@ EXPECT_FALSE(csp->AllowRequest(mojom::RequestContextType::SUBRESOURCE, network::mojom::RequestDestination::kEmpty, url, String(), IntegrityMetadataSet(), - kParserInserted, + kParserInserted, url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); EXPECT_FALSE(csp->AllowRequest(mojom::RequestContextType::XML_HTTP_REQUEST, network::mojom::RequestDestination::kEmpty, url, String(), IntegrityMetadataSet(), - kParserInserted, + kParserInserted, url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); EXPECT_FALSE(csp->AllowRequest(mojom::RequestContextType::BEACON, network::mojom::RequestDestination::kEmpty, url, String(), IntegrityMetadataSet(), - kParserInserted, + kParserInserted, url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); EXPECT_FALSE(csp->AllowRequest(mojom::RequestContextType::FETCH, network::mojom::RequestDestination::kEmpty, url, String(), IntegrityMetadataSet(), - kParserInserted, + kParserInserted, url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); EXPECT_TRUE(csp->AllowRequest(mojom::RequestContextType::PLUGIN, network::mojom::RequestDestination::kEmpty, url, String(), IntegrityMetadataSet(), - kParserInserted, + kParserInserted, url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); } @@ -366,9 +368,11 @@ execution_context->GetContentSecurityPolicyDelegate()); policy->DidReceiveHeader(test.policy, ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); - EXPECT_EQ(test.allowed, policy->AllowScriptFromSource( - resource, String(test.nonce), - IntegrityMetadataSet(), kParserInserted)); + EXPECT_EQ(test.allowed, + policy->AllowScriptFromSource( + resource, String(test.nonce), IntegrityMetadataSet(), + kParserInserted, resource, + ResourceRequest::RedirectStatus::kNoRedirect)); // If this is expected to generate a violation, we should have sent a // report. EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size()); @@ -381,7 +385,7 @@ ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(policy->AllowScriptFromSource( resource, String(test.nonce), IntegrityMetadataSet(), kParserInserted, - ResourceRequest::RedirectStatus::kNoRedirect, + resource, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kReport, ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly)); // If this is expected to generate a violation, we should have sent a @@ -539,12 +543,13 @@ EXPECT_EQ(test.allowed1, policy->AllowScriptFromSource( resource, String(test.nonce), IntegrityMetadataSet(), - kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, + kParserInserted, resource, + ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kReport, ContentSecurityPolicy::CheckHeaderType::kCheckEnforce)); EXPECT_TRUE(policy->AllowScriptFromSource( resource, String(test.nonce), IntegrityMetadataSet(), kParserInserted, - ResourceRequest::RedirectStatus::kNoRedirect, + resource, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kReport, ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly)); EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size()); @@ -559,13 +564,14 @@ ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(policy->AllowScriptFromSource( resource, String(test.nonce), IntegrityMetadataSet(), kParserInserted, - ResourceRequest::RedirectStatus::kNoRedirect, + resource, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kReport, ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly)); EXPECT_EQ(test.allowed2, policy->AllowScriptFromSource( resource, String(test.nonce), IntegrityMetadataSet(), - kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, + kParserInserted, resource, + ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kReport, ContentSecurityPolicy::CheckHeaderType::kCheckEnforce)); EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size()); @@ -581,7 +587,8 @@ EXPECT_EQ(test.allowed1 && test.allowed2, policy->AllowScriptFromSource( resource, String(test.nonce), IntegrityMetadataSet(), - kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, + kParserInserted, resource, + ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kReport, ContentSecurityPolicy::CheckHeaderType::kCheckEnforce)); EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size()); @@ -596,7 +603,7 @@ ContentSecurityPolicySource::kHTTP); EXPECT_TRUE(policy->AllowScriptFromSource( resource, String(test.nonce), IntegrityMetadataSet(), kParserInserted, - ResourceRequest::RedirectStatus::kNoRedirect, + resource, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kReport, ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly)); EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size()); @@ -748,18 +755,20 @@ ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); + const KURL example_url("https://example.com/"); EXPECT_TRUE(csp->AllowRequest(mojom::RequestContextType::OBJECT, network::mojom::RequestDestination::kEmpty, - KURL(base, "https://example.com/"), String(), - IntegrityMetadataSet(), kParserInserted, + example_url, String(), IntegrityMetadataSet(), + kParserInserted, example_url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); + const KURL not_example_url("https://not-example.com/"); EXPECT_FALSE(csp->AllowRequest( mojom::RequestContextType::OBJECT, - network::mojom::RequestDestination::kEmpty, - KURL(base, "https://not-example.com/"), String(), IntegrityMetadataSet(), - kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, + network::mojom::RequestDestination::kEmpty, not_example_url, String(), + IntegrityMetadataSet(), kParserInserted, not_example_url, + ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); // Register "https" as bypassing CSP, which should now bypass it entirely @@ -767,16 +776,16 @@ EXPECT_TRUE(csp->AllowRequest(mojom::RequestContextType::OBJECT, network::mojom::RequestDestination::kEmpty, - KURL(base, "https://example.com/"), String(), - IntegrityMetadataSet(), kParserInserted, + example_url, String(), IntegrityMetadataSet(), + kParserInserted, example_url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); EXPECT_TRUE(csp->AllowRequest( mojom::RequestContextType::OBJECT, - network::mojom::RequestDestination::kEmpty, - KURL(base, "https://not-example.com/"), String(), IntegrityMetadataSet(), - kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, + network::mojom::RequestDestination::kEmpty, not_example_url, String(), + IntegrityMetadataSet(), kParserInserted, not_example_url, + ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); SchemeRegistry::RemoveURLSchemeRegisteredAsBypassingContentSecurityPolicy( @@ -793,38 +802,36 @@ ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); - EXPECT_FALSE( - csp->AllowRequest(mojom::RequestContextType::OBJECT, - network::mojom::RequestDestination::kEmpty, - KURL(base, "filesystem:https://example.com/file.txt"), - String(), IntegrityMetadataSet(), kParserInserted, - ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting)); + const KURL example_url("filesystem:https://example.com/file.txt"); + EXPECT_FALSE(csp->AllowRequest(mojom::RequestContextType::OBJECT, + network::mojom::RequestDestination::kEmpty, + example_url, String(), IntegrityMetadataSet(), + kParserInserted, example_url, + ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting)); + const KURL not_example_url("filesystem:https://not-example.com/file.txt"); EXPECT_FALSE(csp->AllowRequest( mojom::RequestContextType::OBJECT, - network::mojom::RequestDestination::kEmpty, - KURL(base, "filesystem:https://not-example.com/file.txt"), String(), - IntegrityMetadataSet(), kParserInserted, + network::mojom::RequestDestination::kEmpty, not_example_url, String(), + IntegrityMetadataSet(), kParserInserted, not_example_url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); // Register "https" as bypassing CSP, which should now bypass it entirely SchemeRegistry::RegisterURLSchemeAsBypassingContentSecurityPolicy("https"); - EXPECT_TRUE( - csp->AllowRequest(mojom::RequestContextType::OBJECT, - network::mojom::RequestDestination::kEmpty, - KURL(base, "filesystem:https://example.com/file.txt"), - String(), IntegrityMetadataSet(), kParserInserted, - ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting)); + EXPECT_TRUE(csp->AllowRequest(mojom::RequestContextType::OBJECT, + network::mojom::RequestDestination::kEmpty, + example_url, String(), IntegrityMetadataSet(), + kParserInserted, example_url, + ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting)); EXPECT_TRUE(csp->AllowRequest( mojom::RequestContextType::OBJECT, - network::mojom::RequestDestination::kEmpty, - KURL(base, "filesystem:https://not-example.com/file.txt"), String(), - IntegrityMetadataSet(), kParserInserted, + network::mojom::RequestDestination::kEmpty, not_example_url, String(), + IntegrityMetadataSet(), kParserInserted, not_example_url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); @@ -843,39 +850,39 @@ ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP); - EXPECT_FALSE(csp->AllowRequest( - mojom::RequestContextType::OBJECT, - network::mojom::RequestDestination::kEmpty, - KURL(base, "blob:https://example.com/"), String(), IntegrityMetadataSet(), - kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting)); - + const KURL example_url("blob:https://example.com/"); EXPECT_FALSE(csp->AllowRequest(mojom::RequestContextType::OBJECT, network::mojom::RequestDestination::kEmpty, - KURL(base, "blob:https://not-example.com/"), - String(), IntegrityMetadataSet(), - kParserInserted, + example_url, String(), IntegrityMetadataSet(), + kParserInserted, example_url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); + const KURL not_example_url("blob:https://not-example.com/"); + EXPECT_FALSE(csp->AllowRequest( + mojom::RequestContextType::OBJECT, + network::mojom::RequestDestination::kEmpty, not_example_url, String(), + IntegrityMetadataSet(), kParserInserted, not_example_url, + ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting)); + // Register "https" as bypassing CSP, which should now bypass it entirely SchemeRegistry::RegisterURLSchemeAsBypassingContentSecurityPolicy("https"); - EXPECT_TRUE(csp->AllowRequest( - mojom::RequestContextType::OBJECT, - network::mojom::RequestDestination::kEmpty, - KURL(base, "blob:https://example.com/"), String(), IntegrityMetadataSet(), - kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting)); - EXPECT_TRUE(csp->AllowRequest(mojom::RequestContextType::OBJECT, network::mojom::RequestDestination::kEmpty, - KURL(base, "blob:https://not-example.com/"), - String(), IntegrityMetadataSet(), - kParserInserted, + example_url, String(), IntegrityMetadataSet(), + kParserInserted, example_url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); + EXPECT_TRUE(csp->AllowRequest( + mojom::RequestContextType::OBJECT, + network::mojom::RequestDestination::kEmpty, not_example_url, String(), + IntegrityMetadataSet(), kParserInserted, not_example_url, + ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting)); + SchemeRegistry::RemoveURLSchemeRegisteredAsBypassingContentSecurityPolicy( "https"); } @@ -906,19 +913,19 @@ EXPECT_TRUE(csp->AllowScriptFromSource( allowed_url, String(), IntegrityMetadataSet(), kNotParserInserted, + allowed_url, ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting)); + EXPECT_FALSE(csp->AllowScriptFromSource( + http_url, String(), IntegrityMetadataSet(), kNotParserInserted, http_url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); EXPECT_FALSE(csp->AllowScriptFromSource( - http_url, String(), IntegrityMetadataSet(), kNotParserInserted, - ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting)); - EXPECT_FALSE(csp->AllowScriptFromSource( - blob_url, String(), IntegrityMetadataSet(), kNotParserInserted, + blob_url, String(), IntegrityMetadataSet(), kNotParserInserted, blob_url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); EXPECT_FALSE(csp->AllowScriptFromSource( filesystem_url, String(), IntegrityMetadataSet(), kNotParserInserted, - ResourceRequest::RedirectStatus::kNoRedirect, + filesystem_url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); SchemeRegistry::RemoveURLSchemeRegisteredAsBypassingContentSecurityPolicy( @@ -1257,9 +1264,11 @@ csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); EXPECT_TRUE(csp->AllowScriptFromSource( - example_url, String(), IntegrityMetadataSet(), kParserInserted)); + example_url, String(), IntegrityMetadataSet(), kParserInserted, + example_url, ResourceRequest::RedirectStatus::kNoRedirect)); EXPECT_FALSE(csp->AllowScriptFromSource( - not_example_url, String(), IntegrityMetadataSet(), kParserInserted)); + not_example_url, String(), IntegrityMetadataSet(), kParserInserted, + not_example_url, ResourceRequest::RedirectStatus::kNoRedirect)); // Duplicate directive that is in a different case pattern is // correctly treated as a duplicate directive and ignored. @@ -1270,9 +1279,11 @@ csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate()); EXPECT_TRUE(csp->AllowScriptFromSource( - example_url, String(), IntegrityMetadataSet(), kParserInserted)); + example_url, String(), IntegrityMetadataSet(), kParserInserted, + example_url, ResourceRequest::RedirectStatus::kNoRedirect)); EXPECT_FALSE(csp->AllowScriptFromSource( - not_example_url, String(), IntegrityMetadataSet(), kParserInserted)); + not_example_url, String(), IntegrityMetadataSet(), kParserInserted, + not_example_url, ResourceRequest::RedirectStatus::kNoRedirect)); } // Tests that using an empty CSP works and doesn't impose any policy @@ -1324,18 +1335,23 @@ ContentSecurityPolicy::DirectiveType::kStyleSrcElem, ContentSecurityPolicy::DirectiveType::kWorkerSrc}; for (auto type : types_to_test) { - EXPECT_TRUE(csp->AllowFromSource(type, example_url)); + EXPECT_TRUE( + csp->AllowFromSource(type, example_url, example_url, + ResourceRequest::RedirectStatus::kNoRedirect)); } EXPECT_TRUE(csp->AllowObjectFromSource(example_url)); - EXPECT_TRUE(csp->AllowImageFromSource(example_url)); + EXPECT_TRUE(csp->AllowImageFromSource( + example_url, example_url, ResourceRequest::RedirectStatus::kNoRedirect)); EXPECT_TRUE(csp->AllowMediaFromSource(example_url)); - EXPECT_TRUE(csp->AllowConnectToSource(example_url)); + EXPECT_TRUE(csp->AllowConnectToSource( + example_url, example_url, ResourceRequest::RedirectStatus::kNoRedirect)); EXPECT_TRUE(csp->AllowFormAction(example_url)); EXPECT_TRUE(csp->AllowBaseURI(example_url)); EXPECT_TRUE(csp->AllowWorkerContextFromSource(example_url)); EXPECT_TRUE(csp->AllowScriptFromSource( - example_url, nonce, IntegrityMetadataSet(), kParserInserted)); + example_url, nonce, IntegrityMetadataSet(), kParserInserted, example_url, + ResourceRequest::RedirectStatus::kNoRedirect)); EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", true)); EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", false)); @@ -1350,7 +1366,8 @@ EXPECT_TRUE(csp->AllowRequest(mojom::RequestContextType::SCRIPT, network::mojom::RequestDestination::kScript, example_url, nonce, IntegrityMetadataSet(), - kParserInserted)); + kParserInserted, example_url, + ResourceRequest::RedirectStatus::kNoRedirect)); EXPECT_FALSE(csp->IsActive()); EXPECT_FALSE(csp->IsActiveForConnections()); EXPECT_TRUE(csp->FallbackUrlForPlugin().IsEmpty()); @@ -1378,7 +1395,7 @@ EXPECT_TRUE(csp->AllowRequest(mojom::RequestContextType::SUBRESOURCE, network::mojom::RequestDestination::kEmpty, url, String(), IntegrityMetadataSet(), - kParserInserted, + kParserInserted, url, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); }
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc index e3c6678..b60a4ec5 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc +++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
@@ -314,15 +314,16 @@ } void CSPDirectiveList::ReportMixedContent( - const KURL& mixed_url, + const KURL& blocked_url, ResourceRequest::RedirectStatus redirect_status) const { if (StrictMixedContentChecking()) { policy_->ReportViolation( ContentSecurityPolicy::GetDirectiveName( ContentSecurityPolicy::DirectiveType::kBlockAllMixedContent), ContentSecurityPolicy::DirectiveType::kBlockAllMixedContent, String(), - mixed_url, report_endpoints_, use_reporting_api_, header_, header_type_, - ContentSecurityPolicy::kURLViolation, std::unique_ptr<SourceLocation>(), + blocked_url, report_endpoints_, use_reporting_api_, header_, + header_type_, ContentSecurityPolicy::kURLViolation, + std::unique_ptr<SourceLocation>(), nullptr, // contextFrame, redirect_status); } @@ -515,6 +516,7 @@ SourceListDirective* directive, const KURL& url, const ContentSecurityPolicy::DirectiveType effective_type, + const KURL& url_before_redirects, ResourceRequest::RedirectStatus redirect_status) const { if (!directive) return true; @@ -578,7 +580,7 @@ "' because it violates the following Content Security " "Policy directive: \"" + directive->GetText() + "\"." + suffix + "\n", - url, redirect_status); + url_before_redirects, redirect_status); return DenyIfEnforcingPolicy(); } @@ -737,6 +739,7 @@ bool CSPDirectiveList::AllowFromSource( ContentSecurityPolicy::DirectiveType type, const KURL& url, + const KURL& url_before_redirects, ResourceRequest::RedirectStatus redirect_status, ReportingDisposition reporting_disposition, const String& nonce, @@ -782,7 +785,7 @@ bool result = reporting_disposition == ReportingDisposition::kReport ? CheckSourceAndReportViolation(OperativeDirective(type), url, type, - redirect_status) + url_before_redirects, redirect_status) : CheckSource(OperativeDirective(type), url, redirect_status); if (type == ContentSecurityPolicy::DirectiveType::kBaseURI) {
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list.h b/third_party/blink/renderer/core/frame/csp/csp_directive_list.h index b8ac557..6c2f61a5 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_directive_list.h +++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list.h
@@ -79,6 +79,7 @@ bool AllowFromSource(ContentSecurityPolicy::DirectiveType, const KURL&, + const KURL& url_before_redirects, ResourceRequest::RedirectStatus, ReportingDisposition, const String& nonce = String(), @@ -105,7 +106,7 @@ bool StrictMixedContentChecking() const { return strict_mixed_content_checking_enforced_; } - void ReportMixedContent(const KURL& mixed_url, + void ReportMixedContent(const KURL& blocked_url, ResourceRequest::RedirectStatus) const; bool ShouldDisableEval() const { @@ -283,6 +284,7 @@ bool CheckSourceAndReportViolation(SourceListDirective*, const KURL&, const ContentSecurityPolicy::DirectiveType, + const KURL& url_before_redirects, ResourceRequest::RedirectStatus) const; bool CheckMediaTypeAndReportViolation(MediaListDirective*, const String& type,
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc b/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc index c7b50c3..9323d2ec 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc +++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc
@@ -213,21 +213,23 @@ // Report-only Member<CSPDirectiveList> directive_list = CreateList(test.list, ContentSecurityPolicyType::kReport); - EXPECT_EQ(test.expected, - directive_list->AllowFromSource( - ContentSecurityPolicy::DirectiveType::kScriptSrcElem, - script_src, ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting, String(), - IntegrityMetadataSet(), kParserInserted)); + EXPECT_EQ( + test.expected, + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kScriptSrcElem, script_src, + script_src, ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting, String(), + IntegrityMetadataSet(), kParserInserted)); // Enforce directive_list = CreateList(test.list, ContentSecurityPolicyType::kEnforce); - EXPECT_EQ(test.expected, - directive_list->AllowFromSource( - ContentSecurityPolicy::DirectiveType::kScriptSrcElem, - script_src, ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting, String(), - IntegrityMetadataSet(), kParserInserted)); + EXPECT_EQ( + test.expected, + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kScriptSrcElem, script_src, + script_src, ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting, String(), + IntegrityMetadataSet(), kParserInserted)); } } @@ -270,22 +272,24 @@ // Report-only 'script-src' Member<CSPDirectiveList> directive_list = CreateList( String("script-src ") + test.list, ContentSecurityPolicyType::kReport); - EXPECT_EQ(test.expected, - directive_list->AllowFromSource( - ContentSecurityPolicy::DirectiveType::kScriptSrcElem, - resource, ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting, String(test.nonce), - IntegrityMetadataSet(), kParserInserted)); + EXPECT_EQ( + test.expected, + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kScriptSrcElem, resource, + resource, ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting, String(test.nonce), + IntegrityMetadataSet(), kParserInserted)); // Enforce 'script-src' directive_list = CreateList(String("script-src ") + test.list, ContentSecurityPolicyType::kEnforce); - EXPECT_EQ(test.expected, - directive_list->AllowFromSource( - ContentSecurityPolicy::DirectiveType::kScriptSrcElem, - resource, ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting, String(test.nonce), - IntegrityMetadataSet(), kParserInserted)); + EXPECT_EQ( + test.expected, + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kScriptSrcElem, resource, + resource, ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting, String(test.nonce), + IntegrityMetadataSet(), kParserInserted)); // Report-only 'style-src' directive_list = CreateList(String("style-src ") + test.list, @@ -294,7 +298,7 @@ test.expected, directive_list->AllowFromSource( ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource, - ResourceRequest::RedirectStatus::kNoRedirect, + resource, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting, String(test.nonce))); // Enforce 'style-src' @@ -304,7 +308,7 @@ test.expected, directive_list->AllowFromSource( ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource, - ResourceRequest::RedirectStatus::kNoRedirect, + resource, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting, String(test.nonce))); // Report-only 'style-src' @@ -314,29 +318,30 @@ test.expected, directive_list->AllowFromSource( ContentSecurityPolicy::DirectiveType::kScriptSrcElem, resource, - ResourceRequest::RedirectStatus::kNoRedirect, + resource, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting, String(test.nonce))); EXPECT_EQ( test.expected, directive_list->AllowFromSource( ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource, - ResourceRequest::RedirectStatus::kNoRedirect, + resource, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting, String(test.nonce))); // Enforce 'style-src' directive_list = CreateList(String("default-src ") + test.list, ContentSecurityPolicyType::kEnforce); - EXPECT_EQ(test.expected, - directive_list->AllowFromSource( - ContentSecurityPolicy::DirectiveType::kScriptSrcElem, - resource, ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting, String(test.nonce), - IntegrityMetadataSet(), kParserInserted)); + EXPECT_EQ( + test.expected, + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kScriptSrcElem, resource, + resource, ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting, String(test.nonce), + IntegrityMetadataSet(), kParserInserted)); EXPECT_EQ( test.expected, directive_list->AllowFromSource( ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource, - ResourceRequest::RedirectStatus::kNoRedirect, + resource, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting, String(test.nonce))); } } @@ -422,22 +427,24 @@ // Report-only 'script-src' Member<CSPDirectiveList> directive_list = CreateList( String("script-src ") + test.list, ContentSecurityPolicyType::kReport); - EXPECT_EQ(test.expected, - directive_list->AllowFromSource( - ContentSecurityPolicy::DirectiveType::kScriptSrcElem, - resource, ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting, String(), - integrity_metadata, kParserInserted)); + EXPECT_EQ( + test.expected, + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kScriptSrcElem, resource, + resource, ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting, String(), + integrity_metadata, kParserInserted)); // Enforce 'script-src' directive_list = CreateList(String("script-src ") + test.list, ContentSecurityPolicyType::kEnforce); - EXPECT_EQ(test.expected, - directive_list->AllowFromSource( - ContentSecurityPolicy::DirectiveType::kScriptSrcElem, - resource, ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting, String(), - integrity_metadata, kParserInserted)); + EXPECT_EQ( + test.expected, + directive_list->AllowFromSource( + ContentSecurityPolicy::DirectiveType::kScriptSrcElem, resource, + resource, ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting, String(), + integrity_metadata, kParserInserted)); } } @@ -482,7 +489,7 @@ EXPECT_EQ(test.allowed, directive_list->AllowFromSource( ContentSecurityPolicy::DirectiveType::kWorkerSrc, resource, - ResourceRequest::RedirectStatus::kNoRedirect, + resource, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); } } @@ -528,7 +535,7 @@ EXPECT_EQ(test.allowed, directive_list->AllowFromSource( ContentSecurityPolicy::DirectiveType::kWorkerSrc, resource, - ResourceRequest::RedirectStatus::kNoRedirect, + resource, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); } }
diff --git a/third_party/blink/renderer/core/frame/dom_window.cc b/third_party/blink/renderer/core/frame/dom_window.cc index 4664c8268..da734c80 100644 --- a/third_party/blink/renderer/core/frame/dom_window.cc +++ b/third_party/blink/renderer/core/frame/dom_window.cc
@@ -480,7 +480,7 @@ } if (!source_document->GetContentSecurityPolicy()->AllowConnectToSource( - target_url, RedirectStatus::kNoRedirect, + target_url, target_url, RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)) { UseCounter::Count( source_document,
diff --git a/third_party/blink/renderer/core/frame/frame.cc b/third_party/blink/renderer/core/frame/frame.cc index 2599dd84..78fc848 100644 --- a/third_party/blink/renderer/core/frame/frame.cc +++ b/third_party/blink/renderer/core/frame/frame.cc
@@ -58,6 +58,24 @@ namespace blink { +// static +Frame* Frame::ResolveFrame(const base::UnguessableToken& frame_token) { + if (!frame_token) + return nullptr; + + // The frame token could refer to either a RemoteFrame or a LocalFrame, so + // need to check both. + auto* remote = RemoteFrame::FromFrameToken(frame_token); + if (remote) + return remote; + + auto* local = LocalFrame::FromFrameToken(frame_token); + if (local) + return local; + + return nullptr; +} + Frame::~Frame() { InstanceCounters::DecrementCounter(InstanceCounters::kFrameCounter); DCHECK(!owner_);
diff --git a/third_party/blink/renderer/core/frame/frame.h b/third_party/blink/renderer/core/frame/frame.h index cedba94..5d3303c 100644 --- a/third_party/blink/renderer/core/frame/frame.h +++ b/third_party/blink/renderer/core/frame/frame.h
@@ -74,6 +74,10 @@ // input, layout, or painting probably belongs on LocalFrame. class CORE_EXPORT Frame : public GarbageCollected<Frame> { public: + // Returns the Frame instance for the given |frame_token|. + // Note that this Frame can be either a LocalFrame or Remote instance. + static Frame* ResolveFrame(const base::UnguessableToken& frame_token); + virtual ~Frame(); virtual void Trace(Visitor*) const;
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc index b80435d5..483b669 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window.cc +++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -935,7 +935,7 @@ KURL sender(event->origin()); if (!document()->GetContentSecurityPolicy()->AllowConnectToSource( - sender, RedirectStatus::kNoRedirect, + sender, sender, RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)) { UseCounter::Count( document(), WebFeature::kPostMessageIncomingWouldBeBlockedByConnectSrc);
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index d69cd8a..841c3d7 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -176,6 +176,15 @@ namespace { +// Maintain a global (statically-allocated) hash map indexed by the the result +// of hashing the |frame_token| passed on creation of a LocalFrame object. +using LocalFramesByTokenMap = HeapHashMap<uint64_t, WeakMember<LocalFrame>>; +static LocalFramesByTokenMap& GetLocalFramesMap() { + DEFINE_STATIC_LOCAL(Persistent<LocalFramesByTokenMap>, map, + (MakeGarbageCollected<LocalFramesByTokenMap>())); + return *map; +} + // Maximum number of burst download requests allowed. const int kBurstDownloadLimit = 10; @@ -300,6 +309,14 @@ template class CORE_TEMPLATE_EXPORT Supplement<LocalFrame>; +// static +LocalFrame* LocalFrame::FromFrameToken( + const base::UnguessableToken& frame_token) { + LocalFramesByTokenMap& local_frames_map = GetLocalFramesMap(); + auto it = local_frames_map.find(base::UnguessableTokenHash()(frame_token)); + return it == local_frames_map.end() ? nullptr : it->value.Get(); +} + void LocalFrame::Init() { CoreInitializer::GetInstance().InitLocalFrame(*this); @@ -2702,6 +2719,16 @@ ReportingContext::From(DomWindow())->Bind(std::move(receiver)); } +void LocalFrame::UpdateOpener( + const base::Optional<base::UnguessableToken>& opener_frame_token) { + if (auto* web_frame = WebFrame::FromFrame(this)) { + auto* opener_frame = LocalFrame::ResolveFrame( + opener_frame_token.value_or(base::UnguessableToken())); + auto* opener_web_frame = WebFrame::FromFrame(opener_frame); + web_frame->SetOpener(opener_web_frame); + } +} + bool LocalFrame::ShouldThrottleDownload() { const auto now = base::TimeTicks::Now(); if (num_burst_download_requests_ == 0) {
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h index b0dc1826..a163184 100644 --- a/third_party/blink/renderer/core/frame/local_frame.h +++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -138,6 +138,9 @@ USING_GARBAGE_COLLECTED_MIXIN(LocalFrame); public: + // Returns the LocalFrame instance for the given |frame_token|. + static LocalFrame* FromFrameToken(const base::UnguessableToken& frame_token); + // For a description of |inheriting_agent_factory| go see the comment on the // Frame constructor. LocalFrame( @@ -577,6 +580,8 @@ BlinkTransferableMessage message) final; void BindReportingObserver( mojo::PendingReceiver<mojom::blink::ReportingObserver> receiver) final; + void UpdateOpener( + const base::Optional<base::UnguessableToken>& opener_routing_id) final; // blink::mojom::LocalMainFrame overrides: void AnimateDoubleTapZoom(const gfx::Point& point,
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index cd8fe85..9c1062b 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -1205,18 +1205,6 @@ part_update_set_.insert(&object); } -void LocalFrameView::SetDisplayShape(DisplayShape display_shape) { - if (display_shape == display_shape_) - return; - - display_shape_ = display_shape; - - if (frame_->GetDocument()) { - frame_->GetDocument()->MediaQueryAffectingValueChanged( - MediaValueChange::kOther); - } -} - void LocalFrameView::SetMediaType(const AtomicString& media_type) { DCHECK(frame_->GetDocument()); media_type_ = media_type;
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.h b/third_party/blink/renderer/core/frame/local_frame_view.h index 8a928ae..d3fa3c1 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.h +++ b/third_party/blink/renderer/core/frame/local_frame_view.h
@@ -31,7 +31,6 @@ #include "third_party/blink/public/common/metrics/document_update_reason.h" #include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink-forward.h" #include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink-forward.h" -#include "third_party/blink/public/platform/shape_properties.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/frame_view.h" @@ -274,9 +273,6 @@ void SetMediaType(const AtomicString&); void AdjustMediaTypeForPrinting(bool printing); - DisplayShape GetDisplayShape() { return display_shape_; } - void SetDisplayShape(DisplayShape); - // For any viewport-constrained object, we need to know if it's due to fixed // or sticky so that we can support HasStickyViewportConstrainedObject(). enum ViewportConstrainedType { kFixed = 0, kSticky = 1 }; @@ -867,8 +863,6 @@ Member<LocalFrame> frame_; - DisplayShape display_shape_; - bool can_have_scrollbars_; bool has_pending_layout_;
diff --git a/third_party/blink/renderer/core/frame/remote_frame.cc b/third_party/blink/renderer/core/frame/remote_frame.cc index 7a564964..4474785 100644 --- a/third_party/blink/renderer/core/frame/remote_frame.cc +++ b/third_party/blink/renderer/core/frame/remote_frame.cc
@@ -586,7 +586,7 @@ // Update the proxy's SecurityContext with new sandbox flags or feature policy // that were set during navigation. Unlike changes to the FrameOwner, which are -// handled by RenderFrameProxy::OnDidUpdateFramePolicy, these changes should be +// handled by RemoteFrame::DidUpdateFramePolicy, these changes should be // considered effective immediately. // // These flags / policy are needed on the remote frame's SecurityContext to @@ -630,6 +630,16 @@ To<RemoteFrameOwner>(Owner())->SetFramePolicy(frame_policy); } +void RemoteFrame::UpdateOpener( + const base::Optional<base::UnguessableToken>& opener_frame_token) { + if (auto* web_frame = WebFrame::FromFrame(this)) { + auto* opener_frame = LocalFrame::ResolveFrame( + opener_frame_token.value_or(base::UnguessableToken())); + auto* opener_web_frame = WebFrame::FromFrame(opener_frame); + web_frame->SetOpener(opener_web_frame); + } +} + IntSize RemoteFrame::GetMainFrameViewportSize() const { HTMLFrameOwnerElement* owner = DeprecatedLocalOwner(); DCHECK(owner); @@ -694,7 +704,7 @@ void RemoteFrame::AdvanceFocus(mojom::blink::FocusType type, LocalFrame* source) { - Client()->AdvanceFocus(type, source); + GetRemoteFrameHostRemote().AdvanceFocus(type, source->GetFrameToken()); } void RemoteFrame::DetachChildren() {
diff --git a/third_party/blink/renderer/core/frame/remote_frame.h b/third_party/blink/renderer/core/frame/remote_frame.h index f3de29e..e761a5e0 100644 --- a/third_party/blink/renderer/core/frame/remote_frame.h +++ b/third_party/blink/renderer/core/frame/remote_frame.h
@@ -143,6 +143,8 @@ // sandbox flags or container policy. The new policy won't take effect until // the next navigation. void DidUpdateFramePolicy(const FramePolicy& frame_policy) override; + void UpdateOpener(const base::Optional<base::UnguessableToken>& + opener_frame_token) override; // Called only when this frame has a local frame owner. IntSize GetMainFrameViewportSize() const override;
diff --git a/third_party/blink/renderer/core/frame/remote_frame_client.h b/third_party/blink/renderer/core/frame/remote_frame_client.h index 056e0d59..61a06f7 100644 --- a/third_party/blink/renderer/core/frame/remote_frame_client.h +++ b/third_party/blink/renderer/core/frame/remote_frame_client.h
@@ -58,8 +58,6 @@ virtual void UpdateRemoteViewportIntersection( const ViewportIntersectionState& intersection_state) = 0; - virtual void AdvanceFocus(mojom::blink::FocusType, LocalFrame* source) = 0; - virtual uint32_t Print(const IntRect&, cc::PaintCanvas*) const = 0; };
diff --git a/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc b/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc index 12e8a91..f6cc293 100644 --- a/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc +++ b/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc
@@ -144,12 +144,6 @@ web_frame_->Client()->UpdateRemoteViewportIntersection(intersection_state); } -void RemoteFrameClientImpl::AdvanceFocus(mojom::blink::FocusType type, - LocalFrame* source) { - web_frame_->Client()->AdvanceFocus(type, - WebLocalFrameImpl::FromFrame(source)); -} - uint32_t RemoteFrameClientImpl::Print(const IntRect& rect, cc::PaintCanvas* canvas) const { return web_frame_->Client()->Print(rect, canvas);
diff --git a/third_party/blink/renderer/core/frame/remote_frame_client_impl.h b/third_party/blink/renderer/core/frame/remote_frame_client_impl.h index 05d5bfd..15f104f6 100644 --- a/third_party/blink/renderer/core/frame/remote_frame_client_impl.h +++ b/third_party/blink/renderer/core/frame/remote_frame_client_impl.h
@@ -49,7 +49,6 @@ const IntRect& screen_space_rect) override; void UpdateRemoteViewportIntersection( const ViewportIntersectionState& intersection_state) override; - void AdvanceFocus(mojom::blink::FocusType, LocalFrame*) override; uint32_t Print(const IntRect&, cc::PaintCanvas*) const override; WebRemoteFrameImpl* GetWebFrame() const { return web_frame_; }
diff --git a/third_party/blink/renderer/core/frame/screen.cc b/third_party/blink/renderer/core/frame/screen.cc index 2b6b133..507618c 100644 --- a/third_party/blink/renderer/core/frame/screen.cc +++ b/third_party/blink/renderer/core/frame/screen.cc
@@ -100,113 +100,110 @@ return colorDepth(); } -void Screen::RecordIdentifiableSurface(WebFeature feature, int value) const { - if (!DomWindow()) return; +int Screen::RecordThenReturn(WebFeature feature, int value) const { + if (!DomWindow()) return value; Document* document = DomWindow()->document(); - if (!document) return; + if (!document) return value; IdentifiabilityMetricBuilder( base::UkmSourceId::FromInt64(document->UkmSourceID())) - .Set(IdentifiableSurface::FromTypeAndInput( - IdentifiableSurface::Type::kWebFeature, - static_cast<uint64_t>(feature)), - IdentifiabilityDigestHelper(value)) + .SetWebfeature(feature, IdentifiabilityDigestHelper(value)) .Record(document->UkmRecorder()); -} - -int Screen::ComputeAvailLeft() const { - if (display_) { - DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled()); - return display_->work_area.x(); - } - LocalFrame* frame = GetFrame(); - if (!frame) - return 0; - Page* page = frame->GetPage(); - if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) { - WebScreenInfo screen_info = GetScreenInfo(*frame); - return static_cast<int>(lroundf(screen_info.available_rect.x * - screen_info.device_scale_factor)); - } - return static_cast<int>(GetScreenInfo(*frame).available_rect.x); + return value; } int Screen::availLeft() const { - int result = ComputeAvailLeft(); - RecordIdentifiableSurface( - WebFeature::kV8Screen_AvailLeft_AttributeGetter, result); - return result; -} - -int Screen::ComputeAvailTop() const { if (display_) { DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled()); - return display_->work_area.y(); + return RecordThenReturn( + WebFeature::kV8Screen_AvailLeft_AttributeGetter, + display_->work_area.x()); } LocalFrame* frame = GetFrame(); if (!frame) - return 0; + return RecordThenReturn( + WebFeature::kV8Screen_AvailLeft_AttributeGetter, 0); Page* page = frame->GetPage(); if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) { WebScreenInfo screen_info = GetScreenInfo(*frame); - return static_cast<int>(lroundf(screen_info.available_rect.y * - screen_info.device_scale_factor)); + return RecordThenReturn( + WebFeature::kV8Screen_AvailLeft_AttributeGetter, + static_cast<int>(lroundf(screen_info.available_rect.x * + screen_info.device_scale_factor))); } - return static_cast<int>(GetScreenInfo(*frame).available_rect.y); + return RecordThenReturn( + WebFeature::kV8Screen_AvailLeft_AttributeGetter, + static_cast<int>(GetScreenInfo(*frame).available_rect.x)); } int Screen::availTop() const { - int result = ComputeAvailTop(); - RecordIdentifiableSurface( - WebFeature::kV8Screen_AvailTop_AttributeGetter, result); - return result; -} - -int Screen::ComputeAvailHeight() const { if (display_) { DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled()); - return display_->work_area.height(); + return RecordThenReturn( + WebFeature::kV8Screen_AvailTop_AttributeGetter, + display_->work_area.y()); } LocalFrame* frame = GetFrame(); if (!frame) - return 0; + return RecordThenReturn(WebFeature::kV8Screen_AvailTop_AttributeGetter, 0); Page* page = frame->GetPage(); if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) { WebScreenInfo screen_info = GetScreenInfo(*frame); - return static_cast<int>(lroundf(screen_info.available_rect.height * - screen_info.device_scale_factor)); + return RecordThenReturn( + WebFeature::kV8Screen_AvailTop_AttributeGetter, + static_cast<int>(lroundf(screen_info.available_rect.y * + screen_info.device_scale_factor))); } - return GetScreenInfo(*frame).available_rect.height; + return RecordThenReturn( + WebFeature::kV8Screen_AvailTop_AttributeGetter, + static_cast<int>(GetScreenInfo(*frame).available_rect.y)); } int Screen::availHeight() const { - int result = ComputeAvailHeight(); - RecordIdentifiableSurface( - WebFeature::kV8Screen_AvailHeight_AttributeGetter, result); - return result; -} - -int Screen::ComputeAvailWidth() const { if (display_) { DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled()); - return display_->work_area.width(); + return RecordThenReturn( + WebFeature::kV8Screen_AvailHeight_AttributeGetter, + display_->work_area.height()); } LocalFrame* frame = GetFrame(); if (!frame) - return 0; + return RecordThenReturn( + WebFeature::kV8Screen_AvailHeight_AttributeGetter, 0); Page* page = frame->GetPage(); if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) { WebScreenInfo screen_info = GetScreenInfo(*frame); - return static_cast<int>(lroundf(screen_info.available_rect.width * - screen_info.device_scale_factor)); + return RecordThenReturn( + WebFeature::kV8Screen_AvailHeight_AttributeGetter, + static_cast<int>(lroundf(screen_info.available_rect.height * + screen_info.device_scale_factor))); } - return GetScreenInfo(*frame).available_rect.width; + return RecordThenReturn( + WebFeature::kV8Screen_AvailHeight_AttributeGetter, + GetScreenInfo(*frame).available_rect.height); } int Screen::availWidth() const { - int result = ComputeAvailWidth(); - RecordIdentifiableSurface( - WebFeature::kV8Screen_AvailWidth_AttributeGetter, result); - return result; + if (display_) { + DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled()); + return RecordThenReturn( + WebFeature::kV8Screen_AvailWidth_AttributeGetter, + display_->work_area.width()); + } + LocalFrame* frame = GetFrame(); + if (!frame) + return RecordThenReturn( + WebFeature::kV8Screen_AvailWidth_AttributeGetter, 0); + Page* page = frame->GetPage(); + if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) { + WebScreenInfo screen_info = GetScreenInfo(*frame); + return RecordThenReturn( + WebFeature::kV8Screen_AvailWidth_AttributeGetter, + static_cast<int>(lroundf(screen_info.available_rect.width * + screen_info.device_scale_factor))); + } + return RecordThenReturn( + WebFeature::kV8Screen_AvailWidth_AttributeGetter, + GetScreenInfo(*frame).available_rect.width); } void Screen::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/core/frame/screen.h b/third_party/blink/renderer/core/frame/screen.h index feb4cbd..cc99351 100644 --- a/third_party/blink/renderer/core/frame/screen.h +++ b/third_party/blink/renderer/core/frame/screen.h
@@ -83,11 +83,7 @@ int64_t DisplayId() const; private: - int ComputeAvailLeft() const; - int ComputeAvailTop() const; - int ComputeAvailHeight() const; - int ComputeAvailWidth() const; - void RecordIdentifiableSurface(WebFeature, int) const; + int RecordThenReturn(WebFeature, int) const; // A static snapshot of the display's information, provided upon construction. // This member is only valid for Screen objects obtained via the experimental // Screen Enumeration API.
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index b602268..c398786e 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -2198,6 +2198,7 @@ const WebURL& mixed_content_url, mojom::RequestContextType request_context, bool was_allowed, + const WebURL& url_before_redirects, bool had_redirect, const WebSourceLocation& source_location) { DCHECK(GetFrame()); @@ -2209,7 +2210,7 @@ } MixedContentChecker::MixedContentFound( GetFrame(), main_resource_url, mixed_content_url, request_context, - was_allowed, had_redirect, std::move(source)); + was_allowed, url_before_redirects, had_redirect, std::move(source)); } void WebLocalFrameImpl::DidDropNavigation() {
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h index c6421d2..2ffde74 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -136,6 +136,7 @@ const WebURL& mixed_content_url, mojom::RequestContextType, bool was_allowed, + const WebURL& url_before_redirects, bool had_redirect, const WebSourceLocation&) override; void SendOrientationChangeEvent() override;
diff --git a/third_party/blink/renderer/core/html/html_plugin_element.cc b/third_party/blink/renderer/core/html/html_plugin_element.cc index c3d61215..05b6625 100644 --- a/third_party/blink/renderer/core/html/html_plugin_element.cc +++ b/third_party/blink/renderer/core/html/html_plugin_element.cc
@@ -725,7 +725,7 @@ // is specified. return (!mime_type.IsEmpty() && url.IsEmpty()) || !MixedContentChecker::ShouldBlockFetch( - frame, mojom::RequestContextType::OBJECT, + frame, mojom::RequestContextType::OBJECT, url, ResourceRequest::RedirectStatus::kNoRedirect, url, /* devtools_id= */ base::nullopt); }
diff --git a/third_party/blink/renderer/core/html/link_style.cc b/third_party/blink/renderer/core/html/link_style.cc index d262ffb..af40a72d 100644 --- a/third_party/blink/renderer/core/html/link_style.cc +++ b/third_party/blink/renderer/core/html/link_style.cc
@@ -324,7 +324,7 @@ if (!GetDocument().GetSecurityOrigin()->CanDisplay(params.href)) return; if (!GetDocument().GetContentSecurityPolicy()->AllowImageFromSource( - params.href)) + params.href, params.href, RedirectStatus::kNoRedirect)) return; if (GetDocument().GetFrame()) GetDocument().GetFrame()->UpdateFaviconURL();
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.cc b/third_party/blink/renderer/core/html/media/html_media_element.cc index b6aca8ef..df747d42 100644 --- a/third_party/blink/renderer/core/html/media/html_media_element.cc +++ b/third_party/blink/renderer/core/html/media/html_media_element.cc
@@ -1818,6 +1818,7 @@ frame, HasVideo() ? mojom::blink::RequestContextType::VIDEO : mojom::blink::RequestContextType::AUDIO, + current_src_, // Strictly speaking, this check is an approximation; a request could // have have redirected back to its original URL, for example. // However, the redirect status is only used to prevent leaking
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index 8fabf9a..ca692ff 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -80,10 +80,6 @@ #include "third_party/blink/renderer/core/layout/layout_list_marker.h" #include "third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h" #include "third_party/blink/renderer/core/layout/layout_object_factory.h" -#include "third_party/blink/renderer/core/layout/layout_table_caption.h" -#include "third_party/blink/renderer/core/layout/layout_table_cell.h" -#include "third_party/blink/renderer/core/layout/layout_table_col.h" -#include "third_party/blink/renderer/core/layout/layout_table_row.h" #include "third_party/blink/renderer/core/layout/layout_text_fragment.h" #include "third_party/blink/renderer/core/layout/layout_theme.h" #include "third_party/blink/renderer/core/layout/layout_view.h" @@ -245,24 +241,16 @@ return LayoutObjectFactory::CreateBlockFlow(*element, style, legacy); case EDisplay::kTable: case EDisplay::kInlineTable: - UseCounter::Count(element->GetDocument(), - WebFeature::kLegacyLayoutByTable); - return new LayoutTable(element); + return LayoutObjectFactory::CreateTable(*element, style, legacy); case EDisplay::kTableRowGroup: case EDisplay::kTableHeaderGroup: case EDisplay::kTableFooterGroup: - UseCounter::Count(element->GetDocument(), - WebFeature::kLegacyLayoutByTable); - return new LayoutTableSection(element); + return LayoutObjectFactory::CreateTableSection(*element, style, legacy); case EDisplay::kTableRow: - UseCounter::Count(element->GetDocument(), - WebFeature::kLegacyLayoutByTable); - return new LayoutTableRow(element); + return LayoutObjectFactory::CreateTableRow(*element, style, legacy); case EDisplay::kTableColumnGroup: case EDisplay::kTableColumn: - UseCounter::Count(element->GetDocument(), - WebFeature::kLegacyLayoutByTable); - return new LayoutTableCol(element); + return LayoutObjectFactory::CreateTableColumn(*element, style, legacy); case EDisplay::kTableCell: return LayoutObjectFactory::CreateTableCell(*element, style, legacy); case EDisplay::kTableCaption: @@ -431,7 +419,7 @@ !after_child->IsBeforeContent()) { table = after_child; } else { - table = LayoutTable::CreateAnonymousWithParent(this); + table = LayoutObjectFactory::CreateAnonymousTableWithParent(*this); children->InsertChildNode(this, table, before_child); } table->AddChild(new_child);
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index c0ca4d15..3571da1 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -2589,6 +2589,11 @@ return element->GetDisplayLockContext(); } + void SetDocumentForAnonymous(Document* document) { + DCHECK(IsAnonymous()); + node_ = document; + } + protected: enum LayoutObjectType { kLayoutObjectBr, @@ -2731,11 +2736,6 @@ virtual void InsertedIntoTree(); virtual void WillBeRemovedFromTree(); - void SetDocumentForAnonymous(Document* document) { - DCHECK(IsAnonymous()); - node_ = document; - } - #if DCHECK_IS_ON() virtual bool PaintInvalidationStateIsDirty() const; #endif
diff --git a/third_party/blink/renderer/core/layout/layout_object_factory.cc b/third_party/blink/renderer/core/layout/layout_object_factory.cc index eb9bd18..eb65690b 100644 --- a/third_party/blink/renderer/core/layout/layout_object_factory.cc +++ b/third_party/blink/renderer/core/layout/layout_object_factory.cc
@@ -15,8 +15,12 @@ #include "third_party/blink/renderer/core/layout/layout_inside_list_marker.h" #include "third_party/blink/renderer/core/layout/layout_list_item.h" #include "third_party/blink/renderer/core/layout/layout_outside_list_marker.h" +#include "third_party/blink/renderer/core/layout/layout_table.h" #include "third_party/blink/renderer/core/layout/layout_table_caption.h" #include "third_party/blink/renderer/core/layout/layout_table_cell.h" +#include "third_party/blink/renderer/core/layout/layout_table_col.h" +#include "third_party/blink/renderer/core/layout/layout_table_row.h" +#include "third_party/blink/renderer/core/layout/layout_table_section.h" #include "third_party/blink/renderer/core/layout/layout_text.h" #include "third_party/blink/renderer/core/layout/layout_text_fragment.h" #include "third_party/blink/renderer/core/layout/layout_view.h" @@ -32,8 +36,13 @@ #include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h" #include "third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.h" #include "third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.h" +#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h" #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_caption.h" +#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h" #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell_legacy.h" +#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column.h" +#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h" +#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" @@ -147,6 +156,16 @@ LayoutOutsideListMarker>(node, style, legacy); } +LayoutBlock* LayoutObjectFactory::CreateTable(Node& node, + const ComputedStyle& style, + LegacyLayout legacy) { + bool disable_ng_for_type = !RuntimeEnabledFeatures::LayoutNGTableEnabled(); + if (disable_ng_for_type) + UseCounter::Count(node.GetDocument(), WebFeature::kLegacyLayoutByTable); + return CreateObject<LayoutBlock, LayoutNGTable, LayoutTable>( + node, style, legacy, disable_ng_for_type); +} + LayoutTableCaption* LayoutObjectFactory::CreateTableCaption( Node& node, const ComputedStyle& style, @@ -155,12 +174,47 @@ legacy); } -LayoutTableCell* LayoutObjectFactory::CreateTableCell( +LayoutBlockFlow* LayoutObjectFactory::CreateTableCell( Node& node, const ComputedStyle& style, LegacyLayout legacy) { - return CreateObject<LayoutTableCell, LayoutNGTableCellLegacy>(node, style, - legacy); + if (RuntimeEnabledFeatures::LayoutNGTableEnabled()) { + return CreateObject<LayoutBlockFlow, LayoutNGTableCell, LayoutTableCell>( + node, style, legacy); + } else { + return CreateObject<LayoutBlockFlow, LayoutNGTableCellLegacy, + LayoutTableCell>(node, style, legacy); + } +} + +LayoutBox* LayoutObjectFactory::CreateTableColumn(Node& node, + const ComputedStyle& style, + LegacyLayout legacy) { + bool disable_ng_for_type = !RuntimeEnabledFeatures::LayoutNGTableEnabled(); + if (disable_ng_for_type) + UseCounter::Count(node.GetDocument(), WebFeature::kLegacyLayoutByTable); + return CreateObject<LayoutBox, LayoutNGTableColumn, LayoutTableCol>( + node, style, legacy, disable_ng_for_type); +} + +LayoutBox* LayoutObjectFactory::CreateTableRow(Node& node, + const ComputedStyle& style, + LegacyLayout legacy) { + bool disable_ng_for_type = !RuntimeEnabledFeatures::LayoutNGTableEnabled(); + if (disable_ng_for_type) + UseCounter::Count(node.GetDocument(), WebFeature::kLegacyLayoutByTable); + return CreateObject<LayoutBox, LayoutNGTableRow, LayoutTableRow>( + node, style, legacy, disable_ng_for_type); +} + +LayoutBox* LayoutObjectFactory::CreateTableSection(Node& node, + const ComputedStyle& style, + LegacyLayout legacy) { + bool disable_ng_for_type = !RuntimeEnabledFeatures::LayoutNGTableEnabled(); + if (disable_ng_for_type) + UseCounter::Count(node.GetDocument(), WebFeature::kLegacyLayoutByTable); + return CreateObject<LayoutBox, LayoutNGTableSection, LayoutTableSection>( + node, style, legacy, disable_ng_for_type); } LayoutBlock* LayoutObjectFactory::CreateFieldset(Node& node, @@ -229,4 +283,62 @@ legacy); } +LayoutBox* LayoutObjectFactory::CreateAnonymousTableWithParent( + const LayoutObject& parent) { + scoped_refptr<ComputedStyle> new_style = + ComputedStyle::CreateAnonymousStyleWithDisplay( + parent.StyleRef(), + parent.IsLayoutInline() ? EDisplay::kInlineTable : EDisplay::kTable); + LegacyLayout legacy = + parent.ForceLegacyLayout() ? LegacyLayout::kForce : LegacyLayout::kAuto; + + LayoutBlock* new_table = + CreateTable(parent.GetDocument(), *new_style, legacy); + new_table->SetDocumentForAnonymous(&parent.GetDocument()); + new_table->SetStyle(std::move(new_style)); + return new_table; +} + +LayoutBox* LayoutObjectFactory::CreateAnonymousTableSectionWithParent( + const LayoutObject& parent) { + scoped_refptr<ComputedStyle> new_style = + ComputedStyle::CreateAnonymousStyleWithDisplay(parent.StyleRef(), + EDisplay::kTableRowGroup); + LegacyLayout legacy = + parent.ForceLegacyLayout() ? LegacyLayout::kForce : LegacyLayout::kAuto; + + LayoutBox* new_section = + CreateTableSection(parent.GetDocument(), *new_style, legacy); + new_section->SetDocumentForAnonymous(&parent.GetDocument()); + new_section->SetStyle(std::move(new_style)); + return new_section; +} + +LayoutBox* LayoutObjectFactory::CreateAnonymousTableRowWithParent( + const LayoutObject& parent) { + scoped_refptr<ComputedStyle> new_style = + ComputedStyle::CreateAnonymousStyleWithDisplay(parent.StyleRef(), + EDisplay::kTableRow); + LegacyLayout legacy = + parent.ForceLegacyLayout() ? LegacyLayout::kForce : LegacyLayout::kAuto; + LayoutBox* new_row = CreateTableRow(parent.GetDocument(), *new_style, legacy); + new_row->SetDocumentForAnonymous(&parent.GetDocument()); + new_row->SetStyle(std::move(new_style)); + return new_row; +} + +LayoutBlockFlow* LayoutObjectFactory::CreateAnonymousTableCellWithParent( + const LayoutObject& parent) { + scoped_refptr<ComputedStyle> new_style = + ComputedStyle::CreateAnonymousStyleWithDisplay(parent.StyleRef(), + EDisplay::kTableCell); + LegacyLayout legacy = + parent.ForceLegacyLayout() ? LegacyLayout::kForce : LegacyLayout::kAuto; + LayoutBlockFlow* new_cell = + CreateTableCell(parent.GetDocument(), *new_style, legacy); + new_cell->SetDocumentForAnonymous(&parent.GetDocument()); + new_cell->SetStyle(std::move(new_style)); + return new_cell; +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_object_factory.h b/third_party/blink/renderer/core/layout/layout_object_factory.h index 1cc47ff..831a1be 100644 --- a/third_party/blink/renderer/core/layout/layout_object_factory.h +++ b/third_party/blink/renderer/core/layout/layout_object_factory.h
@@ -15,11 +15,11 @@ class LayoutBlock; class LayoutBlockFlow; class LayoutObject; +class LayoutBox; enum class LegacyLayout; class LayoutProgress; class LayoutRubyAsBlock; class LayoutTableCaption; -class LayoutTableCell; class LayoutText; class LayoutTextFragment; class Node; @@ -50,12 +50,21 @@ static LayoutObject* CreateListMarker(Node&, const ComputedStyle&, LegacyLayout); + static LayoutBlock* CreateTable(Node&, const ComputedStyle&, LegacyLayout); static LayoutTableCaption* CreateTableCaption(Node&, const ComputedStyle&, LegacyLayout); - static LayoutTableCell* CreateTableCell(Node&, + static LayoutBlockFlow* CreateTableCell(Node&, const ComputedStyle&, LegacyLayout); + static LayoutBox* CreateTableColumn(Node&, + const ComputedStyle&, + LegacyLayout); + + static LayoutBox* CreateTableRow(Node&, const ComputedStyle&, LegacyLayout); + static LayoutBox* CreateTableSection(Node&, + const ComputedStyle&, + LegacyLayout); static LayoutBlock* CreateFieldset(Node&, const ComputedStyle&, LegacyLayout); static LayoutBlockFlow* CreateFileUploadControl(Node& node, const ComputedStyle& style, @@ -72,6 +81,19 @@ static LayoutRubyAsBlock* CreateRubyAsBlock(Node* node, const ComputedStyle& style, LegacyLayout legacy); + + // Anonoymous creation methods + + static LayoutBox* CreateAnonymousTableWithParent(const LayoutObject& parent); + + static LayoutBox* CreateAnonymousTableSectionWithParent( + const LayoutObject& parent); + + static LayoutBox* CreateAnonymousTableRowWithParent( + const LayoutObject& parent); + + static LayoutBlockFlow* CreateAnonymousTableCellWithParent( + const LayoutObject& parent); }; } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_table.cc b/third_party/blink/renderer/core/layout/layout_table.cc index 2b41ff4..e0ba3917 100644 --- a/third_party/blink/renderer/core/layout/layout_table.cc +++ b/third_party/blink/renderer/core/layout/layout_table.cc
@@ -32,6 +32,7 @@ #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/layout/hit_test_result.h" #include "third_party/blink/renderer/core/layout/layout_analyzer.h" +#include "third_party/blink/renderer/core/layout/layout_object_factory.h" #include "third_party/blink/renderer/core/layout/layout_table_caption.h" #include "third_party/blink/renderer/core/layout/layout_table_cell.h" #include "third_party/blink/renderer/core/layout/layout_table_col.h" @@ -231,8 +232,8 @@ NeedsTableSection(before_child)) before_child = nullptr; - LayoutTableSection* section = - LayoutTableSection::CreateAnonymousWithParent(this); + LayoutBox* section = + LayoutObjectFactory::CreateAnonymousTableSectionWithParent(*this); AddChild(section, before_child); section->AddChild(child); } @@ -1657,16 +1658,9 @@ return false; } -LayoutTable* LayoutTable::CreateAnonymousWithParent( - const LayoutObject* parent) { - scoped_refptr<ComputedStyle> new_style = - ComputedStyle::CreateAnonymousStyleWithDisplay( - parent->StyleRef(), - parent->IsLayoutInline() ? EDisplay::kInlineTable : EDisplay::kTable); - LayoutTable* new_table = new LayoutTable(nullptr); - new_table->SetDocumentForAnonymous(&parent->GetDocument()); - new_table->SetStyle(std::move(new_style)); - return new_table; +LayoutBox* LayoutTable::CreateAnonymousBoxWithSameTypeAs( + const LayoutObject* parent) const { + return LayoutObjectFactory::CreateAnonymousTableWithParent(*parent); } void LayoutTable::EnsureIsReadyForPaintInvalidation() {
diff --git a/third_party/blink/renderer/core/layout/layout_table.h b/third_party/blink/renderer/core/layout/layout_table.h index 53978ca..288e42a7f 100644 --- a/third_party/blink/renderer/core/layout/layout_table.h +++ b/third_party/blink/renderer/core/layout/layout_table.h
@@ -378,11 +378,8 @@ RecalcSections(); } - static LayoutTable* CreateAnonymousWithParent(const LayoutObject*); LayoutBox* CreateAnonymousBoxWithSameTypeAs( - const LayoutObject* parent) const override { - return CreateAnonymousWithParent(parent); - } + const LayoutObject* parent) const override; void AddCaption(const LayoutTableCaption*); void RemoveCaption(const LayoutTableCaption*);
diff --git a/third_party/blink/renderer/core/layout/layout_table_cell.cc b/third_party/blink/renderer/core/layout/layout_table_cell.cc index 7d04131..5e51751 100644 --- a/third_party/blink/renderer/core/layout/layout_table_cell.cc +++ b/third_party/blink/renderer/core/layout/layout_table_cell.cc
@@ -1154,23 +1154,16 @@ Document* document, scoped_refptr<ComputedStyle> style, LegacyLayout legacy) { - LayoutTableCell* layout_object = + LayoutBlockFlow* layout_object = LayoutObjectFactory::CreateTableCell(*document, *style, legacy); layout_object->SetDocumentForAnonymous(document); layout_object->SetStyle(std::move(style)); - return layout_object; + return To<LayoutTableCell>(layout_object); } -LayoutTableCell* LayoutTableCell::CreateAnonymousWithParent( - const LayoutObject* parent) { - scoped_refptr<ComputedStyle> new_style = - ComputedStyle::CreateAnonymousStyleWithDisplay(parent->StyleRef(), - EDisplay::kTableCell); - LegacyLayout legacy = - parent->ForceLegacyLayout() ? LegacyLayout::kForce : LegacyLayout::kAuto; - LayoutTableCell* new_cell = LayoutTableCell::CreateAnonymous( - &parent->GetDocument(), std::move(new_style), legacy); - return new_cell; +LayoutBox* LayoutTableCell::CreateAnonymousBoxWithSameTypeAs( + const LayoutObject* parent) const { + return LayoutObjectFactory::CreateAnonymousTableCellWithParent(*parent); } bool LayoutTableCell::BackgroundIsKnownToBeOpaqueInRect(
diff --git a/third_party/blink/renderer/core/layout/layout_table_cell.h b/third_party/blink/renderer/core/layout/layout_table_cell.h index b2f2dd19..9a5454b5 100644 --- a/third_party/blink/renderer/core/layout/layout_table_cell.h +++ b/third_party/blink/renderer/core/layout/layout_table_cell.h
@@ -241,11 +241,9 @@ static LayoutTableCell* CreateAnonymous(Document*, scoped_refptr<ComputedStyle>, LegacyLayout); - static LayoutTableCell* CreateAnonymousWithParent(const LayoutObject*); + LayoutBox* CreateAnonymousBoxWithSameTypeAs( - const LayoutObject* parent) const override { - return CreateAnonymousWithParent(parent); - } + const LayoutObject* parent) const override; // The table's style determines cell order and cell adjacency in the table. // Collapsed borders also use in table's inline and block directions. @@ -378,7 +376,9 @@ protected: bool IsOfType(LayoutObjectType type) const override { - return type == kLayoutObjectTableCell || LayoutBlockFlow::IsOfType(type); + return type == kLayoutObjectTableCell || + type == kLayoutObjectTableCellLegacy || + LayoutBlockFlow::IsOfType(type); } private: @@ -551,7 +551,7 @@ template <> struct DowncastTraits<LayoutTableCell> { static bool AllowFrom(const LayoutObject& object) { - return object.IsTableCell(); + return object.IsTableCellLegacy(); } };
diff --git a/third_party/blink/renderer/core/layout/layout_table_cell_test.cc b/third_party/blink/renderer/core/layout/layout_table_cell_test.cc index 0826849f..8ebdfc8b 100644 --- a/third_party/blink/renderer/core/layout/layout_table_cell_test.cc +++ b/third_party/blink/renderer/core/layout/layout_table_cell_test.cc
@@ -30,8 +30,12 @@ namespace blink { -class LayoutTableCellDeathTest : public RenderingTest { +class LayoutTableCellDeathTest : public RenderingTest, + public ScopedLayoutNGTableForTest { protected: + // These tests test Legacy behavior only. + LayoutTableCellDeathTest() : ScopedLayoutNGTableForTest(false) {} + void SetUp() override { RenderingTest::SetUp(); auto style = ComputedStyle::Create();
diff --git a/third_party/blink/renderer/core/layout/layout_table_row.cc b/third_party/blink/renderer/core/layout/layout_table_row.cc index 8dbea5a..5cb289c 100644 --- a/third_party/blink/renderer/core/layout/layout_table_row.cc +++ b/third_party/blink/renderer/core/layout/layout_table_row.cc
@@ -29,6 +29,7 @@ #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/layout/hit_test_result.h" #include "third_party/blink/renderer/core/layout/layout_analyzer.h" +#include "third_party/blink/renderer/core/layout/layout_object_factory.h" #include "third_party/blink/renderer/core/layout/layout_state.h" #include "third_party/blink/renderer/core/layout/layout_table_cell.h" #include "third_party/blink/renderer/core/layout/layout_view.h" @@ -154,7 +155,8 @@ return; } - LayoutTableCell* cell = LayoutTableCell::CreateAnonymousWithParent(this); + LayoutBlockFlow* cell = + LayoutObjectFactory::CreateAnonymousTableCellWithParent(*this); AddChild(cell, before_child); cell->AddChild(child); return; @@ -284,15 +286,9 @@ return layout_object; } -LayoutTableRow* LayoutTableRow::CreateAnonymousWithParent( - const LayoutObject* parent) { - LayoutTableRow* new_row = - LayoutTableRow::CreateAnonymous(&parent->GetDocument()); - scoped_refptr<ComputedStyle> new_style = - ComputedStyle::CreateAnonymousStyleWithDisplay(parent->StyleRef(), - EDisplay::kTableRow); - new_row->SetStyle(std::move(new_style)); - return new_row; +LayoutBox* LayoutTableRow::CreateAnonymousBoxWithSameTypeAs( + const LayoutObject* parent) const { + return LayoutObjectFactory::CreateAnonymousTableRowWithParent(*parent); } void LayoutTableRow::ComputeLayoutOverflow() {
diff --git a/third_party/blink/renderer/core/layout/layout_table_row.h b/third_party/blink/renderer/core/layout/layout_table_row.h index 82feffc..eba5cbb3 100644 --- a/third_party/blink/renderer/core/layout/layout_table_row.h +++ b/third_party/blink/renderer/core/layout/layout_table_row.h
@@ -84,11 +84,8 @@ } static LayoutTableRow* CreateAnonymous(Document*); - static LayoutTableRow* CreateAnonymousWithParent(const LayoutObject*); LayoutBox* CreateAnonymousBoxWithSameTypeAs( - const LayoutObject* parent) const override { - return CreateAnonymousWithParent(parent); - } + const LayoutObject* parent) const override; void SetRowIndex(unsigned row_index) { CHECK_LE(row_index, kMaxRowIndex);
diff --git a/third_party/blink/renderer/core/layout/layout_table_section.cc b/third_party/blink/renderer/core/layout/layout_table_section.cc index c67288c..9ad149a 100644 --- a/third_party/blink/renderer/core/layout/layout_table_section.cc +++ b/third_party/blink/renderer/core/layout/layout_table_section.cc
@@ -31,6 +31,7 @@ #include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/layout/hit_test_result.h" #include "third_party/blink/renderer/core/layout/layout_analyzer.h" +#include "third_party/blink/renderer/core/layout/layout_object_factory.h" #include "third_party/blink/renderer/core/layout/layout_table_cell.h" #include "third_party/blink/renderer/core/layout/layout_table_col.h" #include "third_party/blink/renderer/core/layout/layout_table_row.h" @@ -173,7 +174,8 @@ return; } - LayoutObject* row = LayoutTableRow::CreateAnonymousWithParent(this); + LayoutObject* row = + LayoutObjectFactory::CreateAnonymousTableRowWithParent(*this); AddChild(row, before_child); row->AddChild(child); return; @@ -1868,15 +1870,9 @@ return false; } -LayoutTableSection* LayoutTableSection::CreateAnonymousWithParent( - const LayoutObject* parent) { - scoped_refptr<ComputedStyle> new_style = - ComputedStyle::CreateAnonymousStyleWithDisplay(parent->StyleRef(), - EDisplay::kTableRowGroup); - LayoutTableSection* new_section = new LayoutTableSection(nullptr); - new_section->SetDocumentForAnonymous(&parent->GetDocument()); - new_section->SetStyle(std::move(new_style)); - return new_section; +LayoutBox* LayoutTableSection::CreateAnonymousBoxWithSameTypeAs( + const LayoutObject* parent) const { + return LayoutObjectFactory::CreateAnonymousTableSectionWithParent(*parent); } void LayoutTableSection::SetLogicalPositionForCell(
diff --git a/third_party/blink/renderer/core/layout/layout_table_section.h b/third_party/blink/renderer/core/layout/layout_table_section.h index 2e3495c..4731fd7b 100644 --- a/third_party/blink/renderer/core/layout/layout_table_section.h +++ b/third_party/blink/renderer/core/layout/layout_table_section.h
@@ -232,11 +232,8 @@ // information. int DistributeExtraLogicalHeightToRows(int extra_logical_height); - static LayoutTableSection* CreateAnonymousWithParent(const LayoutObject*); LayoutBox* CreateAnonymousBoxWithSameTypeAs( - const LayoutObject* parent) const override { - return CreateAnonymousWithParent(parent); - } + const LayoutObject* parent) const override; void Paint(const PaintInfo&) const override;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h index 3f9a512..e4c111e 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h +++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h
@@ -30,14 +30,18 @@ NGPhysicalStaticPosition static_position; // Continuation root of the optional inline container. const LayoutInline* inline_container; + scoped_refptr<const NGPhysicalContainerFragment> containing_block_fragment; NGPhysicalOutOfFlowPositionedNode( NGBlockNode node, NGPhysicalStaticPosition static_position, - const LayoutInline* inline_container = nullptr) + const LayoutInline* inline_container = nullptr, + scoped_refptr<const NGPhysicalContainerFragment> + containing_block_fragment = nullptr) : node(node), static_position(static_position), - inline_container(inline_container) { + inline_container(inline_container), + containing_block_fragment(std::move(containing_block_fragment)) { DCHECK(!inline_container || inline_container == inline_container->ContinuationRoot()); } @@ -55,16 +59,20 @@ // Continuation root of the optional inline container. const LayoutInline* inline_container; bool needs_block_offset_adjustment; + scoped_refptr<const NGPhysicalContainerFragment> containing_block_fragment; NGLogicalOutOfFlowPositionedNode( NGBlockNode node, NGLogicalStaticPosition static_position, const LayoutInline* inline_container = nullptr, - bool needs_block_offset_adjustment = false) + bool needs_block_offset_adjustment = false, + scoped_refptr<const NGPhysicalContainerFragment> + containing_block_fragment = nullptr) : node(node), static_position(static_position), inline_container(inline_container), - needs_block_offset_adjustment(needs_block_offset_adjustment) { + needs_block_offset_adjustment(needs_block_offset_adjustment), + containing_block_fragment(std::move(containing_block_fragment)) { DCHECK(!inline_container || inline_container == inline_container->ContinuationRoot()); }
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc index 5fed73b..639ac08 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc
@@ -33,6 +33,11 @@ UpdateInFlowBlockLayout(); } +LayoutBox* LayoutNGTable::CreateAnonymousBoxWithSameTypeAs( + const LayoutObject* parent) const { + return LayoutObjectFactory::CreateAnonymousTableWithParent(*parent); +} + bool LayoutNGTable::IsFirstCell(const LayoutNGTableCellInterface& cell) const { const LayoutNGTableRowInterface* row = cell.RowInterface(); if (row->FirstCellInterface() != &cell)
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h index 06186b60..a93cb33 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h
@@ -33,6 +33,9 @@ void UpdateBlockLayout(bool relayout_children) override; + LayoutBox* CreateAnonymousBoxWithSameTypeAs( + const LayoutObject* parent) const override; + // LayoutBlock methods end. // LayoutNGTableInterface methods start.
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc index 8f501b9..cca5eb81 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc
@@ -37,6 +37,11 @@ UpdateColAndRowSpanFlags(); } +LayoutBox* LayoutNGTableCell::CreateAnonymousBoxWithSameTypeAs( + const LayoutObject* parent) const { + return LayoutObjectFactory::CreateAnonymousTableCellWithParent(*parent); +} + Length LayoutNGTableCell::StyleOrColLogicalWidth() const { // TODO(atotic) TablesNG cannot easily get col width before layout. return StyleRef().LogicalWidth();
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h index 4c70aef0..c1295a4 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h
@@ -37,6 +37,9 @@ // compat. const char* GetName() const final { return "LayoutNGTableCellNew"; } + LayoutBox* CreateAnonymousBoxWithSameTypeAs( + const LayoutObject* parent) const override; + // LayoutBlockFlow methods end. // LayoutNGTableCellInterface methods start.
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc index 48db164..e03bffb 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h" #include "third_party/blink/renderer/core/layout/layout_analyzer.h" +#include "third_party/blink/renderer/core/layout/layout_object_factory.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h" #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row_interface.h" @@ -20,6 +21,11 @@ return !FirstChild(); } +LayoutBox* LayoutNGTableRow::CreateAnonymousBoxWithSameTypeAs( + const LayoutObject* parent) const { + return LayoutObjectFactory::CreateAnonymousTableRowWithParent(*parent); +} + unsigned LayoutNGTableRow::RowIndex() const { unsigned index = 0; for (LayoutObject* child = Parent()->SlowFirstChild(); child;
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h index 8b08dd0..2378504 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h
@@ -28,6 +28,9 @@ const char* GetName() const override { return "LayoutNGTableRow"; } + LayoutBox* CreateAnonymousBoxWithSameTypeAs( + const LayoutObject* parent) const override; + // Whether a row has opaque background depends on many factors, e.g. border // spacing, border collapsing, missing cells, etc. // For simplicity, just conservatively assume all table rows are not opaque.
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc index 06225ac..8def5f0e 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h" #include "third_party/blink/renderer/core/layout/layout_analyzer.h" +#include "third_party/blink/renderer/core/layout/layout_object_factory.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h" #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h" @@ -25,6 +26,11 @@ return true; } +LayoutBox* LayoutNGTableSection::CreateAnonymousBoxWithSameTypeAs( + const LayoutObject* parent) const { + return LayoutObjectFactory::CreateAnonymousTableSectionWithParent(*parent); +} + LayoutNGTableInterface* LayoutNGTableSection::TableInterface() const { return ToInterface<LayoutNGTableInterface>(Parent()); }
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h index 64136c5..37e42c8 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h
@@ -27,6 +27,9 @@ const char* GetName() const override { return "LayoutNGTableSection"; } + LayoutBox* CreateAnonymousBoxWithSameTypeAs( + const LayoutObject* parent) const override; + bool AllowsOverflowClip() const override { return false; } bool BackgroundIsKnownToBeOpaqueInRect(const PhysicalRect&) const override {
diff --git a/third_party/blink/renderer/core/loader/base_fetch_context.cc b/third_party/blink/renderer/core/loader/base_fetch_context.cc index 782c3431..5c4596d8 100644 --- a/third_party/blink/renderer/core/loader/base_fetch_context.cc +++ b/third_party/blink/renderer/core/loader/base_fetch_context.cc
@@ -33,10 +33,10 @@ const KURL& url, const ResourceLoaderOptions& options, ReportingDisposition reporting_disposition, - const base::Optional<ResourceRequest::RedirectInfo>& redirect_info) const { + const Vector<KURL>& redirect_chain) const { base::Optional<ResourceRequestBlockedReason> blocked_reason = CanRequestInternal(type, resource_request, url, options, - reporting_disposition, redirect_info); + reporting_disposition, redirect_chain); if (blocked_reason && reporting_disposition == ReportingDisposition::kReport) { DispatchDidBlockRequest(resource_request, options.initiator_info, @@ -60,7 +60,7 @@ bool BaseFetchContext::SendConversionRequestInsteadOfRedirecting( const KURL& url, - const base::Optional<ResourceRequest::RedirectInfo>& redirect_info, + const Vector<KURL>& redirect_chain, ReportingDisposition reporting_disposition) const { return false; } @@ -94,10 +94,11 @@ const KURL& url, const ResourceLoaderOptions& options, ReportingDisposition reporting_disposition, + const KURL& url_before_redirects, ResourceRequest::RedirectStatus redirect_status) const { return CheckCSPForRequestInternal( request_context, request_destination, url, options, reporting_disposition, - redirect_status, + url_before_redirects, redirect_status, ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly); } @@ -108,6 +109,7 @@ const KURL& url, const ResourceLoaderOptions& options, ReportingDisposition reporting_disposition, + const KURL& url_before_redirects, ResourceRequest::RedirectStatus redirect_status, ContentSecurityPolicy::CheckHeaderType check_header_type) const { if (ShouldBypassMainWorldCSP() || @@ -117,26 +119,26 @@ } const ContentSecurityPolicy* csp = GetContentSecurityPolicy(); - if (csp && !csp->AllowRequest(request_context, request_destination, url, - options.content_security_policy_nonce, - options.integrity_metadata, - options.parser_disposition, redirect_status, - reporting_disposition, check_header_type)) { + if (csp && + !csp->AllowRequest(request_context, request_destination, url, + options.content_security_policy_nonce, + options.integrity_metadata, options.parser_disposition, + url_before_redirects, redirect_status, + reporting_disposition, check_header_type)) { return ResourceRequestBlockedReason::kCSP; } return base::nullopt; } base::Optional<ResourceRequestBlockedReason> -BaseFetchContext::CanRequestInternal( - ResourceType type, - const ResourceRequest& resource_request, - const KURL& url, - const ResourceLoaderOptions& options, - ReportingDisposition reporting_disposition, - const base::Optional<ResourceRequest::RedirectInfo>& redirect_info) const { +BaseFetchContext::CanRequestInternal(ResourceType type, + const ResourceRequest& resource_request, + const KURL& url, + const ResourceLoaderOptions& options, + ReportingDisposition reporting_disposition, + const Vector<KURL>& redirect_chain) const { if (GetResourceFetcherProperties().IsDetached()) { - if (!resource_request.GetKeepalive() || !redirect_info) { + if (!resource_request.GetKeepalive() || redirect_chain.IsEmpty()) { return ResourceRequestBlockedReason::kOther; } } @@ -187,16 +189,18 @@ network::mojom::RequestDestination request_destination = resource_request.GetRequestDestination(); - ResourceRequest::RedirectStatus redirect_status = - redirect_info ? ResourceRequest::RedirectStatus::kFollowedRedirect - : ResourceRequest::RedirectStatus::kNoRedirect; - + const KURL& url_before_redirects = + redirect_chain.IsEmpty() ? url : redirect_chain.front(); + const ResourceRequestHead::RedirectStatus redirect_status = + redirect_chain.IsEmpty() + ? ResourceRequestHead::RedirectStatus::kNoRedirect + : ResourceRequestHead::RedirectStatus::kFollowedRedirect; // We check the 'report-only' headers before upgrading the request (in // populateResourceRequest). We check the enforced headers here to ensure we // block things we ought to block. if (CheckCSPForRequestInternal( request_context, request_destination, url, options, - reporting_disposition, redirect_status, + reporting_disposition, url_before_redirects, redirect_status, ContentSecurityPolicy::CheckHeaderType::kCheckEnforce) == ResourceRequestBlockedReason::kCSP) { return ResourceRequestBlockedReason::kCSP; @@ -237,7 +241,7 @@ // Check for mixed content. We do this second-to-last so that when folks block // mixed content via CSP, they don't get a mixed content warning, but a CSP // warning instead. - if (ShouldBlockFetchByMixedContentCheck(request_context, redirect_status, url, + if (ShouldBlockFetchByMixedContentCheck(request_context, redirect_chain, url, reporting_disposition, resource_request.GetDevToolsId())) { return ResourceRequestBlockedReason::kMixedContent; @@ -255,7 +259,7 @@ return ResourceRequestBlockedReason::kOther; } - if (SendConversionRequestInsteadOfRedirecting(url, redirect_info, + if (SendConversionRequestInsteadOfRedirecting(url, redirect_chain, reporting_disposition)) { return ResourceRequestBlockedReason::kOther; }
diff --git a/third_party/blink/renderer/core/loader/base_fetch_context.h b/third_party/blink/renderer/core/loader/base_fetch_context.h index 44ec7a8..d9f12c5 100644 --- a/third_party/blink/renderer/core/loader/base_fetch_context.h +++ b/third_party/blink/renderer/core/loader/base_fetch_context.h
@@ -37,13 +37,14 @@ const KURL&, const ResourceLoaderOptions&, ReportingDisposition, - const base::Optional<ResourceRequest::RedirectInfo>&) const override; + const Vector<KURL>&) const override; base::Optional<ResourceRequestBlockedReason> CheckCSPForRequest( mojom::RequestContextType, network::mojom::RequestDestination request_destination, const KURL&, const ResourceLoaderOptions&, ReportingDisposition, + const KURL& url_before_redirects, ResourceRequest::RedirectStatus) const override; void Trace(Visitor*) const override; @@ -77,7 +78,7 @@ // registration endpoint. virtual bool SendConversionRequestInsteadOfRedirecting( const KURL& url, - const base::Optional<ResourceRequest::RedirectInfo>& redirect_info, + const Vector<KURL>& redirect_chain, ReportingDisposition reporting_disposition) const; virtual const ContentSecurityPolicy* GetContentSecurityPolicy() const = 0; @@ -102,7 +103,7 @@ virtual bool IsSVGImageChromeClient() const = 0; virtual bool ShouldBlockFetchByMixedContentCheck( mojom::blink::RequestContextType request_context, - ResourceRequest::RedirectStatus redirect_status, + const Vector<KURL>& redirect_chain, const KURL& url, ReportingDisposition reporting_disposition, const base::Optional<String>& devtools_id) const = 0; @@ -127,7 +128,7 @@ const KURL&, const ResourceLoaderOptions&, ReportingDisposition, - const base::Optional<ResourceRequest::RedirectInfo>& redirect_info) const; + const Vector<KURL>& redirect_chain) const; base::Optional<ResourceRequestBlockedReason> CheckCSPForRequestInternal( mojom::RequestContextType, @@ -135,7 +136,8 @@ const KURL&, const ResourceLoaderOptions&, ReportingDisposition, - ResourceRequest::RedirectStatus, + const KURL& url_before_redirects, + ResourceRequest::RedirectStatus redirect_status, ContentSecurityPolicy::CheckHeaderType) const; };
diff --git a/third_party/blink/renderer/core/loader/base_fetch_context_test.cc b/third_party/blink/renderer/core/loader/base_fetch_context_test.cc index f7d2d1a..9b3bf81a 100644 --- a/third_party/blink/renderer/core/loader/base_fetch_context_test.cc +++ b/third_party/blink/renderer/core/loader/base_fetch_context_test.cc
@@ -87,7 +87,7 @@ } bool ShouldBlockFetchByMixedContentCheck( mojom::RequestContextType, - ResourceRequest::RedirectStatus, + const Vector<KURL>&, const KURL&, ReportingDisposition, const base::Optional<String>&) const override { @@ -168,11 +168,10 @@ ResourceLoaderOptions options; - EXPECT_EQ( - ResourceRequestBlockedReason::kCSP, - fetch_context_->CanRequest(ResourceType::kScript, resource_request, url, - options, ReportingDisposition::kReport, - ResourceRequest::RedirectInfo())); + EXPECT_EQ(ResourceRequestBlockedReason::kCSP, + fetch_context_->CanRequest( + ResourceType::kScript, resource_request, url, options, + ReportingDisposition::kReport, Vector<KURL, 0>())); EXPECT_EQ(1u, policy->violation_reports_sent_.size()); } @@ -196,6 +195,7 @@ mojom::RequestContextType::SCRIPT, network::mojom::RequestDestination::kScript, url, options, ReportingDisposition::kReport, + KURL(NullURL(), "http://www.redirecting.com/"), ResourceRequest::RedirectStatus::kFollowedRedirect)); EXPECT_EQ(1u, policy->violation_reports_sent_.size()); } @@ -208,53 +208,56 @@ keepalive_request.SetRequestorOrigin(GetSecurityOrigin()); keepalive_request.SetKeepalive(true); - EXPECT_EQ(base::nullopt, - fetch_context_->CanRequest( - ResourceType::kRaw, request, url, ResourceLoaderOptions(), - ReportingDisposition::kSuppressReporting, base::nullopt)); - - EXPECT_EQ(base::nullopt, - fetch_context_->CanRequest(ResourceType::kRaw, keepalive_request, - url, ResourceLoaderOptions(), - ReportingDisposition::kSuppressReporting, - base::nullopt)); - + Vector<KURL> empty_redirect_chain; EXPECT_EQ(base::nullopt, fetch_context_->CanRequest(ResourceType::kRaw, request, url, ResourceLoaderOptions(), ReportingDisposition::kSuppressReporting, - ResourceRequest::RedirectInfo())); + empty_redirect_chain)); EXPECT_EQ(base::nullopt, fetch_context_->CanRequest(ResourceType::kRaw, keepalive_request, url, ResourceLoaderOptions(), ReportingDisposition::kSuppressReporting, - ResourceRequest::RedirectInfo())); + empty_redirect_chain)); + + Vector<KURL> redirect_chain; + redirect_chain.push_back(KURL(NullURL(), "http://www.redirecting.com/")); + EXPECT_EQ(base::nullopt, + fetch_context_->CanRequest( + ResourceType::kRaw, request, url, ResourceLoaderOptions(), + ReportingDisposition::kSuppressReporting, redirect_chain)); + + EXPECT_EQ(base::nullopt, + fetch_context_->CanRequest(ResourceType::kRaw, keepalive_request, + url, ResourceLoaderOptions(), + ReportingDisposition::kSuppressReporting, + redirect_chain)); resource_fetcher_->ClearContext(); EXPECT_EQ(ResourceRequestBlockedReason::kOther, - fetch_context_->CanRequest( - ResourceType::kRaw, request, url, ResourceLoaderOptions(), - ReportingDisposition::kSuppressReporting, base::nullopt)); + fetch_context_->CanRequest(ResourceType::kRaw, request, url, + ResourceLoaderOptions(), + ReportingDisposition::kSuppressReporting, + empty_redirect_chain)); EXPECT_EQ(ResourceRequestBlockedReason::kOther, fetch_context_->CanRequest(ResourceType::kRaw, keepalive_request, url, ResourceLoaderOptions(), ReportingDisposition::kSuppressReporting, - base::nullopt)); + empty_redirect_chain)); EXPECT_EQ(ResourceRequestBlockedReason::kOther, - fetch_context_->CanRequest(ResourceType::kRaw, request, url, - ResourceLoaderOptions(), - ReportingDisposition::kSuppressReporting, - ResourceRequest::RedirectInfo())); + fetch_context_->CanRequest( + ResourceType::kRaw, request, url, ResourceLoaderOptions(), + ReportingDisposition::kSuppressReporting, redirect_chain)); EXPECT_EQ(base::nullopt, fetch_context_->CanRequest(ResourceType::kRaw, keepalive_request, url, ResourceLoaderOptions(), ReportingDisposition::kSuppressReporting, - ResourceRequest::RedirectInfo())); + redirect_chain)); } // Test that User Agent CSS can only load images with data urls. @@ -267,22 +270,22 @@ ResourceLoaderOptions options; options.initiator_info.name = fetch_initiator_type_names::kUacss; + Vector<KURL> redirect_chain; + redirect_chain.push_back(KURL(NullURL(), "http://www.redirecting.com/")); EXPECT_EQ(ResourceRequestBlockedReason::kOther, - fetch_context_->CanRequest(ResourceType::kScript, resource_request, - test_url, options, - ReportingDisposition::kReport, - ResourceRequest::RedirectInfo())); + fetch_context_->CanRequest( + ResourceType::kScript, resource_request, test_url, options, + ReportingDisposition::kReport, redirect_chain)); EXPECT_EQ(ResourceRequestBlockedReason::kOther, - fetch_context_->CanRequest(ResourceType::kImage, resource_request, - test_url, options, - ReportingDisposition::kReport, - ResourceRequest::RedirectInfo())); + fetch_context_->CanRequest( + ResourceType::kImage, resource_request, test_url, options, + ReportingDisposition::kReport, redirect_chain)); - EXPECT_EQ(base::nullopt, fetch_context_->CanRequest( - ResourceType::kImage, resource_request, data_url, - options, ReportingDisposition::kReport, - ResourceRequest::RedirectInfo())); + EXPECT_EQ(base::nullopt, + fetch_context_->CanRequest( + ResourceType::kImage, resource_request, data_url, options, + ReportingDisposition::kReport, redirect_chain)); } // Test that User Agent CSS can bypass CSP to load embedded images. @@ -300,10 +303,12 @@ ResourceLoaderOptions options; options.initiator_info.name = fetch_initiator_type_names::kUacss; - EXPECT_EQ(base::nullopt, fetch_context_->CanRequest( - ResourceType::kImage, resource_request, data_url, - options, ReportingDisposition::kReport, - ResourceRequest::RedirectInfo())); + Vector<KURL> redirect_chain; + redirect_chain.push_back(KURL(NullURL(), "http://www.redirecting.com/")); + EXPECT_EQ(base::nullopt, + fetch_context_->CanRequest( + ResourceType::kImage, resource_request, data_url, options, + ReportingDisposition::kReport, redirect_chain)); } } // namespace blink
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h index 56bb761..b7a6afbe 100644 --- a/third_party/blink/renderer/core/loader/empty_clients.h +++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -421,7 +421,6 @@ const IntRect& transformed_frame_rect) override {} void UpdateRemoteViewportIntersection( const ViewportIntersectionState& intersection_state) override {} - void AdvanceFocus(mojom::blink::FocusType, LocalFrame* source) override {} uint32_t Print(const IntRect& rect, cc::PaintCanvas* canvas) const override { return 0; }
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.cc b/third_party/blink/renderer/core/loader/frame_fetch_context.cc index 5460b77..0adc75e 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context.cc +++ b/third_party/blink/renderer/core/loader/frame_fetch_context.cc
@@ -366,7 +366,7 @@ ResourceType resource_type) { // TODO(yhirano): Clarify which statements are actually needed when // this is called during redirect. - const bool for_redirect = request.GetRedirectInfo().has_value(); + const bool for_redirect = !request.GetRedirectChain().IsEmpty(); SetFirstPartyCookie(request); if (request.GetRequestContext() == @@ -829,7 +829,7 @@ bool FrameFetchContext::ShouldBlockFetchByMixedContentCheck( mojom::RequestContextType request_context, - ResourceRequest::RedirectStatus redirect_status, + const Vector<KURL>& redirect_chain, const KURL& url, ReportingDisposition reporting_disposition, const base::Optional<String>& devtools_id) const { @@ -837,9 +837,14 @@ // TODO(yhirano): Implement the detached case. return false; } + RedirectStatus redirect_status = redirect_chain.IsEmpty() + ? RedirectStatus::kNoRedirect + : RedirectStatus::kFollowedRedirect; + const KURL& url_before_redirects = + redirect_chain.IsEmpty() ? url : redirect_chain.front(); return MixedContentChecker::ShouldBlockFetch( - GetFrame(), request_context, redirect_status, url, devtools_id, - reporting_disposition); + GetFrame(), request_context, url_before_redirects, redirect_status, url, + devtools_id, reporting_disposition); } bool FrameFetchContext::ShouldBlockFetchAsCredentialedSubresource( @@ -1024,7 +1029,7 @@ bool FrameFetchContext::SendConversionRequestInsteadOfRedirecting( const KURL& url, - const base::Optional<ResourceRequest::RedirectInfo>& redirect_info, + const Vector<KURL>& redirect_chain, ReportingDisposition reporting_disposition) const { if (!RuntimeEnabledFeatures::ConversionMeasurementEnabled()) return false; @@ -1035,8 +1040,8 @@ LocalFrame* frame = document_->GetFrame(); DCHECK(frame); // Only register conversions pings that are redirects in the main frame. - if (!frame->IsMainFrame() || !redirect_info || - !SecurityOrigin::AreSameOrigin(url, redirect_info->previous_url)) { + if (!frame->IsMainFrame() || redirect_chain.IsEmpty() || + !SecurityOrigin::AreSameOrigin(url, redirect_chain.back())) { return false; } @@ -1106,7 +1111,7 @@ const KURL& url, const ResourceLoaderOptions& options, ReportingDisposition reporting_disposition, - const base::Optional<ResourceRequest::RedirectInfo>& redirect_info) const { + const Vector<KURL>& redirect_chain) const { if (!GetResourceFetcherProperties().IsDetached() && document_->IsFreezingInProgress() && !resource_request.GetKeepalive()) { AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( @@ -1116,7 +1121,7 @@ return ResourceRequestBlockedReason::kOther; } return BaseFetchContext::CanRequest(type, resource_request, url, options, - reporting_disposition, redirect_info); + reporting_disposition, redirect_chain); } CoreProbeSink* FrameFetchContext::Probe() const {
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.h b/third_party/blink/renderer/core/loader/frame_fetch_context.h index 4f348e5..96b571e1 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context.h +++ b/third_party/blink/renderer/core/loader/frame_fetch_context.h
@@ -75,8 +75,7 @@ const KURL& url, const ResourceLoaderOptions& options, ReportingDisposition reporting_disposition, - const base::Optional<ResourceRequest::RedirectInfo>& redirect_info) - const override; + const Vector<KURL>& redirect_chain) const override; mojom::FetchCacheMode ResourceRequestCachePolicy( const ResourceRequest&, ResourceType, @@ -112,7 +111,7 @@ bool SendConversionRequestInsteadOfRedirecting( const KURL& url, - const base::Optional<ResourceRequest::RedirectInfo>& redirect_info, + const Vector<KURL>& redirect_chain, ReportingDisposition reporting_disposition) const override; mojo::PendingReceiver<mojom::blink::WorkerTimingContainer> @@ -153,7 +152,7 @@ override; bool ShouldBlockFetchByMixedContentCheck( mojom::blink::RequestContextType request_context, - ResourceRequest::RedirectStatus redirect_status, + const Vector<KURL>& redirect_chain, const KURL& url, ReportingDisposition reporting_disposition, const base::Optional<String>& devtools_id) const override;
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc b/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc index ce8c972..fcd34d89 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc +++ b/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc
@@ -239,9 +239,9 @@ .GetSecurityOrigin()); ResourceLoaderOptions options; // DJKim - return GetFetchContext()->CanRequest(ResourceType::kImage, resource_request, - input_url, options, - reporting_disposition, base::nullopt); + return GetFetchContext()->CanRequest( + ResourceType::kImage, resource_request, input_url, options, + reporting_disposition, Vector<KURL, 0>()); } int filtered_load_callback_counter_;
diff --git a/third_party/blink/renderer/core/loader/mixed_content_checker.cc b/third_party/blink/renderer/core/loader/mixed_content_checker.cc index 53a51cb..6c1265a 100644 --- a/third_party/blink/renderer/core/loader/mixed_content_checker.cc +++ b/third_party/blink/renderer/core/loader/mixed_content_checker.cc
@@ -420,6 +420,7 @@ bool MixedContentChecker::ShouldBlockFetch( LocalFrame* frame, mojom::RequestContextType request_context, + const KURL& url_before_redirects, ResourceRequest::RedirectStatus redirect_status, const KURL& url, const base::Optional<String>& devtools_id, @@ -450,7 +451,7 @@ MixedContentChecker::Count(mixed_frame, request_context, frame); if (ContentSecurityPolicy* policy = frame->GetSecurityContext()->GetContentSecurityPolicy()) - policy->ReportMixedContent(url, redirect_status); + policy->ReportMixedContent(url_before_redirects, redirect_status); Settings* settings = mixed_frame->GetSettings(); // Use the current local frame's client; the embedder doesn't distinguish @@ -553,6 +554,7 @@ bool MixedContentChecker::ShouldBlockFetchOnWorker( const WorkerFetchContext& worker_fetch_context, mojom::RequestContextType request_context, + const KURL& url_before_redirects, ResourceRequest::RedirectStatus redirect_status, const KURL& url, ReportingDisposition reporting_disposition, @@ -567,7 +569,7 @@ worker_fetch_context.CountUsage(WebFeature::kMixedContentPresent); worker_fetch_context.CountUsage(WebFeature::kMixedContentBlockable); if (auto* policy = worker_fetch_context.GetContentSecurityPolicy()) - policy->ReportMixedContent(url, redirect_status); + policy->ReportMixedContent(url_before_redirects, redirect_status); // Blocks all mixed content request from worklets. // TODO(horo): Revise this when the spec is updated. @@ -832,6 +834,7 @@ const KURL& mixed_content_url, mojom::RequestContextType request_context, bool was_allowed, + const KURL& url_before_redirects, bool had_redirect, std::unique_ptr<SourceLocation> source_location) { // Logs to the frame console. @@ -850,7 +853,7 @@ frame->GetSecurityContext()->GetContentSecurityPolicy(); if (policy) { policy->ReportMixedContent( - mixed_content_url, + url_before_redirects, had_redirect ? ResourceRequest::RedirectStatus::kFollowedRedirect : ResourceRequest::RedirectStatus::kNoRedirect); }
diff --git a/third_party/blink/renderer/core/loader/mixed_content_checker.h b/third_party/blink/renderer/core/loader/mixed_content_checker.h index c5ad31e..cbb019b 100644 --- a/third_party/blink/renderer/core/loader/mixed_content_checker.h +++ b/third_party/blink/renderer/core/loader/mixed_content_checker.h
@@ -71,6 +71,7 @@ public: static bool ShouldBlockFetch(LocalFrame* frame, mojom::blink::RequestContextType request_context, + const KURL& url_before_redirects, ResourceRequest::RedirectStatus redirect_status, const KURL& url, const base::Optional<String>& devtools_id, @@ -79,6 +80,7 @@ static bool ShouldBlockFetchOnWorker(const WorkerFetchContext&, mojom::RequestContextType, + const KURL& url_before_redirects, ResourceRequest::RedirectStatus, const KURL&, ReportingDisposition, @@ -119,6 +121,7 @@ const KURL& mixed_content_url, mojom::RequestContextType, bool was_allowed, + const KURL& url_before_redirects, bool had_redirect, std::unique_ptr<SourceLocation>);
diff --git a/third_party/blink/renderer/core/loader/mixed_content_checker_test.cc b/third_party/blink/renderer/core/loader/mixed_content_checker_test.cc index 7a36999a..bcc41cc0 100644 --- a/third_party/blink/renderer/core/loader/mixed_content_checker_test.cc +++ b/third_party/blink/renderer/core/loader/mixed_content_checker_test.cc
@@ -205,14 +205,16 @@ // Test that a mixed content favicon is correctly blocked. EXPECT_TRUE(MixedContentChecker::ShouldBlockFetch( &dummy_page_holder->GetFrame(), mojom::RequestContextType::FAVICON, - ResourceRequest::RedirectStatus::kNoRedirect, http_favicon_url, - base::Optional<String>(), ReportingDisposition::kSuppressReporting)); + http_favicon_url, ResourceRequest::RedirectStatus::kNoRedirect, + http_favicon_url, base::Optional<String>(), + ReportingDisposition::kSuppressReporting)); // Test that a secure favicon is not blocked. EXPECT_FALSE(MixedContentChecker::ShouldBlockFetch( &dummy_page_holder->GetFrame(), mojom::RequestContextType::FAVICON, - ResourceRequest::RedirectStatus::kNoRedirect, https_favicon_url, - base::Optional<String>(), ReportingDisposition::kSuppressReporting)); + https_favicon_url, ResourceRequest::RedirectStatus::kNoRedirect, + https_favicon_url, base::Optional<String>(), + ReportingDisposition::kSuppressReporting)); } class TestFetchClientSettingsObject : public FetchClientSettingsObject {
diff --git a/third_party/blink/renderer/core/loader/ping_loader.cc b/third_party/blink/renderer/core/loader/ping_loader.cc index 181b50c9f..0d80a63 100644 --- a/third_party/blink/renderer/core/loader/ping_loader.cc +++ b/third_party/blink/renderer/core/loader/ping_loader.cc
@@ -190,7 +190,7 @@ if (!frame->GetDocument() ->GetContentSecurityPolicyForWorld() - ->AllowConnectToSource(url)) { + ->AllowConnectToSource(url, url, RedirectStatus::kNoRedirect)) { // We're simulating a network failure here, so we return 'true'. return true; }
diff --git a/third_party/blink/renderer/core/loader/threadable_loader.cc b/third_party/blink/renderer/core/loader/threadable_loader.cc index 01ac9de..6f29364 100644 --- a/third_party/blink/renderer/core/loader/threadable_loader.cc +++ b/third_party/blink/renderer/core/loader/threadable_loader.cc
@@ -682,7 +682,6 @@ ResourceRequest cross_origin_request; cross_origin_request.CopyFrom(new_request); - cross_origin_request.SetInitialUrlForResourceTiming(initial_request_url_); // Remove any headers that may have been added by the network layer that cause // access control to fail.
diff --git a/third_party/blink/renderer/core/loader/worker_fetch_context.cc b/third_party/blink/renderer/core/loader/worker_fetch_context.cc index 7d5b688..10ac7c5 100644 --- a/third_party/blink/renderer/core/loader/worker_fetch_context.cc +++ b/third_party/blink/renderer/core/loader/worker_fetch_context.cc
@@ -142,13 +142,18 @@ bool WorkerFetchContext::ShouldBlockFetchByMixedContentCheck( mojom::RequestContextType request_context, - ResourceRequest::RedirectStatus redirect_status, + const Vector<KURL>& redirect_chain, const KURL& url, ReportingDisposition reporting_disposition, const base::Optional<String>& devtools_id) const { + RedirectStatus redirect_status = redirect_chain.IsEmpty() + ? RedirectStatus::kNoRedirect + : RedirectStatus::kFollowedRedirect; + const KURL& url_before_redirects = + redirect_chain.IsEmpty() ? url : redirect_chain.front(); return MixedContentChecker::ShouldBlockFetchOnWorker( - *this, request_context, redirect_status, url, reporting_disposition, - global_scope_->IsWorkletGlobalScope()); + *this, request_context, url_before_redirects, redirect_status, url, + reporting_disposition, global_scope_->IsWorkletGlobalScope()); } bool WorkerFetchContext::ShouldBlockFetchAsCredentialedSubresource(
diff --git a/third_party/blink/renderer/core/loader/worker_fetch_context.h b/third_party/blink/renderer/core/loader/worker_fetch_context.h index af0e47a..7eef6eb 100644 --- a/third_party/blink/renderer/core/loader/worker_fetch_context.h +++ b/third_party/blink/renderer/core/loader/worker_fetch_context.h
@@ -61,7 +61,7 @@ override; bool ShouldBlockFetchByMixedContentCheck( mojom::blink::RequestContextType request_context, - ResourceRequest::RedirectStatus redirect_status, + const Vector<KURL>& redirect_chain, const KURL& url, ReportingDisposition reporting_disposition, const base::Optional<String>& devtools_id) const override;
diff --git a/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc b/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc index 93bef26..b80efde 100644 --- a/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc +++ b/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc
@@ -191,12 +191,43 @@ } void OriginTrialContext::AddToken(const String& token) { + AddTokenInternal(token, GetSecurityOrigin(), IsSecureContext(), nullptr, + false); +} + +void OriginTrialContext::AddTokenFromExternalScript( + const String& token, + const SecurityOrigin* origin) { + bool is_script_origin_secure = false; + if (origin && + RuntimeEnabledFeatures::ThirdPartyOriginTrialsEnabled(context_)) { + DVLOG(1) << "AddTokenFromExternalScript: " + << (origin ? origin->ToString() : "null"); + // Both document origin and script origin needs to be secure for third party + // origin trial token. + is_script_origin_secure = + IsSecureContext() && origin->IsPotentiallyTrustworthy(); + } else { + origin = nullptr; + } + AddTokenInternal(token, GetSecurityOrigin(), IsSecureContext(), origin, + is_script_origin_secure); +} + +void OriginTrialContext::AddTokenInternal(const String& token, + const SecurityOrigin* origin, + bool is_origin_secure, + const SecurityOrigin* script_origin, + bool is_script_origin_secure) { if (token.IsEmpty()) return; tokens_.push_back(token); - if (EnableTrialFromToken(GetSecurityOrigin(), IsSecureContext(), token)) { - // Only install pending features if the provided token is valid. Otherwise, - // there was no change to the list of enabled features. + + bool enabled = EnableTrialFromToken(origin, is_origin_secure, script_origin, + is_script_origin_secure, token); + if (enabled) { + // Only install pending features if the provided token is valid. + // Otherwise, there was no change to the list of enabled features. InitializePendingFeatures(); } }
diff --git a/third_party/blink/renderer/core/origin_trials/origin_trial_context.h b/third_party/blink/renderer/core/origin_trials/origin_trial_context.h index a178597..79d6f065 100644 --- a/third_party/blink/renderer/core/origin_trials/origin_trial_context.h +++ b/third_party/blink/renderer/core/origin_trials/origin_trial_context.h
@@ -73,6 +73,11 @@ const Vector<OriginTrialFeature>*); void AddToken(const String& token); + // Add Token injected from external script. The token may be a third-party + // token, which will be validated against the given origin of the injecting + // script. + void AddTokenFromExternalScript(const String& token, + const SecurityOrigin* origin); void AddTokens(const Vector<String>& tokens); void AddTokens(const SecurityOrigin* origin, bool is_secure, @@ -123,6 +128,14 @@ void Trace(Visitor*) const; private: + // Handle token from document origin or third party origins, initialize + // features if the token is valid. + void AddTokenInternal(const String& token, + const SecurityOrigin* origin, + bool is_origin_secure, + const SecurityOrigin* script_origin, + bool is_script_origin_secure); + // If this returns false, the trial cannot be enabled (e.g. due to it is // invalid in the browser's present configuration). bool CanEnableTrialFromName(const StringView& trial_name);
diff --git a/third_party/blink/renderer/core/origin_trials/origin_trial_context_test.cc b/third_party/blink/renderer/core/origin_trials/origin_trial_context_test.cc index 1956d87..e628dd9 100644 --- a/third_party/blink/renderer/core/origin_trials/origin_trial_context_test.cc +++ b/third_party/blink/renderer/core/origin_trials/origin_trial_context_test.cc
@@ -116,17 +116,16 @@ feature); } - bool IsFeatureEnabledForThirdPartyOrigin(OriginTrialFeature feature, - bool is_secure_script_origin) { - // There's no AddTokenFromExternalScript function so we test directly - // against EnableTrialFromToken function. - scoped_refptr<const SecurityOrigin> origin = - SecurityOrigin::CreateFromString(kFrobulateEnabledOrigin); - scoped_refptr<const SecurityOrigin> script_origin = - SecurityOrigin::CreateFromString(kFrobulateEnabledOrigin); - execution_context_->GetOriginTrialContext()->EnableTrialFromToken( - origin.get(), true, script_origin.get(), is_secure_script_origin, - kTokenPlaceholder); + bool IsFeatureEnabledForThirdPartyOrigin(const String& origin, + const String& script_origin, + OriginTrialFeature feature) { + UpdateSecurityOrigin(origin); + KURL script_url(script_origin); + scoped_refptr<const SecurityOrigin> script_security_origin = + SecurityOrigin::Create(script_url); + // Need at least one token to ensure the token validator is called. + execution_context_->GetOriginTrialContext()->AddTokenFromExternalScript( + kTokenPlaceholder, script_security_origin.get()); return execution_context_->GetOriginTrialContext()->IsFeatureEnabled( feature); } @@ -269,7 +268,8 @@ TokenValidator()->SetResponse(OriginTrialTokenStatus::kSuccess, kFrobulateTrialName, base::Time(), true); bool is_origin_enabled = IsFeatureEnabledForThirdPartyOrigin( - OriginTrialFeature::kOriginTrialsSampleAPI, true); + kFrobulateEnabledOrigin, kFrobulateEnabledOrigin, + OriginTrialFeature::kOriginTrialsSampleAPI); EXPECT_FALSE(is_origin_enabled); EXPECT_EQ(1, TokenValidator()->CallCount()); ExpectStatusUniqueMetric(OriginTrialTokenStatus::kFeatureDisabled, 1); @@ -282,20 +282,51 @@ kFrobulateThirdPartyTrialName, base::Time(), true); bool is_origin_enabled = IsFeatureEnabledForThirdPartyOrigin( - OriginTrialFeature::kOriginTrialsSampleAPIThirdParty, true); + kFrobulateEnabledOrigin, kFrobulateEnabledOrigin, + OriginTrialFeature::kOriginTrialsSampleAPIThirdParty); EXPECT_FALSE(is_origin_enabled); EXPECT_EQ(1, TokenValidator()->CallCount()); ExpectStatusUniqueMetric(OriginTrialTokenStatus::kWrongOrigin, 1); } // The feature should not be enabled if token is injected from insecure external -// script, regardless if the document is secure or not. +// script even if document origin is secure. TEST_F(OriginTrialContextTest, ThirdPartyTokenFromInsecureExternalScript) { TokenValidator()->SetResponse(OriginTrialTokenStatus::kSuccess, kFrobulateThirdPartyTrialName, base::Time(), true); bool is_origin_enabled = IsFeatureEnabledForThirdPartyOrigin( - OriginTrialFeature::kOriginTrialsSampleAPIThirdParty, false); + kFrobulateEnabledOrigin, kFrobulateEnabledOriginUnsecure, + OriginTrialFeature::kOriginTrialsSampleAPIThirdParty); + EXPECT_FALSE(is_origin_enabled); + EXPECT_EQ(1, TokenValidator()->CallCount()); + ExpectStatusUniqueMetric(OriginTrialTokenStatus::kInsecure, 1); +} + +// The feature should not be enabled if token is injected from insecure external +// script when the document origin is also insecure. +TEST_F(OriginTrialContextTest, + ThirdPartyTokenFromInsecureExternalScriptOnInsecureDocument) { + TokenValidator()->SetResponse(OriginTrialTokenStatus::kSuccess, + kFrobulateThirdPartyTrialName, base::Time(), + true); + bool is_origin_enabled = IsFeatureEnabledForThirdPartyOrigin( + kFrobulateEnabledOriginUnsecure, kFrobulateEnabledOriginUnsecure, + OriginTrialFeature::kOriginTrialsSampleAPIThirdParty); + EXPECT_FALSE(is_origin_enabled); + EXPECT_EQ(1, TokenValidator()->CallCount()); + ExpectStatusUniqueMetric(OriginTrialTokenStatus::kInsecure, 1); +} + +// The feature should not be enabled if token is injected from secure external +// script when the document is insecure. +TEST_F(OriginTrialContextTest, ThirdPartyTokenOnInsecureDocument) { + TokenValidator()->SetResponse(OriginTrialTokenStatus::kSuccess, + kFrobulateThirdPartyTrialName, base::Time(), + true); + bool is_origin_enabled = IsFeatureEnabledForThirdPartyOrigin( + kFrobulateEnabledOriginUnsecure, kFrobulateEnabledOrigin, + OriginTrialFeature::kOriginTrialsSampleAPIThirdParty); EXPECT_FALSE(is_origin_enabled); EXPECT_EQ(1, TokenValidator()->CallCount()); ExpectStatusUniqueMetric(OriginTrialTokenStatus::kInsecure, 1); @@ -309,7 +340,8 @@ kFrobulateThirdPartyTrialName, base::Time(), true); bool is_origin_enabled = IsFeatureEnabledForThirdPartyOrigin( - OriginTrialFeature::kOriginTrialsSampleAPIThirdParty, true); + kFrobulateEnabledOrigin, kFrobulateEnabledOrigin, + OriginTrialFeature::kOriginTrialsSampleAPIThirdParty); EXPECT_TRUE(is_origin_enabled); EXPECT_EQ(1, TokenValidator()->CallCount()); ExpectStatusUniqueMetric(OriginTrialTokenStatus::kSuccess, 1);
diff --git a/third_party/blink/renderer/core/paint/video_painter.cc b/third_party/blink/renderer/core/paint/video_painter.cc index b15d3ec..b7b4e462 100644 --- a/third_party/blink/renderer/core/paint/video_painter.cc +++ b/third_party/blink/renderer/core/paint/video_painter.cc
@@ -19,6 +19,10 @@ void VideoPainter::PaintReplaced(const PaintInfo& paint_info, const PhysicalOffset& paint_offset) { + if (paint_info.phase != PaintPhase::kForeground && + paint_info.phase != PaintPhase::kSelectionDragImage) + return; + WebMediaPlayer* media_player = layout_video_.MediaElement()->GetWebMediaPlayer(); bool displaying_poster = @@ -57,8 +61,9 @@ paint_info.GetGlobalPaintFlags() & kGlobalPaintFlattenCompositingLayers; bool paint_with_foreign_layer = - !displaying_poster && !force_software_video_paint && - RuntimeEnabledFeatures::CompositeAfterPaintEnabled(); + RuntimeEnabledFeatures::CompositeAfterPaintEnabled() && + paint_info.phase == PaintPhase::kForeground && !displaying_poster && + !force_software_video_paint; if (paint_with_foreign_layer) { if (cc::Layer* layer = layout_video_.MediaElement()->CcLayer()) { layer->SetBounds(gfx::Size(snapped_replaced_rect.Size()));
diff --git a/third_party/blink/renderer/core/testing/fake_remote_frame_host.cc b/third_party/blink/renderer/core/testing/fake_remote_frame_host.cc index 1c95b1af..fb7cc20 100644 --- a/third_party/blink/renderer/core/testing/fake_remote_frame_host.cc +++ b/third_party/blink/renderer/core/testing/fake_remote_frame_host.cc
@@ -36,6 +36,10 @@ void FakeRemoteFrameHost::DidChangeOpener( const base::Optional<base::UnguessableToken>& opener_frame_token) {} +void FakeRemoteFrameHost::AdvanceFocus( + blink::mojom::FocusType focus_type, + const base::UnguessableToken& source_frame_token) {} + void FakeRemoteFrameHost::BindFrameHostReceiver( mojo::ScopedInterfaceEndpointHandle handle) { receiver_.Bind(mojo::PendingAssociatedReceiver<mojom::blink::RemoteFrameHost>(
diff --git a/third_party/blink/renderer/core/testing/fake_remote_frame_host.h b/third_party/blink/renderer/core/testing/fake_remote_frame_host.h index dec69595..2f39ae6a 100644 --- a/third_party/blink/renderer/core/testing/fake_remote_frame_host.h +++ b/third_party/blink/renderer/core/testing/fake_remote_frame_host.h
@@ -33,6 +33,8 @@ void SetIsInert(bool inert) override; void DidChangeOpener( const base::Optional<base::UnguessableToken>& opener_frame) override; + void AdvanceFocus(blink::mojom::FocusType focus_type, + const base::UnguessableToken& source_frame_token) override; private: void BindFrameHostReceiver(mojo::ScopedInterfaceEndpointHandle handle);
diff --git a/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc b/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc index 66e6f5ec0..ba75f12 100644 --- a/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc +++ b/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc
@@ -119,16 +119,19 @@ // The "script-src 'self'" directive allows this. EXPECT_TRUE(csp->AllowScriptFromSource( - global_scope_->Url(), String(), IntegrityMetadataSet(), kParserInserted)); + global_scope_->Url(), String(), IntegrityMetadataSet(), kParserInserted, + global_scope_->Url(), RedirectStatus::kNoRedirect)); // The "script-src https://allowed.example.com" should allow this. - EXPECT_TRUE(csp->AllowScriptFromSource(KURL("https://allowed.example.com"), - String(), IntegrityMetadataSet(), - kParserInserted)); + EXPECT_TRUE(csp->AllowScriptFromSource( + KURL("https://allowed.example.com"), String(), IntegrityMetadataSet(), + kParserInserted, KURL("https://allowed.example.com"), + RedirectStatus::kNoRedirect)); EXPECT_FALSE(csp->AllowScriptFromSource( KURL("https://disallowed.example.com"), String(), IntegrityMetadataSet(), - kParserInserted)); + kParserInserted, KURL("https://disallowed.example.com"), + RedirectStatus::kNoRedirect)); } TEST_F(MainThreadWorkletTest, UseCounter) {
diff --git a/third_party/blink/renderer/core/workers/threaded_worklet_test.cc b/third_party/blink/renderer/core/workers/threaded_worklet_test.cc index d3d601d..ed970bc 100644 --- a/third_party/blink/renderer/core/workers/threaded_worklet_test.cc +++ b/third_party/blink/renderer/core/workers/threaded_worklet_test.cc
@@ -106,18 +106,20 @@ ContentSecurityPolicy* csp = GlobalScope()->GetContentSecurityPolicy(); // The "script-src 'self'" directive allows this. - EXPECT_TRUE(csp->AllowScriptFromSource(GlobalScope()->Url(), String(), - IntegrityMetadataSet(), - kParserInserted)); + EXPECT_TRUE(csp->AllowScriptFromSource( + GlobalScope()->Url(), String(), IntegrityMetadataSet(), kParserInserted, + GlobalScope()->Url(), RedirectStatus::kNoRedirect)); // The "script-src https://allowed.example.com" should allow this. - EXPECT_TRUE(csp->AllowScriptFromSource(KURL("https://allowed.example.com"), - String(), IntegrityMetadataSet(), - kParserInserted)); + EXPECT_TRUE(csp->AllowScriptFromSource( + KURL("https://allowed.example.com"), String(), IntegrityMetadataSet(), + kParserInserted, KURL("https://allowed.example.com"), + RedirectStatus::kNoRedirect)); EXPECT_FALSE(csp->AllowScriptFromSource( KURL("https://disallowed.example.com"), String(), - IntegrityMetadataSet(), kParserInserted)); + IntegrityMetadataSet(), kParserInserted, + KURL("https://disallowed.example.com"), RedirectStatus::kNoRedirect)); PostCrossThreadTask(*GetParentTaskRunnerForTesting(), FROM_HERE, CrossThreadBindOnce(&test::ExitRunLoop));
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.cc b/third_party/blink/renderer/core/workers/worker_global_scope.cc index 5c64378..4c20b7d4 100644 --- a/third_party/blink/renderer/core/workers/worker_global_scope.cc +++ b/third_party/blink/renderer/core/workers/worker_global_scope.cc
@@ -253,7 +253,8 @@ return; } if (!GetContentSecurityPolicy()->AllowScriptFromSource( - url, AtomicString(), IntegrityMetadataSet(), kNotParserInserted)) { + url, AtomicString(), IntegrityMetadataSet(), kNotParserInserted, + url, RedirectStatus::kNoRedirect)) { exception_state.ThrowDOMException( DOMExceptionCode::kNetworkError, "The script at '" + url.ElidedString() + "' failed to load.");
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc index d67d8d6..4166fe0a 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc
@@ -68,7 +68,8 @@ bool ShouldBlockDueToCSP(ExecutionContext* execution_context, const KURL& request_url) { return !execution_context->GetContentSecurityPolicyForWorld() - ->AllowConnectToSource(request_url); + ->AllowConnectToSource(request_url, request_url, + RedirectStatus::kNoRedirect); } bool ShouldBlockPort(const KURL& request_url) {
diff --git a/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc b/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc index d3c0145..4d3666b 100644 --- a/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc +++ b/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc
@@ -239,10 +239,10 @@ void RealtimeAudioDestinationHandler::SetDetectSilenceIfNecessary( bool has_automatic_pull_nodes) { - // When there is one or more automatic pull nodes, and the input is not - // connected, the silence detection should be turned off. + // When there is no automatic pull nodes, or the destination has an active + // input connection, the silence detection should be turned on. bool needs_silence_detection = - has_automatic_pull_nodes && !Input(0).IsConnected(); + !has_automatic_pull_nodes || Input(0).IsConnected(); // Post a cross-thread task only when the detecting condition has changed. if (is_detecting_silence_ != needs_silence_detection) {
diff --git a/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.h b/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.h index dc68c087..a0a3bae 100644 --- a/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.h +++ b/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.h
@@ -134,8 +134,9 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - // The current condition of silence detection. - bool is_detecting_silence_ = false; + // Represents the current condition of silence detection. By default, the + // silence detection is active. + bool is_detecting_silence_ = true; }; // -----------------------------------------------------------------------------
diff --git a/third_party/blink/renderer/modules/websockets/websocket_common.cc b/third_party/blink/renderer/modules/websockets/websocket_common.cc index a416644..4cd6d80 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_common.cc +++ b/third_party/blink/renderer/modules/websockets/websocket_common.cc
@@ -88,7 +88,7 @@ } if (!execution_context->GetContentSecurityPolicyForWorld() - ->AllowConnectToSource(url_)) { + ->AllowConnectToSource(url_, url_, RedirectStatus::kNoRedirect)) { state_ = kClosed; return ConnectResult::kAsyncError;
diff --git a/third_party/blink/renderer/modules/webtransport/quic_transport.cc b/third_party/blink/renderer/modules/webtransport/quic_transport.cc index 968a86a..b256692 100644 --- a/third_party/blink/renderer/modules/webtransport/quic_transport.cc +++ b/third_party/blink/renderer/modules/webtransport/quic_transport.cc
@@ -626,7 +626,7 @@ auto* execution_context = GetExecutionContext(); if (!execution_context->GetContentSecurityPolicyForWorld() - ->AllowConnectToSource(url_)) { + ->AllowConnectToSource(url_, url_, RedirectStatus::kNoRedirect)) { // TODO(ricea): This error should probably be asynchronous like it is for // WebSockets and fetch. exception_state.ThrowSecurityError(
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc index f07dcdab..6d3aa04 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
@@ -463,7 +463,7 @@ // flushing once to see if that releases the read refs. We can avoid a copy // by queuing this work before writing to this resource. if (is_accelerated_) - surface_->flush(); + surface_->flushAndSubmit(); return !resource_->HasOneRef(); } @@ -505,7 +505,7 @@ // SkSurface here. if (IsGpuContextLost()) return; - GetGrContext()->flush(); + GetGrContext()->flushAndSubmit(); } void EnsureWriteAccess() { @@ -1332,7 +1332,7 @@ sk_sp<cc::PaintRecord> last_recording) { EnsureSkiaCanvas(); skia_canvas_->drawPicture(std::move(last_recording)); - GetSkSurface()->flush(); + GetSkSurface()->flushAndSubmit(); } bool CanvasResourceProvider::IsGpuContextLost() const {
diff --git a/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc b/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc index 8f7fee0..81ba146e 100644 --- a/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc +++ b/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc
@@ -192,9 +192,7 @@ 1, { {gfx::Point(0, 0), SkColorSetARGB(0, 0, 0, 0)}, - // If the color space is sRGB, pre-multiplied red should be 187.84. - // http://www.color.org/sRGB.pdf - {gfx::Point(1, 1), SkColorSetARGB(128, 188, 0, 0)}, + {gfx::Point(1, 1), SkColorSetARGB(128, 255, 0, 0)}, {gfx::Point(2, 2), SkColorSetARGB(255, 255, 0, 0)}, }}, #endif @@ -265,9 +263,7 @@ 1, { {gfx::Point(0, 0), SkColorSetARGB(0, 0, 0, 0)}, - // If the color space is sRGB, pre-multiplied red should be 187.84. - // http://www.color.org/sRGB.pdf - {gfx::Point(1, 1), SkColorSetARGB(128, 188, 0, 0)}, + {gfx::Point(1, 1), SkColorSetARGB(128, 255, 0, 0)}, {gfx::Point(2, 2), SkColorSetARGB(255, 255, 0, 0)}, }}, #endif @@ -374,9 +370,7 @@ 1, { {gfx::Point(0, 0), SkColorSetARGB(0, 0, 0, 0)}, - // If the color space is sRGB, pre-multiplied red should be 187.84. - // http://www.color.org/sRGB.pdf - {gfx::Point(1, 1), SkColorSetARGB(128, 188, 0, 0)}, + {gfx::Point(1, 1), SkColorSetARGB(128, 255, 0, 0)}, {gfx::Point(2, 2), SkColorSetARGB(255, 255, 0, 0)}, }}, #endif @@ -423,7 +417,7 @@ ColorType::kRgb, ImageDecoder::kLosslessFormat, ImageDecoder::kAlphaNotPremultiplied, - ColorBehavior::Tag(), + ColorBehavior::Ignore(), 1, { {gfx::Point(0, 0), SkColorSetARGB(255, 0, 0, 255)},
diff --git a/third_party/blink/renderer/platform/image-decoders/image_frame.cc b/third_party/blink/renderer/platform/image-decoders/image_frame.cc index 600c03c..c90797b 100644 --- a/third_party/blink/renderer/platform/image-decoders/image_frame.cc +++ b/third_party/blink/renderer/platform/image-decoders/image_frame.cc
@@ -194,7 +194,7 @@ SkImage::MakeFromRaster(src_pixmap, nullptr, nullptr); surface->getCanvas()->drawImage(src_image, 0, 0); - surface->flush(); + surface->flushAndSubmit(); } void ImageFrame::BlendRGBARawF16Buffer(PixelDataF16* dst,
diff --git a/third_party/blink/renderer/platform/loader/fetch/fetch_context.h b/third_party/blink/renderer/platform/loader/fetch/fetch_context.h index 8f7f1a13..a55f9f8 100644 --- a/third_party/blink/renderer/platform/loader/fetch/fetch_context.h +++ b/third_party/blink/renderer/platform/loader/fetch/fetch_context.h
@@ -114,8 +114,7 @@ const KURL&, const ResourceLoaderOptions&, ReportingDisposition, - const base::Optional<ResourceRequest::RedirectInfo>& redirect_info) - const { + const Vector<KURL>& redirect_chain) const { return ResourceRequestBlockedReason::kOther; } virtual base::Optional<ResourceRequestBlockedReason> CheckCSPForRequest( @@ -124,6 +123,7 @@ const KURL&, const ResourceLoaderOptions&, ReportingDisposition, + const KURL& url_before_redirects, ResourceRequest::RedirectStatus) const { return ResourceRequestBlockedReason::kOther; }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc index 91d9c371..15ba1fa321 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -314,10 +314,7 @@ scoped_refptr<ResourceTimingInfo> info, base::TimeTicks response_end, int64_t encoded_data_length) { - info->SetInitialURL( - resource->GetResourceRequest().GetInitialUrlForResourceTiming().IsNull() - ? resource->GetResourceRequest().Url() - : resource->GetResourceRequest().GetInitialUrlForResourceTiming()); + info->SetInitialURL(resource->Url()); info->SetFinalResponse(resource->GetResponse()); info->SetLoadResponseEnd(response_end); // encodedDataLength == -1 means "not available". @@ -647,12 +644,9 @@ scoped_refptr<ResourceTimingInfo> info = ResourceTimingInfo::Create( resource->Options().initiator_info.name, base::TimeTicks::Now(), request.GetRequestContext(), request.GetRequestDestination()); - // TODO(yoav): GetInitialUrlForResourceTiming() is only needed until + // TODO(yoav): GetOriginalURLBeforeRedirects() is only needed until // Out-of-Blink CORS lands: https://crbug.com/736308 - info->SetInitialURL( - resource->GetResourceRequest().GetInitialUrlForResourceTiming().IsNull() - ? resource->GetResourceRequest().Url() - : resource->GetResourceRequest().GetInitialUrlForResourceTiming()); + info->SetInitialURL(resource->Url()); ResourceResponse final_response = resource->GetResponse(); final_response.SetResourceLoadTiming(nullptr); info->SetFinalResponse(final_response); @@ -837,22 +831,28 @@ ? ReportingDisposition::kSuppressReporting : ReportingDisposition::kReport; - // Note that resource_request.GetRedirectInfo() may non-null here since e.g. - // ThreadableLoader may create a new Resource from a ResourceRequest that + // Note that resource_request.GetRedirectChain() may be non-empty here since + // e.g. ThreadableLoader may create a new Resource from a ResourceRequest that // originates from the ResourceRequest passed to the redirect handling // callback. // Before modifying the request for CSP, evaluate report-only headers. This // allows site owners to learn about requests that are being modified // (e.g. mixed content that is being upgraded by upgrade-insecure-requests). + const Vector<KURL>& redirect_chain = resource_request.GetRedirectChain(); + const KURL& url_before_redirects = + redirect_chain.IsEmpty() ? params.Url() : redirect_chain.front(); + const ResourceRequestHead::RedirectStatus redirect_status = + redirect_chain.IsEmpty() + ? ResourceRequestHead::RedirectStatus::kNoRedirect + : ResourceRequestHead::RedirectStatus::kFollowedRedirect; Context().CheckCSPForRequest( resource_request.GetRequestContext(), resource_request.GetRequestDestination(), MemoryCache::RemoveFragmentIdentifierIfNeeded(params.Url()), options, reporting_disposition, - resource_request.GetRedirectInfo() - ? ResourceRequest::RedirectStatus::kFollowedRedirect - : ResourceRequest::RedirectStatus::kNoRedirect); + MemoryCache::RemoveFragmentIdentifierIfNeeded(url_before_redirects), + redirect_status); // This may modify params.Url() (via the resource_request argument). Context().PopulateResourceRequest( @@ -914,7 +914,7 @@ base::Optional<ResourceRequestBlockedReason> blocked_reason = Context().CanRequest(resource_type, resource_request, url, options, reporting_disposition, - resource_request.GetRedirectInfo()); + resource_request.GetRedirectChain()); if (Context().CalculateIfAdSubresource(resource_request, resource_type, options.initiator_info)) @@ -2085,7 +2085,7 @@ Context().CanRequest(resource->GetType(), last_resource_request, last_resource_request.Url(), params.Options(), ReportingDisposition::kReport, - last_resource_request.GetRedirectInfo()); + last_resource_request.GetRedirectChain()); DidLoadResourceFromMemoryCache(resource, params.GetResourceRequest(), false /* is_static_data */); }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc index d7d1bfebf..14b6031d 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -749,6 +749,8 @@ const ResourceResponse& redirect_response( passed_redirect_response.ToResourceResponse()); + const KURL& url_before_redirects = initial_request.Url(); + if (!IsManualRedirectFetchRequest(initial_request)) { bool unused_preload = resource_->IsUnusedPreload(); @@ -761,13 +763,13 @@ // ensure that violations are sent. Context().CheckCSPForRequest( request_context, request_destination, new_url, options, - reporting_disposition, + reporting_disposition, url_before_redirects, ResourceRequest::RedirectStatus::kFollowedRedirect); base::Optional<ResourceRequestBlockedReason> blocked_reason = Context().CanRequest(resource_type, *new_request, new_url, options, reporting_disposition, - new_request->GetRedirectInfo()); + new_request->GetRedirectChain()); if (Context().CalculateIfAdSubresource(*new_request, resource_type, options.initiator_info)) @@ -1042,18 +1044,19 @@ // pre-request checks, and consider running the checks regardless of service // worker interception. const KURL& response_url = response.ResponseUrl(); + Vector<KURL> redirect_chain = request.GetRedirectChain(); + redirect_chain.push_back(request.Url()); // CanRequest() below only checks enforced policies: check report-only // here to ensure violations are sent. Context().CheckCSPForRequest( request_context, request_destination, response_url, options, - ReportingDisposition::kReport, + ReportingDisposition::kReport, redirect_chain.front(), ResourceRequest::RedirectStatus::kFollowedRedirect); base::Optional<ResourceRequestBlockedReason> blocked_reason = Context().CanRequest(resource_type, ResourceRequest(initial_request), response_url, options, - ReportingDisposition::kReport, - ResourceRequest::RedirectInfo()); + ReportingDisposition::kReport, redirect_chain); if (blocked_reason) { HandleError(ResourceError::CancelledDueToAccessCheckError( response_url, blocked_reason.value()));
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc index 0ee5c7d..776e195 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
@@ -76,8 +76,7 @@ referrer_policy_(network::mojom::ReferrerPolicy::kDefault), is_external_request_(false), cors_preflight_policy_( - network::mojom::CorsPreflightPolicy::kConsiderPreflight), - redirect_info_(base::nullopt) {} + network::mojom::CorsPreflightPolicy::kConsiderPreflight) {} ResourceRequestHead::ResourceRequestHead(const ResourceRequestHead&) = default; @@ -155,7 +154,8 @@ request->SetReferrerString(referrer); request->SetReferrerPolicy(new_referrer_policy); request->SetSkipServiceWorker(skip_service_worker); - request->SetRedirectInfo(RedirectInfo(Url())); + request->redirect_chain_ = GetRedirectChain(); + request->redirect_chain_.push_back(Url()); // Copy from parameters for |this|. request->SetDownloadToBlob(DownloadToBlob()); @@ -197,14 +197,6 @@ url_ = url; } -const KURL& ResourceRequestHead::GetInitialUrlForResourceTiming() const { - return initial_url_for_resource_timing_; -} - -void ResourceRequestHead::SetInitialUrlForResourceTiming(const KURL& url) { - initial_url_for_resource_timing_ = url; -} - void ResourceRequestHead::RemoveUserAndPassFromURL() { if (url_.User().IsEmpty() && url_.Pass().IsEmpty()) return;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.h b/third_party/blink/renderer/platform/loader/fetch/resource_request.h index 542981b..ab8037c 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_request.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.h
@@ -64,16 +64,10 @@ DISALLOW_NEW(); public: - enum class RedirectStatus : uint8_t { kFollowedRedirect, kNoRedirect }; - - struct RedirectInfo { - // Previous url in the redirect chain. - KURL previous_url; - - RedirectInfo() = default; - explicit RedirectInfo(const KURL& previous_url) - : previous_url(previous_url) {} - }; + enum class RedirectStatus : uint8_t { + kFollowedRedirect, + kNoRedirect + }; // TO REMOVE ResourceRequestHead(); explicit ResourceRequestHead(const KURL&); @@ -101,14 +95,6 @@ const KURL& Url() const; void SetUrl(const KURL&); - // ThreadableLoader sometimes breaks redirect chains into separate Resource - // and ResourceRequests. The ResourceTiming API needs the initial URL for the - // name attribute of PerformanceResourceTiming entries. This property - // remembers the initial URL for that purpose. Note that it can return a null - // URL. In that case, use Url() instead. - const KURL& GetInitialUrlForResourceTiming() const; - void SetInitialUrlForResourceTiming(const KURL&); - void RemoveUserAndPassFromURL(); mojom::FetchCacheMode GetCacheMode() const; @@ -344,10 +330,7 @@ cors_preflight_policy_ = policy; } - void SetRedirectInfo(const RedirectInfo& info) { redirect_info_ = info; } - const base::Optional<RedirectInfo>& GetRedirectInfo() const { - return redirect_info_; - } + const Vector<KURL>& GetRedirectChain() const { return redirect_chain_; } void SetSuggestedFilename(const base::Optional<String>& suggested_filename) { suggested_filename_ = suggested_filename; @@ -472,9 +455,6 @@ bool NeedsHTTPOrigin() const; KURL url_; - // TODO(yoav): initial_url_for_resource_timing_ is a stop-gap only needed - // until Out-of-Blink CORS lands: https://crbug.com/736308 - KURL initial_url_for_resource_timing_; // base::TimeDelta::Max() represents the default timeout on platforms that // have one. base::TimeDelta timeout_interval_; @@ -515,7 +495,7 @@ network::mojom::ReferrerPolicy referrer_policy_; bool is_external_request_; network::mojom::CorsPreflightPolicy cors_preflight_policy_; - base::Optional<RedirectInfo> redirect_info_; + Vector<KURL> redirect_chain_; base::Optional<network::mojom::blink::TrustTokenParams> trust_token_params_; base::Optional<String> suggested_filename_;
diff --git a/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h b/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h index 09146d1..471ae6f 100644 --- a/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h +++ b/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h
@@ -40,8 +40,7 @@ const KURL&, const ResourceLoaderOptions&, ReportingDisposition, - const base::Optional<ResourceRequest::RedirectInfo>& redirect_info) - const override { + const Vector<KURL>& redirect_chain) const override { return base::nullopt; } base::Optional<ResourceRequestBlockedReason> CheckCSPForRequest( @@ -50,6 +49,7 @@ const KURL& url, const ResourceLoaderOptions& options, ReportingDisposition reporting_disposition, + const KURL& url_before_redirects, ResourceRequest::RedirectStatus redirect_status) const override { return base::nullopt; }
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 01c5ae4..80fb963 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1082,10 +1082,6 @@ name: "MediaQueryNavigationControls", }, { - name: "MediaQueryShape", - status: "experimental", - }, - { name: "MediaSession", status: "stable", }, @@ -1740,6 +1736,10 @@ status: "stable", }, { + name: "ThirdPartyOriginTrials", + status: "test", + }, + { name: "TimerThrottlingForBackgroundTabs", status: "stable", },
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py index 2bb7f07..7e4242c 100755 --- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py +++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -408,6 +408,9 @@ # HTTP status codes 'net::HTTP_.+', + # For ConnectionInfo enumeration + 'net::HttpResponseInfo', + # Network service. 'network::.+', @@ -543,7 +546,9 @@ ], }, { - 'paths': ['third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc'], + 'paths': [ + 'third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc' + ], 'allowed': [ 'gpu::SHARED_IMAGE_USAGE_DISPLAY', 'gpu::SHARED_IMAGE_USAGE_SCANOUT',
diff --git a/third_party/blink/web_tests/FlagExpectations/composite-after-paint b/third_party/blink/web_tests/FlagExpectations/composite-after-paint index abc7a33..5256720 100644 --- a/third_party/blink/web_tests/FlagExpectations/composite-after-paint +++ b/third_party/blink/web_tests/FlagExpectations/composite-after-paint
@@ -64,7 +64,6 @@ printing/webgl-repeated-printing.html [ Failure ] transforms/3d/general/background-visibility-layers.html [ Failure ] -virtual/forced-high-contrast-colors/fast/css/forced-colors-mode/forced-colors-mode-22.html [ Crash ] # Raster invalidation doesn't work for huge layers. paint/invalidation/raster-under-invalidation-checking.html [ Failure ]
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng index f682233..f50293d 100644 --- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng +++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -64,6 +64,8 @@ crbug.com/998423 external/wpt/css/css-multicol/with-custom-layout-on-same-element.https.html [ Skip ] ### external/wpt/css/css-position/ +crbug.com/591099 external/wpt/css/css-position/position-absolute-center-003.html [ Failure ] +crbug.com/591099 external/wpt/css/css-position/position-absolute-center-004.html [ Failure ] crbug.com/591099 external/wpt/css/css-position/position-absolute-crash-chrome-006.html [ Crash ] crbug.com/591099 external/wpt/css/css-position/position-absolute-dynamic-overflow-002.html [ Failure ]
diff --git a/third_party/blink/web_tests/MSANExpectations b/third_party/blink/web_tests/MSANExpectations index b9e5ff8..e81c8d1 100644 --- a/third_party/blink/web_tests/MSANExpectations +++ b/third_party/blink/web_tests/MSANExpectations
@@ -82,9 +82,6 @@ crbug.com/902685 [ Linux ] http/tests/devtools/isolated-code-cache/same-origin-test.js [ Pass Timeout ] crbug.com/902685 [ Linux ] http/tests/devtools/isolated-code-cache/cross-origin-test.js [ Pass Timeout ] -# Timing out consistenly on WebKit Linux Trusty MSAN -crbug.com/824455 [ Linux ] external/wpt/webaudio/idlharness.https.html [ Skip ] - # Memory allocation hooks are disabled on ASAN/MSAN crbug.com/803276 inspector-protocol/memory/sampling-native-profile.js [ Skip ] crbug.com/803276 inspector-protocol/memory/sampling-native-snapshot.js [ Skip ] @@ -100,91 +97,10 @@ crbug.com/856601 [ Linux ] http/tests/devtools/elements/styles-4/styles-inline-element-style-changes-should-not-force-style-recalc.js [ Pass Timeout ] crbug.com/856601 [ Linux ] external/wpt/event-timing/retrievability.html [ Pass Timeout ] -# Slow idlharness.js tests on MSAN -crbug.com/856601 [ Linux ] external/wpt/BackgroundSync/interfaces.https.any.html [ Timeout Pass ] -crbug.com/856601 [ Linux ] external/wpt/FileAPI/idlharness.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/FileAPI/idlharness.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/IndexedDB/idlharness.any.sharedworker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/IndexedDB/idlharness.any.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/IndexedDB/idlharness.https.any.serviceworker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/IndexedDB/interfaces.any.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/appmanifest/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/bluetooth/idl/idlharness.tentative.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/cookie-store/idlharness.tentative.https.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/css/css-animations/idlharness.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/css/css-font-loading/idlharness.https.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/css/css-paint-api/idlharness.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/css/css-typed-om/interfaces.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/css/cssom-view/interfaces.html [ Pass Timeout ] +# Flaky-timeout on MSAN; incorrectly attributed to crbug.com/856601 crbug.com/856601 [ Linux ] external/wpt/dom/nodes/Element-classlist.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/encrypted-media/idlharness.https.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/fetch/cors-rfc1918/idlharness.tentative.any.sharedworker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/fetch/cors-rfc1918/idlharness.tentative.any.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/gamepad/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/hr-time/idlharness.any.sharedworker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/media-capabilities/idlharness.any.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/mediacapture-image/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/mediacapture-streams/idlharness.https.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/netinfo/idlharness.any.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/notifications/idlharness.https.any.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/notifications/idlharness.https.any.serviceworker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/origin-policy/idlharness.any.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/origin-policy/idlharness.any.serviceworker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/origin-policy/idlharness.any.sharedworker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/origin-policy/idlharness.any.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/permissions/interfaces.any.worker.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/pointerevents/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/presentation-api/controlling-ua/idlharness.https.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/push-api/idlharness.https.any.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/push-api/idlharness.https.any.serviceworker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/push-api/idlharness.https.any.sharedworker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/push-api/idlharness.https.any.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/remote-playback/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/resource-timing/idlharness.any.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/resource-timing/idlharness.any.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/screen-capture/idlharness.https.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/screen-orientation/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/selection/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/service-workers/service-worker/idlharness-sw.https.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/speech-api/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/subresource-integrity/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/svg/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/touch-events/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/screen-wake-lock/idlharness.https.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/webstorage/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaDevices-IDL-enumerateDevices.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/fetch/api/idl.any.sharedworker.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/fetch/cors-rfc1918/idlharness.tentative.https.any.serviceworker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/media-capabilities/idlharness.any.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/orientation-event/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/pointerlock/interfaces.window.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/bluetooth/idl/idlharness.tentative.https.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/css/css-pseudo/idlharness.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/hr-time/idlharness.any.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/media-source/idlharness.any.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/page-visibility/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/css/filter-effects/interfaces.any.html [ Timeout Pass ] -crbug.com/856601 [ Linux ] external/wpt/webxr/idlharness.https.window.html [ Skip ] crbug.com/856601 [ Linux ] fast/js/toString-stack-overflow.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/css/css-masking/idlharness.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/css/css-transitions/idlharness.html [ Skip ] crbug.com/856601 [ Linux ] external/wpt/import-maps/fallback.sub.tentative.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/notifications/idlharness.https.any.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/sms/idlharness.https.any.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/screen-wake-lock/idlharness.https.any.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/trusted-types/idlharness.tentative.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/trusted-types/idlharness.tentative.https.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/hr-time/idlharness.any.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/media-playback-quality/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/native-file-system/idlharness.https.any.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/native-file-system/idlharness.https.any.worker.html [ Skip ] - -# Disabled by sheriff due to repeated flakes -crbug.com/873045 [ Linux ] external/wpt/WebCryptoAPI/idlharness.https.any.worker.html [ Skip ] -crbug.com/873045 [ Linux ] external/wpt/picture-in-picture/idlharness.window.html [ Skip ] -# Also flaking according to crbug.com/873045 but mentioned in existing entries above: -# external/wpt/notifications/idlharness.https.any.worker.html -# external/wpt/xhr/idlharness.any.worker.html # Disabled by sheriff due to test crash crbug.com/896068 [ Linux ] webaudio/AudioBuffer/huge-buffer.html [ Crash ] @@ -194,44 +110,15 @@ crbug.com/856601 [ Linux ] http/tests/devtools/elements/elements-save-to-temp-var.js [ Pass Timeout ] # Sheriff 2018-12-13 -crbug.com/914900 [ Linux ] external/wpt/content-security-policy/embedded-enforcement/idlharness.window.html [ Skip ] -crbug.com/914900 [ Linux ] external/wpt/credential-management/idlharness.https.window.html [ Skip ] -crbug.com/914900 [ Linux ] external/wpt/fetch/api/idl.any.worker.html [ Pass Timeout ] -crbug.com/914900 [ Linux ] external/wpt/secure-contexts/idlharness.any.worker.html [ Skip ] crbug.com/914900 [ Linux ] http/tests/devtools/network/preview-searchable.js [ Pass Timeout ] # Sheriff 2019-01-28 crbug.com/925600 [ Linux ] external/wpt/webrtc-quic/RTCQuicStream.https.html [ Pass Timeout ] # Sheriff 2019-02-13 -crbug.com/931660 [ Linux ] external/wpt/payment-handler/idlharness.https.any.sharedworker.html [ Skip ] -crbug.com/931660 [ Linux ] external/wpt/trusted-types/idlharness.window.html [ Skip ] crbug.com/931660 [ Linux ] fast/history/replacestate-nocrash.html [ Pass Timeout ] -# Sheriff 2019-02-18 -crbug.com/856601 [ Linux ] external/wpt/fetch/api/idl.any.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/fetch/cors-rfc1918/idlharness.tentative.any.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/secure-contexts/idlharness.any.sharedworker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/BackgroundSync/interfaces.https.any.worker.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/animation-worklet/idlharness.any.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/fullscreen/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/payment-handler/idlharness.https.any.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/payment-handler/idlharness.https.any.serviceworker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/payment-request/idlharness.https.window.html [ Skip ] - -# Sheriff 2019-02-22 -crbug.com/929122 [ Linux ] external/wpt/html/dom/interfaces.worker.html [ Timeout ] - -# Sheriff 2019-05-21 -crbug.com/856601 [ Linux ] external/wpt/notifications/idlharness.https.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/fetch/cors-rfc1918/idlharness.tentative.any.serviceworker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/notifications/idlharness.https.any.sharedworker.html [ Skip ] - -# Sheriff 2019-06-05 -crbug.com/856601 [ Linux ] external/wpt/orientation-event/idlharness.https.window.html [ Skip ] - # Sheriff 2019-06-27 -crbug.com/856601 [ Linux ] external/wpt/IndexedDB/idlharness.any.serviceworker.html [ Skip ] crbug.com/856601 [ Linux ] external/wpt/IndexedDB/nested-cloning-large-multiple.any.html [ Pass Timeout ] crbug.com/856601 [ Linux ] external/wpt/IndexedDB/nested-cloning-large-multiple.any.serviceworker.html [ Pass Timeout ] crbug.com/856601 [ Linux ] external/wpt/IndexedDB/nested-cloning-large-multiple.any.sharedworker.html [ Pass Timeout ] @@ -241,128 +128,31 @@ crbug.com/856601 [ Linux ] external/wpt/IndexedDB/nested-cloning-large.any.sharedworker.html [ Pass Timeout ] crbug.com/856601 [ Linux ] external/wpt/IndexedDB/nested-cloning-large.any.worker.html [ Pass Timeout ] crbug.com/856601 [ Linux ] external/wpt/IndexedDB/nested-cloning-small.any.serviceworker.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/animation-worklet/idlharness.any.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/audio-output/idlharness.https.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/background-fetch/idlharness.https.any.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/background-fetch/idlharness.https.any.sharedworker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/css/cssom/interfaces.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/css/filter-effects/interfaces.any.worker.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/feature-policy/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/fetch/api/idl.any.serviceworker.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/idle-detection/idlharness.https.any.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/mediacapture-record/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/netinfo/idlharness.any.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/sms/idlharness.https.any.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/storage/idlharness.https.any.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/web-locks/idlharness.tentative.https.any.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/webmidi/idlharness.https.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/webrtc/idlharness.https.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/webvtt/api/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/xhr/idlharness.any.worker.html [ Skip ] crbug.com/856601 [ Linux ] http/tests/devtools/a11y-axe-core/console/console-a11y-test.js [ Pass Timeout ] crbug.com/856601 [ Linux ] http/tests/devtools/a11y-axe-core/network/network-condition-a11y-test.js [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/webrtc-identity/idlharness.https.window.html [ Skip ] # Sheriff 2019-06-28 -crbug.com/856601 [ Linux ] external/wpt/battery-status/battery-interface-idlharness.https.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/hr-time/idlharness.any.serviceworker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/mediacapture-fromelement/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/permissions/interfaces.any.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/requestidlecallback/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/webdriver/tests/interface.html [ Pass Timeout ] crbug.com/856601 [ Linux ] http/tests/devtools/a11y-axe-core/security/security-origin-a11y-test.js [ Pass Timeout ] crbug.com/856601 [ Linux ] http/tests/devtools/indexeddb/live-update-indexeddb-content.js [ Pass Timeout ] crbug.com/856601 [ Linux ] http/tests/devtools/indexeddb/live-update-indexeddb-list.js [ Pass Timeout ] -# Sheriff 2019-07-19 -crbug.com/856601 [ Linux ] external/wpt/WebCryptoAPI/idlharness.https.any.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/web-animations/interfaces/Animation/idlharness.window.html [ Skip ] - -# Sheriff 2019-07-29 -crbug.com/856601 [ Linux ] external/wpt/web-locks/idlharness.tentative.https.any.serviceworker.html [ Skip ] - # Time out on MSAN -crbug.com/856601 [ Linux ] external/wpt/IndexedDB/idlharness.any.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/background-fetch/idlharness.https.any.serviceworker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/background-fetch/idlharness.https.any.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/geolocation-API/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/payment-handler/idlharness.https.any.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/web-nfc/idlharness.https.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/xhr/idlharness.any.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/xhr/idlharness.any.sharedworker.html [ Skip ] -crbug.com/856601 [ Linux ] wpt_internal/std-switch/tentative/interface.html [ Pass Timeout ] crbug.com/856601 [ Linux ] http/tests/devtools/a11y-axe-core/elements/main-tool-test.js [ Pass Timeout ] crbug.com/856601 [ Linux ] webaudio/Analyser/realtimeanalyser-freq-data.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/secure-contexts/idlharness.any.serviceworker.html [ Skip ] crbug.com/993953 [ Linux ] http/tests/devtools/wasm-isolated-code-cache/wasm-cache-test.js [ Pass Timeout ] -crbug.com/856601 [ Linux ] external/wpt/dom/idlharness.any.serviceworker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/css/css-typed-om/idlharness.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/css/cssom-view/idlharness.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/css/cssom/idlharness.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/css/filter-effects/idlharness.any.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/css/filter-effects/idlharness.any.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/fetch/api/idlharness.any.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/html/dom/idlharness.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/mediasession/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/BackgroundSync/idlharness.https.any.worker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/fetch/api/idlharness.any.serviceworker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/BackgroundSync/idlharness.https.any.html [ Skip ] - -# Sheriff 2019-09-05 -crbug.com/856601 [ Linux ] external/wpt/fetch/api/idlharness.any.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/fetch/api/idlharness.any.sharedworker.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/generic-sensor/idlharness.https.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/html-media-capture/idlharness.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/pointerlock/idlharness.window.html [ Skip ] - -# Sheriff 2019-09-06 -crbug.com/856601 [ Linux ] external/wpt/idle-detection/idlharness.https.any.html [ Skip ] # Sheriff 2019-11-11 -crbug.com/856601 [ Linux ] external/wpt/web-animations/idlharness.window.html [ Skip ] crbug.com/856601 [ Linux ] virtual/controls-refresh/color/color-picker-manual-color-change-invalid-values.html [ Pass Timeout ] -# Note to sheriffs: Timeouts about "idlharness" or "interfaces" are usually crbug.com/856601. -crbug.com/856601 [ Linux ] external/wpt/secure-contexts/idlharness.any.html [ Skip ] crbug.com/856601 [ Linux ] external/wpt/compression/compression-stream.tentative.any.serviceworker.html [ Pass Timeout ] -# Sheriff 2019-12-27 -crbug.com/856601 [ Linux ] external/wpt/battery-status/idlharness.https.window.html [ Skip ] -crbug.com/856601 [ Linux ] external/wpt/permissions/idlharness.any.html [ Skip ] - # Sheriff 2020-01-10 crbug.com/1041052 [ Linux ] external/wpt/html/canvas/offscreen/filter/offscreencanvas.filter.w.html [ Timeout ] crbug.com/1041052 [ Linux ] external/wpt/html/canvas/element/fill-and-stroke-styles/canvas_colorsandstyles_createlineargradient_001.htm [ Timeout ] -# Sheriff 2020-02-04 -crbug.com/1047818 [ Linux ] external/wpt/visual-viewport/idlharness.window.html [ Skip ] -crbug.com/1047818 [ Linux ] external/wpt/permissions/idlharness.any.worker.html [ Skip ] - # Sheriff 2020-02-10 crbug.com/1050559 [ Linux ] external/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.worker.html?1-1000 [ Skip ] -# Sheriff 2020-02-11 -crbug.com/1047818 [ Linux ] external/wpt/badging/idlharness.any.html [ Skip ] -crbug.com/1047818 [ Linux ] external/wpt/badging/idlharness.any.worker.html [ Skip ] -crbug.com/1047818 [ Linux ] external/wpt/input-events/idlharness.window.html [ Skip ] -crbug.com/1047818 [ Linux ] external/wpt/permissions-request/idlharness.any.worker.html [ Skip ] -crbug.com/1047818 [ Linux ] external/wpt/permissions-revoke/idlharness.any.html [ Skip ] -crbug.com/1047818 [ Linux ] external/wpt/shape-detection/idlharness.https.any.html [ Skip ] -crbug.com/1047818 [ Linux ] external/wpt/web-locks/idlharness.tentative.https.any.html [ Skip ] -crbug.com/1047818 [ Linux ] external/wpt/web-share/idlharness.https.window.html [ Skip ] - -# Sheriff 2020-02-19 -crbug.com/856601 [ Linux ] external/wpt/badging/idlharness.https.any.html [ Skip ] - -# Sheriff 2020-02-20 -crbug.com/856601 [ Linux ] external/wpt/badging/idlharness.https.any.worker.html [ Skip ] - -# Sheriff 2020-02-28 -crbug.com/1047818 [ Linux ] external/wpt/permissions-revoke/idlharness.any.worker.html [ Skip ] - # Sheriff 2020-03-31 crbug.com/1066647 [ Linux ] http/tests/devtools/sources/debugger-breakpoints/breakpoint-with-sourcemap-dart.js [ Timeout ] - -# Sheriff 2020-04-21 -crbug.com/1073062 [ Linux ] external/wpt/page-lifecycle/idlharness.html [ Timeout ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index c762e73..d31b1810 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -5926,4 +5926,6 @@ crbug.com/1084502 [ Mac ] virtual/controls-refresh/color-scheme/select/select-multiple-appearance-basic.html [ Pass Failure ] # Disabled for landing DevTools change -crbug.com/1079233 http/tests/devtools/sources/debugger-ui/sourcemap-src-not-loaded.js [ Pass Failure ] +crbug.com/1011811 http/tests/devtools/network/network-xhr-data-received-async-response-type-blob.js [ Pass Failure ] +crbug.com/1011811 http/tests/devtools/network/download.js [ Pass Failure ] +crbug.com/1011811 http/tests/devtools/sxg/sxg-disable-cache.js [ Pass Failure ]
diff --git a/third_party/blink/web_tests/WPTOverrideExpectations b/third_party/blink/web_tests/WPTOverrideExpectations index dbbc889..2dbb4d7 100644 --- a/third_party/blink/web_tests/WPTOverrideExpectations +++ b/third_party/blink/web_tests/WPTOverrideExpectations
@@ -575,7 +575,7 @@ external/wpt/html/browsers/windows/noreferrer-window-name.html [ Timeout ] # wpt_subtest_failure external/wpt/html/cross-origin-embedder-policy/coep-frame-javascript.https.html [ Pass Timeout ] # wpt_subtest_failure external/wpt/html/cross-origin-embedder-policy/javascript.https.html [ Pass Timeout ] # wpt_subtest_failure -external/wpt/html/cross-origin-embedder-policy/reporting-to-endpoint.https.html [ Pass Failure ] # wpt_subtest_failure +external/wpt/html/cross-origin-embedder-policy/reporting.https.html [ Pass Failure ] # wpt_subtest_failure external/wpt/html/cross-origin-embedder-policy/require-corp.https.html [ Pass ] # wpt_subtest_failure external/wpt/html/cross-origin-opener-policy/blob-popup.https.html [ Pass Failure ] external/wpt/html/cross-origin-opener-policy/coep-blob-popup.https.html [ Timeout ] # wpt_subtest_failure
diff --git a/third_party/blink/web_tests/android/ClankWPTOverrideExpectations b/third_party/blink/web_tests/android/ClankWPTOverrideExpectations index 0bf215f..70602838 100644 --- a/third_party/blink/web_tests/android/ClankWPTOverrideExpectations +++ b/third_party/blink/web_tests/android/ClankWPTOverrideExpectations
@@ -1996,7 +1996,7 @@ crbug.com/1050754 external/wpt/html/browsers/windows/embedded-opener.html [ Failure ] crbug.com/1050754 external/wpt/html/browsers/windows/noreferrer-window-name.html [ Timeout ] crbug.com/1050754 external/wpt/html/cross-origin-embedder-policy/cache-storage-reporting.https.html [ Failure ] -crbug.com/1050754 external/wpt/html/cross-origin-embedder-policy/reporting-to-endpoint.https.html [ Failure ] +crbug.com/1050754 external/wpt/html/cross-origin-embedder-policy/reporting.https.html [ Failure ] crbug.com/1050754 external/wpt/html/cross-origin-embedder-policy/require-corp.https.html [ Failure ] crbug.com/1050754 external/wpt/html/cross-origin-opener-policy/blob-popup.https.html [ Failure ] crbug.com/1050754 external/wpt/html/cross-origin-opener-policy/coep-blob-popup.https.html [ Timeout ]
diff --git a/third_party/blink/web_tests/android/WeblayerWPTOverrideExpectations b/third_party/blink/web_tests/android/WeblayerWPTOverrideExpectations index 735ea0b..1c4e6a1 100644 --- a/third_party/blink/web_tests/android/WeblayerWPTOverrideExpectations +++ b/third_party/blink/web_tests/android/WeblayerWPTOverrideExpectations
@@ -1637,7 +1637,7 @@ crbug.com/1050754 external/wpt/html/cross-origin-embedder-policy/dedicated-worker-cache-storage.https.html [ Failure ] crbug.com/1050754 external/wpt/html/cross-origin-embedder-policy/javascript.https.html [ Failure ] crbug.com/1050754 external/wpt/html/cross-origin-embedder-policy/none-sw-from-require-corp.https.html [ Failure ] -crbug.com/1050754 external/wpt/html/cross-origin-embedder-policy/reporting-to-endpoint.https.html [ Failure ] +crbug.com/1050754 external/wpt/html/cross-origin-embedder-policy/reporting.https.html [ Failure ] crbug.com/1050754 external/wpt/html/cross-origin-embedder-policy/require-corp-load-from-cache-storage.https.html [ Failure ] crbug.com/1050754 external/wpt/html/cross-origin-embedder-policy/require-corp-sw-from-none.https.html [ Failure ] crbug.com/1050754 external/wpt/html/cross-origin-embedder-policy/require-corp-sw-from-require-corp.https.html [ Failure ]
diff --git a/third_party/blink/web_tests/android/WebviewWPTOverrideExpectations b/third_party/blink/web_tests/android/WebviewWPTOverrideExpectations index 854a29a..8288999 100644 --- a/third_party/blink/web_tests/android/WebviewWPTOverrideExpectations +++ b/third_party/blink/web_tests/android/WebviewWPTOverrideExpectations
@@ -2074,7 +2074,7 @@ external/wpt/html/cross-origin-embedder-policy/none-sw-from-require-corp.https.html [ Failure ] external/wpt/html/cross-origin-embedder-policy/none.https.html [ Timeout ] external/wpt/html/cross-origin-embedder-policy/report-only-require-corp.https.html [ Timeout ] -external/wpt/html/cross-origin-embedder-policy/reporting-to-endpoint.https.html [ Failure ] +external/wpt/html/cross-origin-embedder-policy/reporting.https.html [ Failure ] external/wpt/html/cross-origin-embedder-policy/require-corp-load-from-cache-storage.https.html [ Failure ] external/wpt/html/cross-origin-embedder-policy/require-corp-sw-from-none.https.html [ Failure ] external/wpt/html/cross-origin-embedder-policy/require-corp-sw-from-require-corp.https.html [ Failure ]
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 67bc135..030e8f7 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
@@ -42254,6 +42254,32 @@ {} ] ], + "border-width-pixel-snapping-001-a.html": [ + "664e652c2bf277913eff4b15bcebbb4f6c679743", + [ + null, + [ + [ + "/css/css-backgrounds/reference/border-width-pixel-snapping-001-ref.html", + "!=" + ] + ], + {} + ] + ], + "border-width-pixel-snapping-001-b.html": [ + "2bbb4f8b355bca712b1e2d6e4a3c15e01d9fd7e6", + [ + null, + [ + [ + "/css/css-backgrounds/reference/border-width-pixel-snapping-001-ref.html", + "==" + ] + ], + {} + ] + ], "box-shadow-005.html": [ "705ced279d30e6113eed68b819b287f7e48219cd", [ @@ -153323,6 +153349,10 @@ "549f3dbaa2e302777799d14c5ca1eb13a83493bf", [] ], + "report-original-url-on-mixed-content-frame.https.sub.html.sub.headers": [ + "d079fb134a5316191380e0e3065072f57d629d29", + [] + ], "report-original-url.sub.html.sub.headers": [ "1031a7a00a989d6f6b95c0aecf9ba5125ce026a3", [] @@ -161086,6 +161116,10 @@ "67324c71786b92d4207976284d915f1893b8007d", [] ], + "border-width-pixel-snapping-001-ref.html": [ + "99dd2f0beb2a6a9b5bcf79408d1fbf089b8e15ec", + [] + ], "box-shadow-005-ref.html": [ "81a5cbf6b8e06f6435bc133287f128ed6af8ed62", [] @@ -217682,6 +217716,18 @@ ] } }, + "idlharness.https.any.serviceworker-expected.txt": [ + "a568348cfd3a3e40a3e9354811cd1ccda4c193cf", + [] + ], + "idlharness.https.any.sharedworker-expected.txt": [ + "b1a70df638d24b9415079efd76126df25eb00947", + [] + ], + "idlharness.https.any.worker-expected.txt": [ + "b1a70df638d24b9415079efd76126df25eb00947", + [] + ], "service-worker": { "ServiceWorkerGlobalScope": { "isSecureContext.serviceworker.js": [ @@ -217843,6 +217889,10 @@ "54836e4b4571ec6e7a194c1f4520abbebe9b98a3", [] ], + "interface-requirements-sw.https-expected.txt": [ + "42f0b416105ad4f8e380c533efca92f325c88097", + [] + ], "local-url-inherit-controller.https-expected.txt": [ "829d98050ac563ea591a4daef9b8d14cafb8fdc7", [] @@ -218528,10 +218578,6 @@ "bcab35364dff6f4494d73adfa150d800efc6bf70", [] ], - "idlharness-worker.sub.js": [ - "44bd0870b9561eff46eaf1e56aa27912ce0c11a7", - [] - ], "iframe-with-image.html": [ "ce78840cb28310947f39232acd87fba0c0262f0b", [] @@ -218624,6 +218670,10 @@ "ed20cd4dca6a14e427b907a1d5147c88596bb1f0", [] ], + "interface-requirements-worker.sub.js": [ + "a3f239b654811317bfcedd09149afab928235c1b", + [] + ], "invalid-blobtype-iframe.https.html": [ "1e6cacb55d7f80f6c71e3be513c10a756d66543b", [] @@ -221764,7 +221814,7 @@ [] ], "serve.py": [ - "0e5090c2eef80abd774797771297df2759265c59", + "43ff7bd0dfbac5eae74cbe43235f016c4fe14d35", [] ], "test_functional.py": [ @@ -245806,7 +245856,7 @@ ] ], "idlharness.https.any.js": [ - "b0ccebd9f48999284ec36dbfb11a35314efa3135", + "ae65eb49f2120e1a6d7222a7c0ecc9836c4ff5a8", [ "WebCryptoAPI/idlharness.https.any.html", { @@ -245818,8 +245868,13 @@ [ "script", "/resources/idlharness.js" + ], + [ + "timeout", + "long" ] - ] + ], + "timeout": "long" } ], [ @@ -245833,8 +245888,13 @@ [ "script", "/resources/idlharness.js" + ], + [ + "timeout", + "long" ] - ] + ], + "timeout": "long" } ] ], @@ -254038,8 +254098,15 @@ {} ] ], + "report-original-url-on-mixed-content-frame.https.sub.html": [ + "67db730631fee8acf261b0cdbcdbd8647e21e46c", + [ + null, + {} + ] + ], "report-original-url.sub.html": [ - "45c1aeb2de86e64ec7de51bf0898c85f42d13320", + "5c9c4566bf7d008be44c770c7695ebde0b469b44", [ null, {} @@ -349945,7 +350012,7 @@ }, "netinfo": { "idlharness.any.js": [ - "96b114fdb56d38935c085b8fd5f4f4689dad9858", + "21d5595012735079165e68f8aa8a5b29a7fb7bdb", [ "netinfo/idlharness.any.html", { @@ -349957,8 +350024,13 @@ [ "script", "/resources/idlharness.js" + ], + [ + "timeout", + "long" ] - ] + ], + "timeout": "long" } ], [ @@ -349972,8 +350044,13 @@ [ "script", "/resources/idlharness.js" + ], + [ + "timeout", + "long" ] - ] + ], + "timeout": "long" } ] ], @@ -366943,6 +367020,137 @@ ] } }, + "idlharness.https.any.js": [ + "a6c434f5566f5f9f695fce43b5c41e88b39dcc67", + [ + "service-workers/idlharness.https.any.html", + { + "script_metadata": [ + [ + "global", + "window,worker" + ], + [ + "script", + "/resources/WebIDLParser.js" + ], + [ + "script", + "/resources/idlharness.js" + ], + [ + "script", + "cache-storage/resources/test-helpers.js" + ], + [ + "script", + "service-worker/resources/test-helpers.sub.js" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ], + [ + "service-workers/idlharness.https.any.serviceworker.html", + { + "script_metadata": [ + [ + "global", + "window,worker" + ], + [ + "script", + "/resources/WebIDLParser.js" + ], + [ + "script", + "/resources/idlharness.js" + ], + [ + "script", + "cache-storage/resources/test-helpers.js" + ], + [ + "script", + "service-worker/resources/test-helpers.sub.js" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ], + [ + "service-workers/idlharness.https.any.sharedworker.html", + { + "script_metadata": [ + [ + "global", + "window,worker" + ], + [ + "script", + "/resources/WebIDLParser.js" + ], + [ + "script", + "/resources/idlharness.js" + ], + [ + "script", + "cache-storage/resources/test-helpers.js" + ], + [ + "script", + "service-worker/resources/test-helpers.sub.js" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ], + [ + "service-workers/idlharness.https.any.worker.html", + { + "script_metadata": [ + [ + "global", + "window,worker" + ], + [ + "script", + "/resources/WebIDLParser.js" + ], + [ + "script", + "/resources/idlharness.js" + ], + [ + "script", + "cache-storage/resources/test-helpers.js" + ], + [ + "script", + "service-worker/resources/test-helpers.sub.js" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ] + ], "service-worker": { "Service-Worker-Allowed-header.https.html": [ "6f44bb17e7da958a195e8602aa5aef9c135a80b3", @@ -367264,6 +367472,13 @@ {} ] ], + "data-iframe.html": [ + "d767d574345bf7058d58381d94e5dabffd1fca9e", + [ + null, + {} + ] + ], "data-transfer-files.https.html": [ "cc8ab6e672726e168b44dfee5b4720012fffee0a", [ @@ -367707,24 +367922,6 @@ {} ] ], - "idlharness-sw.https.html": [ - "5209cc6702e147c023032398211a365874162227", - [ - null, - { - "timeout": "long" - } - ] - ], - "idlharness-window.https.html": [ - "cc3bdaf11fc7bc174eef555a60263e192efdc539", - [ - null, - { - "timeout": "long" - } - ] - ], "immutable-prototype-serviceworker.https.html": [ "e63f6b348a861345101670b9c3d87aaa4977b0c4", [ @@ -367788,6 +367985,15 @@ {} ] ], + "interface-requirements-sw.https.html": [ + "eef868c889f04d257055d9f08ce22832b6cc34fd", + [ + null, + { + "timeout": "long" + } + ] + ], "invalid-blobtype.https.html": [ "1c5920fb039101b18fc3c39e53f7cbb9b5e1ebfc", [ @@ -386971,7 +387177,7 @@ ] ], "idlharness.https.window.js": [ - "1520387caf133dc43c5f036bbf24a99ef73a7f3c", + "fbe59864af99c0a55b83e942f0e40f4d45de72a6", [ "web-share/idlharness.https.window.html", { @@ -386983,8 +387189,13 @@ [ "script", "/resources/idlharness.js" + ], + [ + "timeout", + "long" ] - ] + ], + "timeout": "long" } ] ],
diff --git a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/idlharness.https.any.js b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/idlharness.https.any.js index b0ccebd..ae65eb4 100644 --- a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/idlharness.https.any.js +++ b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/idlharness.https.any.js
@@ -1,5 +1,6 @@ // META: script=/resources/WebIDLParser.js // META: script=/resources/idlharness.js +// META: timeout=long // https://w3c.github.io/webcrypto/Overview.html
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-original-url-on-mixed-content-frame.https.sub.html b/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-original-url-on-mixed-content-frame.https.sub.html new file mode 100644 index 0000000..67db7306 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-original-url-on-mixed-content-frame.https.sub.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<html> +<head> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> +<body> +<script async defer src='../support/checkReport.sub.js?reportField=blocked-uri&reportValue={{location[scheme]}}%3A%2F%2F{{location[host]}}/common/redirect.py%3Flocation%3Dhttp%253A%252F%252F{{hosts[][]}}%253A{{ports[http][0]}}%252Fcontent-security-policy%252Fsupport%252Ffail.html%253Ft%253D1'></script> +<iframe src='{{location[scheme]}}://{{location[host]}}/common/redirect.py?location=http%3A%2F%2F{{hosts[][]}}%3A{{ports[http][0]}}%2Fcontent-security-policy%2Fsupport%2Ffail.html%3Ft%3D1' style='display: none;'> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-original-url-on-mixed-content-frame.https.sub.html.sub.headers b/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-original-url-on-mixed-content-frame.https.sub.html.sub.headers new file mode 100644 index 0000000..d079fb13 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-original-url-on-mixed-content-frame.https.sub.html.sub.headers
@@ -0,0 +1,6 @@ +Expires: Mon, 26 Jul 1997 05:00:00 GMT +Cache-Control: no-store, no-cache, must-revalidate +Cache-Control: post-check=0, pre-check=0, false +Pragma: no-cache +Set-Cookie: report-original-url-on-mixed-content-frame={{$id:uuid()}}; Path=/content-security-policy/reporting/ +Content-Security-Policy: block-all-mixed-content; report-uri ../support/report.py?op=put&reportID={{$id}}
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-original-url.sub.html b/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-original-url.sub.html index 45c1aeb2..5c9c456 100644 --- a/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-original-url.sub.html +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/reporting/report-original-url.sub.html
@@ -34,14 +34,14 @@ async_test(t => { var i = document.createElement('img'); var url = "{{location[scheme]}}://{{domains[www1]}}:{{ports[http][0]}}/common/redirect.py?location=" + encodeURIComponent("{{location[scheme]}}://{{location[host]}}/content-security-policy/support/fail.png?t=3"); - createListener("{{location[scheme]}}://{{location[host]}}/content-security-policy/support/fail.png?t=3", t); + createListener(url, t); i.src = url; }, "Block after redirect, same-origin = original URL in report"); async_test(t => { var i = document.createElement('img'); var url = "{{location[scheme]}}://{{domains[www1]}}:{{ports[http][0]}}/common/redirect.py?location=" + encodeURIComponent("{{location[scheme]}}://{{domains[www2]}}:{{ports[http][0]}}/content-security-policy/support/fail.png?t=4"); - createListener("{{location[scheme]}}://{{domains[www2]}}:{{ports[http][0]}}", t); + createListener(url, t); i.src = url; }, "Block after redirect, cross-origin = original URL in report"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-center-003.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-center-003.html new file mode 100644 index 0000000..187fae6f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-center-003.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<link rel="help" href="https://crbug.com/1081872"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<meta name="assert" content="A positioned absolute child with center alignment should be centered based on its margin-box."> +<style> +.s100 { + width: 100px; + height: 100px; + box-sizing: border-box; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="s100" style="position: relative;"> + <div class="s100" style="position: absolute; background: red; border: solid green; border-width: 30px 20px 20px 30px;"></div> + <div class="s100" style="display: flex; align-items: center; justify-content: center;"> + <div style="position: absolute; width: 50px; height: 50px; margin-left: 10px; margin-top: 10px; background: green;"></div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-center-004.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-center-004.html new file mode 100644 index 0000000..b4922ef --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-center-004.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<link rel="help" href="https://crbug.com/1081872"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<meta name="assert" content="A positioned absolute child with center alignment should be centered based on its margin-box."> +<style> +.s100 { + width: 100px; + height: 100px; + box-sizing: border-box; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="s100" style="position: relative;"> + <div class="s100" style="position: absolute; background: red; border: solid green; border-width: 20px 30px 30px 20px;"></div> + <div class="s100" style="display: flex; align-items: center; justify-content: center;"> + <div style="position: absolute; width: 50px; height: 50px; margin-right: 10px; margin-bottom: 10px; background: green;"></div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-navigation.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-navigation.https.html index 5e80a1c..503e521 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-navigation.https.html +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-navigation.https.html
@@ -6,11 +6,9 @@ <script src="/common/get-host-info.sub.js"></script> <script> const {ORIGIN, REMOTE_ORIGIN} = get_host_info(); -const COEP = '|header(cross-origin-embedder-policy,require-corp)'; -const COEP_RO = +const COEP = + '|header(cross-origin-embedder-policy,require-corp)' + '|header(cross-origin-embedder-policy-report-only,require-corp)'; -const CORP_CROSS_ORIGIN = - '|header(cross-origin-resource-policy,cross-origin)'; const FRAME_URL = `${ORIGIN}/common/blank.html?pipe=`; const REMOTE_FRAME_URL = `${REMOTE_ORIGIN}/common/blank.html?pipe=`; @@ -21,13 +19,6 @@ assert_equals(report.body['blocked-url'], blockedUrl); } -function checkCoepMismatchReport(report, contextUrl, blockedUrl) { - assert_equals(report.type, 'coep'); - assert_equals(report.url, contextUrl); - assert_equals(report.body.type, 'navigation'); - assert_equals(report.body['blocked-url'], blockedUrl); -} - function loadFrame(document, url) { return new Promise((resolve, reject) => { const frame = document.createElement('iframe'); @@ -38,111 +29,49 @@ }); } -// |parentSuffix| is a suffix for the parent frame URL. -// When |withEmptyFrame| is true, this function creates an empty frame -// between the parent and target frames. -// |targetUrl| is a URL for the target frame. -async function loadFrames(test, parentSuffix, withEmptyFrame, targetUrl) { - const frame = await loadFrame(document, FRAME_URL + parentSuffix); - test.add_cleanup(() => frame.remove()); - let parent; - if (withEmptyFrame) { - parent = frame.contentDocument.createElement('iframe'); - frame.contentDocument.body.appendChild(parent); - } else { - parent = frame; - } - // Here we don't need "await". This loading may or may not succeed, and - // we're not interested in the result. - loadFrame(parent.contentDocument, targetUrl); - - return parent; -} - -async function observeReports(global) { +function observeReportsUpTo(global, upto) { const reports = []; - const observer = new global.ReportingObserver((rs) => { - for (const r of rs) { - reports.push(r.toJSON()); - } - }); - observer.observe(); - - // Wait 1500ms for reports to settle. - await new Promise(r => step_timeout(r, 1500)); - return reports; -} - -// CASES is a list of test case. Each test case consists of: -// parent: the suffix of the URL of the parent frame. -// target: the suffix of the URL of the target frame. -// reports: the expectation of reports to be made. Each report is one of: -// 'CORP': CORP violation -// 'CORP-RO' CORP violation (report only) -// 'NAV': COEP mismatch between the frames. -// 'NAV-RO': COEP mismatch between the frames (report only). -// Currently '-RO' is no-op, e.g., 'CORP' and 'CORP-RO' have the same -// expectation. We are planning to introduce "disposition" member in -// reports, which will differentiate them each other. -const CASES = [ - { parent: '', target: '', reports: [] }, - { parent: '', target: COEP, reports: [] }, - { parent: COEP, target: COEP, reports: ['CORP'] }, - { parent: COEP, target: '', reports: ['CORP'] }, - - { parent: '', target: CORP_CROSS_ORIGIN, reports: [] }, - { parent: COEP, target: CORP_CROSS_ORIGIN, reports: ['NAV'] }, - - { parent: '', target: COEP + CORP_CROSS_ORIGIN, reports: [] }, - { parent: COEP, target: COEP + CORP_CROSS_ORIGIN, reports: [] }, - - { parent: COEP_RO, target: COEP, reports: ['CORP-RO'] }, - { parent: COEP_RO, target: '', reports: ['CORP-RO', 'NAV-RO'] }, - { parent: COEP_RO, target: CORP_CROSS_ORIGIN, reports: ['NAV-RO'] }, - { parent: COEP_RO, target: COEP + CORP_CROSS_ORIGIN, reports: [] }, - - { parent: COEP, target: COEP_RO + CORP_CROSS_ORIGIN, reports: ['NAV'] }, -]; - -for (const testcase of CASES) { - for (const withEmptyFrame of [false, true]) { - function desc(s) { - return s === '' ? '(none)' : s; - } - async_test(async (t) => { - try { - const targetUrl = REMOTE_FRAME_URL + testcase.target; - const parent = - await loadFrames(t, testcase.parent, withEmptyFrame, targetUrl); - - const contextUrl = parent.src ? parent.src : 'about:blank'; - const reports = await observeReports(parent.contentWindow); - assert_equals(reports.length, testcase.reports.length); - - for (let i = 0; i < reports.length; i += 1) { - const report = reports[i]; - switch (testcase.reports[i]) { - case 'CORP': - case 'CORP-RO': - checkCorpReport(report, contextUrl, targetUrl); - break; - case 'NAV': - case 'NAV-RO': - checkCoepMismatchReport(report, contextUrl, targetUrl); - break; - default: - assert_unreached( - 'Unexpected report expeaction: ' + testcase.reports[i]); - } + return new Promise(resolve => { + const observer = new global.ReportingObserver((rs) => { + for (const r of rs) { + reports.push(r.toJSON()); + if (reports.length == upto) { + observer.disconnect(); + resolve(reports); } - t.done(); - } catch (e) { - t.step(() => { throw e; }); } - }, `parent: ${desc(testcase.parent)}, target: ${desc(testcase.target)}, ` + - `with empty frame: ${withEmptyFrame}`); - } + }); + observer.observe(); + }); } +promise_test(async (t) => { + const parent = await loadFrame(document, FRAME_URL + COEP); + t.add_cleanup(() => parent.remove()); + loadFrame(parent.contentDocument, REMOTE_FRAME_URL + COEP); + + // One for COEP, one for COEP-RO. + const reports = await observeReportsUpTo(parent.contentWindow, 2); + + assert_equals(reports.length, 2); + checkCorpReport(reports[0], parent.src, REMOTE_FRAME_URL + COEP); + checkCorpReport(reports[1], parent.src, REMOTE_FRAME_URL + COEP); +}, 'Navigation CORP'); + +promise_test(async (t) => { + const grandParent = await loadFrame(document, FRAME_URL + COEP); + t.add_cleanup(() => grandParent.remove()); + const parent = grandParent.contentDocument.createElement('iframe'); + grandParent.contentDocument.body.appendChild(parent); + loadFrame(parent.contentDocument, REMOTE_FRAME_URL + COEP); + + // One for COEP, one for COEP-RO. + const reports = await observeReportsUpTo(parent.contentWindow, 2); + + assert_equals(reports.length, 2); + checkCorpReport(reports[0], 'about:blank', REMOTE_FRAME_URL + COEP); + checkCorpReport(reports[1], 'about:blank', REMOTE_FRAME_URL + COEP); +}, 'Navigation CORP and about:blank'); + </script> </body></html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https-expected.txt b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https-expected.txt index 171032a..62ff46e 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https-expected.txt
@@ -15,9 +15,5 @@ PASS [service worker] blocked by CORP: same-origin PASS [service worker] blocked due to COEP PASS [service worker] blocked during redirect -PASS [between service worker and page] same-origin -PASS [between service worker and page] blocked by CORP: same-origin -PASS [between service worker and page] blocked due to COEP -PASS [between service worker and page] blocked during redirect Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https.html index 5314ec93..aa76bbe 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https.html +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https.html
@@ -28,9 +28,9 @@ assert_equals(report.body['blocked-url'], blockedUrl); } -async function fetchInFrame(t, frameUrl, url) { +async function fetchInFrame(t, url) { const reports = []; - const frame = await with_iframe(frameUrl); + const frame = await with_iframe(FRAME_URL); t.add_cleanup(() => frame.remove()); const observer = new frame.contentWindow.ReportingObserver((rs) => { @@ -80,7 +80,7 @@ tag: 'document', contextUrl: FRAME_URL, run: async (test, url) => { - return await fetchInFrame(test, FRAME_URL, url); + return await fetchInFrame(test, url); }, }, { tag: 'dedicated worker', @@ -113,21 +113,6 @@ worker.addEventListener('error', test.unreached_func('Worker.onerror')); return await fetchInWorker(worker, url); }, -}, { - tag: 'between service worker and page', - contextUrl: `${ORIGIN}${BASE}/reporting-empty-frame.html`, - run: async (test, url) => { - const SCOPE = `${BASE}/reporting-empty-frame.html`; - // Here we use a Service Worker without COEP. - const WORKER_URL = `${ORIGIN}${BASE}/sw.js`; - const reg = - await service_worker_unregister_and_register(test, WORKER_URL, SCOPE); - test.add_cleanup(() => reg.unregister()); - const worker = reg.installing || reg.waiting || reg.active; - worker.addEventListener('error', test.unreached_func('Worker.onerror')); - return await fetchInFrame( - test, `${ORIGIN}${BASE}/reporting-empty-frame.html`, url); - }, }]; const CASES = [{
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-to-endpoint.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-to-endpoint.https.html deleted file mode 100644 index cfff7bcb..0000000 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-to-endpoint.https.html +++ /dev/null
@@ -1,171 +0,0 @@ -<!doctype html> -<html> -<meta name="timeout" content="long"> -<body> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/common/utils.js"></script> -<script src="/common/get-host-info.sub.js"></script> -<script> -// This file consists of tests for COEP reporting. The tests make COEP -// violations and see whether reports are sent to the network as specified. -// We only have basic tests in this file - one for each kind of reports, -// because we can also test the reporting functionality with ReportingObserver, -// and that way is faster, easier to debug, and less flaky. -// -// For more detailed tests and tests with workers, see tests in other files -// such as -// - reporting-navigation.https.html -// - reporting-subresource-corp.https.html -// - cache-storage-reporting*.https.html -// . -const { REMOTE_ORIGIN } = get_host_info(); -const BASE = new URL("resources", location).pathname - -function wait(ms) { - return new Promise(resolve => step_timeout(resolve, ms)); -} - -async function pollReports(endpoint, reports) { - while (true) { - await wait(200); - const res = await fetch(`resources/report.py?endpoint=${endpoint}`, {cache: 'no-store'}); - if (res.status !== 200) { - continue; - } - for (const report of await res.json()) { - reports.push(report); - } - } -} - -const reports = []; -const reportsForReportOnly = []; -pollReports('endpoint', reports); -pollReports('report-only-endpoint', reportsForReportOnly); - -function checkCorpReportExistence(reports, blockedUrl, contextUrl) { - blockedUrl = new URL(blockedUrl, location).href; - contextUrl = new URL(contextUrl, location).href; - for (const report of reports) { - if (report.type !== 'coep' || report.url !== contextUrl || - report.body.type !== 'corp') { - continue; - } - if (report.body['blocked-url'] === blockedUrl) { - return; - } - } - assert_unreached(`A report whose blocked-url is ${blockedUrl} and url is ${contextUrl} is not found.`); -} - -function checkNavigationReportExistence(reports, blockedUrl, contextUrl) { - blockedUrl = new URL(blockedUrl, location).href; - contextUrl = new URL(contextUrl, location).href; - for (const report of reports) { - if (report.type !== 'coep' || report.url !== contextUrl || - report.body.type !== 'navigation') { - continue; - } - if (report.body['blocked-url'] === blockedUrl) { - return; - } - } - assert_unreached(`A report whose blocked-url is ${blockedUrl} and url is ${contextUrl} is not found.`); -} - -async_test(async (t) => { - try { - const iframe = document.createElement('iframe'); - t.add_cleanup(() => iframe.remove()); - - iframe.src = `resources/reporting-empty-frame.html` - document.body.appendChild(iframe); - await new Promise(resolve => { - iframe.addEventListener('load', resolve, {once: true}); - }); - - const url = `${REMOTE_ORIGIN}/common/text-plain.txt?${token()}`; - const init = { mode: 'no-cors', cache: 'no-store' }; - // The response comes from cross-origin, and doesn't have a CORP - // header, so it is blocked. - iframe.contentWindow.fetch(url, init).catch(() => {}); - - // Wait 3 seconds for reports to settle. - await wait(3000); - - checkCorpReportExistence(reports, url, iframe.src); - checkCorpReportExistence(reportsForReportOnly, url, iframe.src); - - t.done(); - } catch (e) { - t.step(() => { throw e }); - } -}, 'subresource CORP'); - -async_test(async (t) => { - try { - const iframe = document.createElement('iframe'); - t.add_cleanup(() => iframe.remove()); - - iframe.src = `resources/reporting-empty-frame.html` - document.body.appendChild(iframe); - await new Promise(resolve => { - iframe.addEventListener('load', resolve, {once: true}); - }); - - const w = iframe.contentWindow; - - function attachFrame(url) { - const frame = w.document.createElement('iframe'); - frame.src = url; - w.document.body.appendChild(frame); - } - - const url = `${REMOTE_ORIGIN}/common/blank.html?${token()}`; - // The nested frame comes from cross-origin and doesn't have a CORP - // header, so it is blocked. - attachFrame(url); - - // Wait 3 seconds for reports to settle. - await wait(3000); - - checkCorpReportExistence(reports, url, iframe.src); - checkCorpReportExistence(reportsForReportOnly, url, iframe.src); - - t.done(); - } catch (e) { - t.step(() => { throw e }); - } -}, 'navigation CORP'); - -async_test(async (t) => { - try { - const iframe = document.createElement('iframe'); - t.add_cleanup(() => iframe.remove()); - - iframe.src = 'resources/reporting-empty-frame.html'; - const targetUrl = `/common/blank.html?${token()}`; - iframe.addEventListener('load', () => { - const nested = iframe.contentDocument.createElement('iframe'); - nested.src = targetUrl; - // |nested| doesn't have COEP whereas |iframe| has, so it is blocked. - iframe.contentDocument.body.appendChild(nested); - }, {once: true}); - - document.body.appendChild(iframe); - - // Wait 3 seconds for reports to settle. - await wait(3000); - - checkNavigationReportExistence(reports, targetUrl, iframe.src); - checkNavigationReportExistence( - reportsForReportOnly, targetUrl, iframe.src); - - t.done(); - } catch (e) { - t.step(() => { throw e }); - } -}, 'COEP violation on nested frame navigation'); - -</script>$
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting.https-expected.txt b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting.https-expected.txt new file mode 100644 index 0000000..59458db --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting.https-expected.txt
@@ -0,0 +1,10 @@ +This is a testharness.js-based test. +PASS subresource CORP +PASS CORP for subresource requests initiated from a service worker +PASS navigation CORP +PASS COEP violation on nested frame navigation +FAIL subresource requests initiated from DedicatedWorker assert_unreached: A report whose blocked-url is https://www1.web-platform.test:8444/common/text-plain.txt?abc&subresource-corp-from-dedicated-worker and url is https://web-platform.test:8444/html/cross-origin-embedder-policy/resources/fetch-in-dedicated-worker.js is not found. Reached unreachable code +FAIL subresource requests initiated from DedicatedWorker controlled by a passthrough service worker assert_unreached: A report whose blocked-url is https://www1.web-platform.test:8444/common/text-plain.txt?abc&subresource-corp-from-dedicated-worker-via-passthrough-sw and url is https://web-platform.test:8444/html/cross-origin-embedder-policy/resources/fetch-in-dedicated-worker.js is not found. Reached unreachable code +PASS subresource CORP in an iframe hosted by a service worker without COEP +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting.https.html new file mode 100644 index 0000000..42d5e6c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting.https.html
@@ -0,0 +1,462 @@ +<!doctype html> +<html> +<meta name="timeout" content="long"> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> +<script> +const HOST = get_host_info(); +const REMOTE_ORIGIN = HOST.REMOTE_ORIGIN; +const BASE = new URL("resources", location).pathname + +function wait(ms) { + return new Promise(resolve => step_timeout(resolve, ms)); +} + +async function pollReports(endpoint, reports) { + while (true) { + await wait(200); + const res = await fetch(`resources/report.py?endpoint=${endpoint}`, {cache: 'no-store'}); + if (res.status !== 200) { + continue; + } + for (const report of await res.json()) { + reports.push(report); + } + } +} + +const reports = []; +const reportsForReportOnly = []; +pollReports('endpoint', reports); +pollReports('report-only-endpoint', reportsForReportOnly); + +function checkCorpReportExistence(reports, blockedUrl, contextUrl) { + blockedUrl = new URL(blockedUrl, location).href; + contextUrl = new URL(contextUrl, location).href; + for (const report of reports) { + if (report.type !== 'coep' || report.url !== contextUrl || + report.body.type !== 'corp') { + continue; + } + if (report.body['blocked-url'] === blockedUrl) { + return; + } + } + assert_unreached(`A report whose blocked-url is ${blockedUrl} and url is ${contextUrl} is not found.`); +} + +function checkNavigationReportExistence(reports, blockedUrl, contextUrl) { + blockedUrl = new URL(blockedUrl, location).href; + contextUrl = new URL(contextUrl, location).href; + for (const report of reports) { + if (report.type !== 'coep' || report.url !== contextUrl || + report.body.type !== 'navigation') { + continue; + } + if (report.body['blocked-url'] === blockedUrl) { + return; + } + } + assert_unreached(`A report whose blocked-url is ${blockedUrl} and url is ${contextUrl} is not found.`); +} + +function checkReportNonExistence(reports, blockedUrl, contextUrl) { + blockedUrl = new URL(blockedUrl, location).href; + contextUrl = new URL(contextUrl, location).href; + for (const report of reports) { + if (report.type !== 'coep' || report.url !== contextUrl) { + continue; + } + assert_not_equals(report.body['blocked-url'], blockedUrl); + } +} + +async_test(async (t) => { + try { + const iframe = document.createElement('iframe'); + t.add_cleanup(() => iframe.remove()); + + iframe.src = `resources/reporting-empty-frame.html` + document.body.appendChild(iframe); + await new Promise(resolve => { + iframe.addEventListener('load', resolve, {once: true}); + }); + + function fetchInIframe(url) { + const init = { mode: 'no-cors', cache: 'no-store' }; + iframe.contentWindow.fetch(url, init).catch(() => {}); + } + + const suffix = 'subresource-corp'; + const sameOriginUrl = `/common/text-plain.txt?${suffix}`; + const blockedByPureCorp = `${REMOTE_ORIGIN}${BASE}/nothing-same-origin-corp.txt?${suffix}`; + const blockedDueToCoep = `${REMOTE_ORIGIN}/common/text-plain.txt?abc&${suffix}`; + const dest = `${REMOTE_ORIGIN}/common/text-plain.txt?xyz&${suffix}`; + const redirect = `/common/redirect.py?location=${encodeURIComponent(dest)}&${suffix}`; + + fetchInIframe(sameOriginUrl); + fetchInIframe(blockedByPureCorp); + fetchInIframe(blockedDueToCoep); + fetchInIframe(redirect); + + // Wait 3 seconds for reports to settle. + await wait(3000); + + checkReportNonExistence(reports, sameOriginUrl, iframe.src); + checkReportNonExistence(reports, blockedByPureCorp, iframe.src); + checkCorpReportExistence(reports, blockedDueToCoep, iframe.src); + checkCorpReportExistence(reports, redirect, iframe.src); + checkReportNonExistence(reports, dest, iframe.src); + + t.done(); + } catch (e) { + t.step(() => { throw e }); + } +}, 'subresource CORP'); + +async_test(async (t) => { + try { + const IFRAME_SRC = 'resources/coep-iframe.html'; + const SCOPE = new URL(IFRAME_SRC, location).pathname; + const SCRIPT = + 'resources/sw.js?' + + `pipe=header(service-worker-allowed,${SCOPE})|` + + 'header(cross-origin-embedder-policy,require-corp%3breport-to=%22endpoint%22)|' + + 'header(cross-origin-embedder-policy-report-only,require-corp%3breport-to=%22report-only-endpoint%22)'; + + const reg = await service_worker_unregister_and_register(t, SCRIPT, SCOPE); + await wait_for_state(t, reg.installing, 'activated'); + + const iframe = document.createElement('iframe'); + t.add_cleanup(() => { + iframe.remove(); + reg.unregister(); + }); + iframe.src = IFRAME_SRC; + document.body.appendChild(iframe); + await new Promise(resolve => { + iframe.addEventListener('load', resolve, {once: true}); + }); + + document.body.appendChild(iframe); + await new Promise(resolve => { + iframe.addEventListener('load', resolve, {once: true}); + }); + + function fetchInIframe(url) { + const init = { mode: 'no-cors', cache: 'no-store' }; + iframe.contentWindow.fetch(url, init).catch(() => {}); + } + + const suffix = 'subresource-corp-sw'; + const sameOriginUrl = `/common/text-plain.txt?${suffix}`; + const blockedByPureCorp = `${REMOTE_ORIGIN}${BASE}/nothing-same-origin-corp.txt?${suffix}`; + const blockedDueToCoep = `${REMOTE_ORIGIN}/common/text-plain.txt?abc&${suffix}`; + const dest = `${REMOTE_ORIGIN}/common/text-plain.txt?xyz&${suffix}`; + const redirect = `/common/redirect.py?location=${encodeURIComponent(dest)}&${suffix}`; + + fetchInIframe(sameOriginUrl); + fetchInIframe(blockedByPureCorp); + fetchInIframe(blockedDueToCoep); + fetchInIframe(redirect); + + // Wait 3 seconds for reports to settle. + await wait(3000); + + const contextUrl = SCRIPT; + checkReportNonExistence(reports, sameOriginUrl, contextUrl); + checkReportNonExistence(reports, blockedByPureCorp, contextUrl); + checkCorpReportExistence(reports, blockedDueToCoep, contextUrl); + checkCorpReportExistence(reports, redirect, contextUrl); + checkReportNonExistence(reports, dest, contextUrl); + + t.done(); + } catch (e) { + t.step(() => { throw e }); + } +}, 'CORP for subresource requests initiated from a service worker'); + +async_test(async (t) => { + try { + const iframe = document.createElement('iframe'); + t.add_cleanup(() => iframe.remove()); + + iframe.src = `resources/reporting-empty-frame.html` + document.body.appendChild(iframe); + await new Promise(resolve => { + iframe.addEventListener('load', resolve, {once: true}); + }); + + const w = iframe.contentWindow; + + function attachFrame(url) { + const frame = w.document.createElement('iframe'); + frame.src = url; + w.document.body.appendChild(frame); + } + + const suffix = 'navigation-corp'; + const coep = `pipe=header(cross-origin-embedder-policy,require-corp)`; + const sameOrigin = `/common/blank.html?${coep}&${suffix}`; + const blockedDueToCoep = `${REMOTE_ORIGIN}/common/blank.html?${coep}&${suffix}-a`; + const dest = `${REMOTE_ORIGIN}/common/blank.html?${coep}&${suffix}-b`; + const redirect = `/common/redirect.py?location=${encodeURIComponent(dest)}&${suffix}`; + + attachFrame(sameOrigin); + attachFrame(blockedDueToCoep); + attachFrame(redirect); + + // Wait 3 seconds for reports to settle. + await wait(3000); + + checkReportNonExistence(reports, sameOrigin, iframe.src); + checkCorpReportExistence(reports, blockedDueToCoep, iframe.src); + checkCorpReportExistence(reports, redirect, iframe.src); + checkReportNonExistence(reports, dest, iframe.src); + + t.done(); + } catch (e) { + t.step(() => { throw e }); + } +}, 'navigation CORP'); + +async_test(async (t) => { + try { + const iframe = document.createElement('iframe'); + t.add_cleanup(() => iframe.remove()); + + const suffix = '&navigation-coep'; + const corp = 'header(cross-origin-resource-policy,cross-origin)'; + const noCoep = `pipe=${corp}`; + const coep = + `pipe=header(cross-origin-embedder-policy,require-corp%3breport-to=%22endpoint%22)|${corp}`; + const coepReportOnly = + `pipe=header(cross-origin-embedder-policy-report-only,require-corp%3breport-to=%22report-only-endpoint%22)|${corp}`; + const path = `/common/blank.html`; + const pipes = [noCoep, coep, coepReportOnly]; + const settings = new Map(); + settings.set(noCoep, { + pipe: noCoep, + value: 'unsafe-none', + reportOnlyValue: 'unsafe-none', + }); + settings.set(coep, { + pipe: coep, + value: 'require-corp', + reportOnlyValue: 'unsafe-none', + }); + settings.set(coepReportOnly, { + pipe: coepReportOnly, + value: 'unsafe-none', + reportOnlyValue: 'require-corp', + }); + + function genUrl(pipe) { + return `${path}?${pipe}${suffix}`; + } + + for (const outer of settings.keys()) { + for (const inner of settings.keys()) { + const iframe = document.createElement('iframe'); + t.add_cleanup(() => iframe.remove()); + + iframe.src = genUrl(outer); + iframe.addEventListener('load', () => { + const w = iframe.contentWindow; + const d = iframe.contentDocument; + const nested = d.createElement('iframe'); + nested.src = genUrl(inner) + '-nested'; + d.body.appendChild(nested); + }, {once: true}); + document.body.appendChild(iframe); + } + } + + // Wait 3 seconds for reports to settle. + await wait(3000); + + function check(rs, inner, outer) { + checkNavigationReportExistence( + rs, genUrl(inner) + '-nested', genUrl(outer)); + } + function checkNoReport(reports, inner, outer) { + checkReportNonExistence( + reports, genUrl(inner) + '-nested', genUrl(outer)); + } + + // outer === noCoep + checkNoReport(reports, noCoep, noCoep); + checkNoReport(reports, coep, noCoep); + checkNoReport(reports, coepReportOnly, noCoep); + checkNoReport(reportsForReportOnly, noCoep, noCoep); + checkNoReport(reportsForReportOnly, coep, noCoep); + checkNoReport(reportsForReportOnly, coepReportOnly, noCoep); + + // outer === coep + check(reports, noCoep, coep); + checkNoReport(reports, coep, coep); + check(reports, coepReportOnly, coep); + checkNoReport(reportsForReportOnly, noCoep, coep); + checkNoReport(reportsForReportOnly, coep, coep); + checkNoReport(reportsForReportOnly, coepReportOnly, coep); + + // outer === coepReportOnly + checkNoReport(reports, noCoep, coepReportOnly); + checkNoReport(reports, coep, coepReportOnly); + checkNoReport(reports, coepReportOnly, coepReportOnly); + check(reportsForReportOnly, noCoep, coepReportOnly); + checkNoReport(reportsForReportOnly, coep, coepReportOnly); + check(reportsForReportOnly, coepReportOnly, coepReportOnly); + + t.done(); + } catch (e) { + t.step(() => { throw e }); + } +}, 'COEP violation on nested frame navigation'); + +async_test(async (t) => { + try { + const iframe = document.createElement('iframe'); + t.add_cleanup(() => iframe.remove()); + + iframe.src = `resources/reporting-empty-frame.html` + document.body.appendChild(iframe); + await new Promise(resolve => { + iframe.addEventListener('load', resolve, {once: true}); + }); + const worker_url = new URL('resources/fetch-in-dedicated-worker.js', location); + const worker = new iframe.contentWindow.Worker(worker_url); + + function fetchInWorker(url) { + const init = { mode: 'no-cors', cache: 'no-store' }; + worker.postMessage({url, init}); + return new Promise((resolve) => { + worker.addEventListener('message', resolve); + }); + } + + const suffix = 'subresource-corp-from-dedicated-worker'; + const sameOriginUrl = `/common/text-plain.txt?${suffix}`; + const blockedByPureCorp = `${REMOTE_ORIGIN}${BASE}/nothing-same-origin-corp.txt?${suffix}`; + const blockedDueToCoep = `${REMOTE_ORIGIN}/common/text-plain.txt?abc&${suffix}`; + const dest = `${REMOTE_ORIGIN}/common/text-plain.txt?xyz&${suffix}`; + const redirect = `/common/redirect.py?location=${encodeURIComponent(dest)}&${suffix}`; + + fetchInWorker(sameOriginUrl); + fetchInWorker(blockedByPureCorp); + fetchInWorker(blockedDueToCoep); + fetchInWorker(redirect); + + // Wait 1 seconds for reports to settle. + await wait(1000); + + checkReportNonExistence(reports, sameOriginUrl, worker_url.href); + checkReportNonExistence(reports, blockedByPureCorp, worker_url.href); + checkCorpReportExistence(reports, blockedDueToCoep, worker_url.href); + checkCorpReportExistence(reports, redirect, worker_url.href); + checkReportNonExistence(reports, dest, worker_url.href); + t.done(); + } catch (e) { + t.step(() => { throw e }); + } +}, 'subresource requests initiated from DedicatedWorker'); + +promise_test(async (t) => { + const suffix = 'subresource-corp-from-dedicated-worker-via-passthrough-sw'; + const iframe_src = `resources/reporting-empty-frame.html?passthrough&${suffix}`; + // Register a service worker that controls an iframe. + const registration = await service_worker_unregister_and_register( + t, 'resources/sw.js', iframe_src); + t.add_cleanup(() => registration.unregister()); + await wait_for_state(t, registration.installing, 'activated'); + + const iframe = document.createElement('iframe'); + t.add_cleanup(() => iframe.remove()); + + iframe.src = iframe_src; + document.body.appendChild(iframe); + await new Promise(resolve => { + iframe.addEventListener('load', resolve, {once: true}); + }); + + const worker_url = new URL('resources/fetch-in-dedicated-worker.js', location); + const worker = new iframe.contentWindow.Worker(worker_url); + + function fetchInWorker(url) { + const init = { mode: 'no-cors', cache: 'no-store' }; + worker.postMessage({url, init}); + return new Promise((resolve) => { + worker.addEventListener('message', resolve); + }); + } + + const sameOriginUrl = `/common/text-plain.txt?${suffix}`; + const blockedByPureCorp = `${REMOTE_ORIGIN}${BASE}/nothing-same-origin-corp.txt?${suffix}`; + const blockedDueToCoep = `${REMOTE_ORIGIN}/common/text-plain.txt?abc&${suffix}`; + const dest = `${REMOTE_ORIGIN}/common/text-plain.txt?xyz&${suffix}`; + const redirect = `/common/redirect.py?location=${encodeURIComponent(dest)}&${suffix}`; + + fetchInWorker(sameOriginUrl); + fetchInWorker(blockedByPureCorp); + fetchInWorker(blockedDueToCoep); + fetchInWorker(redirect); + + // Wait 1 seconds for reports to settle. + await wait(1000); + + checkReportNonExistence(reports, sameOriginUrl, worker_url.href); + checkReportNonExistence(reports, blockedByPureCorp, worker_url.href); + checkCorpReportExistence(reports, blockedDueToCoep, worker_url.href); + checkCorpReportExistence(reports, redirect, worker_url.href); + checkReportNonExistence(reports, dest, worker_url.href); +}, 'subresource requests initiated from DedicatedWorker controlled by a passthrough service worker'); + +promise_test(async (t) => { + const iframe_src = `resources/reporting-empty-frame.html?passthrough`; + // Register a service worker that controls an iframe. + const registration = await service_worker_unregister_and_register( + t, 'resources/sw.js', iframe_src); + t.add_cleanup(() => registration.unregister()); + await wait_for_state(t, registration.installing, 'activated'); + + const iframe = document.createElement('iframe'); + t.add_cleanup(() => iframe.remove()); + + iframe.src = iframe_src; + document.body.appendChild(iframe); + await new Promise(resolve => { + iframe.addEventListener('load', resolve, {once: true}); + }); + + async function fetchInIframe(url) { + const init = { mode: 'no-cors', cache: 'no-store' }; + // Ignore errors. + return iframe.contentWindow.fetch(url, init).catch(() => {}); + } + + const suffix = 'subresource-corp-passthrough-sw'; + const sameOriginUrl = `/common/text-plain.txt?${suffix}`; + const blockedByPureCorp = `${REMOTE_ORIGIN}${BASE}/nothing-same-origin-corp.txt?${suffix}`; + const blockedDueToCoep = `${REMOTE_ORIGIN}/common/text-plain.txt?abc&${suffix}`; + const dest = `${REMOTE_ORIGIN}/common/text-plain.txt?xyz&${suffix}`; + const redirect = `/common/redirect.py?location=${encodeURIComponent(dest)}&${suffix}`; + + fetchInIframe(sameOriginUrl); + fetchInIframe(blockedByPureCorp); + fetchInIframe(blockedDueToCoep); + fetchInIframe(redirect); + + // Wait until |reports| is ready. + await wait(1000); + + checkReportNonExistence(reports, sameOriginUrl, iframe.src); + checkReportNonExistence(reports, blockedByPureCorp, iframe.src); + checkCorpReportExistence(reports, blockedDueToCoep, iframe.src); + checkCorpReportExistence(reports, redirect, iframe.src); + checkReportNonExistence(reports, dest, iframe.src); +}, 'subresource CORP in an iframe hosted by a service worker without COEP'); +</script>$
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-to-endpoint.https.html.sub.headers b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting.https.html.sub.headers similarity index 100% rename from third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting-to-endpoint.https.html.sub.headers rename to third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/reporting.https.html.sub.headers
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-image/idlharness.window.js b/third_party/blink/web_tests/external/wpt/mediacapture-image/idlharness.window.js index 9d8f7ee..b76348b 100644 --- a/third_party/blink/web_tests/external/wpt/mediacapture-image/idlharness.window.js +++ b/third_party/blink/web_tests/external/wpt/mediacapture-image/idlharness.window.js
@@ -1,5 +1,6 @@ // META: script=/resources/WebIDLParser.js // META: script=/resources/idlharness.js +// META: timeout=long // https://w3c.github.io/mediacapture-image/
diff --git a/third_party/blink/web_tests/external/wpt/netinfo/idlharness.any.js b/third_party/blink/web_tests/external/wpt/netinfo/idlharness.any.js index 96b114f..21d55950 100644 --- a/third_party/blink/web_tests/external/wpt/netinfo/idlharness.any.js +++ b/third_party/blink/web_tests/external/wpt/netinfo/idlharness.any.js
@@ -1,5 +1,6 @@ // META: script=/resources/WebIDLParser.js // META: script=/resources/idlharness.js +// META: timeout=long 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.js b/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.js new file mode 100644 index 0000000..a6c434f5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.js
@@ -0,0 +1,53 @@ +// META: global=window,worker +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js +// META: script=cache-storage/resources/test-helpers.js +// META: script=service-worker/resources/test-helpers.sub.js +// META: timeout=long + +// https://w3c.github.io/ServiceWorker + +idl_test( + ['service-workers'], + ['dom', 'html'], + async (idl_array, t) => { + self.cacheInstance = await create_temporary_cache(t); + + idl_array.add_objects({ + CacheStorage: ['caches'], + Cache: ['self.cacheInstance'], + ServiceWorkerContainer: ['navigator.serviceWorker'] + }); + + // TODO: Add ServiceWorker and ServiceWorkerRegistration instances for the + // other worker scopes. + if (self.GLOBAL.isWindow()) { + idl_array.add_objects({ + ServiceWorkerRegistration: ['registrationInstance'], + ServiceWorker: ['registrationInstance.installing'] + }); + + const scope = 'service-worker/resources/scope/idlharness'; + const registration = await service_worker_unregister_and_register( + t, 'service-worker/resources/empty-worker.js', scope); + t.add_cleanup(() => registration.unregister()); + + self.registrationInstance = registration; + } else if (self.ServiceWorkerGlobalScope) { + // self.ServiceWorkerGlobalScope should only be defined for the + // ServiceWorker scope, which allows us to detect and test the interfaces + // exposed only for ServiceWorker. + idl_array.add_objects({ + Clients: ['clients'], + ExtendableEvent: ['new ExtendableEvent("type")'], + FetchEvent: ['new FetchEvent("type")'], + ServiceWorkerGlobalScope: ['self'], + ServiceWorkerRegistration: ['registration'], + ServiceWorker: ['serviceWorker'], + // TODO: Test instances of Client and WindowClient, e.g. + // Client: ['self.clientInstance'], + // WindowClient: ['self.windowClientInstance'] + }); + } + } +);
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.serviceworker-expected.txt new file mode 100644 index 0000000..a568348c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.serviceworker-expected.txt
@@ -0,0 +1,298 @@ +This is a testharness.js-based test. +Found 294 tests; 252 PASS, 42 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS idl_test setup +PASS idl_test validation +PASS Partial interface Navigator: original interface defined +PASS Partial interface Navigator: member names are unique +PASS Partial interface WorkerNavigator: original interface defined +PASS Partial interface WorkerNavigator: member names are unique +PASS Partial interface mixin WindowOrWorkerGlobalScope: original interface mixin defined +PASS Partial interface mixin WindowOrWorkerGlobalScope: member names are unique +PASS Partial interface mixin NavigatorID: member names are unique +PASS Partial interface Window: member names are unique +PASS ServiceWorker includes AbstractWorker: member names are unique +PASS Window includes GlobalEventHandlers: member names are unique +PASS Window includes WindowEventHandlers: member names are unique +PASS Window includes WindowOrWorkerGlobalScope: member names are unique +PASS Window includes AnimationFrameProvider: member names are unique +PASS Window includes WindowSessionStorage: member names are unique +PASS Window includes WindowLocalStorage: member names are unique +PASS WorkerGlobalScope includes WindowOrWorkerGlobalScope: member names are unique +PASS Navigator includes NavigatorID: member names are unique +PASS Navigator includes NavigatorLanguage: member names are unique +PASS Navigator includes NavigatorOnLine: member names are unique +PASS Navigator includes NavigatorContentUtils: member names are unique +PASS Navigator includes NavigatorCookies: member names are unique +PASS Navigator includes NavigatorPlugins: member names are unique +PASS Navigator includes NavigatorConcurrentHardware: member names are unique +PASS WorkerNavigator includes NavigatorID: member names are unique +PASS WorkerNavigator includes NavigatorLanguage: member names are unique +PASS WorkerNavigator includes NavigatorOnLine: member names are unique +PASS WorkerNavigator includes NavigatorConcurrentHardware: member names are unique +PASS ServiceWorker interface: existence and properties of interface object +PASS ServiceWorker interface object length +PASS ServiceWorker interface object name +PASS ServiceWorker interface: existence and properties of interface prototype object +PASS ServiceWorker interface: existence and properties of interface prototype object's "constructor" property +PASS ServiceWorker interface: existence and properties of interface prototype object's @@unscopables property +PASS ServiceWorker interface: attribute scriptURL +PASS ServiceWorker interface: attribute state +PASS ServiceWorker interface: operation postMessage(any, sequence<object>) +PASS ServiceWorker interface: operation postMessage(any, optional PostMessageOptions) +PASS ServiceWorker interface: attribute onstatechange +PASS ServiceWorker must be primary interface of serviceWorker +PASS Stringification of serviceWorker +PASS ServiceWorker interface: serviceWorker must inherit property "scriptURL" with the proper type +PASS ServiceWorker interface: serviceWorker must inherit property "state" with the proper type +PASS ServiceWorker interface: serviceWorker must inherit property "postMessage(any, sequence<object>)" with the proper type +PASS ServiceWorker interface: calling postMessage(any, sequence<object>) on serviceWorker with too few arguments must throw TypeError +PASS ServiceWorker interface: serviceWorker must inherit property "postMessage(any, optional PostMessageOptions)" with the proper type +PASS ServiceWorker interface: calling postMessage(any, optional PostMessageOptions) on serviceWorker with too few arguments must throw TypeError +PASS ServiceWorker interface: serviceWorker must inherit property "onstatechange" with the proper type +PASS ServiceWorkerRegistration interface: existence and properties of interface object +PASS ServiceWorkerRegistration interface object length +PASS ServiceWorkerRegistration interface object name +PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object +PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property +PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's @@unscopables property +PASS ServiceWorkerRegistration interface: attribute installing +PASS ServiceWorkerRegistration interface: attribute waiting +PASS ServiceWorkerRegistration interface: attribute active +PASS ServiceWorkerRegistration interface: attribute navigationPreload +PASS ServiceWorkerRegistration interface: attribute scope +PASS ServiceWorkerRegistration interface: attribute updateViaCache +PASS ServiceWorkerRegistration interface: operation update() +PASS ServiceWorkerRegistration interface: operation unregister() +PASS ServiceWorkerRegistration interface: attribute onupdatefound +PASS ServiceWorkerRegistration must be primary interface of registration +PASS Stringification of registration +PASS ServiceWorkerRegistration interface: registration must inherit property "installing" with the proper type +PASS ServiceWorkerRegistration interface: registration must inherit property "waiting" with the proper type +PASS ServiceWorkerRegistration interface: registration must inherit property "active" with the proper type +PASS ServiceWorkerRegistration interface: registration must inherit property "navigationPreload" with the proper type +PASS ServiceWorkerRegistration interface: registration must inherit property "scope" with the proper type +PASS ServiceWorkerRegistration interface: registration must inherit property "updateViaCache" with the proper type +PASS ServiceWorkerRegistration interface: registration must inherit property "update()" with the proper type +PASS ServiceWorkerRegistration interface: registration must inherit property "unregister()" with the proper type +PASS ServiceWorkerRegistration interface: registration must inherit property "onupdatefound" with the proper type +FAIL ServiceWorkerContainer interface: existence and properties of interface object assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface object length assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface object name assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: attribute controller assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: attribute ready assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: operation register(USVString, optional RegistrationOptions) assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: operation getRegistration(optional USVString) assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: operation getRegistrations() assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: operation startMessages() assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: attribute oncontrollerchange assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: attribute onmessage assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: attribute onmessageerror assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer must be primary interface of navigator.serviceWorker assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL Stringification of navigator.serviceWorker assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "controller" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "ready" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "register(USVString, optional RegistrationOptions)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: calling register(USVString, optional RegistrationOptions) on navigator.serviceWorker with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "getRegistration(optional USVString)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: calling getRegistration(optional USVString) on navigator.serviceWorker with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "getRegistrations()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "startMessages()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "oncontrollerchange" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "onmessage" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "onmessageerror" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +PASS NavigationPreloadManager interface: existence and properties of interface object +PASS NavigationPreloadManager interface object length +PASS NavigationPreloadManager interface object name +PASS NavigationPreloadManager interface: existence and properties of interface prototype object +PASS NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property +PASS NavigationPreloadManager interface: existence and properties of interface prototype object's @@unscopables property +PASS NavigationPreloadManager interface: operation enable() +PASS NavigationPreloadManager interface: operation disable() +PASS NavigationPreloadManager interface: operation setHeaderValue(ByteString) +PASS NavigationPreloadManager interface: operation getState() +PASS ServiceWorkerGlobalScope interface: existence and properties of interface object +PASS ServiceWorkerGlobalScope interface object length +PASS ServiceWorkerGlobalScope interface object name +PASS ServiceWorkerGlobalScope interface: existence and properties of interface prototype object +PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Object.setPrototypeOf should throw a TypeError +PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via __proto__ should throw a TypeError +PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Reflect.setPrototypeOf should return false +PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Object.setPrototypeOf should not throw +PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via __proto__ should not throw +PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Reflect.setPrototypeOf should return true +PASS ServiceWorkerGlobalScope interface: existence and properties of interface prototype object's "constructor" property +PASS ServiceWorkerGlobalScope interface: existence and properties of interface prototype object's @@unscopables property +PASS ServiceWorkerGlobalScope interface: attribute clients +PASS ServiceWorkerGlobalScope interface: attribute registration +PASS ServiceWorkerGlobalScope interface: attribute serviceWorker +PASS ServiceWorkerGlobalScope interface: operation skipWaiting() +PASS ServiceWorkerGlobalScope interface: attribute oninstall +PASS ServiceWorkerGlobalScope interface: attribute onactivate +PASS ServiceWorkerGlobalScope interface: attribute onfetch +PASS ServiceWorkerGlobalScope interface: attribute onmessage +PASS ServiceWorkerGlobalScope interface: attribute onmessageerror +PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Object.setPrototypeOf should throw a TypeError +PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via __proto__ should throw a TypeError +PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Reflect.setPrototypeOf should return false +PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Object.setPrototypeOf should not throw +PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via __proto__ should not throw +PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Reflect.setPrototypeOf should return true +PASS ServiceWorkerGlobalScope must be primary interface of self +PASS Stringification of self +PASS ServiceWorkerGlobalScope interface: self must inherit property "clients" with the proper type +PASS ServiceWorkerGlobalScope interface: self must inherit property "registration" with the proper type +PASS ServiceWorkerGlobalScope interface: self must inherit property "serviceWorker" with the proper type +PASS ServiceWorkerGlobalScope interface: self must inherit property "skipWaiting()" with the proper type +PASS ServiceWorkerGlobalScope interface: self must inherit property "oninstall" with the proper type +PASS ServiceWorkerGlobalScope interface: self must inherit property "onactivate" with the proper type +PASS ServiceWorkerGlobalScope interface: self must inherit property "onfetch" with the proper type +PASS ServiceWorkerGlobalScope interface: self must inherit property "onmessage" with the proper type +PASS ServiceWorkerGlobalScope interface: self must inherit property "onmessageerror" with the proper type +PASS WorkerGlobalScope interface: self must inherit property "caches" with the proper type +PASS Client interface: existence and properties of interface object +PASS Client interface object length +PASS Client interface object name +PASS Client interface: existence and properties of interface prototype object +PASS Client interface: existence and properties of interface prototype object's "constructor" property +PASS Client interface: existence and properties of interface prototype object's @@unscopables property +PASS Client interface: attribute url +PASS Client interface: attribute frameType +PASS Client interface: attribute id +PASS Client interface: attribute type +PASS Client interface: operation postMessage(any, sequence<object>) +PASS Client interface: operation postMessage(any, optional PostMessageOptions) +PASS WindowClient interface: existence and properties of interface object +PASS WindowClient interface object length +PASS WindowClient interface object name +PASS WindowClient interface: existence and properties of interface prototype object +PASS WindowClient interface: existence and properties of interface prototype object's "constructor" property +PASS WindowClient interface: existence and properties of interface prototype object's @@unscopables property +PASS WindowClient interface: attribute visibilityState +PASS WindowClient interface: attribute focused +FAIL WindowClient interface: attribute ancestorOrigins assert_true: The prototype object must have a property "ancestorOrigins" expected true got false +PASS WindowClient interface: operation focus() +PASS WindowClient interface: operation navigate(USVString) +PASS Clients interface: existence and properties of interface object +PASS Clients interface object length +PASS Clients interface object name +PASS Clients interface: existence and properties of interface prototype object +PASS Clients interface: existence and properties of interface prototype object's "constructor" property +PASS Clients interface: existence and properties of interface prototype object's @@unscopables property +PASS Clients interface: operation get(DOMString) +PASS Clients interface: operation matchAll(optional ClientQueryOptions) +PASS Clients interface: operation openWindow(USVString) +PASS Clients interface: operation claim() +PASS Clients must be primary interface of clients +PASS Stringification of clients +PASS Clients interface: clients must inherit property "get(DOMString)" with the proper type +PASS Clients interface: calling get(DOMString) on clients with too few arguments must throw TypeError +PASS Clients interface: clients must inherit property "matchAll(optional ClientQueryOptions)" with the proper type +PASS Clients interface: calling matchAll(optional ClientQueryOptions) on clients with too few arguments must throw TypeError +PASS Clients interface: clients must inherit property "openWindow(USVString)" with the proper type +PASS Clients interface: calling openWindow(USVString) on clients with too few arguments must throw TypeError +PASS Clients interface: clients must inherit property "claim()" with the proper type +PASS ExtendableEvent interface: existence and properties of interface object +PASS ExtendableEvent interface object length +PASS ExtendableEvent interface object name +PASS ExtendableEvent interface: existence and properties of interface prototype object +PASS ExtendableEvent interface: existence and properties of interface prototype object's "constructor" property +PASS ExtendableEvent interface: existence and properties of interface prototype object's @@unscopables property +PASS ExtendableEvent interface: operation waitUntil(Promise<any>) +PASS ExtendableEvent must be primary interface of new ExtendableEvent("type") +PASS Stringification of new ExtendableEvent("type") +PASS ExtendableEvent interface: new ExtendableEvent("type") must inherit property "waitUntil(Promise<any>)" with the proper type +PASS ExtendableEvent interface: calling waitUntil(Promise<any>) on new ExtendableEvent("type") with too few arguments must throw TypeError +PASS FetchEvent interface: existence and properties of interface object +PASS FetchEvent interface object length +PASS FetchEvent interface object name +PASS FetchEvent interface: existence and properties of interface prototype object +PASS FetchEvent interface: existence and properties of interface prototype object's "constructor" property +PASS FetchEvent interface: existence and properties of interface prototype object's @@unscopables property +PASS FetchEvent interface: attribute request +PASS FetchEvent interface: attribute preloadResponse +PASS FetchEvent interface: attribute clientId +PASS FetchEvent interface: attribute resultingClientId +FAIL FetchEvent interface: attribute replacesClientId assert_true: The prototype object must have a property "replacesClientId" expected true got false +PASS FetchEvent interface: operation respondWith(Promise<Response>) +FAIL FetchEvent must be primary interface of new FetchEvent("type") assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'FetchEvent': 2 arguments required, but only 1 present." +FAIL Stringification of new FetchEvent("type") assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'FetchEvent': 2 arguments required, but only 1 present." +FAIL FetchEvent interface: new FetchEvent("type") must inherit property "request" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'FetchEvent': 2 arguments required, but only 1 present." +FAIL FetchEvent interface: new FetchEvent("type") must inherit property "preloadResponse" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'FetchEvent': 2 arguments required, but only 1 present." +FAIL FetchEvent interface: new FetchEvent("type") must inherit property "clientId" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'FetchEvent': 2 arguments required, but only 1 present." +FAIL FetchEvent interface: new FetchEvent("type") must inherit property "resultingClientId" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'FetchEvent': 2 arguments required, but only 1 present." +FAIL FetchEvent interface: new FetchEvent("type") must inherit property "replacesClientId" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'FetchEvent': 2 arguments required, but only 1 present." +FAIL FetchEvent interface: new FetchEvent("type") must inherit property "respondWith(Promise<Response>)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'FetchEvent': 2 arguments required, but only 1 present." +FAIL FetchEvent interface: calling respondWith(Promise<Response>) on new FetchEvent("type") with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'FetchEvent': 2 arguments required, but only 1 present." +FAIL ExtendableEvent interface: new FetchEvent("type") must inherit property "waitUntil(Promise<any>)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'FetchEvent': 2 arguments required, but only 1 present." +FAIL ExtendableEvent interface: calling waitUntil(Promise<any>) on new FetchEvent("type") with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'FetchEvent': 2 arguments required, but only 1 present." +PASS ExtendableMessageEvent interface: existence and properties of interface object +PASS ExtendableMessageEvent interface object length +PASS ExtendableMessageEvent interface object name +PASS ExtendableMessageEvent interface: existence and properties of interface prototype object +PASS ExtendableMessageEvent interface: existence and properties of interface prototype object's "constructor" property +PASS ExtendableMessageEvent interface: existence and properties of interface prototype object's @@unscopables property +PASS ExtendableMessageEvent interface: attribute data +PASS ExtendableMessageEvent interface: attribute origin +PASS ExtendableMessageEvent interface: attribute lastEventId +PASS ExtendableMessageEvent interface: attribute source +PASS ExtendableMessageEvent interface: attribute ports +PASS Cache interface: existence and properties of interface object +PASS Cache interface object length +PASS Cache interface object name +PASS Cache interface: existence and properties of interface prototype object +PASS Cache interface: existence and properties of interface prototype object's "constructor" property +PASS Cache interface: existence and properties of interface prototype object's @@unscopables property +PASS Cache interface: operation match(RequestInfo, optional CacheQueryOptions) +PASS Cache interface: operation matchAll(optional RequestInfo, optional CacheQueryOptions) +PASS Cache interface: operation add(RequestInfo) +PASS Cache interface: operation addAll(sequence<RequestInfo>) +PASS Cache interface: operation put(RequestInfo, Response) +PASS Cache interface: operation delete(RequestInfo, optional CacheQueryOptions) +PASS Cache interface: operation keys(optional RequestInfo, optional CacheQueryOptions) +PASS Cache must be primary interface of self.cacheInstance +PASS Stringification of self.cacheInstance +PASS Cache interface: self.cacheInstance must inherit property "match(RequestInfo, optional CacheQueryOptions)" with the proper type +PASS Cache interface: calling match(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "matchAll(optional RequestInfo, optional CacheQueryOptions)" with the proper type +PASS Cache interface: calling matchAll(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "add(RequestInfo)" with the proper type +PASS Cache interface: calling add(RequestInfo) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "addAll(sequence<RequestInfo>)" with the proper type +PASS Cache interface: calling addAll(sequence<RequestInfo>) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "put(RequestInfo, Response)" with the proper type +PASS Cache interface: calling put(RequestInfo, Response) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "delete(RequestInfo, optional CacheQueryOptions)" with the proper type +PASS Cache interface: calling delete(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "keys(optional RequestInfo, optional CacheQueryOptions)" with the proper type +PASS Cache interface: calling keys(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError +PASS CacheStorage interface: existence and properties of interface object +PASS CacheStorage interface object length +PASS CacheStorage interface object name +PASS CacheStorage interface: existence and properties of interface prototype object +PASS CacheStorage interface: existence and properties of interface prototype object's "constructor" property +PASS CacheStorage interface: existence and properties of interface prototype object's @@unscopables property +PASS CacheStorage interface: operation match(RequestInfo, optional MultiCacheQueryOptions) +PASS CacheStorage interface: operation has(DOMString) +PASS CacheStorage interface: operation open(DOMString) +PASS CacheStorage interface: operation delete(DOMString) +PASS CacheStorage interface: operation keys() +PASS CacheStorage must be primary interface of caches +PASS Stringification of caches +PASS CacheStorage interface: caches must inherit property "match(RequestInfo, optional MultiCacheQueryOptions)" with the proper type +PASS CacheStorage interface: calling match(RequestInfo, optional MultiCacheQueryOptions) on caches with too few arguments must throw TypeError +PASS CacheStorage interface: caches must inherit property "has(DOMString)" with the proper type +PASS CacheStorage interface: calling has(DOMString) on caches with too few arguments must throw TypeError +PASS CacheStorage interface: caches must inherit property "open(DOMString)" with the proper type +PASS CacheStorage interface: calling open(DOMString) on caches with too few arguments must throw TypeError +PASS CacheStorage interface: caches must inherit property "delete(DOMString)" with the proper type +PASS CacheStorage interface: calling delete(DOMString) on caches with too few arguments must throw TypeError +PASS CacheStorage interface: caches must inherit property "keys()" with the proper type +PASS Window interface: existence and properties of interface object +PASS Navigator interface: existence and properties of interface object +PASS WorkerGlobalScope interface: attribute caches +FAIL WorkerNavigator interface: attribute serviceWorker assert_true: The prototype object must have a property "serviceWorker" expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.sharedworker-expected.txt new file mode 100644 index 0000000..b1a70df --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.sharedworker-expected.txt
@@ -0,0 +1,159 @@ +This is a testharness.js-based test. +Found 155 tests; 115 PASS, 40 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS idl_test setup +PASS idl_test validation +PASS Partial interface Navigator: original interface defined +PASS Partial interface Navigator: member names are unique +PASS Partial interface WorkerNavigator: original interface defined +PASS Partial interface WorkerNavigator: member names are unique +PASS Partial interface mixin WindowOrWorkerGlobalScope: original interface mixin defined +PASS Partial interface mixin WindowOrWorkerGlobalScope: member names are unique +PASS Partial interface mixin NavigatorID: member names are unique +PASS Partial interface Window: member names are unique +PASS ServiceWorker includes AbstractWorker: member names are unique +PASS Window includes GlobalEventHandlers: member names are unique +PASS Window includes WindowEventHandlers: member names are unique +PASS Window includes WindowOrWorkerGlobalScope: member names are unique +PASS Window includes AnimationFrameProvider: member names are unique +PASS Window includes WindowSessionStorage: member names are unique +PASS Window includes WindowLocalStorage: member names are unique +PASS WorkerGlobalScope includes WindowOrWorkerGlobalScope: member names are unique +PASS Navigator includes NavigatorID: member names are unique +PASS Navigator includes NavigatorLanguage: member names are unique +PASS Navigator includes NavigatorOnLine: member names are unique +PASS Navigator includes NavigatorContentUtils: member names are unique +PASS Navigator includes NavigatorCookies: member names are unique +PASS Navigator includes NavigatorPlugins: member names are unique +PASS Navigator includes NavigatorConcurrentHardware: member names are unique +PASS WorkerNavigator includes NavigatorID: member names are unique +PASS WorkerNavigator includes NavigatorLanguage: member names are unique +PASS WorkerNavigator includes NavigatorOnLine: member names are unique +PASS WorkerNavigator includes NavigatorConcurrentHardware: member names are unique +FAIL ServiceWorker interface: existence and properties of interface object assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface object length assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface object name assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: attribute scriptURL assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: attribute state assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: operation postMessage(any, sequence<object>) assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: operation postMessage(any, optional PostMessageOptions) assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: attribute onstatechange assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +PASS ServiceWorkerRegistration interface: existence and properties of interface object +PASS ServiceWorkerRegistration interface object length +PASS ServiceWorkerRegistration interface object name +PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object +PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property +PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's @@unscopables property +PASS ServiceWorkerRegistration interface: attribute installing +PASS ServiceWorkerRegistration interface: attribute waiting +PASS ServiceWorkerRegistration interface: attribute active +PASS ServiceWorkerRegistration interface: attribute navigationPreload +PASS ServiceWorkerRegistration interface: attribute scope +PASS ServiceWorkerRegistration interface: attribute updateViaCache +PASS ServiceWorkerRegistration interface: operation update() +PASS ServiceWorkerRegistration interface: operation unregister() +PASS ServiceWorkerRegistration interface: attribute onupdatefound +FAIL ServiceWorkerContainer interface: existence and properties of interface object assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface object length assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface object name assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: attribute controller assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: attribute ready assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: operation register(USVString, optional RegistrationOptions) assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: operation getRegistration(optional USVString) assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: operation getRegistrations() assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: operation startMessages() assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: attribute oncontrollerchange assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: attribute onmessage assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: attribute onmessageerror assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer must be primary interface of navigator.serviceWorker assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL Stringification of navigator.serviceWorker assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "controller" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "ready" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "register(USVString, optional RegistrationOptions)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: calling register(USVString, optional RegistrationOptions) on navigator.serviceWorker with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "getRegistration(optional USVString)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: calling getRegistration(optional USVString) on navigator.serviceWorker with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "getRegistrations()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "startMessages()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "oncontrollerchange" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "onmessage" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "onmessageerror" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +PASS NavigationPreloadManager interface: existence and properties of interface object +PASS NavigationPreloadManager interface object length +PASS NavigationPreloadManager interface object name +PASS NavigationPreloadManager interface: existence and properties of interface prototype object +PASS NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property +PASS NavigationPreloadManager interface: existence and properties of interface prototype object's @@unscopables property +PASS NavigationPreloadManager interface: operation enable() +PASS NavigationPreloadManager interface: operation disable() +PASS NavigationPreloadManager interface: operation setHeaderValue(ByteString) +PASS NavigationPreloadManager interface: operation getState() +PASS ServiceWorkerGlobalScope interface: existence and properties of interface object +PASS Client interface: existence and properties of interface object +PASS WindowClient interface: existence and properties of interface object +PASS Clients interface: existence and properties of interface object +PASS ExtendableEvent interface: existence and properties of interface object +PASS FetchEvent interface: existence and properties of interface object +PASS ExtendableMessageEvent interface: existence and properties of interface object +PASS Cache interface: existence and properties of interface object +PASS Cache interface object length +PASS Cache interface object name +PASS Cache interface: existence and properties of interface prototype object +PASS Cache interface: existence and properties of interface prototype object's "constructor" property +PASS Cache interface: existence and properties of interface prototype object's @@unscopables property +PASS Cache interface: operation match(RequestInfo, optional CacheQueryOptions) +PASS Cache interface: operation matchAll(optional RequestInfo, optional CacheQueryOptions) +PASS Cache interface: operation add(RequestInfo) +PASS Cache interface: operation addAll(sequence<RequestInfo>) +PASS Cache interface: operation put(RequestInfo, Response) +PASS Cache interface: operation delete(RequestInfo, optional CacheQueryOptions) +PASS Cache interface: operation keys(optional RequestInfo, optional CacheQueryOptions) +PASS Cache must be primary interface of self.cacheInstance +PASS Stringification of self.cacheInstance +PASS Cache interface: self.cacheInstance must inherit property "match(RequestInfo, optional CacheQueryOptions)" with the proper type +PASS Cache interface: calling match(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "matchAll(optional RequestInfo, optional CacheQueryOptions)" with the proper type +PASS Cache interface: calling matchAll(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "add(RequestInfo)" with the proper type +PASS Cache interface: calling add(RequestInfo) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "addAll(sequence<RequestInfo>)" with the proper type +PASS Cache interface: calling addAll(sequence<RequestInfo>) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "put(RequestInfo, Response)" with the proper type +PASS Cache interface: calling put(RequestInfo, Response) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "delete(RequestInfo, optional CacheQueryOptions)" with the proper type +PASS Cache interface: calling delete(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "keys(optional RequestInfo, optional CacheQueryOptions)" with the proper type +PASS Cache interface: calling keys(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError +PASS CacheStorage interface: existence and properties of interface object +PASS CacheStorage interface object length +PASS CacheStorage interface object name +PASS CacheStorage interface: existence and properties of interface prototype object +PASS CacheStorage interface: existence and properties of interface prototype object's "constructor" property +PASS CacheStorage interface: existence and properties of interface prototype object's @@unscopables property +PASS CacheStorage interface: operation match(RequestInfo, optional MultiCacheQueryOptions) +PASS CacheStorage interface: operation has(DOMString) +PASS CacheStorage interface: operation open(DOMString) +PASS CacheStorage interface: operation delete(DOMString) +PASS CacheStorage interface: operation keys() +PASS CacheStorage must be primary interface of caches +PASS Stringification of caches +PASS CacheStorage interface: caches must inherit property "match(RequestInfo, optional MultiCacheQueryOptions)" with the proper type +PASS CacheStorage interface: calling match(RequestInfo, optional MultiCacheQueryOptions) on caches with too few arguments must throw TypeError +PASS CacheStorage interface: caches must inherit property "has(DOMString)" with the proper type +PASS CacheStorage interface: calling has(DOMString) on caches with too few arguments must throw TypeError +PASS CacheStorage interface: caches must inherit property "open(DOMString)" with the proper type +PASS CacheStorage interface: calling open(DOMString) on caches with too few arguments must throw TypeError +PASS CacheStorage interface: caches must inherit property "delete(DOMString)" with the proper type +PASS CacheStorage interface: calling delete(DOMString) on caches with too few arguments must throw TypeError +PASS CacheStorage interface: caches must inherit property "keys()" with the proper type +PASS Window interface: existence and properties of interface object +PASS Navigator interface: existence and properties of interface object +PASS WorkerGlobalScope interface: attribute caches +FAIL WorkerNavigator interface: attribute serviceWorker assert_true: The prototype object must have a property "serviceWorker" expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.worker-expected.txt new file mode 100644 index 0000000..b1a70df --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.worker-expected.txt
@@ -0,0 +1,159 @@ +This is a testharness.js-based test. +Found 155 tests; 115 PASS, 40 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS idl_test setup +PASS idl_test validation +PASS Partial interface Navigator: original interface defined +PASS Partial interface Navigator: member names are unique +PASS Partial interface WorkerNavigator: original interface defined +PASS Partial interface WorkerNavigator: member names are unique +PASS Partial interface mixin WindowOrWorkerGlobalScope: original interface mixin defined +PASS Partial interface mixin WindowOrWorkerGlobalScope: member names are unique +PASS Partial interface mixin NavigatorID: member names are unique +PASS Partial interface Window: member names are unique +PASS ServiceWorker includes AbstractWorker: member names are unique +PASS Window includes GlobalEventHandlers: member names are unique +PASS Window includes WindowEventHandlers: member names are unique +PASS Window includes WindowOrWorkerGlobalScope: member names are unique +PASS Window includes AnimationFrameProvider: member names are unique +PASS Window includes WindowSessionStorage: member names are unique +PASS Window includes WindowLocalStorage: member names are unique +PASS WorkerGlobalScope includes WindowOrWorkerGlobalScope: member names are unique +PASS Navigator includes NavigatorID: member names are unique +PASS Navigator includes NavigatorLanguage: member names are unique +PASS Navigator includes NavigatorOnLine: member names are unique +PASS Navigator includes NavigatorContentUtils: member names are unique +PASS Navigator includes NavigatorCookies: member names are unique +PASS Navigator includes NavigatorPlugins: member names are unique +PASS Navigator includes NavigatorConcurrentHardware: member names are unique +PASS WorkerNavigator includes NavigatorID: member names are unique +PASS WorkerNavigator includes NavigatorLanguage: member names are unique +PASS WorkerNavigator includes NavigatorOnLine: member names are unique +PASS WorkerNavigator includes NavigatorConcurrentHardware: member names are unique +FAIL ServiceWorker interface: existence and properties of interface object assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface object length assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface object name assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: attribute scriptURL assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: attribute state assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: operation postMessage(any, sequence<object>) assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: operation postMessage(any, optional PostMessageOptions) assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: attribute onstatechange assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +PASS ServiceWorkerRegistration interface: existence and properties of interface object +PASS ServiceWorkerRegistration interface object length +PASS ServiceWorkerRegistration interface object name +PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object +PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property +PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's @@unscopables property +PASS ServiceWorkerRegistration interface: attribute installing +PASS ServiceWorkerRegistration interface: attribute waiting +PASS ServiceWorkerRegistration interface: attribute active +PASS ServiceWorkerRegistration interface: attribute navigationPreload +PASS ServiceWorkerRegistration interface: attribute scope +PASS ServiceWorkerRegistration interface: attribute updateViaCache +PASS ServiceWorkerRegistration interface: operation update() +PASS ServiceWorkerRegistration interface: operation unregister() +PASS ServiceWorkerRegistration interface: attribute onupdatefound +FAIL ServiceWorkerContainer interface: existence and properties of interface object assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface object length assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface object name assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: attribute controller assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: attribute ready assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: operation register(USVString, optional RegistrationOptions) assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: operation getRegistration(optional USVString) assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: operation getRegistrations() assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: operation startMessages() assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: attribute oncontrollerchange assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: attribute onmessage assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: attribute onmessageerror assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer must be primary interface of navigator.serviceWorker assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL Stringification of navigator.serviceWorker assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "controller" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "ready" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "register(USVString, optional RegistrationOptions)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: calling register(USVString, optional RegistrationOptions) on navigator.serviceWorker with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "getRegistration(optional USVString)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: calling getRegistration(optional USVString) on navigator.serviceWorker with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "getRegistrations()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "startMessages()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "oncontrollerchange" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "onmessage" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "onmessageerror" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +PASS NavigationPreloadManager interface: existence and properties of interface object +PASS NavigationPreloadManager interface object length +PASS NavigationPreloadManager interface object name +PASS NavigationPreloadManager interface: existence and properties of interface prototype object +PASS NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property +PASS NavigationPreloadManager interface: existence and properties of interface prototype object's @@unscopables property +PASS NavigationPreloadManager interface: operation enable() +PASS NavigationPreloadManager interface: operation disable() +PASS NavigationPreloadManager interface: operation setHeaderValue(ByteString) +PASS NavigationPreloadManager interface: operation getState() +PASS ServiceWorkerGlobalScope interface: existence and properties of interface object +PASS Client interface: existence and properties of interface object +PASS WindowClient interface: existence and properties of interface object +PASS Clients interface: existence and properties of interface object +PASS ExtendableEvent interface: existence and properties of interface object +PASS FetchEvent interface: existence and properties of interface object +PASS ExtendableMessageEvent interface: existence and properties of interface object +PASS Cache interface: existence and properties of interface object +PASS Cache interface object length +PASS Cache interface object name +PASS Cache interface: existence and properties of interface prototype object +PASS Cache interface: existence and properties of interface prototype object's "constructor" property +PASS Cache interface: existence and properties of interface prototype object's @@unscopables property +PASS Cache interface: operation match(RequestInfo, optional CacheQueryOptions) +PASS Cache interface: operation matchAll(optional RequestInfo, optional CacheQueryOptions) +PASS Cache interface: operation add(RequestInfo) +PASS Cache interface: operation addAll(sequence<RequestInfo>) +PASS Cache interface: operation put(RequestInfo, Response) +PASS Cache interface: operation delete(RequestInfo, optional CacheQueryOptions) +PASS Cache interface: operation keys(optional RequestInfo, optional CacheQueryOptions) +PASS Cache must be primary interface of self.cacheInstance +PASS Stringification of self.cacheInstance +PASS Cache interface: self.cacheInstance must inherit property "match(RequestInfo, optional CacheQueryOptions)" with the proper type +PASS Cache interface: calling match(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "matchAll(optional RequestInfo, optional CacheQueryOptions)" with the proper type +PASS Cache interface: calling matchAll(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "add(RequestInfo)" with the proper type +PASS Cache interface: calling add(RequestInfo) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "addAll(sequence<RequestInfo>)" with the proper type +PASS Cache interface: calling addAll(sequence<RequestInfo>) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "put(RequestInfo, Response)" with the proper type +PASS Cache interface: calling put(RequestInfo, Response) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "delete(RequestInfo, optional CacheQueryOptions)" with the proper type +PASS Cache interface: calling delete(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "keys(optional RequestInfo, optional CacheQueryOptions)" with the proper type +PASS Cache interface: calling keys(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError +PASS CacheStorage interface: existence and properties of interface object +PASS CacheStorage interface object length +PASS CacheStorage interface object name +PASS CacheStorage interface: existence and properties of interface prototype object +PASS CacheStorage interface: existence and properties of interface prototype object's "constructor" property +PASS CacheStorage interface: existence and properties of interface prototype object's @@unscopables property +PASS CacheStorage interface: operation match(RequestInfo, optional MultiCacheQueryOptions) +PASS CacheStorage interface: operation has(DOMString) +PASS CacheStorage interface: operation open(DOMString) +PASS CacheStorage interface: operation delete(DOMString) +PASS CacheStorage interface: operation keys() +PASS CacheStorage must be primary interface of caches +PASS Stringification of caches +PASS CacheStorage interface: caches must inherit property "match(RequestInfo, optional MultiCacheQueryOptions)" with the proper type +PASS CacheStorage interface: calling match(RequestInfo, optional MultiCacheQueryOptions) on caches with too few arguments must throw TypeError +PASS CacheStorage interface: caches must inherit property "has(DOMString)" with the proper type +PASS CacheStorage interface: calling has(DOMString) on caches with too few arguments must throw TypeError +PASS CacheStorage interface: caches must inherit property "open(DOMString)" with the proper type +PASS CacheStorage interface: calling open(DOMString) on caches with too few arguments must throw TypeError +PASS CacheStorage interface: caches must inherit property "delete(DOMString)" with the proper type +PASS CacheStorage interface: calling delete(DOMString) on caches with too few arguments must throw TypeError +PASS CacheStorage interface: caches must inherit property "keys()" with the proper type +PASS Window interface: existence and properties of interface object +PASS Navigator interface: existence and properties of interface object +PASS WorkerGlobalScope interface: attribute caches +FAIL WorkerNavigator interface: attribute serviceWorker assert_true: The prototype object must have a property "serviceWorker" expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/data-iframe.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/data-iframe.html new file mode 100644 index 0000000..d767d57 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/data-iframe.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<title>Service Workers in data iframes</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/test-helpers.sub.js"></script> +<body></body> +<script> +'use strict'; + +promise_test(t => { + const url = encodeURI(`data:text/html,<!DOCTYPE html> + <script> + parent.postMessage({ isDefined: 'serviceWorker' in navigator }, '*'); + </` + `script>`); + var p = new Promise((resolve, reject) => { + window.addEventListener('message', event => { + resolve(event.data.isDefined); + }); + }); + with_iframe(url); + return p.then(isDefined => { + assert_false(isDefined, 'navigator.serviceWorker should not be defined in iframe'); + }); +}, 'navigator.serviceWorker is not available in a data: iframe'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/idlharness-window.https.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/idlharness-window.https.html deleted file mode 100644 index cc3bdaf11..0000000 --- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/idlharness-window.https.html +++ /dev/null
@@ -1,70 +0,0 @@ -<!DOCTYPE html> -<title>Service Worker: Interfaces</title> -<meta name="timeout" content="long"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/resources/WebIDLParser.js"></script> -<script src="/resources/idlharness.js"></script> -<script src="resources/test-helpers.sub.js"></script> -<script> -'use strict'; - -promise_test(async (t) => { - const srcs = ['dom', 'html', 'service-workers']; - const [dom, html, serviceWorkerIdl] = await Promise.all( - srcs.map(i => fetch(`/interfaces/${i}.idl`).then(r => r.text()))); - - var idlArray = new IdlArray(); - idlArray.add_idls(serviceWorkerIdl, { only: [ - 'ServiceWorkerGlobalScope', - 'Client', - 'WindowClient', - 'Clients', - 'ServiceWorker', - 'ServiceWorkerState', - 'ServiceWorkerUpdateViaCache', - 'ServiceWorkerRegistration', - 'EventTarget', - 'NavigationPreloadManager', - 'Cache', - 'CacheStorage', - ]}); - idlArray.add_dependency_idls(dom); - idlArray.add_dependency_idls(html); - idlArray.add_objects({ - ServiceWorkerContainer: ['navigator.serviceWorker'] - }); - var scope = 'resources/scope/interfaces-and-attributes'; - - return service_worker_unregister_and_register( - t, 'resources/empty-worker.js', scope) - .then(function(registration) { - t.add_cleanup(function() { - return registration.unregister(); - }); - - window.registrationInstance = registration; - idlArray.add_objects({ - ServiceWorkerRegistration: ['window.registrationInstance'], - ServiceWorker: ['window.registrationInstance.installing'] - }); - idlArray.test(); - }); -}, 'test setup (worker registration)'); - -promise_test(t => { - const url = encodeURI(`data:text/html,<!DOCTYPE html> - <script> - parent.postMessage({ isDefined: 'serviceWorker' in navigator }, '*'); - </` + `script>`); - var p = new Promise((resolve, reject) => { - window.addEventListener('message', event => { - resolve(event.data.isDefined); - }); - }); - with_iframe(url); - return p.then(isDefined => { - assert_false(isDefined, 'navigator.serviceWorker should not be defined in iframe'); - }); -}, 'navigator.serviceWorker is not available in a data: iframe'); -</script>
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/interface-requirements-sw.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/interface-requirements-sw.https-expected.txt new file mode 100644 index 0000000..42f0b416 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/interface-requirements-sw.https-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +PASS Interfaces and attributes in ServiceWorkerGlobalScope +FAIL Event constructors assert_equals: FetchEvent.isReload should not exist expected (undefined) undefined but got (boolean) false +PASS xhr is not exposed +PASS URL.createObjectURL is not exposed +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/idlharness-sw.https.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/interface-requirements-sw.https.html similarity index 63% rename from third_party/blink/web_tests/external/wpt/service-workers/service-worker/idlharness-sw.https.html rename to third_party/blink/web_tests/external/wpt/service-workers/service-worker/interface-requirements-sw.https.html index 5209cc6..eef868c 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/idlharness-sw.https.html +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/interface-requirements-sw.https.html
@@ -7,9 +7,10 @@ <script> 'use strict'; -// NOTE: affected when 'resources/idlharness-worker.sub.js' srcs change: -// const srcs = ['dom', 'html', 'service-workers']; +// interface-requirements-worker.sub.js checks additional interface +// requirements, on top of the basic IDL that is validated in +// service-workers/idlharness.any.js service_worker_test( - 'resources/idlharness-worker.sub.js', + 'resources/interface-requirements-worker.sub.js', 'Interfaces and attributes in ServiceWorkerGlobalScope'); </script>
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/next-hop-protocol.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/next-hop-protocol.https-expected.txt new file mode 100644 index 0000000..c6d12e4eb --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/next-hop-protocol.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS nextHopProtocol reports H1 correctly when routed via a service worker. +FAIL nextHopProtocol reports H2 correctly when routed via a service worker. assert_equals: nextHopProtocol is set on fallback expected "h2" but got "http/1.1" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/next-hop-protocol.https.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/next-hop-protocol.https.html new file mode 100644 index 0000000..7a90743 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/next-hop-protocol.https.html
@@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Service Worker: Verify nextHopProtocol is set correctly</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/test-helpers.sub.js"></script> +<script> + +async function getNextHopProtocol(frame, url) { + let final_url = new URL(url, self.location).href; + await frame.contentWindow.fetch(final_url).then(r => r.text()); + let entryList = frame.contentWindow.performance.getEntriesByName(final_url); + let entry = entryList[entryList.length - 1]; + return entry.nextHopProtocol; +} + +async function runTest(t, base_url, expected_protocol) { + const scope = 'resources/empty.html?next-hop-protocol'; + const script = 'resources/fetch-rewrite-worker.js'; + let frame; + + const registration = + await service_worker_unregister_and_register(t, script, scope); + t.add_cleanup(async _ => registration.unregister()); + await wait_for_state(t, registration.installing, 'activated'); + frame = await with_iframe(scope); + t.add_cleanup(_ => frame.remove()); + + assert_equals(await getNextHopProtocol(frame, `${base_url}?generate-png`), + '', 'nextHopProtocol is not set on synthetic response'); + assert_equals(await getNextHopProtocol(frame, `${base_url}?ignore`), + expected_protocol, 'nextHopProtocol is set on fallback'); + assert_equals(await getNextHopProtocol(frame, `${base_url}`), + expected_protocol, 'nextHopProtocol is set on pass-through'); + assert_equals(await getNextHopProtocol(frame, `${base_url}?cache`), + expected_protocol, 'nextHopProtocol is set on cached response'); +} + +promise_test(async (t) => { + return runTest(t, 'resources/empty.js', 'http/1.1'); +}, 'nextHopProtocol reports H1 correctly when routed via a service worker.'); + +// This may be expected to fail if the WPT infrastructure does not fully +// support H2 protocol testing yet. +promise_test(async (t) => { + return runTest(t, 'resources/empty.h2.js', 'h2'); +}, 'nextHopProtocol reports H2 correctly when routed via a service worker.'); + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/empty.h2.js b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/empty.h2.js new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/empty.h2.js
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/idlharness-worker.sub.js b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/interface-requirements-worker.sub.js similarity index 63% rename from third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/idlharness-worker.sub.js rename to third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/interface-requirements-worker.sub.js index 44bd087..a3f239b6 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/idlharness-worker.sub.js +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/interface-requirements-worker.sub.js
@@ -1,48 +1,9 @@ 'use strict'; -importScripts('worker-testharness.js'); -importScripts('/resources/WebIDLParser.js'); -importScripts('/resources/idlharness.js'); +// This file checks additional interface requirements, on top of the basic IDL +// that is validated in service-workers/idlharness.any.js -promise_test(async (t) => { - const srcs = ['dom', 'html', 'service-workers']; - const [dom, html, serviceWorkerIdl] = await Promise.all( - srcs.map(i => fetch(`/interfaces/${i}.idl`).then(r => r.text()))); - - var idlArray = new IdlArray(); - idlArray.add_idls(serviceWorkerIdl, { only: [ - 'ServiceWorkerGlobalScope', - 'Client', - 'WindowClient', - 'Clients', - 'ServiceWorker', - 'ServiceWorkerState', - 'ServiceWorkerUpdateViaCache', - 'ServiceWorkerRegistration', - 'EventTarget', - 'NavigationPreloadManager', - 'Cache', - 'CacheStorage', - ]}); - idlArray.add_dependency_idls(dom); - idlArray.add_dependency_idls(html); - idlArray.add_objects({ - ServiceWorkerGlobalScope: ['self'], - Clients: ['self.clients'], - ServiceWorkerRegistration: ['self.registration'], - CacheStorage: ['self.caches'] - // TODO: Test instances of Client and WindowClient, e.g. - // Client: ['self.clientInstance'], - // WindowClient: ['self.windowClientInstance'] - }); - return create_temporary_cache(t) - .then(function(cache) { - self.cacheInstance = cache; - - idlArray.add_objects({ Cache: ['self.cacheInstance'] }); - idlArray.test(); - }); -}, 'test setup (cache creation)'); +importScripts('/resources/testharness.js'); test(function() { var req = new Request('http://{{host}}/',
diff --git a/third_party/blink/web_tests/external/wpt/tools/serve/serve.py b/third_party/blink/web_tests/external/wpt/tools/serve/serve.py index 0e5090c..43ff7bd0 100644 --- a/third_party/blink/web_tests/external/wpt/tools/serve/serve.py +++ b/third_party/blink/web_tests/external/wpt/tools/serve/serve.py
@@ -922,17 +922,22 @@ signal.signal(signal.SIGTERM, handle_signal) signal.signal(signal.SIGINT, handle_signal) - while (all(item.is_alive() for item in iter_procs(servers)) and + while (all(subproc.is_alive() for subproc in iter_procs(servers)) and not received_signal.is_set()): - for item in iter_procs(servers): - item.join(1) - exited = [item for item in iter_procs(servers) if not item.is_alive()] - subject = "subprocess" if len(exited) == 1 else "subprocesses" + for subproc in iter_procs(servers): + subproc.join(1) - logger.info("%s %s exited:" % (len(exited), subject)) - - for item in iter_procs(servers): - logger.info("Status of %s:\t%s" % (item.name, "running" if item.is_alive() else "not running")) + failed_subproc = 0 + for subproc in iter_procs(servers): + if subproc.is_alive(): + logger.info('Status of subprocess "%s": running' % subproc.name) + else: + if subproc.exitcode == 0: + logger.info('Status of subprocess "%s": exited correctly' % subproc.name) + else: + logger.warning('Status of subprocess "%s": failed. Exit with non-zero status: %d' % (subproc.name, subproc.exitcode)) + failed_subproc += 1 + return failed_subproc def main():
diff --git a/third_party/blink/web_tests/external/wpt/web-share/idlharness.https.window.js b/third_party/blink/web_tests/external/wpt/web-share/idlharness.https.window.js index 1520387..fbe59864a 100644 --- a/third_party/blink/web_tests/external/wpt/web-share/idlharness.https.window.js +++ b/third_party/blink/web_tests/external/wpt/web-share/idlharness.https.window.js
@@ -1,5 +1,6 @@ // META: script=/resources/WebIDLParser.js // META: script=/resources/idlharness.js +// META: timeout=long // https://w3c.github.io/web-share/
diff --git a/third_party/blink/web_tests/fast/dom/Window/mozilla-focus-blur.html b/third_party/blink/web_tests/fast/dom/Window/mozilla-focus-blur.html index 98de853..b5cad4b 100644 --- a/third_party/blink/web_tests/fast/dom/Window/mozilla-focus-blur.html +++ b/third_party/blink/web_tests/fast/dom/Window/mozilla-focus-blur.html
@@ -30,7 +30,7 @@ action(w); - roundTripToBrowserThen(() => { + roundTripToBrowser().then(() => { originatingWindow.removeEventListener('focus', failHandler, false); w.removeEventListener('blur', failHandler, false); @@ -92,7 +92,7 @@ focusWithUserGesture(w); - roundTripToBrowserThen(() => { + roundTripToBrowser().then(() => { w.removeEventListener('focus', handler, false); log(!fail, 'The last opened window should be able to get focus');
diff --git a/third_party/blink/web_tests/fast/media/mq-shape-expected.html b/third_party/blink/web_tests/fast/media/mq-shape-expected.html deleted file mode 100644 index b538565a..0000000 --- a/third_party/blink/web_tests/fast/media/mq-shape-expected.html +++ /dev/null
@@ -1,22 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<style> - body { - background: gray; - } - - div { - border: 2px solid black; - background: blue; - height:300px; - width: 300px; - } -</style> -</head> -<body> -<div> - This page should have a rectagle box and the background should be blue. -</div> -</body> -</html>
diff --git a/third_party/blink/web_tests/fast/media/mq-shape.html b/third_party/blink/web_tests/fast/media/mq-shape.html deleted file mode 100644 index 5c086a5d2..0000000 --- a/third_party/blink/web_tests/fast/media/mq-shape.html +++ /dev/null
@@ -1,27 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<style> - body { - background: red; - } - @media (shape: rect) { - body { - background: gray; - } - - div { - border: 2px solid black; - background: blue; - height:300px; - width: 300px; - } - } -</style> -</head> -<body> -<div> - This page should have a rectagle box and the background should be blue. -</div> -</body> -</html>
diff --git a/third_party/blink/web_tests/geolocation-api/watchPosition-page-visibility.html b/third_party/blink/web_tests/geolocation-api/watchPosition-page-visibility.html index afde45f..096b674 100644 --- a/third_party/blink/web_tests/geolocation-api/watchPosition-page-visibility.html +++ b/third_party/blink/web_tests/geolocation-api/watchPosition-page-visibility.html
@@ -2,6 +2,7 @@ <html> <head> <script src="../resources/js-test.js"></script> +<script src="../resources/user-gesture-utils.js"></script> <script src="../resources/visibility.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/device/geolocation/public/interfaces/geolocation.mojom.js"></script> @@ -67,19 +68,27 @@ state++; checkPosition(p); switch(state) { + case 1: + updatePosition(); + break; case 2: { debug("* Hiding page"); setMainWindowHidden(true).then(() => { isPageVisible = false; - showPageAndUpdatePosition(); + // This should not be received. + updatePosition(); + // Wait for it to not be received, then continue. + roundTripToBrowser().then(showPageAndUpdatePosition); }); break; } + case 3: + updatePosition(); + break; case 4: finishJSTest(); return; } - updatePosition(); }, function(e) { testFailed('Error callback invoked unexpectedly'); finishJSTest();
diff --git a/third_party/blink/web_tests/http/tests/resources/user-gesture-utils.js b/third_party/blink/web_tests/http/tests/resources/user-gesture-utils.js index 122222e..27d9bb9 100644 --- a/third_party/blink/web_tests/http/tests/resources/user-gesture-utils.js +++ b/third_party/blink/web_tests/http/tests/resources/user-gesture-utils.js
@@ -32,13 +32,15 @@ * When testing focus, this is useful to avoid long timeouts waiting to see * if a focus event will be dispatched or not. */ -function roundTripToBrowserThen(f) { - var frame = document.createElement('iframe'); - // An OOPIF navigation requires the browser to participate. - frame.src = "http://localhost:8080/resources/blank.html"; - frame.addEventListener('load', () => { - document.body.removeChild(frame); - f(); +function roundTripToBrowser() { + return new Promise((resolve, reject) => { + var frame = document.createElement('iframe'); + // An OOPIF navigation requires the browser to participate. + frame.src = "http://localhost:8080/resources/blank.html"; + frame.addEventListener('load', () => { + document.body.removeChild(frame); + resolve(); + }); + document.body.appendChild(frame); }); - document.body.appendChild(frame); }
diff --git a/third_party/blink/web_tests/resources/user-gesture-utils.js b/third_party/blink/web_tests/resources/user-gesture-utils.js index 122222e..27d9bb9 100644 --- a/third_party/blink/web_tests/resources/user-gesture-utils.js +++ b/third_party/blink/web_tests/resources/user-gesture-utils.js
@@ -32,13 +32,15 @@ * When testing focus, this is useful to avoid long timeouts waiting to see * if a focus event will be dispatched or not. */ -function roundTripToBrowserThen(f) { - var frame = document.createElement('iframe'); - // An OOPIF navigation requires the browser to participate. - frame.src = "http://localhost:8080/resources/blank.html"; - frame.addEventListener('load', () => { - document.body.removeChild(frame); - f(); +function roundTripToBrowser() { + return new Promise((resolve, reject) => { + var frame = document.createElement('iframe'); + // An OOPIF navigation requires the browser to participate. + frame.src = "http://localhost:8080/resources/blank.html"; + frame.addEventListener('load', () => { + document.body.removeChild(frame); + resolve(); + }); + document.body.appendChild(frame); }); - document.body.appendChild(frame); }
diff --git a/third_party/blink/web_tests/virtual/cache-storage-eager-reading/external/wpt/service-workers/idlharness.https.any.sharedworker-expected.txt b/third_party/blink/web_tests/virtual/cache-storage-eager-reading/external/wpt/service-workers/idlharness.https.any.sharedworker-expected.txt new file mode 100644 index 0000000..b1a70df --- /dev/null +++ b/third_party/blink/web_tests/virtual/cache-storage-eager-reading/external/wpt/service-workers/idlharness.https.any.sharedworker-expected.txt
@@ -0,0 +1,159 @@ +This is a testharness.js-based test. +Found 155 tests; 115 PASS, 40 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS idl_test setup +PASS idl_test validation +PASS Partial interface Navigator: original interface defined +PASS Partial interface Navigator: member names are unique +PASS Partial interface WorkerNavigator: original interface defined +PASS Partial interface WorkerNavigator: member names are unique +PASS Partial interface mixin WindowOrWorkerGlobalScope: original interface mixin defined +PASS Partial interface mixin WindowOrWorkerGlobalScope: member names are unique +PASS Partial interface mixin NavigatorID: member names are unique +PASS Partial interface Window: member names are unique +PASS ServiceWorker includes AbstractWorker: member names are unique +PASS Window includes GlobalEventHandlers: member names are unique +PASS Window includes WindowEventHandlers: member names are unique +PASS Window includes WindowOrWorkerGlobalScope: member names are unique +PASS Window includes AnimationFrameProvider: member names are unique +PASS Window includes WindowSessionStorage: member names are unique +PASS Window includes WindowLocalStorage: member names are unique +PASS WorkerGlobalScope includes WindowOrWorkerGlobalScope: member names are unique +PASS Navigator includes NavigatorID: member names are unique +PASS Navigator includes NavigatorLanguage: member names are unique +PASS Navigator includes NavigatorOnLine: member names are unique +PASS Navigator includes NavigatorContentUtils: member names are unique +PASS Navigator includes NavigatorCookies: member names are unique +PASS Navigator includes NavigatorPlugins: member names are unique +PASS Navigator includes NavigatorConcurrentHardware: member names are unique +PASS WorkerNavigator includes NavigatorID: member names are unique +PASS WorkerNavigator includes NavigatorLanguage: member names are unique +PASS WorkerNavigator includes NavigatorOnLine: member names are unique +PASS WorkerNavigator includes NavigatorConcurrentHardware: member names are unique +FAIL ServiceWorker interface: existence and properties of interface object assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface object length assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface object name assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: attribute scriptURL assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: attribute state assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: operation postMessage(any, sequence<object>) assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: operation postMessage(any, optional PostMessageOptions) assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +FAIL ServiceWorker interface: attribute onstatechange assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing +PASS ServiceWorkerRegistration interface: existence and properties of interface object +PASS ServiceWorkerRegistration interface object length +PASS ServiceWorkerRegistration interface object name +PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object +PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property +PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's @@unscopables property +PASS ServiceWorkerRegistration interface: attribute installing +PASS ServiceWorkerRegistration interface: attribute waiting +PASS ServiceWorkerRegistration interface: attribute active +PASS ServiceWorkerRegistration interface: attribute navigationPreload +PASS ServiceWorkerRegistration interface: attribute scope +PASS ServiceWorkerRegistration interface: attribute updateViaCache +PASS ServiceWorkerRegistration interface: operation update() +PASS ServiceWorkerRegistration interface: operation unregister() +PASS ServiceWorkerRegistration interface: attribute onupdatefound +FAIL ServiceWorkerContainer interface: existence and properties of interface object assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface object length assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface object name assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: attribute controller assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: attribute ready assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: operation register(USVString, optional RegistrationOptions) assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: operation getRegistration(optional USVString) assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: operation getRegistrations() assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: operation startMessages() assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: attribute oncontrollerchange assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: attribute onmessage assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer interface: attribute onmessageerror assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing +FAIL ServiceWorkerContainer must be primary interface of navigator.serviceWorker assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL Stringification of navigator.serviceWorker assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "controller" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "ready" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "register(USVString, optional RegistrationOptions)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: calling register(USVString, optional RegistrationOptions) on navigator.serviceWorker with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "getRegistration(optional USVString)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: calling getRegistration(optional USVString) on navigator.serviceWorker with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "getRegistrations()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "startMessages()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "oncontrollerchange" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "onmessage" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "onmessageerror" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +PASS NavigationPreloadManager interface: existence and properties of interface object +PASS NavigationPreloadManager interface object length +PASS NavigationPreloadManager interface object name +PASS NavigationPreloadManager interface: existence and properties of interface prototype object +PASS NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property +PASS NavigationPreloadManager interface: existence and properties of interface prototype object's @@unscopables property +PASS NavigationPreloadManager interface: operation enable() +PASS NavigationPreloadManager interface: operation disable() +PASS NavigationPreloadManager interface: operation setHeaderValue(ByteString) +PASS NavigationPreloadManager interface: operation getState() +PASS ServiceWorkerGlobalScope interface: existence and properties of interface object +PASS Client interface: existence and properties of interface object +PASS WindowClient interface: existence and properties of interface object +PASS Clients interface: existence and properties of interface object +PASS ExtendableEvent interface: existence and properties of interface object +PASS FetchEvent interface: existence and properties of interface object +PASS ExtendableMessageEvent interface: existence and properties of interface object +PASS Cache interface: existence and properties of interface object +PASS Cache interface object length +PASS Cache interface object name +PASS Cache interface: existence and properties of interface prototype object +PASS Cache interface: existence and properties of interface prototype object's "constructor" property +PASS Cache interface: existence and properties of interface prototype object's @@unscopables property +PASS Cache interface: operation match(RequestInfo, optional CacheQueryOptions) +PASS Cache interface: operation matchAll(optional RequestInfo, optional CacheQueryOptions) +PASS Cache interface: operation add(RequestInfo) +PASS Cache interface: operation addAll(sequence<RequestInfo>) +PASS Cache interface: operation put(RequestInfo, Response) +PASS Cache interface: operation delete(RequestInfo, optional CacheQueryOptions) +PASS Cache interface: operation keys(optional RequestInfo, optional CacheQueryOptions) +PASS Cache must be primary interface of self.cacheInstance +PASS Stringification of self.cacheInstance +PASS Cache interface: self.cacheInstance must inherit property "match(RequestInfo, optional CacheQueryOptions)" with the proper type +PASS Cache interface: calling match(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "matchAll(optional RequestInfo, optional CacheQueryOptions)" with the proper type +PASS Cache interface: calling matchAll(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "add(RequestInfo)" with the proper type +PASS Cache interface: calling add(RequestInfo) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "addAll(sequence<RequestInfo>)" with the proper type +PASS Cache interface: calling addAll(sequence<RequestInfo>) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "put(RequestInfo, Response)" with the proper type +PASS Cache interface: calling put(RequestInfo, Response) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "delete(RequestInfo, optional CacheQueryOptions)" with the proper type +PASS Cache interface: calling delete(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError +PASS Cache interface: self.cacheInstance must inherit property "keys(optional RequestInfo, optional CacheQueryOptions)" with the proper type +PASS Cache interface: calling keys(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError +PASS CacheStorage interface: existence and properties of interface object +PASS CacheStorage interface object length +PASS CacheStorage interface object name +PASS CacheStorage interface: existence and properties of interface prototype object +PASS CacheStorage interface: existence and properties of interface prototype object's "constructor" property +PASS CacheStorage interface: existence and properties of interface prototype object's @@unscopables property +PASS CacheStorage interface: operation match(RequestInfo, optional MultiCacheQueryOptions) +PASS CacheStorage interface: operation has(DOMString) +PASS CacheStorage interface: operation open(DOMString) +PASS CacheStorage interface: operation delete(DOMString) +PASS CacheStorage interface: operation keys() +PASS CacheStorage must be primary interface of caches +PASS Stringification of caches +PASS CacheStorage interface: caches must inherit property "match(RequestInfo, optional MultiCacheQueryOptions)" with the proper type +PASS CacheStorage interface: calling match(RequestInfo, optional MultiCacheQueryOptions) on caches with too few arguments must throw TypeError +PASS CacheStorage interface: caches must inherit property "has(DOMString)" with the proper type +PASS CacheStorage interface: calling has(DOMString) on caches with too few arguments must throw TypeError +PASS CacheStorage interface: caches must inherit property "open(DOMString)" with the proper type +PASS CacheStorage interface: calling open(DOMString) on caches with too few arguments must throw TypeError +PASS CacheStorage interface: caches must inherit property "delete(DOMString)" with the proper type +PASS CacheStorage interface: calling delete(DOMString) on caches with too few arguments must throw TypeError +PASS CacheStorage interface: caches must inherit property "keys()" with the proper type +PASS Window interface: existence and properties of interface object +PASS Navigator interface: existence and properties of interface object +PASS WorkerGlobalScope interface: attribute caches +FAIL WorkerNavigator interface: attribute serviceWorker assert_true: The prototype object must have a property "serviceWorker" expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/zlib/google/BUILD.gn b/third_party/zlib/google/BUILD.gn index 4eddc61..a628d2f 100644 --- a/third_party/zlib/google/BUILD.gn +++ b/third_party/zlib/google/BUILD.gn
@@ -21,18 +21,18 @@ "//third_party/zlib:minizip", ] } -} -static_library("compression_utils") { - sources = [ - "compression_utils.cc", - "compression_utils.h", - ] - deps = [ - ":compression_utils_portable", - "//base", - "//third_party/zlib", - ] + static_library("compression_utils") { + sources = [ + "compression_utils.cc", + "compression_utils.h", + ] + deps = [ + ":compression_utils_portable", + "//base", + "//third_party/zlib", + ] + } } # This allows other users of Chromium's zlib library, but don't use Chromium's
diff --git a/tools/android/dependency_analysis/.style.yapf b/tools/android/dependency_analysis/.style.yapf new file mode 100644 index 0000000..557fa7b --- /dev/null +++ b/tools/android/dependency_analysis/.style.yapf
@@ -0,0 +1,2 @@ +[style] +based_on_style = pep8
diff --git a/tools/android/dependency_analysis/OWNERS b/tools/android/dependency_analysis/OWNERS new file mode 100644 index 0000000..f7f92ceb --- /dev/null +++ b/tools/android/dependency_analysis/OWNERS
@@ -0,0 +1,3 @@ +yjlong@google.com +hnakashima@chromium.org +
diff --git a/tools/android/dependency_analysis/README.md b/tools/android/dependency_analysis/README.md new file mode 100644 index 0000000..a4b4181 --- /dev/null +++ b/tools/android/dependency_analysis/README.md
@@ -0,0 +1,17 @@ +# Chrome Android Dependency Analysis Tool +## Overview +As part of Chrome Modularization, this directory contains various tools for +analyzing the dependencies contained within the Chrome Android project. + +## Usage +Currently there is only one tool. + +### JDeps Parser +Runs jdeps on a JAR file and constructs a graph data structure in-memory of the +dependencies. Currently only creates the graph for class-level dependencies. + +usage: + python3 process\_jdeps.py [-h] filepath +positional arguments: + filepath: Path of the JAR to run jdeps on +
diff --git a/tools/android/dependency_analysis/class_dependency.py b/tools/android/dependency_analysis/class_dependency.py new file mode 100644 index 0000000..4b88520f --- /dev/null +++ b/tools/android/dependency_analysis/class_dependency.py
@@ -0,0 +1,71 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +"""Implementation of the graph module for a [Java class] dependency graph.""" + +import re +from typing import Tuple + +import graph + +# Matches w/o parens: (some.package.name).(class)$($optional$nested$class) +JAVA_CLASS_FULL_NAME_REGEX = re.compile( + r"^(?P<package>.*)\.(?P<class_name>.*?)(\$(?P<nested>.*))?$") + + +def java_class_params_to_key(package: str, class_name: str): + """Returns the unique key created from a package and class name.""" + return f"{package}.{class_name}" + + +def split_nested_class_from_key(key: str) -> Tuple[str, str]: + """Splits a jdeps class name into its key and nested class, if any.""" + re_match = JAVA_CLASS_FULL_NAME_REGEX.match(key) + package = re_match.group("package") + class_name = re_match.group("class_name") + nested = re_match.group("nested") + return java_class_params_to_key(package, class_name), nested + + +class JavaClass(graph.Node): + """A representation of a Java class. + + Some classes may have nested classes (eg. explicitly, or + implicitly through lambdas). We treat these nested classes as part of + the outer class, storing only their names as metadata. + """ + def __init__(self, package: str, class_name: str): + """Initializes a new Java class structure. + + The package and class_name are used to create a unique key per class. + + Args: + package: The package the class belongs to. + class_name: The name of the class. For nested classes, this is + the name of the class that contains them. + """ + super().__init__(java_class_params_to_key(package, class_name)) + + self._package = package + self._class_name = class_name + + self._nested_classes = set() + + def add_nested_class(self, nested: str): # pylint: disable=missing-function-docstring + self._nested_classes.add(nested) + + +class JavaClassDependencyGraph(graph.Graph): + """A graph representation of the dependencies between Java classes. + + A directed edge A -> B indicates that A depends on B. + """ + def create_node_from_key(self, key: str): + """See comment above the regex definition.""" + re_match = JAVA_CLASS_FULL_NAME_REGEX.match(key) + package = re_match.group("package") + class_name = re_match.group("class_name") + return JavaClass(package, class_name) + + def add_nested_class_to_key(self, key: str, nested: str): # pylint: disable=missing-function-docstring + self.get_node_by_key(key).add_nested_class(nested)
diff --git a/tools/android/dependency_analysis/graph.py b/tools/android/dependency_analysis/graph.py new file mode 100644 index 0000000..ad4e605 --- /dev/null +++ b/tools/android/dependency_analysis/graph.py
@@ -0,0 +1,114 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +"""Utility classes (and functions, in the future) for graph operations.""" + + +class Node(object): # pylint: disable=useless-object-inheritance + """A node/vertex in a directed graph. + + Attributes: + name: A unique string representation of the node. + inbound: A set of Nodes that have a directed edge into this Node. + outbound: A set of Nodes that this Node has a directed edge into. + """ + def __init__(self, unique_key: str): + """Initializes a new node with the given key. + + Args: + unique_key: A key uniquely identifying the node. + """ + self._unique_key = unique_key + self._outbound = set() + self._inbound = set() + + def __eq__(self, other: "Node"): # pylint: disable=missing-function-docstring + return self._unique_key == other._unique_key + + def __hash__(self): # pylint: disable=missing-function-docstring + return hash(self._unique_key) + + @property + def name(self): + """A unique string representation of the node.""" + return self._unique_key + + @property + def inbound(self): + """A set of Nodes that have a directed edge into this Node.""" + return self._inbound + + @property + def outbound(self): + """A set of Nodes that this Node has a directed edge into.""" + return self._outbound + + def add_outbound(self, node: "Node"): + """Creates an edge from the current node to the provided node.""" + self._outbound.add(node) + + def add_inbound(self, node: "Node"): + """Creates an edge from the provided node to the current node.""" + self._inbound.add(node) + + +class Graph(object): # pylint: disable=useless-object-inheritance + """A directed graph data structure. + + Maintains an internal Dict[str, Node] _key_to_node + mapping the unique key of nodes to their Node objects. + + Attributes: + num_nodes: The number of nodes in the graph. + num_edges: The number of edges in the graph. + """ + def __init__(self): # pylint: disable=missing-function-docstring + self._key_to_node = {} + + @property + def num_nodes(self): # pylint: disable=missing-function-docstring + return len(self._key_to_node) + + @property + def num_edges(self): # pylint: disable=missing-function-docstring + return sum(len(node.outbound) for node in self._key_to_node.values()) + + def get_node_by_key(self, key: str): # pylint: disable=missing-function-docstring + return self._key_to_node.get(key) + + def create_node_from_key(self, key: str): + """Given a unique key, creates and returns a Node object. + + Should be overridden by child classes. + """ + return Node(key) + + def add_node_if_new(self, key: str): + """Adds a Node to the graph. + + A new Node object is constructed from the given key and added. + If the key already exists in the graph, this is a no-op. + + Args: + key: A unique key to create the new Node from. + """ + if key not in self._key_to_node: + self._key_to_node[key] = self.create_node_from_key(key) + + def add_edge_if_new(self, src: str, dest: str): + """Adds a directed edge to the graph. + + The source and destination nodes are created and added if they + do not already exist. If the edge already exists in the graph, + this is a no-op. + + Args: + src: A unique key representing the source node. + dest: A unique key representing the destination node. + """ + self.add_node_if_new(src) + self.add_node_if_new(dest) + src_node = self.get_node_by_key(src) + dest_node = self.get_node_by_key(dest) + src_node.add_outbound(dest_node) + dest_node.add_inbound(src_node)
diff --git a/tools/android/dependency_analysis/process_jdeps.py b/tools/android/dependency_analysis/process_jdeps.py new file mode 100644 index 0000000..238a49e --- /dev/null +++ b/tools/android/dependency_analysis/process_jdeps.py
@@ -0,0 +1,106 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +"""Python wrapper for running jdeps and parsing its output""" + +import argparse +import pathlib +import subprocess + +import class_dependency + +SRC_PATH = pathlib.Path(__file__).resolve().parents[3] # src/ +JDEPS_PATH = SRC_PATH.joinpath("third_party/jdk/current/bin/jdeps") + + +def class_is_interesting(name: str): + """Checks if a jdeps class is a class we are actually interested in.""" + if name.startswith("org.chromium."): + return True + return False + + +class JavaClassJdepsParser(object): # pylint: disable=useless-object-inheritance + """A parser for jdeps class-level dependency output.""" + def __init__(self): # pylint: disable=missing-function-docstring + self._graph = class_dependency.JavaClassDependencyGraph() + + def parse_raw_jdeps_output(self, jdeps_output: str): + """Parses the entirety of the jdeps output.""" + for line in jdeps_output.split("\n"): + self.parse_line(line) + + def get_resulting_graph(self): + """Returns the dependency graph of the parsed output. + + parse_raw_jdeps_output should be called before this method. + """ + return self._graph + + def parse_line(self, line: str): + """Parses a line of jdeps output. + + The assumed format of the line starts with "name_1 -> name_2". + """ + parsed = line.split() + if len(parsed) <= 3: + return + if "not found" in line: + return + if parsed[1] != "->": + return + + dep_from = parsed[0] + dep_to = parsed[2] + if not class_is_interesting(dep_from): + return + if not class_is_interesting(dep_to): + return + + key_from, nested_from = class_dependency.split_nested_class_from_key( + dep_from) + key_to, nested_to = class_dependency.split_nested_class_from_key( + dep_to) + + self._graph.add_node_if_new(key_from) + self._graph.add_node_if_new(key_to) + if key_from != key_to: # Skip self-edges (class-nested dependency) + self._graph.add_edge_if_new(key_from, key_to) + if nested_from is not None: + self._graph.add_nested_class_to_key(key_from, nested_from) + if nested_to is not None: + self._graph.add_nested_class_to_key(key_from, nested_to) + + +def run_jdeps(filepath: str): + """Runs jdeps on the given filepath and returns the output.""" + jdeps_res = subprocess.run([JDEPS_PATH, "-R", "-verbose:class", filepath], + capture_output=True, + text=True, + check=True) + return jdeps_res.stdout + + +def main(): + """Parses args, runs jdeps, and creates a graph from the output. + + Currently only works for class-level dependencies. + The goal is to have more functions available for interfacing with the + constructed graph, but currently we just print its number of nodes/edges. + """ + arg_parser = argparse.ArgumentParser( + description="Run jdeps and process output") + arg_parser.add_argument("filepath", help="Path of the JAR to run jdeps on") + arguments = arg_parser.parse_args() + + raw_jdeps_output = run_jdeps(arguments.filepath) + jdeps_parser = JavaClassJdepsParser() + jdeps_parser.parse_raw_jdeps_output(raw_jdeps_output) + graph = jdeps_parser.get_resulting_graph() + + print(f"Parsed graph, got {graph.num_nodes} nodes " + f"and {graph.num_edges} edges.") + + +if __name__ == "__main__": + main()
diff --git a/tools/binary_size/libsupersize/parallel.py b/tools/binary_size/libsupersize/parallel.py index 19cef2d6..0467864 100644 --- a/tools/binary_size/libsupersize/parallel.py +++ b/tools/binary_size/libsupersize/parallel.py
@@ -192,12 +192,12 @@ """Calls |func| in a fork'ed process for each set of args within |arg_tuples|. Args: - kwargs: Common key word arguments to be passed to |func|. + kwargs: Common keyword arguments to be passed to |func|. Yields the return values as they come in. """ arg_tuples = list(arg_tuples) - if not len(arg_tuples): + if not arg_tuples: return if DISABLE_ASYNC:
diff --git a/tools/json_schema_compiler/js_externs_generator_test.py b/tools/json_schema_compiler/js_externs_generator_test.py index 72d3dd1..58e09e54 100755 --- a/tools/json_schema_compiler/js_externs_generator_test.py +++ b/tools/json_schema_compiler/js_externs_generator_test.py
@@ -84,6 +84,7 @@ optional double num, object obj, optional boolean bool, + optional Baz baz, VoidCallback callback); static void multipleOptionalParams(optional DOMString param1, @@ -227,10 +228,11 @@ * @param {?number|undefined} num * @param {Object} obj * @param {?boolean|undefined} bool + * @param {?chrome.fakeApi.Baz|undefined} baz * @param {function():void} callback * @see https://developer.chrome.com/extensions/fakeApi#method-nonFinalOptionalParams */ -chrome.fakeApi.nonFinalOptionalParams = function(string, num, obj, bool, callback) {}; +chrome.fakeApi.nonFinalOptionalParams = function(string, num, obj, bool, baz, callback) {}; /** * @param {string=} param1
diff --git a/tools/json_schema_compiler/js_util.py b/tools/json_schema_compiler/js_util.py index 7bf0f99..ebe491f 100644 --- a/tools/json_schema_compiler/js_util.py +++ b/tools/json_schema_compiler/js_util.py
@@ -89,7 +89,13 @@ # If the parameter was originally optional, but was followed by # non-optional parameters, allow it to be `null` or `undefined` instead. if not optional and param.optional: - js_type = Code().Append('?%s|undefined' % js_type.Render()) + js_type_string = js_type.Render() + + # Remove the leading "!" from |js_type_string| if it exists, since "?!" + # is not a valid type modifier. + if js_type_string.startswith('!'): + js_type_string = js_type_string[1:] + js_type = Code().Append('?%s|undefined' % js_type_string) append_field(c, 'param', js_type, param.name, optional, param.description)
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index f0359cd..e6e7ca5 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -410,8 +410,8 @@ 'Android FYI 64 dEQP Vk Release (Pixel 2)': 'angle_deqp_android_vulkan_ndk_release_trybot_arm64', 'Android FYI SkiaRenderer GL (Nexus 5X)': 'gpu_tests_android_release_trybot_arm64', 'Android FYI SkiaRenderer Vulkan (Pixel 2)': 'gpu_tests_android_release_trybot', - 'ChromeOS FYI Release (amd64-generic)': 'gpu_tests_chromeos_amd64_release_trybot_dcheck_off', - 'ChromeOS FYI Release (kevin)': 'gpu_tests_chromeos_kevin_release_trybot_dcheck_off', + 'ChromeOS FYI Release (amd64-generic)': 'gpu_tests_chromeos_amd64_release_trybot_dcheck_off_no_symbols', + 'ChromeOS FYI Release (kevin)': 'gpu_tests_chromeos_kevin_release_trybot_dcheck_off_no_symbols', 'GPU FYI Linux Builder': 'gpu_fyi_tests_release_trybot', 'GPU FYI Linux Ozone Builder': 'angle_ozone_linux_system_gbm_libdrm_release_trybot', 'GPU FYI Linux Builder (dbg)': 'gpu_fyi_tests_debug_trybot', @@ -785,8 +785,8 @@ 'chromeos-arm-generic-rel': 'chromeos_arm-generic_dcheck_always_on', 'chromeos-kevin-compile-rel': 'chromeos_kevin', 'chromeos-kevin-rel': 'chromeos_kevin', - 'gpu-fyi-try-chromeos-amd64-generic': 'gpu_tests_chromeos_amd64_release_trybot_dcheck_off', - 'gpu-fyi-try-chromeos-kevin': 'gpu_tests_chromeos_kevin_release_trybot_dcheck_off', + 'gpu-fyi-try-chromeos-amd64-generic': 'gpu_tests_chromeos_amd64_release_trybot_dcheck_off_no_symbols', + 'gpu-fyi-try-chromeos-kevin': 'gpu_tests_chromeos_kevin_release_trybot_dcheck_off_no_symbols', 'linux-chromeos-rel': 'chromeos_with_codecs_release_trybot_code_coverage', 'linux-chromeos-compile-dbg': 'chromeos_with_codecs_debug_bot', 'linux-chromeos-dbg': 'chromeos_with_codecs_debug_bot', @@ -1767,12 +1767,13 @@ 'use_java_coverage', 'partial_code_coverage_instrumentation', ], - 'gpu_tests_chromeos_amd64_release_trybot_dcheck_off': [ + 'gpu_tests_chromeos_amd64_release_trybot_dcheck_off_no_symbols': [ 'gpu_tests', 'chromeos_amd64-generic', 'release_trybot_dcheck_off', + 'no_symbols', ], - 'gpu_tests_chromeos_kevin_release_trybot_dcheck_off': [ - 'gpu_tests', 'chromeos_kevin', 'release_trybot_dcheck_off', + 'gpu_tests_chromeos_kevin_release_trybot_dcheck_off_no_symbols': [ + 'gpu_tests', 'chromeos_kevin', 'release_trybot_dcheck_off', 'no_symbols', ], 'gpu_tests_debug_bot': [
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index f7e75d1..d32c8b0 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -297,7 +297,7 @@ </histogram> <histogram name="Accessibility.CrosSelectToSpeak" enum="BooleanEnabled" - expires_after="2020-09-13"> + expires_after="2020-11-15"> <owner>dmazzoni@chromium.org</owner> <owner>katie@chromium.org</owner> <owner>chrome-a11y-core@google.com</owner> @@ -2021,7 +2021,7 @@ </histogram> <histogram name="Android.AppNotificationStatus" enum="NotificationAppStatus" - expires_after="2020-09-13"> + expires_after="2020-11-15"> <owner>peter@chromium.org</owner> <summary> Records whether notifications are enabled for Chrome, as the Android app, @@ -4888,15 +4888,19 @@ </summary> </histogram> -<histogram name="Android.WebView.DevUi.FragmentNavigation" +<histogram base="true" name="Android.WebView.DevUi.FragmentNavigation" enum="AndroidWebViewDevUiFragments" expires_after="2021-01-20"> +<!-- Name completed by histogram_suffixes + name="Android.WebView.DevUi.NavType" --> + <owner>ntfschr@chromium.org</owner> <owner>hazems@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> - Records the user's navigation to a Fragment. This is primarily intentional - navigations through the bottom navigation bar, but this also includes - creating the default Fragment for the app's home page. + Records the user's navigation to a Fragment. "FromIntent" tracks + navigations triggered by an Intent (ex. navigating to HomeFragment on + launch) and "NavBar" tracks user interaction with the bottom + navigation bar. "AnyMethod" should be the sum of the other two. </summary> </histogram> @@ -8388,7 +8392,7 @@ </histogram> <histogram name="Arc.OptInCancel" enum="ArcOptInCancel" - expires_after="2020-09-13"> + expires_after="2020-11-15"> <owner>elijahtaylor@google.com</owner> <owner>shihuis@google.com</owner> <summary>Arc OptIn cancelation reason.</summary> @@ -9841,7 +9845,7 @@ </histogram> <histogram name="Ash.PowerButtonScreenshot.DelayBetweenAccelKeyPressed" - units="ms" expires_after="2020-09-13"> + units="ms" expires_after="2020-11-15"> <owner>zentaro@chromium.org</owner> <owner>baileyberro@chromium.org</owner> <summary> @@ -9910,7 +9914,7 @@ </histogram> <histogram name="Ash.Shelf.NumberOfItems" units="Icons" - expires_after="2020-09-13"> + expires_after="2020-11-15"> <owner>anasalazar@google.com</owner> <owner>mmourgos@google.com</owner> <summary> @@ -9930,7 +9934,7 @@ </histogram> <histogram name="Ash.Shelf.NumberOfUnpinnedItems" units="Icons" - expires_after="2020-09-13"> + expires_after="2020-11-15"> <owner>anasalazar@google.com</owner> <owner>mmourgos@google.com</owner> <summary> @@ -11051,7 +11055,7 @@ </histogram> <histogram name="Assistant.ProactiveSuggestions.CardClick" - enum="BooleanClicked" expires_after="2020-08-30"> + enum="BooleanClicked" expires_after="2020-11-15"> <owner>xiaohuic@chromium.org</owner> <owner>dmblack@google.com</owner> <owner>croissant-eng@chromium.org</owner> @@ -11064,7 +11068,7 @@ </histogram> <histogram name="Assistant.ProactiveSuggestions.CardClick.ByCategory" - enum="ProactiveSuggestionsCategory" expires_after="2020-08-30"> + enum="ProactiveSuggestionsCategory" expires_after="2020-11-15"> <owner>xiaohuic@chromium.org</owner> <owner>dmblack@google.com</owner> <owner>croissant-eng@chromium.org</owner> @@ -11075,7 +11079,7 @@ </histogram> <histogram name="Assistant.ProactiveSuggestions.CardClick.ByIndex" - units="index" expires_after="2020-08-30"> + units="index" expires_after="2020-11-15"> <owner>xiaohuic@chromium.org</owner> <owner>dmblack@google.com</owner> <owner>croissant-eng@chromium.org</owner> @@ -11086,7 +11090,7 @@ </histogram> <histogram name="Assistant.ProactiveSuggestions.CardClick.ByVeId" - enum="ProactiveSuggestionsVeId" expires_after="2020-08-30"> + enum="ProactiveSuggestionsVeId" expires_after="2020-11-15"> <owner>xiaohuic@chromium.org</owner> <owner>dmblack@google.com</owner> <owner>croissant-eng@chromium.org</owner> @@ -11194,7 +11198,7 @@ </histogram> <histogram name="Assistant.ProactiveSuggestions.ReshowAttempt" - enum="ProactiveSuggestionsShowAttempt" expires_after="2020-11-08"> + enum="ProactiveSuggestionsShowAttempt" expires_after="2020-11-15"> <owner>xiaohuic@chromium.org</owner> <owner>dmblack@google.com</owner> <owner>croissant-eng@chromium.org</owner> @@ -12004,7 +12008,7 @@ </summary> </histogram> -<histogram name="AsyncDNS.ServerCount" units="units" expires_after="2020-08-30"> +<histogram name="AsyncDNS.ServerCount" units="units" expires_after="2020-11-15"> <owner>pauljensen@chromium.org</owner> <owner>mef@chromium.org</owner> <summary> @@ -12552,7 +12556,7 @@ </histogram> <histogram name="AuthPolicy.TimeToGetUserKerberosFiles" units="ms" - expires_after="2020-09-13"> + expires_after="2020-11-15"> <owner>fsandrade@chromium.org</owner> <owner>tomdobro@chromium.org</owner> <summary> @@ -20619,7 +20623,7 @@ </histogram> <histogram name="Blink.VisibleBeforeLoaded.LazyLoadImages.AboveTheFold" - enum="NQEEffectiveConnectionType" expires_after="2020-09-13"> + enum="NQEEffectiveConnectionType" expires_after="2020-11-15"> <owner>sclittle@chromium.org</owner> <owner>rajendrant@chromium.org</owner> <summary> @@ -23120,7 +23124,7 @@ </histogram> <histogram name="BrowserSwitcher.LaunchSuccess" enum="BooleanSuccess" - expires_after="2020-09-13"> + expires_after="2020-11-15"> <owner>nicolaso@chromium.org</owner> <owner>pastarmovj@chromium.org</owner> <summary> @@ -23130,7 +23134,7 @@ </histogram> <histogram name="BrowserSwitcher.LaunchTime" units="ms" - expires_after="2020-09-13"> + expires_after="2020-11-15"> <owner>nicolaso@chromium.org</owner> <owner>pastarmovj@chromium.org</owner> <summary> @@ -24923,7 +24927,7 @@ </histogram> <histogram name="ChromeOS.Apps.IntentPickerDestinationPlatform" - enum="ArcIntentHandlerDestinationPlatform" expires_after="2020-09-13"> + enum="ArcIntentHandlerDestinationPlatform" expires_after="2020-11-15"> <owner>elijahtaylor@google.com</owner> <owner>dominickn@chromium.org</owner> <owner>shihuis@google.com</owner> @@ -29546,6 +29550,21 @@ </summary> </histogram> +<histogram name="ContentSuggestions.Feed.TimeSpentInFeed" units="ms" + expires_after="2021-05-01"> + <owner>carlosk@chromium.org</owner> + <owner>harringtond@chromium.org</owner> + <owner>feed@chromium.org</owner> + <summary> + How long a user used the Feed in one day (local time midnight to midnight). + Reported at most once per day. Usage reported is typically from the previous + day, but could be from several days ago if the user is not active. Time is + calculated starting with the first Feed interaction, until the Feed surface + is closed, or the user is idle (no scrolling or other actions) for 30 + seconds. + </summary> +</histogram> + <histogram name="ContentSuggestions.Feed.TokenCompleted.ContentCount" units="count" expires_after="2020-02-25"> <obsolete> @@ -30430,7 +30449,7 @@ </summary> </histogram> -<histogram name="Cookie.Count" units="units" expires_after="2020-09-13"> +<histogram name="Cookie.Count" units="units" expires_after="2020-11-15"> <owner>battre@chromium.org</owner> <summary> Number of cookies in the store (recorded every 10 minutes of active browsing @@ -33970,7 +33989,7 @@ </histogram> <histogram name="Cryptohome.MigrationUI.MigrationResult" - enum="MigrationUIMigrationResult" expires_after="2020-09-13"> + enum="MigrationUIMigrationResult" expires_after="2020-11-15"> <owner>fukino@chromium.org</owner> <summary> The result of encryption migration from eCryptfs to Ext4 dircrypto. The @@ -44273,7 +44292,7 @@ </histogram> <histogram name="Download.Service.Files.FreeDiskSpace" units="%" - expires_after="2020-09-06"> + expires_after="2020-11-15"> <owner>xingliu@chromium.org</owner> <summary> The percentage of free disk space to total disk space. Recorded during @@ -46005,14 +46024,30 @@ <histogram name="Enterprise.AppRestrictionLoadTime" units="ms" expires_after="M85"> + <obsolete> + Code removed in M46. + </obsolete> <owner>aberent@chromium.org</owner> <summary> Android Only - Time to load the App Restrictions from the O.S.. </summary> </histogram> +<histogram name="Enterprise.AppRestrictionLoadTime2" units="ms" + expires_after="2020-12-01"> + <owner>twellington@google.com</owner> + <owner>tedchcoc@chromium.org</owner> + <summary> + Records the time it takes to retrieve applicaton restrictions from the + system. Android only. + </summary> +</histogram> + <histogram name="Enterprise.AppRestrictionsCacheLoad" enum="BooleanSuccess" expires_after="M85"> + <obsolete> + Code removed in M46. + </obsolete> <owner>aberent@chromium.org</owner> <summary> Android Only - Whether Chrome was able to read and decode the @@ -47645,7 +47680,7 @@ </histogram> <histogram name="EnterpriseCheck.IsDomainJoined" enum="BooleanEnabled" - expires_after="2020-09-13"> + expires_after="2020-11-15"> <owner>mad@chromium.org</owner> <summary> Whether the machine is joined to an AD domain. This check is performed once @@ -47683,15 +47718,24 @@ </histogram> <histogram name="EnterpriseCheck.IsManaged" enum="BooleanEnabled" - expires_after="2020-11-08"> + expires_after="2020-12-01"> <owner>rogerta@chromium.org</owner> <owner>pastarmovj@chromium.org</owner> <summary> On Windows: Whether the machine is managed via MDM. On macOS: Whether Chrome found a file of managed policies to follow. On Android (with version M and - higher): Whether the device is managed by any policies. This check is - performed once at start-up. Note that this data is bogus before M81 on the - Mac. + higher): Whether the device has a profile owner app. This check is performed + once at start-up. Note that this data is bogus before M81 on the Mac. + </summary> +</histogram> + +<histogram name="EnterpriseCheck.IsRunningOnManagedProfileDuration" units="ms" + expires_after="2020-12-01"> + <owner>twellington@google.com</owner> + <owner>tedchcoc@chromium.org</owner> + <summary> + Records the time it takes to calculate whether there is a profile owner app + on the device. Android only. </summary> </histogram> @@ -50633,7 +50677,7 @@ </histogram> <histogram name="Event.Latency.ScrollUpdate.Wheel.TimeToHandled2" - units="microseconds" expires_after="2020-08-23"> + units="microseconds" expires_after="2020-11-15"> <owner>tdresser@chromium.org</owner> <summary> Time between initial creation of a wheel event and the generated @@ -51887,7 +51931,7 @@ </histogram> <histogram name="ExploreSites.RequestStatus" enum="ExploreSitesRequestStatus" - expires_after="2020-09-01"> + expires_after="2020-11-15"> <owner>dimich@chromium.org</owner> <owner>freedjm@chromium.org</owner> <summary> @@ -57192,6 +57236,19 @@ </summary> </histogram> +<histogram + name="Extensions.SettingsOverridden.GenericSearchOverriddenDialogResult" + enum="SettingsOverriddenDialogResult" expires_after="2021-05-01"> + <owner>rdevlin.cronin@chromium.org</owner> + <owner>extensions-core@chromium.org</owner> + <summary> + The action taken on the settings overridden dialog that was shown to alert + the user of an extension overriding the default search provider, when the + dialog shown is the generic version. Recorded once per instance of the + dialog being shown, after the action is taken. + </summary> +</histogram> + <histogram name="Extensions.SettingsQuotaExceeded.BytesPerSetting" units="units" expires_after="2016-09-13"> <obsolete> @@ -59923,7 +59980,7 @@ </histogram> <histogram name="FirstRun.NewUserExperience.NtpBackgroundInteraction" - enum="NuxNtpBackgroundInteractions" expires_after="2020-09-13"> + enum="NuxNtpBackgroundInteractions" expires_after="2020-11-15"> <owner>hcarmona@chromium.org</owner> <owner>johntlee@chromium.org</owner> <summary> @@ -62071,7 +62128,7 @@ </histogram> <histogram name="GPU.BlacklistFeatureTestResults" - enum="GPUBlacklistFeatureTestResults" expires_after="2020-08-02"> + enum="GPUBlacklistFeatureTestResults" expires_after="2020-11-15"> <owner>vmiura@chromium.org</owner> <summary> Counts number of browser invocations for which a GPU feature is @@ -63555,7 +63612,7 @@ </histogram> <histogram name="GPU.SharedImage.ContentConsumed" enum="BooleanMatched" - expires_after="2020-08-12"> + expires_after="2020-11-15"> <owner>penghuang@chromium.org</owner> <owner>backer@chromium.org</owner> <summary> @@ -63652,7 +63709,7 @@ </histogram> <histogram name="GPU.SwapTimeUs" units="microseconds" - expires_after="2020-09-13"> + expires_after="2020-11-15"> <owner>vasilyt@chromium.org</owner> <owner>backer@chromium.org</owner> <summary> @@ -63783,7 +63840,7 @@ </histogram> <histogram name="GPU.WatchdogThread.ExtraThreadTime" units="# timeouts" - expires_after="2020-09-13"> + expires_after="2020-11-15"> <!-- Name completed by histogram_suffixes name="GPU.WatchdogStage" --> <owner>magchen@chromium.org</owner> @@ -63795,7 +63852,7 @@ </histogram> <histogram name="GPU.WatchdogThread.ExtraThreadTime.NumOfUsers" - units="# timeouts" expires_after="2020-09-13"> + units="# timeouts" expires_after="2020-11-15"> <owner>magchen@chromium.org</owner> <owner>zmo@chromium.org</owner> <summary> @@ -63818,7 +63875,7 @@ </histogram> <histogram name="GPU.WatchdogThread.V1.ExtraThreadTime" units="ms" - expires_after="2020-09-13"> + expires_after="2020-11-15"> <owner>magchen@chromium.org</owner> <owner>zmo@chromium.org</owner> <summary> @@ -64189,7 +64246,7 @@ </histogram> <histogram base="true" name="GridTabSwitcher.DirtySpan" units="ms" - expires_after="2020-09-13"> + expires_after="2020-11-15"> <owner>yusufo@chromium.org</owner> <owner>wychen@chromium.org</owner> <summary> @@ -70368,7 +70425,7 @@ </histogram> <histogram base="true" name="JSDialogs.Scheme" enum="NavigationScheme" - expires_after="2020-08-30"> + expires_after="2020-11-15"> <owner>avi@chromium.org</owner> <owner>carlosil@chromium.org</owner> <owner>meacer@chromium.org</owner> @@ -111918,7 +111975,7 @@ </histogram> <histogram name="OOBE.RecommendApps.Fetcher.DownloadTime" units="ms" - expires_after="2020-08-30"> + expires_after="2020-11-15"> <owner>rsorokin@chromium.org</owner> <owner>cros-oac@google.com</owner> <owner>play-bm-eng@google.com</owner> @@ -128054,6 +128111,19 @@ </summary> </histogram> +<histogram name="Power.CpuTimeSecondsPerProcessType" enum="ProcessType2" + expires_after="2021-05-14"> + <owner>eseckler@chromium.org</owner> + <owner>skyostil@chromium.org</owner> + <summary> + Total seconds of CPU time consumed by Chrome, split by process type. + Currently only implemented on Android. For every second of CPU time consumed + by one process, a sample is recorded into the bucket for the process's type. + The histogram thus shows the total sum of CPU time seconds spent per process + type across all users. + </summary> +</histogram> + <histogram name="Power.DarkResumeWakeDurationMs" units="ms" expires_after="M85"> <owner>chirantan@chromium.org</owner> <owner>abhishekbh@chromium.org</owner> @@ -160169,7 +160239,7 @@ </histogram> <histogram base="true" name="Spellcheck.Windows.ChromeLocalesSupport" - units="locales" expires_after="2020-07-01"> + units="locales" expires_after="2020-12-01"> <owner>gujen@google.com</owner> <owner>chrome-language@google.com</owner> <summary> @@ -160191,7 +160261,7 @@ </histogram> <histogram name="Spellcheck.Windows.HunspellUnsupportedLanguageCount" - units="locales" expires_after="2020-07-01"> + units="locales" expires_after="2020-06-01"> <obsolete> Reworked as Spellcheck.Windows.ChromeLocalesSupport.NoSupport and Spellcheck.Windows.ChromeLocalesSupport.NativeOnly in M80. @@ -160207,7 +160277,7 @@ </histogram> <histogram name="Spellcheck.Windows.MissingLanguagePacksCount" units="locales" - expires_after="2020-07-01"> + expires_after="2020-06-01"> <obsolete> Reworked as Spellcheck.Windows.SpellcheckLocalesSupport.HunspellOnly and Spellcheck.Windows.SpellcheckLocalesSupport.NoSupport in M80. @@ -160225,7 +160295,7 @@ </histogram> <histogram base="true" name="Spellcheck.Windows.SpellcheckLocalesSupport" - units="locales" expires_after="2020-07-01"> + units="locales" expires_after="2020-12-01"> <owner>gujen@google.com</owner> <owner>chrome-language@google.com</owner> <summary> @@ -160243,7 +160313,7 @@ </histogram> <histogram base="true" name="Spellcheck.Windows.SpellcheckRequestDuration" - units="ms" expires_after="2020-07-01"> + units="ms" expires_after="2020-12-01"> <owner>gujen@google.com</owner> <owner>chrome-language@google.com</owner> <summary> @@ -160259,7 +160329,7 @@ </histogram> <histogram base="true" name="Spellcheck.Windows.SuggestionGatheringDuration" - units="ms" expires_after="2020-07-01"> + units="ms" expires_after="2020-12-01"> <owner>gujen@google.com</owner> <owner>chrome-language@google.com</owner> <summary> @@ -165035,7 +165105,7 @@ </histogram> <histogram name="Sync.BackendInitializeFirstTime" units="ms" - expires_after="2020-09-01"> + expires_after="2020-11-15"> <owner>mastiz@chromium.org</owner> <owner>treib@chromium.org</owner> <summary> @@ -166407,7 +166477,7 @@ </histogram> <histogram name="Sync.KeystoreDecryptionFailed" - enum="SyncKeystoreDecryptionFailure" expires_after="2020-08-09"> + enum="SyncKeystoreDecryptionFailure" expires_after="2020-11-15"> <owner>mastiz@chromium.org</owner> <owner>treib@chromium.org</owner> <summary> @@ -168125,7 +168195,10 @@ </histogram> <histogram base="true" name="Sync.USSMigrationEntityCount" units="entries" - expires_after="2020-10-25"> + expires_after="2020-05-20"> + <obsolete> + Removed in M85. + </obsolete> <owner>mastiz@chromium.org</owner> <summary> Counts the number of sync entities per model type successfully migrated from @@ -168134,14 +168207,20 @@ </histogram> <histogram name="Sync.USSMigrationFailure" enum="SyncModelTypes" - expires_after="2020-06-30"> + expires_after="2020-05-20"> + <obsolete> + Removed in M85. + </obsolete> <owner>treib@chromium.org</owner> <owner>mastiz@chromium.org</owner> <summary>Counts directory to USS migration failures per model type.</summary> </histogram> <histogram name="Sync.USSMigrationSuccess" enum="SyncModelTypes" - expires_after="2020-08-30"> + expires_after="2020-05-20"> + <obsolete> + Removed in M85. + </obsolete> <owner>treib@chromium.org</owner> <owner>mastiz@chromium.org</owner> <summary>Counts directory to USS migration successes per model type.</summary> @@ -172667,7 +172746,7 @@ </histogram> <histogram name="Tracing.Background.FinalizationDisallowedReason" - enum="TracingFinalizationDisallowedReason" expires_after="2020-09-13"> + enum="TracingFinalizationDisallowedReason" expires_after="2020-11-15"> <owner>ssid@chromium.org</owner> <summary> Reason why background tracing finalization was not allowed. Also see @@ -172677,7 +172756,7 @@ </histogram> <histogram name="Tracing.Background.FinalizingTraceSizeInKB" units="KB" - expires_after="2020-09-13"> + expires_after="2020-11-15"> <owner>oysteine@chromium.org</owner> <summary> The size, in kilobytes, of a finalized trace ready to be uploaded. @@ -173036,7 +173115,7 @@ </histogram> <histogram name="Translate.HrefHint.Status" enum="HrefTranslateStatus" - expires_after="2020-06-28"> + expires_after="2020-12-01"> <owner>megjablon@google.com</owner> <owner>chrome-language@google.com</owner> <summary> @@ -175251,7 +175330,7 @@ </histogram> <histogram name="UMA.TruncatedEvents.UserAction" units="events" - expires_after="2020-11-08"> + expires_after="2020-11-15"> <owner>rkaplow@chromium.org</owner> <owner>src/base/metrics/OWNERS</owner> <summary> @@ -185489,7 +185568,7 @@ </histogram> <histogram name="WebRTC.ReceivedAudioTrackDuration" units="ms" - expires_after="2020-09-13"> + expires_after="2020-11-15"> <owner>perkj@chromium.org</owner> <summary> Durations of audio tracks received over a PeerConnection. The stopwatch @@ -185499,7 +185578,7 @@ </histogram> <histogram name="WebRTC.ReceivedVideoTrackDuration" units="ms" - expires_after="2020-09-13"> + expires_after="2020-11-15"> <owner>perkj@chromium.org</owner> <summary> Durations of video tracks received over a PeerConnection. The stopwatch @@ -185509,7 +185588,7 @@ </histogram> <histogram name="WebRTC.ReliableDataChannelMessageSize" units="bytes" - expires_after="2020-09-13"> + expires_after="2020-11-15"> <owner>perkj@chromium.org</owner> <summary> Sizes of messages sent over reliable data channels. The size of an @@ -185525,7 +185604,7 @@ </histogram> <histogram name="WebRTC.SentAudioTrackDuration" units="ms" - expires_after="2020-09-13"> + expires_after="2020-11-15"> <owner>perkj@chromium.org</owner> <summary> Durations of audio tracks sent over a PeerConnection. The stopwatch starts @@ -185614,7 +185693,7 @@ </histogram> <histogram name="WebRTC.UnreliableDataChannelMessageSize" units="bytes" - expires_after="2020-09-13"> + expires_after="2020-11-15"> <owner>perkj@chromium.org</owner> <summary> Sizes of messages sent over unreliable data channels. The size of an @@ -186070,7 +186149,7 @@ </histogram> <histogram name="WebRTC.Video.InterframeDelayInMs" units="ms" - expires_after="2020-08-31"> + expires_after="2020-11-15"> <owner>ilnik@chromium.org</owner> <owner>webrtc-video@google.com</owner> <summary> @@ -187016,7 +187095,7 @@ </histogram> <histogram name="WebRTC.Video.TimeInBlockyVideoPercentage" units="%" - expires_after="2020-09-13"> + expires_after="2020-11-15"> <owner>ilnik@chromium.org</owner> <owner>webrtc-video@google.com</owner> <summary> @@ -187493,7 +187572,7 @@ </histogram> <histogram name="WebUITabStrip.CloseAction" enum="WebUITabStripCloseActions" - expires_after="2020-09-15"> + expires_after="2020-11-15"> <owner>collinbaker@chromium.org</owner> <owner>dfried@chromium.org</owner> <summary> @@ -187504,7 +187583,7 @@ </histogram> <histogram name="WebUITabStrip.CloseTabAction" - enum="WebUITabStripCloseTabActions" expires_after="2020-09-15"> + enum="WebUITabStripCloseTabActions" expires_after="2020-11-15"> <owner>johntlee@chromium.org</owner> <owner>dpapad@chromium.org</owner> <summary> @@ -187515,7 +187594,7 @@ </histogram> <histogram name="WebUITabStrip.OpenAction" enum="WebUITabStripOpenActions" - expires_after="2020-09-15"> + expires_after="2020-11-15"> <owner>collinbaker@chromium.org</owner> <owner>dfried@chromium.org</owner> <summary> @@ -187526,7 +187605,7 @@ </histogram> <histogram name="WebUITabStrip.OpenDuration" units="ms" - expires_after="2020-09-15"> + expires_after="2020-11-15"> <owner>collinbaker@chromium.org</owner> <owner>dfried@chromium.org</owner> <summary> @@ -189329,6 +189408,14 @@ <affected-histogram name="AnchorElementMetrics.RatioVisibleArea"/> </histogram_suffixes> +<histogram_suffixes name="Android.WebView.DevUi.NavType" separator="."> + <suffix name="AnyMethod" label="User navigation through any means"/> + <suffix name="FromIntent" + label="User navigation through the bottom navigation bar"/> + <suffix name="NavBar" label="User navigation in response to an Intent"/> + <affected-histogram name="Android.WebView.DevUi.FragmentNavigation"/> +</histogram_suffixes> + <histogram_suffixes name="AndroidBootProgressEvents" separator="_"> <suffix name="ams_ready" label="For the boot_progress_ams_ready event."/> <suffix name="enable_screen" @@ -205889,7 +205976,11 @@ Deprecated 05/2019. </obsolete> </affected-histogram> - <affected-histogram name="Sync.USSMigrationEntityCount"/> + <affected-histogram name="Sync.USSMigrationEntityCount"> + <obsolete> + Deprecated 05/2020. + </obsolete> + </affected-histogram> </histogram_suffixes> <histogram_suffixes name="SyncModelTypeByMacro" separator="" ordering="prefix">
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 20089cc..a1abfc6 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -9668,7 +9668,8 @@ a cookie which is being sent on a request along with the secureness of the origin the cookie is attempting to be sent to. This is recorded once per cookie when the cookie is included in the request or if the cookie - excluded due to insufficent same-site context only. + excluded due to insufficent same-site context only. Cookies that meet the + above conditions but without a downgrade warning are not recorded. </summary> </metric> <metric name="ResponsePerCookie" @@ -9678,7 +9679,8 @@ a cookie which is being set by a response along with the secureness of the origin that is attempting to set the cookie. This is recorded once per cookie when the cookie is allowed to be set or if the cookie is ignored - due to insufficent same-site context only. + due to insufficent same-site context only. Cookies that meet the above + conditions but without a downgrade warning are not recorded. </summary> </metric> </event>
diff --git a/ui/accessibility/ax_node.cc b/ui/accessibility/ax_node.cc index 3fd6060..cae86027 100644 --- a/ui/accessibility/ax_node.cc +++ b/ui/accessibility/ax_node.cc
@@ -585,6 +585,20 @@ } void AXNode::GetTableColHeaderNodeIds( + std::vector<int32_t>* col_header_ids) const { + DCHECK(col_header_ids); + const AXTableInfo* table_info = GetAncestorTableInfo(); + if (!table_info) + return; + + // Flatten and add column header ids of each column to |col_header_ids|. + for (std::vector<int32_t> col_headers_at_index : table_info->col_headers) { + col_header_ids->insert(col_header_ids->end(), col_headers_at_index.begin(), + col_headers_at_index.end()); + } +} + +void AXNode::GetTableColHeaderNodeIds( int col_index, std::vector<int32_t>* col_header_ids) const { DCHECK(col_header_ids);
diff --git a/ui/accessibility/ax_node.h b/ui/accessibility/ax_node.h index 192d5a2d..5c66d9d2 100644 --- a/ui/accessibility/ax_node.h +++ b/ui/accessibility/ax_node.h
@@ -335,8 +335,12 @@ AXNode* GetTableCaption() const; AXNode* GetTableCellFromIndex(int index) const; AXNode* GetTableCellFromCoords(int row_index, int col_index) const; + // Get all the column header node ids of the table. + void GetTableColHeaderNodeIds(std::vector<int32_t>* col_header_ids) const; + // Get the column header node ids associated with |col_index|. void GetTableColHeaderNodeIds(int col_index, std::vector<int32_t>* col_header_ids) const; + // Get the row header node ids associated with |row_index|. void GetTableRowHeaderNodeIds(int row_index, std::vector<int32_t>* row_header_ids) const; void GetTableUniqueCellIds(std::vector<int32_t>* row_header_ids) const;
diff --git a/ui/accessibility/platform/ax_platform_node_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_win_unittest.cc index 1f6e935..f63b3cd 100644 --- a/ui/accessibility/platform/ax_platform_node_win_unittest.cc +++ b/ui/accessibility/platform/ax_platform_node_win_unittest.cc
@@ -3474,6 +3474,124 @@ EXPECT_EQ(nullptr, safearray.Get()); } +TEST_F(AXPlatformNodeWinTest, ITableProviderGetColumnHeadersMultipleHeaders) { + // Build a table like this: + // header_r1c1 | header_r1c2 | header_r1c3 + // cell_r2c1 | cell_r2c2 | cell_r2c3 + // cell_r3c1 | header_r3c2 | + + // <table> + // <tr aria-label="row1"> + // <th>header_r1c1</th> + // <th>header_r1c2</th> + // <th>header_r1c3</th> + // </tr> + // <tr aria-label="row2"> + // <td>cell_r2c1</td> + // <td>cell_r2c2</td> + // <td>cell_r2c3</td> + // </tr> + // <tr aria-label="row3"> + // <td>cell_r3c1</td> + // <th>header_r3c2</th> + // </tr> + // </table> + + AXNodeData root; + root.id = 1; + root.role = ax::mojom::Role::kTable; + + AXNodeData row1; + row1.id = 2; + row1.role = ax::mojom::Role::kRow; + root.child_ids.push_back(row1.id); + + AXNodeData row2; + row2.id = 3; + row2.role = ax::mojom::Role::kRow; + root.child_ids.push_back(row2.id); + + AXNodeData row3; + row3.id = 4; + row3.role = ax::mojom::Role::kRow; + root.child_ids.push_back(row3.id); + + // <tr aria-label="row1"> + // <th>header_r1c1</th> <th>header_r1c2</th> <th>header_r1c3</th> + // </tr> + AXNodeData header_r1c1; + header_r1c1.id = 5; + header_r1c1.role = ax::mojom::Role::kColumnHeader; + header_r1c1.SetName(L"header_r1c1"); + row1.child_ids.push_back(header_r1c1.id); + + AXNodeData header_r1c2; + header_r1c2.id = 6; + header_r1c2.role = ax::mojom::Role::kColumnHeader; + header_r1c2.SetName(L"header_r1c2"); + row1.child_ids.push_back(header_r1c2.id); + + AXNodeData header_r1c3; + header_r1c3.id = 7; + header_r1c3.role = ax::mojom::Role::kColumnHeader; + header_r1c3.SetName(L"header_r1c3"); + row1.child_ids.push_back(header_r1c3.id); + + // <tr aria-label="row2"> + // <td>cell_r2c1</td> <td>cell_r2c2</td> <td>cell_r2c3</td> + // </tr> + AXNodeData cell_r2c1; + cell_r2c1.id = 8; + cell_r2c1.role = ax::mojom::Role::kCell; + cell_r2c1.SetName(L"cell_r2c1"); + row2.child_ids.push_back(cell_r2c1.id); + + AXNodeData cell_r2c2; + cell_r2c2.id = 9; + cell_r2c2.role = ax::mojom::Role::kCell; + cell_r2c2.SetName(L"cell_r2c2"); + row2.child_ids.push_back(cell_r2c2.id); + + AXNodeData cell_r2c3; + cell_r2c3.id = 10; + cell_r2c3.role = ax::mojom::Role::kCell; + cell_r2c3.SetName(L"cell_r2c3"); + row2.child_ids.push_back(cell_r2c3.id); + + // <tr aria-label="row3"> + // <td>cell_r3c1</td> <th>header_r3c2</th> + // </tr> + AXNodeData cell_r3c1; + cell_r3c1.id = 11; + cell_r3c1.role = ax::mojom::Role::kCell; + cell_r3c1.SetName(L"cell_r3c1"); + row3.child_ids.push_back(cell_r3c1.id); + + AXNodeData header_r3c2; + header_r3c2.id = 12; + header_r3c2.role = ax::mojom::Role::kColumnHeader; + header_r3c2.SetName(L"header_r3c2"); + row3.child_ids.push_back(header_r3c2.id); + + Init(root, row1, row2, row3, header_r1c1, header_r1c2, header_r1c3, cell_r2c1, + cell_r2c2, cell_r2c3, cell_r3c1, header_r3c2); + + ComPtr<ITableProvider> root_itableprovider( + QueryInterfaceFromNode<ITableProvider>(GetRootAsAXNode())); + + base::win::ScopedSafearray safearray; + EXPECT_HRESULT_SUCCEEDED( + root_itableprovider->GetColumnHeaders(safearray.Receive())); + EXPECT_NE(nullptr, safearray.Get()); + + // Validate that we retrieve all column headers of the table and in the order + // below. + std::vector<std::wstring> expected_names = {L"header_r1c1", L"header_r1c2", + L"header_r3c2", L"header_r1c3"}; + EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(safearray.Get(), UIA_NamePropertyId, + expected_names); +} + TEST_F(AXPlatformNodeWinTest, ITableProviderGetRowHeaders) { AXNodeData root; root.id = 1;
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.cc b/ui/accessibility/platform/test_ax_node_wrapper.cc index 85283d3..9432586f 100644 --- a/ui/accessibility/platform/test_ax_node_wrapper.cc +++ b/ui/accessibility/platform/test_ax_node_wrapper.cc
@@ -461,7 +461,7 @@ std::vector<int32_t> TestAXNodeWrapper::GetColHeaderNodeIds() const { std::vector<int32_t> header_ids; - node_->GetTableCellColHeaderNodeIds(&header_ids); + node_->GetTableColHeaderNodeIds(&header_ids); return header_ids; }
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn index caa1b99..cebfe37f 100644 --- a/ui/android/BUILD.gn +++ b/ui/android/BUILD.gn
@@ -214,7 +214,9 @@ deps = [ "//base:base_java", "//components/payments/mojom:mojom_java", - "//third_party/android_deps:android_support_v7_appcompat_java", + "//third_party/android_deps:androidx_appcompat_appcompat_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", + "//third_party/android_deps:androidx_core_core_java", "//third_party/blink/public/mojom:mojom_platform_java", ] } @@ -346,6 +348,7 @@ "//base:jni_java", "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:androidx_annotation_annotation_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", "//third_party/android_deps:androidx_asynclayoutinflater_asynclayoutinflater_java", "//third_party/android_deps:androidx_recyclerview_recyclerview_java", "//ui/base/cursor/mojom:cursor_type_java", @@ -426,6 +429,9 @@ "//base:base_java_test_support", "//base:base_junit_test_support", "//base/test:test_support_java", + "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", + "//third_party/android_deps:androidx_asynclayoutinflater_asynclayoutinflater_java", + "//third_party/hamcrest:hamcrest_java", ] } @@ -472,6 +478,7 @@ deps = [ "//base:base_java", "//base:base_java_test_support", + "//base:jni_java", ] }
diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc index 1bd35c1..d2936c4 100644 --- a/ui/base/x/x11_util.cc +++ b/ui/base/x/x11_util.cc
@@ -160,19 +160,17 @@ } unsigned int GetMaxCursorSize() { - // Although XQueryBestCursor() takes unsigned ints, the width and height will - // be sent over the wire as 16 bit integers. constexpr unsigned int kQuerySize = std::numeric_limits<uint16_t>::max(); - XDisplay* display = gfx::GetXDisplay(); - unsigned int width = 0; - unsigned int height = 0; - XQueryBestCursor(display, DefaultRootWindow(display), kQuerySize, kQuerySize, - &width, &height); - unsigned int min_dimension = std::min(width, height); + auto* connection = x11::Connection::Get(); + x11::XProto::QueryBestSizeRequest request{ + x11::XProto::QueryShapeOf::LargestCursor, + static_cast<x11::Window>(GetX11RootWindow()), kQuerySize, kQuerySize}; + if (auto response = connection->QueryBestSize(request).Sync()) + return std::min(response->width, response->height); // libXcursor defines MAX_BITMAP_CURSOR_SIZE to 64 in src/xcursorint.h, so use // this as a fallback in case the X server returns zero size, which can happen // on some buggy implementations of XWayland/XMir. - return min_dimension > 0 ? min_dimension : 64; + return 64; } // A process wide singleton cache for custom X cursors. @@ -485,11 +483,10 @@ motif_hints.flags = (1L << 1); motif_hints.decorations = use_os_window_frame ? 1 : 0; - auto hint_atom = static_cast<uint32_t>(gfx::GetAtom("_MOTIF_WM_HINTS")); - XChangeProperty(gfx::GetXDisplay(), window, hint_atom, hint_atom, 32, - PropModeReplace, - reinterpret_cast<unsigned char*>(&motif_hints), - sizeof(MotifWmHints) / sizeof(long)); + std::vector<uint32_t> hints(sizeof(MotifWmHints) / sizeof(uint32_t)); + memcpy(hints.data(), &motif_hints, sizeof(MotifWmHints)); + x11::Atom hint_atom = gfx::GetAtom("_MOTIF_WM_HINTS"); + SetArrayProperty(window, hint_atom, hint_atom, hints); } bool IsShapeExtensionAvailable() { @@ -533,10 +530,10 @@ bool IsWindowVisible(XID window) { TRACE_EVENT0("ui", "IsWindowVisible"); - XWindowAttributes win_attributes; - if (!XGetWindowAttributes(gfx::GetXDisplay(), window, &win_attributes)) - return false; - if (win_attributes.map_state != IsViewable) + auto x11_window = static_cast<x11::Window>(window); + auto* connection = x11::Connection::Get(); + auto response = connection->GetWindowAttributes({x11_window}).Sync(); + if (!response || response->map_state != x11::XProto::MapState::Viewable) return false; // Minimized windows are not visible. @@ -556,21 +553,22 @@ } bool GetInnerWindowBounds(XID window, gfx::Rect* rect) { - Window root, child; - int x, y; - unsigned int width, height; - unsigned int border_width, depth; + auto x11_window = static_cast<x11::Window>(window); + auto root = static_cast<x11::Window>(GetX11RootWindow()); - if (!XGetGeometry(gfx::GetXDisplay(), window, &root, &x, &y, &width, &height, - &border_width, &depth)) + x11::Connection* connection = x11::Connection::Get(); + auto get_geometry = connection->GetGeometry({x11_window}); + auto translate_coords = connection->TranslateCoordinates({x11_window, root}); + + // Sync after making both requests so only one round-trip is made. + auto geometry = get_geometry.Sync(); + auto coords = translate_coords.Sync(); + + if (!geometry || !coords) return false; - if (!XTranslateCoordinates(gfx::GetXDisplay(), window, root, 0, 0, &x, &y, - &child)) - return false; - - *rect = gfx::Rect(x, y, width, height); - + *rect = gfx::Rect(coords->dst_x, coords->dst_y, geometry->width, + geometry->height); return true; } @@ -901,12 +899,7 @@ // Returns true if |window| is a named window. bool IsWindowNamed(XID window) { - XTextProperty prop; - if (!XGetWMName(gfx::GetXDisplay(), window, &prop) || !prop.value) - return false; - - XFree(prop.value); - return true; + return PropertyExists(window, "WM_NAME"); } bool EnumerateChildren(EnumerateWindowsDelegate* delegate, @@ -1123,8 +1116,8 @@ ? "_ICC_PROFILE" : base::StringPrintf("_ICC_PROFILE_%d", monitor); std::vector<uint8_t> data; - if (GetRawBytesOfProperty(DefaultRootWindow(gfx::GetXDisplay()), - gfx::GetAtom(atom_name), &data, nullptr)) { + if (GetRawBytesOfProperty(GetX11RootWindow(), gfx::GetAtom(atom_name), &data, + nullptr)) { icc_profile = gfx::ICCProfile::FromData(data.data(), data.size()); } return icc_profile; @@ -1409,9 +1402,8 @@ XVisualManager::XVisualData::~XVisualData() = default; Colormap XVisualManager::XVisualData::GetColormap() { - XDisplay* display = gfx::GetXDisplay(); if (colormap_ == static_cast<int>(x11::XProto::WindowClass::CopyFromParent)) { - colormap_ = XCreateColormap(display, DefaultRootWindow(display), + colormap_ = XCreateColormap(gfx::GetXDisplay(), GetX11RootWindow(), visual_info.visual, AllocNone); } return colormap_;
diff --git a/ui/gfx/x/gen_xproto.py b/ui/gfx/x/gen_xproto.py index ef4e9ddd6..5aebd13d 100644 --- a/ui/gfx/x/gen_xproto.py +++ b/ui/gfx/x/gen_xproto.py
@@ -177,6 +177,11 @@ # so this global is unavoidable. output = collections.defaultdict(int) +MODULE_NAMES = { + 'xproto': 'XProto', + 'glx': 'Glx', +} + UPPER_CASE_PATTERN = re.compile(r'^[A-Z0-9_]+$') @@ -328,6 +333,9 @@ # Map of enums to their underlying types self.enum_types = collections.defaultdict(set) + # Map from (XML tag, XML name) to XML element + self.module_names = {} + # Write a line to the current file. def write(self, line=''): indent = self.indent if line and not line.startswith('#') else 0 @@ -472,16 +480,45 @@ assert expr.lenfield_name return expr.lenfield_name + def get_xidunion_element(self, name): + key = ('xidunion', name[-1]) + return self.module_names.get(key, None) + + def declare_xidunion(self, xidunion, xidname): + names = [type_element.text for type_element in xidunion] + types = list(set([self.module.get_type(name) for name in names])) + assert len(types) == 1 + value_type = types[0] + value_typename = self.qualtype(value_type, value_type.name) + with Indent(self, 'struct %s {' % xidname, '};'): + self.write('%s() : value{} {}' % xidname) + self.write() + for name in names: + cpp_name = self.module.get_type_name(name) + typename = self.qualtype(value_type, cpp_name) + self.write('%s(%s value) : value{static_cast<%s>(value)} {}' % + (xidname, typename, value_typename)) + self.write( + 'operator %s() const { return static_cast<%s>(value); }' % + (typename, typename)) + self.write() + self.write('%s value;' % value_typename) + def declare_simple(self, item, name): # The underlying type of an enum must be integral, so avoid defining # FLOAT32 or FLOAT64. Usages are renamed to float and double instead. renamed = tuple(self.rename_type(item, name)) - if name[-1] not in ('FLOAT32', 'FLOAT64' - ) and renamed not in self.replace_with_enum: - self.write( - 'enum class %s : %s {};' % - (adjust_type_case(name[-1]), self.qualtype(item, item.name))) - self.write() + if (name[-1] in ('FLOAT32', 'FLOAT64') + or renamed in self.replace_with_enum): + return + + xidunion = self.get_xidunion_element(name) + if xidunion: + self.declare_xidunion(xidunion, renamed[-1]) + else: + self.write('enum class %s : %s {};' % + (renamed[-1], self.qualtype(item, item.name))) + self.write() def copy_primitive(self, name): self.write('%s(&%s, &buf);' % @@ -931,19 +968,26 @@ self.replace_with_enum.add(t) self.enum_types[enum.name] = simple.name + for node in self.module.namespace.root: + if 'name' in node.attrib: + key = (node.tag, node.attrib['name']) + assert key not in self.module_names + self.module_names[key] = node + # The order of types in xcbproto's xml files are inconsistent, so sort - # them in the order {type aliases, enums, structs, requests/replies}. - def type_order_priority(item): + # them in the order {type aliases, enums, xidunions, structs, + # requests/replies}. + def type_order_priority((name, item)): if item.is_simple: - return 0 + return 2 if self.get_xidunion_element(name) else 0 if isinstance(item, self.xcbgen.xtypes.Enum): return 1 if isinstance(item, self.xcbgen.xtypes.Request): - return 3 - return 2 + return 4 + return 3 - def cmp((_1, item1), (_2, item2)): - return type_order_priority(item1) - type_order_priority(item2) + def cmp(type1, type2): + return type_order_priority(type1) - type_order_priority(type2) # sort() is guaranteed to be stable. self.module.all.sort(cmp=cmp)
diff --git a/ui/ozone/demo/skia/skia_gl_renderer.cc b/ui/ozone/demo/skia/skia_gl_renderer.cc index ceb5cc4..808b765a 100644 --- a/ui/ozone/demo/skia/skia_gl_renderer.cc +++ b/ui/ozone/demo/skia/skia_gl_renderer.cc
@@ -106,7 +106,7 @@ } else { Draw(sk_surface_->getCanvas(), NextFraction()); } - gr_context_->flush(); + gr_context_->flushAndSubmit(); glFinish(); if (gl_surface_->SupportsAsyncSwap()) {
diff --git a/ui/ozone/demo/skia/skia_surfaceless_gl_renderer.cc b/ui/ozone/demo/skia/skia_surfaceless_gl_renderer.cc index e2ee943..c3079392 100644 --- a/ui/ozone/demo/skia/skia_surfaceless_gl_renderer.cc +++ b/ui/ozone/demo/skia/skia_surfaceless_gl_renderer.cc
@@ -244,7 +244,7 @@ } else { Draw(sk_surface->getCanvas(), NextFraction()); } - gr_context_->flush(); + gr_context_->flushAndSubmit(); glFinish(); if (!disable_primary_plane_) {
diff --git a/ui/views/bubble/bubble_dialog_delegate_view.cc b/ui/views/bubble/bubble_dialog_delegate_view.cc index 26c5fede..81a9a03 100644 --- a/ui/views/bubble/bubble_dialog_delegate_view.cc +++ b/ui/views/bubble/bubble_dialog_delegate_view.cc
@@ -197,6 +197,7 @@ BubbleBorder::Arrow arrow, BubbleBorder::Shadow shadow) : shadow_(shadow) { + set_owned_by_client(); WidgetDelegate::SetShowCloseButton(false); SetArrow(arrow); @@ -250,7 +251,31 @@ GetFocusManager()->AdvanceFocus(accelerator.key_code() != ui::VKEY_DOWN); return true; } - return DialogDelegateView::AcceleratorPressed(accelerator); + return View::AcceleratorPressed(accelerator); +} + +Widget* BubbleDialogDelegateView::GetWidget() { + return View::GetWidget(); +} + +const Widget* BubbleDialogDelegateView::GetWidget() const { + return View::GetWidget(); +} + +void BubbleDialogDelegateView::ViewHierarchyChanged( + const ViewHierarchyChangedDetails& details) { + if (details.is_add && details.child == this && GetWidget() && + ui::IsAlert(GetAccessibleWindowRole())) { + NotifyAccessibilityEvent(ax::mojom::Event::kAlert, true); + } +} + +View* BubbleDialogDelegateView::GetContentsView() { + return this; +} + +void BubbleDialogDelegateView::DeleteDelegate() { + delete this; } void BubbleDialogDelegateView::OnWidgetClosing(Widget* widget) { @@ -450,7 +475,7 @@ } void BubbleDialogDelegateView::OnThemeChanged() { - DialogDelegateView::OnThemeChanged(); + View::OnThemeChanged(); UpdateColorsFromTheme(); }
diff --git a/ui/views/bubble/bubble_dialog_delegate_view.h b/ui/views/bubble/bubble_dialog_delegate_view.h index c56ab1fa..203d347 100644 --- a/ui/views/bubble/bubble_dialog_delegate_view.h +++ b/ui/views/bubble/bubble_dialog_delegate_view.h
@@ -39,8 +39,10 @@ class Button; -// BubbleDialogDelegateView is a special DialogDelegateView for bubbles. -class VIEWS_EXPORT BubbleDialogDelegateView : public DialogDelegateView, +// BubbleDialogDelegateView is a special DialogDelegate that is also a View for +// bubbles. +class VIEWS_EXPORT BubbleDialogDelegateView : public DialogDelegate, + public View, public WidgetObserver { public: METADATA_HEADER(BubbleDialogDelegateView); @@ -65,10 +67,17 @@ ~BubbleDialogDelegateView() override; - // DialogDelegateView: + // DialogDelegate: BubbleDialogDelegateView* AsBubbleDialogDelegate() override; NonClientFrameView* CreateNonClientFrameView(Widget* widget) override; bool AcceleratorPressed(const ui::Accelerator& accelerator) override; + View* GetContentsView() override; + void DeleteDelegate() override; + + // View: + Widget* GetWidget() override; + const Widget* GetWidget() const override; + void ViewHierarchyChanged(const ViewHierarchyChangedDetails& change) override; // WidgetObserver: void OnWidgetClosing(Widget* widget) override;
diff --git a/ui/webui/resources/cr_components/certificate_manager/BUILD.gn b/ui/webui/resources/cr_components/certificate_manager/BUILD.gn index 661dff8..46b2c659 100644 --- a/ui/webui/resources/cr_components/certificate_manager/BUILD.gn +++ b/ui/webui/resources/cr_components/certificate_manager/BUILD.gn
@@ -20,6 +20,15 @@ ":certificates_browser_proxy", ":certificates_error_dialog", ] + + # These are Chrome OS specific but always included because of limitations + # around conditional imports (https://crbug.com/1071641#c10). + deps += [ + ":certificate_provisioning_browser_proxy", + ":certificate_provisioning_details_dialog", + ":certificate_provisioning_entry", + ":certificate_provisioning_list", + ] } js_library("ca_trust_edit_dialog") { @@ -80,6 +89,42 @@ ] } +js_library("certificate_provisioning_browser_proxy") { + deps = [ "//ui/webui/resources/js:cr.m" ] +} + +js_library("certificate_provisioning_details_dialog") { + deps = [ + ":certificate_manager_types", + ":certificate_provisioning_browser_proxy", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:load_time_data.m", + ] +} + +js_library("certificate_provisioning_entry") { + deps = [ + ":certificate_manager_types", + ":certificate_provisioning_browser_proxy", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu.m", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:load_time_data.m", + ] +} + +js_library("certificate_provisioning_list") { + deps = [ + ":certificate_provisioning_browser_proxy", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:load_time_data.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", + ] +} + js_library("certificate_password_decryption_dialog") { deps = [ ":certificates_browser_proxy", @@ -134,4 +179,12 @@ "certificate_subentry.js", "certificates_error_dialog.js", ] + + # These are Chrome OS specific but always included because of limitations + # around conditional imports (https://crbug.com/1071641#c10). + js_files += [ + "certificate_provisioning_details_dialog.js", + "certificate_provisioning_entry.js", + "certificate_provisioning_list.js", + ] }
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_manager.html b/ui/webui/resources/cr_components/certificate_manager/certificate_manager.html index 13342918..4db93d9 100644 --- a/ui/webui/resources/cr_components/certificate_manager/certificate_manager.html +++ b/ui/webui/resources/cr_components/certificate_manager/certificate_manager.html
@@ -38,6 +38,9 @@ certificate-type="[[certificateTypeEnum_.PERSONAL]]" import-allowed="[[clientImportAllowed]]"> </certificate-list> +<if expr="chromeos"> + <certificate-provisioning-list></certificate-provisioning-list> +</if> </div> <div> <template is="dom-if" if="[[isTabSelected_(selected, 1)]]">
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_manager.js b/ui/webui/resources/cr_components/certificate_manager/certificate_manager.js index bd4c7a5..7497187 100644 --- a/ui/webui/resources/cr_components/certificate_manager/certificate_manager.js +++ b/ui/webui/resources/cr_components/certificate_manager/certificate_manager.js
@@ -14,6 +14,7 @@ import './certificate_password_decryption_dialog.js'; import './certificate_password_encryption_dialog.js'; import './certificates_error_dialog.js'; +import './certificate_provisioning_list.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_manager_types.js b/ui/webui/resources/cr_components/certificate_manager/certificate_manager_types.js index 2260a23..d8ee0b93 100644 --- a/ui/webui/resources/cr_components/certificate_manager/certificate_manager_types.js +++ b/ui/webui/resources/cr_components/certificate_manager/certificate_manager_types.js
@@ -7,7 +7,8 @@ */ // clang-format off -import { CertificatesError, CertificatesImportError,CertificateSubnode, CertificateType, NewCertificateSubNode} from './certificates_browser_proxy.js'; +import {CertificateProvisioningProcess} from './certificate_provisioning_browser_proxy.js'; +import {CertificatesError, CertificatesImportError,CertificateSubnode, CertificateType, NewCertificateSubNode} from './certificates_browser_proxy.js'; // clang-format on /** @@ -46,3 +47,20 @@ * dropdown menu. CertificateActionEventDetail is passed as the event detail. */ export const CertificateActionEvent = 'certificate-action'; + +/** + * The payload of the 'certificate-provisioning-view-details-action' event. + * @typedef {{ + * model: !CertificateProvisioningProcess, + * anchor: !HTMLElement + * }} + */ +export let CertificateProvisioningActionEventDetail; + +/** + * The name of the event fired when a the "View Details" action is selected on + * the dropdown menu next to a certificate provisioning process. + * CertificateActionEventDetail is passed as the event detail. + */ +export const CertificateProvisioningViewDetailsActionEvent = + 'certificate-provisioning-view-details-action';
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_browser_proxy.js b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_browser_proxy.js new file mode 100644 index 0000000..57e3428e --- /dev/null +++ b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_browser_proxy.js
@@ -0,0 +1,74 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview A helper object used on Chrome OS from the "Manage + * certificates" section to interact with certificate provisioining processes. + */ + +import {addSingletonGetter} from 'chrome://resources/js/cr.m.js'; + +/** + * The 'certificate-provisioning-processes-changed' event will have an array of + * CertificateProvisioningProcesses as its argument. This typedef is currently + * declared here to be consistent with certificates_browser_proxy.js, but it is + * not specific to CertificateProvisioningBrowserProxy. + * + * @typedef {{ + * certProfileId: string, + * isDeviceWide: boolean, + * status: string, + * stateId: number, + * timeSinceLastUpdate: string, + * publicKey: string + * }} + * @see chrome/browser/ui/webui/settings/certificates_handler.cc + */ +export let CertificateProvisioningProcess; + +/** @interface */ +export class CertificateProvisioningBrowserProxy { + // <if expr="chromeos"> + // TODO(https://crbug.com/1071641): When it is possible to have conditional + // imports in ui/webui/resources/cr_components/, this file should be + // conditionally imported. Until then, it is imported unconditionally but its + // non-exported code is omitted for non-ChromeOS platforms. + + /** + * Refreshes the list of client certificate processes. + * Triggers the 'certificate-provisioning-processes-changed' event. + * This is Chrome OS specific, but always present for simplicity. + */ + refreshCertificateProvisioningProcesses() {} + + /** + * Attempts to manually advance/refresh the status of the client certificate + * provisioning process identified by |certProfileId|. + * This is Chrome OS specific, but always present for simplicity. + * @param {string} certProfileId + * @param {boolean} isDeviceWide + */ + triggerCertificateProvisioningProcessUpdate(certProfileId, isDeviceWide) {} + + // </if> +} + +/** @implements {CertificateProvisioningBrowserProxy} */ +export class CertificateProvisioningBrowserProxyImpl { + /** override */ + refreshCertificateProvisioningProcesses() { + chrome.send('refreshCertificateProvisioningProcessses'); + } + + /** override */ + triggerCertificateProvisioningProcessUpdate(certProfileId, isDeviceWide) { + chrome.send( + 'triggerCertificateProvisioningProcessUpdate', + [certProfileId, isDeviceWide]); + } +} + +// The singleton instance_ is replaced with a test version of this wrapper +// during testing. +addSingletonGetter(CertificateProvisioningBrowserProxyImpl);
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_details_dialog.html b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_details_dialog.html new file mode 100644 index 0000000..fba5360 --- /dev/null +++ b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_details_dialog.html
@@ -0,0 +1,64 @@ +<style include="iron-flex"> + .button-box { + align-items: center; + display: flex; + min-height: 48px; + } + + .label { + color: var(--cr-secondary-text-color); + font-size: 85%; + } + + + /* A row with two lines of text. + * Consistnt with chrome/browser/resources/settings/settings_shared_css.html + * (which can not be imported here because this is in cr_components). + */ + .two-line { + min-height: var(--settings-row-two-line-min-height); + } + + .value { + color: var(--cr-primary-text-color); + } +</style> +<cr-dialog id="dialog" show-on-attach show-close-button close-text="[[i18n('close')]]"> + <div slot="title"> + [[i18n('certificateProvisioningDetails')]] + </div> + <div slot="body"> + <div class="two-line"> + <div class="label">[[i18n('certificateProvisioningProfile')]]</div> + <div class="value">[[model.certProfileId]]</div> + </div> + <div class="button-box"> + <div class="two-line flex"> + <div class="label">[[i18n('certificateProvisioningStatus')]]</div> + <span class="value">[[model.status]]</span> + </div> + <cr-button id="refresh" role="button" on-click="onRefresh_"> + [[i18n('certificateProvisioningRefresh')]] + </cr-button> + </div> + <div class="two-line"> + <div class="label">[[i18n('certificateProvisioningLastUpdate')]]</div> + <div class="value">[[model.timeSinceLastUpdate]]</div> + </div> + <hr></hr> + <cr-expand-button expanded="{{advancedExpanded_}}" + aria-expanded$="[[boolToString_(advancedOpened)]]"> + <div>[[i18n('certificateProvisioningAdvancedSectionTitle')]]</div> + </cr-expand-button> + <iron-collapse id="advancedInfo" opened="[[advancedExpanded_]]"> + <div class="two-line"> + <div class="label">[[i18n('certificateProvisioningStatusId')]]</div> + <div class="value">[[model.stateId]]</div> + </div> + <div class="two-line"> + <div class="label">[[i18n('certificateProvisioningPublicKey')]]</div> + <div class="value">[[model.publicKey]]</div> + </div> + </iron-collapse> + </div> +</cr-dialog>
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_details_dialog.js b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_details_dialog.js new file mode 100644 index 0000000..c04422d --- /dev/null +++ b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_details_dialog.js
@@ -0,0 +1,65 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview 'certificate-provisioning-details-dialog' allows the user to + * view the details of an in-progress certiifcate provisioning process. + */ +import 'chrome://resources/cr_elements/cr_expand_button/cr_expand_button.m.js'; +import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js'; +import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js'; + +import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {CertificateProvisioningBrowserProxyImpl, CertificateProvisioningProcess} from './certificate_provisioning_browser_proxy.js'; + +// <if expr="chromeos"> +// TODO(https://crbug.com/1071641): When it is possible to have conditional +// imports in ui/webui/resources/cr_components/, this file should be +// conditionally imported. Until then, it is imported unconditionally but its +// contents are omitted for non-ChromeOS platforms. + +Polymer({ + is: 'certificate-provisioning-details-dialog', + + _template: html`{__html_template__}`, + + behaviors: [I18nBehavior], + + properties: { + /** @type {!CertificateProvisioningProcess} */ + model: Object, + + /** @private */ + advancedExpanded_: Boolean, + }, + + /** @private */ + onRefresh_() { + CertificateProvisioningBrowserProxyImpl.getInstance() + .triggerCertificateProvisioningProcessUpdate( + this.model.certProfileId, this.model.isDeviceWide); + }, + + /** + * @param {boolean} opened Whether the menu is expanded. + * @return {string} Which icon to use. + * @private + * */ + arrowState_(opened) { + return opened ? 'cr:arrow-drop-up' : 'cr:arrow-drop-down'; + }, + + /** + * @param {boolean} bool + * @return {string} + * @private + */ + boolToString_(bool) { + return bool.toString(); + }, +}); + +// </if>
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_entry.html b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_entry.html new file mode 100644 index 0000000..c2efcda5f --- /dev/null +++ b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_entry.html
@@ -0,0 +1,25 @@ +<style include="certificate-shared iron-flex"> + .cert-box { + align-items: center; + border-top: var(--cr-separator-line); + display: flex; + min-height: 48px; + padding: 0 20px; + } +</style> +<div class="cert-box"> + <div class="flex" tabindex="0">[[model.certProfileId]]</div> + <cr-icon-button class="icon-more-vert" id="dots" + title="[[i18n('moreActions')]]" on-click="onDotsClick_"> + </cr-icon-button> + <cr-lazy-render id="menu"> + <template> + <cr-action-menu role-description="[[i18n('menu')]]"> + <button class="dropdown-item" id="details" + on-click="onDetailsClick_"> + [[i18n('certificateProvisioningDetails')]] + </button> + </cr-action-menu> + </template> + </cr-lazy-render> +</div>
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_entry.js b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_entry.js new file mode 100644 index 0000000..711e24f4 --- /dev/null +++ b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_entry.js
@@ -0,0 +1,65 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview 'certificate-provisioning-entry' is an element that displays + * one certificate provisioning processes. + */ +import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.m.js'; +import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js'; +import 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.m.js'; +import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js'; +import './certificate_shared_css.js'; + +import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {CertificateProvisioningActionEventDetail, CertificateProvisioningViewDetailsActionEvent} from './certificate_manager_types.js'; +import {CertificateProvisioningProcess} from './certificate_provisioning_browser_proxy.js'; + +// <if expr="chromeos"> +// TODO(https://crbug.com/1071641): When it is possible to have conditional +// imports in ui/webui/resources/cr_components/, this file should be +// conditionally imported. Until then, it is imported unconditionally but its +// contents are omitted for non-ChromeOS platforms. + +Polymer({ + is: 'certificate-provisioning-entry', + + _template: html`{__html_template__}`, + + properties: { + /** @type {!CertificateProvisioningProcess} */ + model: Object, + }, + + behaviors: [I18nBehavior], + + /** @private */ + closePopupMenu_() { + this.$$('cr-action-menu').close(); + }, + + /** @private */ + onDotsClick_() { + const actionMenu = /** @type {!CrActionMenuElement} */ (this.$.menu.get()); + actionMenu.showAt(this.$.dots); + }, + + /** + * @param {!Event} event + * @private + */ + onDetailsClick_(event) { + this.closePopupMenu_(); + this.fire( + CertificateProvisioningViewDetailsActionEvent, + /** @type {!CertificateProvisioningActionEventDetail} */ ({ + model: this.model, + anchor: this.$.dots, + })); + }, +}); + +// </if>
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_list.html b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_list.html new file mode 100644 index 0000000..1fae157 --- /dev/null +++ b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_list.html
@@ -0,0 +1,29 @@ +<style include="cr-shared-style iron-flex "> + .header-box { + align-items: center; + display: flex; + margin-top: 16px; + min-height: 24px; + padding: 0 20px; + } + + .hidden { + display: none; + } +</style> + +<template is="dom-if" if="[[showProvisioningDetailsDialog_]]" restamp> + <certificate-provisioning-details-dialog model="[[provisioningDetailsDialogModel_]]"> + </certificate-provisioning-details-dialog> +</template> + +<div class="header-box" aria-role="heading" aria-labelledby="headingLabel" + hidden="[[!hasCertificateProvisioningEntries_(provisioningProcesses_)]]"> + <span id="headingLabel" class="flex"> + [[i18n('certificateProvisioningListHeader')]] + </span> +</div> +<template is="dom-repeat" items="[[provisioningProcesses_]]"> + <certificate-provisioning-entry model="[[item]]"> + </certificate-provisioning-entry> +</template>
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_list.js b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_list.js new file mode 100644 index 0000000..3e7d025 --- /dev/null +++ b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_list.js
@@ -0,0 +1,124 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview 'certificate-provisioning-list' is an element that displays a + * list of certificate provisioning processes. + */ +import 'chrome://resources/cr_elements/shared_style_css.m.js'; +import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js'; +import './certificate_provisioning_details_dialog.js'; +import './certificate_provisioning_entry.js'; + +import {assert} from 'chrome://resources/js/assert.m.js'; +import {focusWithoutInk} from 'chrome://resources/js/cr/ui/focus_without_ink.m.js'; +import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; +import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js'; +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {CertificateProvisioningActionEventDetail, CertificateProvisioningViewDetailsActionEvent} from './certificate_manager_types.js'; +import {CertificateProvisioningBrowserProxyImpl, CertificateProvisioningProcess} from './certificate_provisioning_browser_proxy.js'; + +// <if expr="chromeos"> +// TODO(https://crbug.com/1071641): When it is possible to have conditional +// imports in ui/webui/resources/cr_components/, this file should be +// conditionally imported. Until then, it is imported unconditionally but its +// contents are omitted for non-ChromeOS platforms. + +Polymer({ + is: 'certificate-provisioning-list', + + _template: html`{__html_template__}`, + + behaviors: [I18nBehavior, WebUIListenerBehavior], + + properties: { + /** @type {!Array<!CertificateProvisioningProcess>} */ + provisioningProcesses_: { + type: Array, + value() { + return []; + } + }, + + /** + * The model to be passed to certificate provisioning details dialog. + * @private {?CertificateProvisioningProcess} + */ + provisioningDetailsDialogModel_: Object, + + /** @private */ + showProvisioningDetailsDialog_: Boolean, + }, + + /** + * @param {!Array<!CertificateProvisioningProcess>} provisioningProcesses The + * list of certificate provisioning processes. + * @return {boolean} true if |provisioningProcesses| contains at least one + * entry. + * @private + */ + hasCertificateProvisioningEntries_(provisioningProcesses) { + return provisioningProcesses.length !== 0; + }, + + /** + * @param {!Array<!CertificateProvisioningProcess>} certProvisioningProcesses + * The currently active certificate provisioning processes + * @private + */ + onCertificateProvisioningProcessesChanged_(certProvisioningProcesses) { + this.provisioningProcesses_ = certProvisioningProcesses; + + // If a cert provisioning process details dialog is being shown, update its + // model. + if (!this.provisioningDetailsDialogModel_) { + return; + } + + const certProfileId = this.provisioningDetailsDialogModel_.certProfileId; + const newDialogModel = this.provisioningProcesses_.find((process) => { + return process.certProfileId === certProfileId; + }); + if (newDialogModel) { + this.provisioningDetailsDialogModel_ = newDialogModel; + } + }, + + /** @override */ + attached() { + this.addWebUIListener( + 'certificate-provisioning-processes-changed', + this.onCertificateProvisioningProcessesChanged_.bind(this)); + CertificateProvisioningBrowserProxyImpl.getInstance() + .refreshCertificateProvisioningProcesses(); + }, + + /** @override */ + ready() { + this.addEventListener( + CertificateProvisioningViewDetailsActionEvent, event => { + const detail = + /** @type {!CertificateProvisioningActionEventDetail} */ ( + event.detail); + this.provisioningDetailsDialogModel_ = detail.model; + + const previousAnchor = assert(detail.anchor); + this.showProvisioningDetailsDialog_ = true; + this.async(() => { + const dialog = this.$$('certificate-provisioning-details-dialog'); + // The listener is destroyed when the dialog is removed (because of + // 'restamp'). + dialog.addEventListener('close', () => { + this.showProvisioningDetailsDialog_ = false; + focusWithoutInk(previousAnchor); + }); + }); + + event.stopPropagation(); + }); + } +}); + +// </if>
diff --git a/ui/webui/resources/cr_components/cr_components_resources_v3.grdp b/ui/webui/resources/cr_components/cr_components_resources_v3.grdp index 82b97da..b4bdcad 100644 --- a/ui/webui/resources/cr_components/cr_components_resources_v3.grdp +++ b/ui/webui/resources/cr_components/cr_components_resources_v3.grdp
@@ -37,6 +37,7 @@ <include name="IDR_WEBUI_CERTIFICATE_MANAGER_JS" file="${root_gen_dir}/ui/webui/resources/cr_components/certificate_manager/certificate_manager.js" use_base_dir="false" + preprocess="true" type="BINDATA" compress="gzip" /> <include name="IDR_WEBUI_CERTIFICATE_PASSWORD_ENCRYPTION_DIALOG_JS" @@ -79,6 +80,32 @@ use_base_dir="false" type="BINDATA" compress="gzip" /> + <!-- TODO(https://crbug.com/1071641): When conditional imports are possible + in cr_components, only include the certificate provisioning items for + ChromeOS platforms. --> + <include name="IDR_WEBUI_CERTIFICATE_PROVISIONING_LIST_JS" + file="${root_gen_dir}/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_list.js" + use_base_dir="false" + type="BINDATA" + preprocess="true" + compress="gzip" /> + <include name="IDR_WEBUI_CERTIFICATE_PROVISIONING_ENTRY_JS" + file="${root_gen_dir}/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_entry.js" + use_base_dir="false" + type="BINDATA" + preprocess="true" + compress="gzip" /> + <include name="IDR_WEBUI_CERTIFICATE_PROVISIONING_DETAILS_DIALOG_JS" + file="${root_gen_dir}/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_details_dialog.js" + use_base_dir="false" + type="BINDATA" + preprocess="true" + compress="gzip" /> + <include name="IDR_WEBUI_CERTIFICATE_PROVISIONING_BROWSER_PROXY" + file="cr_components/certificate_manager/certificate_provisioning_browser_proxy.js" + type="BINDATA" + preprocess="true" + compress="gzip" /> <include name="IDR_WEBUI_CERTIFICATES_BROWSER_PROXY_JS" file="cr_components/certificate_manager/certificates_browser_proxy.js" type="BINDATA"
diff --git a/weblayer/browser/android/javatests/BUILD.gn b/weblayer/browser/android/javatests/BUILD.gn index 05c3023..3f5b6f418 100644 --- a/weblayer/browser/android/javatests/BUILD.gn +++ b/weblayer/browser/android/javatests/BUILD.gn
@@ -49,6 +49,7 @@ "//third_party/android_deps:androidx_fragment_fragment_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", + "//third_party/hamcrest:hamcrest_java", "//third_party/junit:junit", "//weblayer/browser/java:interfaces_java", "//weblayer/public/java", @@ -100,7 +101,11 @@ "//content/public/test/android:content_java_test_support", "//net/android:net_java_test_support", "//third_party/android_deps:androidx_core_core_java", + "//third_party/android_deps:androidx_fragment_fragment_java", + "//third_party/android_support_test_runner:rules_java", + "//third_party/android_support_test_runner:runner_java", "//third_party/hamcrest:hamcrest_java", + "//third_party/junit:junit", "//weblayer/public/java", "//weblayer/shell/android:weblayer_shell_java", ] @@ -194,11 +199,15 @@ ] deps = [ ":weblayer_java_test_support", + "//base:base_java", + "//base:base_java_test_support", + "//content/public/test/android:content_java_test_support", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", "//third_party/junit:junit", "//weblayer/public/java", "//weblayer/public/javatestutil:test_java", + "//weblayer/shell/android:weblayer_shell_java", ] never_incremental = true }
diff --git a/weblayer/browser/java/BUILD.gn b/weblayer/browser/java/BUILD.gn index d9c876e..5142bcd5 100644 --- a/weblayer/browser/java/BUILD.gn +++ b/weblayer/browser/java/BUILD.gn
@@ -142,6 +142,7 @@ "//components/webrtc/android:java", "//content/public/android:content_java", "//net/android:net_java", + "//services/network/public/mojom:cookies_mojom_java", "//services/network/public/mojom:mojom_java", "//third_party/android_deps:androidx_core_core_java", "//ui/android:ui_full_java", @@ -182,6 +183,7 @@ ":java", ":weblayer_test_resources", "//base:jni_java", + "//components/location/android:location_java", "//components/permissions/android:java", "//content/public/test/android:content_java_test_support", "//net/android:net_java",