diff --git a/DEPS b/DEPS index 8eb2a6bd..d3ba6421 100644 --- a/DEPS +++ b/DEPS
@@ -206,11 +206,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': 'fd74ac6498c418497e971a4441ba6b94c1a8bb4a', + 'skia_revision': '7db7139f40321161d3db4f2c4c7b478855d1e237', # 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': 'f3b5599f3d1002a512135925a9b7c6f86f509803', + 'v8_revision': 'b0723ad5a4612732df247bf98099f4e61fc32681', # 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. @@ -218,11 +218,11 @@ # 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': 'b4fb7cc9ec8f4c1751f84dcf5098b1ec5212a9ec', + 'angle_revision': '119d867c232d0abd85c9b7e37bced413466653fa', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '04bd4d8e4ece08cc4efbb4754665f46ec42eff79', + 'swiftshader_revision': 'a23231ea7d9174adf545b803a57835e1a2ff8ed0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -277,7 +277,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': 'd8da6adce186a280ce4f69772793b6cf02b50c4b', + 'devtools_frontend_revision': 'ae3dc89611ac4e73e790716441a96d1ccba29238', # 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. @@ -329,11 +329,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': 'b1938273e4050931cadf697a946a0bcb49821ce1', + 'dawn_revision': '2a8ada79514632d2b9a60bd570cc3fcbf02b18e8', # 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': '7df418b6dc0ad8fe543e00e2c34c274b70bf771c', + 'quiche_revision': 'ed30357616a74eb59b1f99d7bfad9a28f699a6b3', # 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. @@ -1497,7 +1497,7 @@ }, 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '711de82cd1ce75d9e7c0a1230fa080a5eaf6b07d', + Var('webrtc_git') + '/src.git' + '@' + 'a667f878b15c30cb18d39716b676fc151d809d5a', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1569,7 +1569,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@985f6835c9007b21de4931b40f701b017d38bc1d', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@71478928d7c28b0b60d6b0892ed64b1c82039a12', 'condition': 'checkout_src_internal', }, @@ -1577,7 +1577,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': '92sajF7l5YU_FHOF0S5XbbEL1anK6DQMIxOzfUm2nZQC', + 'version': 'rrmrHRTSDAizvCLGZJ2cK4G6dB81VsAGljn1FJVQwlAC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -1588,7 +1588,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'tzLm8HyLE4vYMwHlQ9sxWnDlV3EFRrx_A_t8MIGN9YcC', + 'version': '9Q3G72W_FP-DamN_GtRTUZe7jm4X8tsVnaUJ3Gp3fuMC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/android_webview/browser/gfx/surfaces_instance.cc b/android_webview/browser/gfx/surfaces_instance.cc index 5d495a0..935bd47 100644 --- a/android_webview/browser/gfx/surfaces_instance.cc +++ b/android_webview/browser/gfx/surfaces_instance.cc
@@ -235,7 +235,7 @@ gfx::Transform()); viz::SharedQuadState* quad_state = render_pass->CreateAndAppendSharedQuadState(); - quad_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, + quad_state->SetAll(gfx::Transform(), rect, rect, gfx::MaskFilterInfo(), rect, is_clipped, are_contents_opaque, 1.f, SkBlendMode::kSrcOver, 0); viz::SolidColorDrawQuad* solid_quad =
diff --git a/android_webview/browser/metrics/aw_metrics_service_client.cc b/android_webview/browser/metrics/aw_metrics_service_client.cc index 63a8a07..d16ef6a 100644 --- a/android_webview/browser/metrics/aw_metrics_service_client.cc +++ b/android_webview/browser/metrics/aw_metrics_service_client.cc
@@ -9,6 +9,7 @@ #include "android_webview/browser/metrics/aw_stability_metrics_provider.h" #include "android_webview/browser_jni_headers/AwMetricsServiceClient_jni.h" +#include "base/android/callback_android.h" #include "base/android/jni_android.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/persistent_histogram_allocator.h" @@ -161,4 +162,14 @@ base::TimeDelta::FromMilliseconds(upload_interval_ms)); } +// static +void JNI_AwMetricsServiceClient_SetOnFinalMetricsCollectedListenerForTesting( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& listener) { + AwMetricsServiceClient::GetInstance() + ->SetOnFinalMetricsCollectedListenerForTesting(base::BindRepeating( + base::android::RunRunnableAndroid, + base::android::ScopedJavaGlobalRef<jobject>(listener))); +} + } // namespace android_webview
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java index 5d9da63..7249bc2 100644 --- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java +++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -96,5 +96,7 @@ "Enables display cutout (notch) support in WebView for Android P and above."), Flag.commandLine(AwSwitches.WEBVIEW_FORCE_LITTLE_CORES, "Forces WebView to do rendering work in little cores"), + Flag.baseFeature(BlinkFeatures.WEBVIEW_ACCELERATE_SMALL_CANVASES, + "Accelerate all canvases in webview."), }; }
diff --git a/android_webview/java/src/org/chromium/android_webview/metrics/AwMetricsServiceClient.java b/android_webview/java/src/org/chromium/android_webview/metrics/AwMetricsServiceClient.java index 0f49c219..9c6cbb4 100644 --- a/android_webview/java/src/org/chromium/android_webview/metrics/AwMetricsServiceClient.java +++ b/android_webview/java/src/org/chromium/android_webview/metrics/AwMetricsServiceClient.java
@@ -72,10 +72,19 @@ AwMetricsServiceClientJni.get().setUploadIntervalForTesting(uploadIntervalMs); } + /** + * Sets a callback to run each time after final metrics have been collected. + */ + @VisibleForTesting + public static void setOnFinalMetricsCollectedListenerForTesting(Runnable listener) { + AwMetricsServiceClientJni.get().setOnFinalMetricsCollectedListenerForTesting(listener); + } + @NativeMethods interface Natives { void setHaveMetricsConsent(boolean userConsent, boolean appConsent); void setFastStartupForTesting(boolean fastStartupForTesting); void setUploadIntervalForTesting(long uploadIntervalMs); + void setOnFinalMetricsCollectedListenerForTesting(Runnable listener); } }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwMetricsIntegrationTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwMetricsIntegrationTest.java index d730abd1f..c26d421 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwMetricsIntegrationTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwMetricsIntegrationTest.java
@@ -4,6 +4,10 @@ package org.chromium.android_webview.test; +import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.MULTI_PROCESS; + +import android.support.test.InstrumentationRegistry; + import androidx.test.filters.MediumTest; import org.junit.Assert; @@ -19,12 +23,14 @@ import org.chromium.base.Callback; import org.chromium.base.ThreadUtils; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; import org.chromium.components.metrics.ChromeUserMetricsExtensionProtos.ChromeUserMetricsExtension; import org.chromium.components.metrics.MetricsSwitches; import org.chromium.components.metrics.SystemProfileProtos.SystemProfileProto; import org.chromium.content_public.browser.test.util.TestThreadUtils; +import org.chromium.net.test.EmbeddedTestServer; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; @@ -305,4 +311,56 @@ // onPageStarted & onPageFinished, in which case onPageFinished would *also* wake up the // metrics service, and we might potentially have a third metrics log in the queue. } + + @Test + @MediumTest + @Feature({"AndroidWebView"}) + @OnlyRunIn(MULTI_PROCESS) // This test is specific to the OOP-renderer + public void testRendererHistograms() throws Throwable { + EmbeddedTestServer embeddedTestServer = EmbeddedTestServer.createAndStartServer( + InstrumentationRegistry.getInstrumentation().getContext()); + try { + // Discard initial log since the renderer process hasn't been created yet. + mPlatformServiceBridge.waitForNextMetricsLog(); + + final CallbackHelper helper = new CallbackHelper(); + int finalMetricsCollectedCount = helper.getCallCount(); + + // Load a page and wait for final metrics collection. + TestThreadUtils.runOnUiThreadBlocking(() -> { + AwMetricsServiceClient.setOnFinalMetricsCollectedListenerForTesting( + () -> { helper.notifyCalled(); }); + }); + + // Load a page to ensure the renderer process is created. + mRule.loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), + embeddedTestServer.getURL("/simple_page.html")); + helper.waitForCallback(finalMetricsCollectedCount, 1); + + // At this point we know one of two things must be true: + // + // 1. The renderer process completed startup (logging the expected histogram) before + // subprocess histograms were collected. In this case, we know the desired histogram + // has been copied into the browser process. + // 2. Subprocess histograms were collected before the renderer process completed + // startup. While we don't know if our histogram was copied over, we do know the + // page load has finished and this woke up the metrics service, so MetricsService + // will collect subprocess metrics again. + // + // Load a page and wait for another final log collection. We know this log collection + // must be triggered by either the second page load start (scenario 1) or the first page + // load finish (scenario 2), either of which ensures the renderer startup histogram must + // have been copied into the browser process. + + mRule.loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), + embeddedTestServer.getURL("/simple_page.html")); + helper.waitForCallback(finalMetricsCollectedCount, 2); + + Assert.assertEquals(1, + RecordHistogram.getHistogramTotalCountForTesting( + "Android.SeccompStatus.RendererSandbox")); + } finally { + embeddedTestServer.stopAndDestroyServer(); + } + } }
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 6f633218..7c856d9 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -946,6 +946,8 @@ "system/gesture_education/gesture_education_notification_controller.h", "system/holding_space/holding_space_color_provider_impl.cc", "system/holding_space/holding_space_color_provider_impl.h", + "system/holding_space/holding_space_drag_util.cc", + "system/holding_space/holding_space_drag_util.h", "system/holding_space/holding_space_item_chip_view.cc", "system/holding_space/holding_space_item_chip_view.h", "system/holding_space/holding_space_item_chips_container.cc", @@ -2354,6 +2356,7 @@ "//chromeos/services/multidevice_setup/public/mojom", "//chromeos/services/network_config/public/mojom", "//chromeos/system", + "//chromeos/ui/frame:test_support", "//components/account_id", "//components/arc:notification_test_support", "//components/media_message_center",
diff --git a/ash/app_list/views/privacy_info_view.cc b/ash/app_list/views/privacy_info_view.cc index 94bb8d0a..d23e543 100644 --- a/ash/app_list/views/privacy_info_view.cc +++ b/ash/app_list/views/privacy_info_view.cc
@@ -161,10 +161,8 @@ void PrivacyInfoView::SelectInitialResultAction(bool reverse_tab_order) { if (!reverse_tab_order) { selected_action_ = Action::kTextLink; - text_view_->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true); } else { selected_action_ = Action::kCloseButton; - close_button_->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true); } // Update visual indicators for focus. @@ -179,12 +177,10 @@ if (!reverse_tab_order && selected_action_ == Action::kTextLink) { // Move selection forward from the text view to the close button. selected_action_ = Action::kCloseButton; - close_button_->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true); action_changed = true; } else if (reverse_tab_order && selected_action_ == Action::kCloseButton) { // Move selection backward from the close button to the text view. selected_action_ = Action::kTextLink; - text_view_->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true); action_changed = true; } else { selected_action_ = Action::kNone; @@ -196,17 +192,14 @@ return action_changed; } -void PrivacyInfoView::NotifyA11yResultSelected() { +views::View* PrivacyInfoView::GetSelectedView() { switch (selected_action_) { case Action::kTextLink: - text_view_->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true); - break; + return text_view_; case Action::kCloseButton: - close_button_->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, - true); - break; + return close_button_; case Action::kNone: - break; + return this; } }
diff --git a/ash/app_list/views/privacy_info_view.h b/ash/app_list/views/privacy_info_view.h index b534631b..3316a1f 100644 --- a/ash/app_list/views/privacy_info_view.h +++ b/ash/app_list/views/privacy_info_view.h
@@ -38,7 +38,7 @@ // SearchResultBaseView: void SelectInitialResultAction(bool reverse_tab_order) override; bool SelectNextResultAction(bool reverse_tab_order) override; - void NotifyA11yResultSelected() override; + views::View* GetSelectedView() override; virtual void LinkClicked() = 0; virtual void CloseButtonPressed() = 0;
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc index dafc50e8..d171fde 100644 --- a/ash/app_list/views/search_box_view.cc +++ b/ash/app_list/views/search_box_view.cc
@@ -280,6 +280,17 @@ } } +void SearchBoxView::OnSearchBoxActiveChanged(bool active) { + if (active) { + search_box()->SetAccessibleName(base::string16()); + } else { + search_box()->SetAccessibleName(l10n_util::GetStringUTF16( + is_tablet_mode_ + ? IDS_APP_LIST_SEARCH_BOX_ACCESSIBILITY_NAME_TABLET + : IDS_APP_LIST_SEARCH_BOX_ACCESSIBILITY_NAME_CLAMSHELL)); + } +} + void SearchBoxView::OnKeyEvent(ui::KeyEvent* event) { app_list_view_->RedirectKeyEventToSearchBox(event); @@ -492,6 +503,13 @@ ResetHighlightRange(); } +void SearchBoxView::OnBeforeUserAction(views::Textfield* sender) { + if (a11y_selection_on_search_result_) { + a11y_selection_on_search_result_ = false; + search_box()->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true); + } +} + void SearchBoxView::ContentsChanged(views::Textfield* sender, const base::string16& new_contents) { if (IsTrimmedQueryEmpty(current_query_) && !IsSearchBoxTrimmedQueryEmpty()) { @@ -565,6 +583,7 @@ contents_view_->search_results_page_view() ->result_selection_controller() ->ClearSelection(); + a11y_selection_on_search_result_ = false; ClearSearch(); SetSearchBoxActive(false, ui::ET_UNKNOWN); } @@ -691,6 +710,9 @@ DCHECK(close_button()->GetVisible()); close_button()->RequestFocus(); + close_button()->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, + true); + a11y_selection_on_search_result_ = false; break; case ResultSelectionController::MoveResult::kResultChanged: UpdateSearchBoxTextForSelectedResult(
diff --git a/ash/app_list/views/search_box_view.h b/ash/app_list/views/search_box_view.h index 7d9e76d..3a96dc3c 100644 --- a/ash/app_list/views/search_box_view.h +++ b/ash/app_list/views/search_box_view.h
@@ -60,6 +60,7 @@ void SetupCloseButton() override; void SetupBackButton() override; void RecordSearchBoxActivationHistogram(ui::EventType event_type) override; + void OnSearchBoxActiveChanged(bool active) override; // Overridden from views::View: void OnKeyEvent(ui::KeyEvent* event) override; @@ -110,6 +111,10 @@ } ContentsView* contents_view() { return contents_view_; } + void set_a11y_selection_on_search_result(bool value) { + a11y_selection_on_search_result_ = value; + } + void set_highlight_range_for_test(const gfx::Range& range) { highlight_range_ = range; } @@ -133,6 +138,7 @@ void SetAutocompleteText(const base::string16& autocomplete_text); // Overridden from views::TextfieldController: + void OnBeforeUserAction(views::Textfield* sender) override; void ContentsChanged(views::Textfield* sender, const base::string16& new_contents) override; bool HandleKeyEvent(views::Textfield* sender, @@ -175,10 +181,13 @@ // True if app list search autocomplete is enabled. const bool is_app_list_search_autocomplete_enabled_; - // Whether tablet mode is active. bool is_tablet_mode_ = false; + // Set by SearchResultPageView when the accessibility selection moves to a + // search result view. + bool a11y_selection_on_search_result_ = false; + base::WeakPtrFactory<SearchBoxView> weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(SearchBoxView);
diff --git a/ash/app_list/views/search_result_actions_view.cc b/ash/app_list/views/search_result_actions_view.cc index 6ea5f74..a6f6232a 100644 --- a/ash/app_list/views/search_result_actions_view.cc +++ b/ash/app_list/views/search_result_actions_view.cc
@@ -254,16 +254,16 @@ return true; } -void SearchResultActionsView::NotifyA11yResultSelected() { +views::View* SearchResultActionsView::GetSelectedView() { DCHECK(HasSelectedAction()); int selected_action = GetSelectedAction(); for (views::View* child : children()) { - if (static_cast<views::Button*>(child)->tag() == selected_action) { - child->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true); - return; - } + if (static_cast<views::Button*>(child)->tag() == selected_action) + return child; } + + return nullptr; } void SearchResultActionsView::ClearSelectedAction() {
diff --git a/ash/app_list/views/search_result_actions_view.h b/ash/app_list/views/search_result_actions_view.h index 05d4e8a9..521f8b74 100644 --- a/ash/app_list/views/search_result_actions_view.h +++ b/ash/app_list/views/search_result_actions_view.h
@@ -56,8 +56,8 @@ // getting cleared). bool SelectNextAction(bool reverse_tab_order); - // Sends kSelection a11y notification for the selected action button. - void NotifyA11yResultSelected(); + // Returns the selected action button. + views::View* GetSelectedView(); // Clears selected action state. void ClearSelectedAction();
diff --git a/ash/app_list/views/search_result_base_view.cc b/ash/app_list/views/search_result_base_view.cc index 905c5b8..af790ab 100644 --- a/ash/app_list/views/search_result_base_view.cc +++ b/ash/app_list/views/search_result_base_view.cc
@@ -62,12 +62,10 @@ return true; } -void SearchResultBaseView::NotifyA11yResultSelected() { - if (actions_view_ && actions_view_->HasSelectedAction()) { - actions_view_->NotifyA11yResultSelected(); - return; - } - NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true); +views::View* SearchResultBaseView::GetSelectedView() { + if (actions_view_ && actions_view_->HasSelectedAction()) + return actions_view_->GetSelectedView(); + return this; } void SearchResultBaseView::SetResult(SearchResult* result) { @@ -112,10 +110,8 @@ } void SearchResultBaseView::SelectInitialResultAction(bool reverse_tab_order) { - if (actions_view_ && actions_view_->SelectInitialAction(reverse_tab_order)) - return; - - NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true); + if (actions_view_) + actions_view_->SelectInitialAction(reverse_tab_order); } void SearchResultBaseView::ClearSelectedResultAction() {
diff --git a/ash/app_list/views/search_result_base_view.h b/ash/app_list/views/search_result_base_view.h index c2e106f..eb31696 100644 --- a/ash/app_list/views/search_result_base_view.h +++ b/ash/app_list/views/search_result_base_view.h
@@ -45,11 +45,10 @@ // Returns whether the selected result action was changed. virtual bool SelectNextResultAction(bool reverse_tab_order); - // If the search result is currently selected, sends the appropriate - // kSelection view accessibility event. For example, if a result action is - // selected, the notification will be sent for the selected action button - // view. - virtual void NotifyA11yResultSelected(); + // Returns the view that is currently selected - for example, if the result + // supports action views and an action view is currently selected, this + // should return the action view, otherwise it should return `this`. + virtual views::View* GetSelectedView(); SearchResult* result() const { return result_; } void SetResult(SearchResult* result);
diff --git a/ash/app_list/views/search_result_list_view.cc b/ash/app_list/views/search_result_list_view.cc index 9517006..c53f29a 100644 --- a/ash/app_list/views/search_result_list_view.cc +++ b/ash/app_list/views/search_result_list_view.cc
@@ -249,9 +249,6 @@ view_delegate_->InvokeSearchResultAction(view->result()->id(), action_index, event_flags); } else if (action == OmniBoxZeroStateAction::kAppendSuggestion) { - // Make sure ChromeVox will focus on the search box. - main_view_->search_box_view()->search_box()->NotifyAccessibilityEvent( - ax::mojom::Event::kSelection, true); main_view_->search_box_view()->UpdateQuery(view->result()->title()); } }
diff --git a/ash/app_list/views/search_result_page_view.cc b/ash/app_list/views/search_result_page_view.cc index ce9f125..2b7cb08 100644 --- a/ash/app_list/views/search_result_page_view.cc +++ b/ash/app_list/views/search_result_page_view.cc
@@ -75,7 +75,7 @@ // The amount of time by which notifications to accessibility framework about // result page changes are delayed. constexpr base::TimeDelta kNotifyA11yDelay = - base::TimeDelta::FromMilliseconds(500); + base::TimeDelta::FromMilliseconds(1500); // A container view that ensures the card background and the shadow are painted // in the correct order. @@ -341,6 +341,7 @@ ignore_result_changes_for_a11y_ = ignore; GetViewAccessibility().OverrideIsLeaf(ignore); + GetViewAccessibility().OverrideIsIgnored(ignore); NotifyAccessibilityEvent(ax::mojom::Event::kTreeChanged, true); } @@ -370,8 +371,20 @@ return; } + SearchBoxView* search_box = AppListPage::contents_view()->GetSearchBoxView(); + // Ignore result selection change if the focus moved away from the search boc + // textfield, for example to the close button. + if (!search_box->search_box()->HasFocus()) + return; + + views::View* selected_view = + result_selection_controller_->selected_result()->GetSelectedView(); + if (!selected_view) + return; + + selected_view->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true); NotifyAccessibilityEvent(ax::mojom::Event::kSelectedChildrenChanged, true); - result_selection_controller_->selected_result()->NotifyA11yResultSelected(); + search_box->set_a11y_selection_on_search_result(true); } void SearchResultPageView::OnSearchResultContainerResultsChanging() {
diff --git a/ash/app_list/views/search_result_view.cc b/ash/app_list/views/search_result_view.cc index 7d1f99f..98fe943f 100644 --- a/ash/app_list/views/search_result_view.cc +++ b/ash/app_list/views/search_result_view.cc
@@ -341,7 +341,6 @@ if (actions_view()->IsValidActionIndex( OmniBoxZeroStateAction::kRemoveSuggestion)) { ScrollRectToVisible(GetLocalBounds()); - NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true); SetSelected(true, base::nullopt); confirm_remove_by_long_press_ = true; OnSearchResultActionActivated(OmniBoxZeroStateAction::kRemoveSuggestion,
diff --git a/ash/capture_mode/capture_label_view.cc b/ash/capture_mode/capture_label_view.cc index 1b4bc356..4e4b3964 100644 --- a/ash/capture_mode/capture_label_view.cc +++ b/ash/capture_mode/capture_label_view.cc
@@ -149,7 +149,7 @@ } bool CaptureLabelView::ShouldHandleEvent() { - return label_button_->GetVisible(); + return label_button_->GetVisible() && !IsInCountDownAnimation(); } void CaptureLabelView::StartCountDown( @@ -166,6 +166,10 @@ &CaptureLabelView::CountDown); } +bool CaptureLabelView::IsInCountDownAnimation() const { + return !!countdown_finished_callback_; +} + void CaptureLabelView::Layout() { label_button_->SetBoundsRect(GetLocalBounds());
diff --git a/ash/capture_mode/capture_label_view.h b/ash/capture_mode/capture_label_view.h index 9898ab4..5e1e3f0b 100644 --- a/ash/capture_mode/capture_label_view.h +++ b/ash/capture_mode/capture_label_view.h
@@ -46,6 +46,9 @@ // Called when starting 3-seconds count down before recording video. void StartCountDown(base::OnceClosure countdown_finished_callback); + // Returns true if count down animation is in progress. + bool IsInCountDownAnimation() const; + // views::View: void Layout() override; gfx::Size CalculatePreferredSize() const override;
diff --git a/ash/capture_mode/capture_mode_session.cc b/ash/capture_mode/capture_mode_session.cc index 8f08ed0..712230a 100644 --- a/ash/capture_mode/capture_mode_session.cc +++ b/ash/capture_mode/capture_mode_session.cc
@@ -25,6 +25,7 @@ #include "ui/compositor/layer.h" #include "ui/compositor/layer_type.h" #include "ui/compositor/paint_recorder.h" +#include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/display/screen.h" #include "ui/display/types/display_constants.h" #include "ui/events/types/event_type.h" @@ -37,6 +38,7 @@ #include "ui/gfx/scoped_canvas.h" #include "ui/gfx/shadow_value.h" #include "ui/gfx/skia_paint_util.h" +#include "ui/gfx/transform_util.h" #include "ui/views/background.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/controls/label.h" @@ -99,6 +101,23 @@ // padding, it will be placed below or above the capture region. constexpr int kCaptureRegionMinimumPaddingDp = 16; +// Animation parameters needed when countdown starts. +// The animation duration that the label fades out and scales down before count +// down starts. +constexpr base::TimeDelta kCaptureLabelAnimationDuration = + base::TimeDelta::FromMilliseconds(267); +// The animation duration that the capture bar fades out before count down +// starts. +constexpr base::TimeDelta kCaptureBarFadeOutDuration = + base::TimeDelta::FromMilliseconds(167); +// The animation duration that the fullscreen shield fades out before count down +// starts. +constexpr base::TimeDelta kCaptureShieldFadeOutDuration = + base::TimeDelta::FromMilliseconds(333); +// If there is no text message was showing when count down starts, the label +// widget will shrink down from 120% -> 100% and fade in. +constexpr float kLabelScaleUpOnCountdown = 1.2; + // Mouse cursor warping is disabled when the capture source is a custom region. // Sets the mouse warp status to |enable| and return the original value. bool SetMouseWarpEnabled(bool enable) { @@ -236,7 +255,27 @@ CaptureLabelView* label_view = static_cast<CaptureLabelView*>(capture_label_widget_->GetContentsView()); label_view->StartCountDown(std::move(countdown_finished_callback)); - UpdateCaptureLabelWidgetBounds(); + UpdateCaptureLabelWidgetBounds(/*animate=*/true); + + // Fade out toolbar. + ui::Layer* toolbar_layer = capture_mode_bar_widget_.GetLayer(); + ui::ScopedLayerAnimationSettings toolbar_settings( + toolbar_layer->GetAnimator()); + toolbar_settings.SetTransitionDuration(kCaptureBarFadeOutDuration); + toolbar_settings.SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN); + toolbar_settings.SetPreemptionStrategy( + ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); + toolbar_layer->SetOpacity(0.f); + + // Fade out the shield if it's recording fullscreen. + if (controller_->source() == CaptureModeSource::kFullscreen) { + ui::ScopedLayerAnimationSettings shield_settings(layer()->GetAnimator()); + shield_settings.SetTransitionDuration(kCaptureShieldFadeOutDuration); + shield_settings.SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN); + shield_settings.SetPreemptionStrategy( + ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); + layer()->SetOpacity(0.f); + } } void CaptureModeSession::OnPaintLayer(const ui::PaintContext& context) { @@ -762,12 +801,63 @@ CaptureLabelView* label_view = static_cast<CaptureLabelView*>(capture_label_widget_->GetContentsView()); label_view->UpdateIconAndText(); - UpdateCaptureLabelWidgetBounds(); + UpdateCaptureLabelWidgetBounds(/*animate=*/false); } -void CaptureModeSession::UpdateCaptureLabelWidgetBounds() { +void CaptureModeSession::UpdateCaptureLabelWidgetBounds(bool animate) { DCHECK(capture_label_widget_); + const gfx::Rect bounds = CalculateCaptureLabelWidgetBounds(); + const gfx::Rect old_bounds = + capture_label_widget_->GetNativeWindow()->GetBoundsInScreen(); + if (old_bounds == bounds) + return; + + if (!animate) { + capture_label_widget_->SetBounds(bounds); + return; + } + + ui::Layer* layer = capture_label_widget_->GetLayer(); + if (!old_bounds.IsEmpty()) { + // This happens if there is a label or a label button showing when count + // down starts. In this case we'll do a bounds change animation. + ui::ScopedLayerAnimationSettings settings(layer->GetAnimator()); + settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); + settings.SetPreemptionStrategy( + ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); + settings.SetTransitionDuration(kCaptureLabelAnimationDuration); + capture_label_widget_->SetBounds(bounds); + } else { + // This happens when no text message was showing when count down starts, in + // this case we'll do a fade in + shrinking down animation. + capture_label_widget_->SetBounds(bounds); + const gfx::Point center_point = bounds.CenterPoint(); + layer->SetTransform( + gfx::GetScaleTransform(gfx::Point(center_point.x() - bounds.x(), + center_point.y() - bounds.y()), + kLabelScaleUpOnCountdown)); + layer->SetOpacity(0.f); + + // Fade in. + ui::ScopedLayerAnimationSettings settings(layer->GetAnimator()); + settings.SetTransitionDuration(kCaptureLabelAnimationDuration); + settings.SetTweenType(gfx::Tween::LINEAR); + settings.SetPreemptionStrategy( + ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); + layer->SetOpacity(1.f); + + // Scale down from 120% -> 100%. + settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); + layer->SetTransform(gfx::Transform()); + } +} + +gfx::Rect CaptureModeSession::CalculateCaptureLabelWidgetBounds() { + DCHECK(capture_label_widget_); + CaptureLabelView* label_view = + static_cast<CaptureLabelView*>(capture_label_widget_->GetContentsView()); + // For fullscreen and window capture mode, the capture label is placed in the // middle of the screen. For region capture mode, if it's in select phase, the // capture label is also placed in the middle of the screen, and if it's in @@ -776,49 +866,57 @@ // below the capture region. gfx::Rect bounds(current_root_->bounds()); const gfx::Rect capture_region = controller_->user_capture_region(); - const gfx::Size preferred_size = - capture_label_widget_->GetContentsView()->GetPreferredSize(); + const gfx::Size preferred_size = label_view->GetPreferredSize(); if (controller_->source() == CaptureModeSource::kRegion && !is_selecting_region_ && !capture_region.IsEmpty()) { - bounds = capture_region; - - // The capture region must be at least the size of |preferred_size| plus - // some padding for the capture label to be centered inside it. - gfx::Size capture_region_min_size = preferred_size; - capture_region_min_size.Enlarge(kCaptureRegionMinimumPaddingDp, - kCaptureRegionMinimumPaddingDp); - if (bounds.width() > capture_region_min_size.width() && - bounds.height() > capture_region_min_size.height()) { + if (label_view->IsInCountDownAnimation()) { + // If countdown starts, calculate the bounds based on the old capture + // label's position, otherwise, since the countdown label bounds is + // smaller than the label bounds and may fit into the capture region even + // if the old capture label doesn't fit thus was place outside of the + // capture region, it's possible that we see the countdown label animates + // to inside of the capture region from outside of the capture region. + bounds = capture_label_widget_->GetNativeWindow()->bounds(); bounds.ClampToCenteredSize(preferred_size); } else { - // The capture region is too small for the capture label to be inside it. - // Align |bounds| so that its horizontal centerpoint aligns with the - // capture regions centerpoint. - bounds.set_size(preferred_size); - bounds.set_x(capture_region.CenterPoint().x() - - preferred_size.width() / 2); - - // Try to put the capture label slightly below the capture region. If it - // does not fully fit in the root window bounds, place the capture label - // slightly above. - const int under_region_label_y = - capture_region.bottom() + kCaptureButtonDistanceFromRegionDp; - if (under_region_label_y + preferred_size.height() < - current_root_->bounds().bottom()) { - bounds.set_y(under_region_label_y); + bounds = capture_region; + // The capture region must be at least the size of |preferred_size| plus + // some padding for the capture label to be centered inside it. + gfx::Size capture_region_min_size = preferred_size; + capture_region_min_size.Enlarge(kCaptureRegionMinimumPaddingDp, + kCaptureRegionMinimumPaddingDp); + if (bounds.width() > capture_region_min_size.width() && + bounds.height() > capture_region_min_size.height()) { + bounds.ClampToCenteredSize(preferred_size); } else { - bounds.set_y(capture_region.y() - kCaptureButtonDistanceFromRegionDp - - preferred_size.height()); + // The capture region is too small for the capture label to be inside + // it. Align |bounds| so that its horizontal centerpoint aligns with the + // capture regions centerpoint. + bounds.set_size(preferred_size); + bounds.set_x(capture_region.CenterPoint().x() - + preferred_size.width() / 2); + + // Try to put the capture label slightly below the capture region. If it + // does not fully fit in the root window bounds, place the capture label + // slightly above. + const int under_region_label_y = + capture_region.bottom() + kCaptureButtonDistanceFromRegionDp; + if (under_region_label_y + preferred_size.height() < + current_root_->bounds().bottom()) { + bounds.set_y(under_region_label_y); + } else { + bounds.set_y(capture_region.y() - kCaptureButtonDistanceFromRegionDp - + preferred_size.height()); + } } } } else { bounds.ClampToCenteredSize(preferred_size); } - // User capture region bounds are in root window coordinates so convert them // here. wm::ConvertRectToScreen(current_root_, &bounds); - capture_label_widget_->SetBounds(bounds); + return bounds; } bool CaptureModeSession::ShouldCaptureLabelHandleEvent( @@ -860,7 +958,7 @@ // bounds, moving it onto the correct display, but will early return if the // region is already empty. if (controller_->user_capture_region().IsEmpty()) - UpdateCaptureLabelWidgetBounds(); + UpdateCaptureLabelWidgetBounds(/*animate=*/false); // Start with a new region when we switch displays. is_selecting_region_ = true;
diff --git a/ash/capture_mode/capture_mode_session.h b/ash/capture_mode/capture_mode_session.h index 51884b7..38cc6db 100644 --- a/ash/capture_mode/capture_mode_session.h +++ b/ash/capture_mode/capture_mode_session.h
@@ -159,9 +159,13 @@ // anchor points if |position| is an edge. std::vector<gfx::Point> GetAnchorPointsForPosition(FineTunePosition position); - // Updates the capture label widget. + // Updates the capture label widget's icon/text and bounds. void UpdateCaptureLabelWidget(); - void UpdateCaptureLabelWidgetBounds(); + // Updates the capture label widget's bounds. If |animate| is true, do bounds + // animation. + void UpdateCaptureLabelWidgetBounds(bool animate); + // Calculates the targeted capture label widget bounds in screen coordinates. + gfx::Rect CalculateCaptureLabelWidgetBounds(); // Returns true if the capture label should handle the event. |event_target| // is the window which is receiving the event. The capture label should handle
diff --git a/ash/fast_ink/fast_ink_host.cc b/ash/fast_ink/fast_ink_host.cc index 93e2eba0..ba041e1 100644 --- a/ash/fast_ink/fast_ink_host.cc +++ b/ash/fast_ink/fast_ink_host.cc
@@ -408,7 +408,7 @@ buffer_to_target_transform, /*quad_layer_rect=*/output_rect, /*visible_quad_layer_rect=*/output_rect, - /*rounded_corner_bounds=*/gfx::RRectF(), + /*mask_filter_info=*/gfx::MaskFilterInfo(), /*clip_rect=*/gfx::Rect(), /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/1.f, /*blend_mode=*/SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
diff --git a/ash/fast_ink/view_tree_host_root_view.cc b/ash/fast_ink/view_tree_host_root_view.cc index dd05502..9bb359c8 100644 --- a/ash/fast_ink/view_tree_host_root_view.cc +++ b/ash/fast_ink/view_tree_host_root_view.cc
@@ -452,7 +452,7 @@ buffer_to_target_transform, /*quad_layer_rect=*/output_rect, /*visible_quad_layer_rect=*/output_rect, - /*rounded_corner_bounds=*/gfx::RRectF(), + /*mask_filter_info=*/gfx::MaskFilterInfo(), /*clip_rect=*/gfx::Rect(), /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/1.f, /*blend_mode=*/SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
diff --git a/ash/frame/header_view.h b/ash/frame/header_view.h index b15321f..1ac31d4 100644 --- a/ash/frame/header_view.h +++ b/ash/frame/header_view.h
@@ -9,11 +9,11 @@ #include "ash/ash_export.h" #include "ash/public/cpp/frame_header.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller_delegate.h" #include "ash/public/cpp/tablet_mode_observer.h" #include "base/callback.h" #include "base/macros.h" #include "base/scoped_observer.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_delegate.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/aura/window.h" #include "ui/aura/window_observer.h" @@ -42,10 +42,11 @@ // View which paints the frame header (title, caption buttons...). It slides off // and on screen in immersive fullscreen. -class ASH_EXPORT HeaderView : public views::View, - public ImmersiveFullscreenControllerDelegate, - public TabletModeObserver, - public aura::WindowObserver { +class ASH_EXPORT HeaderView + : public views::View, + public chromeos::ImmersiveFullscreenControllerDelegate, + public TabletModeObserver, + public aura::WindowObserver { public: // |target_widget| is the widget that the caption buttons act on. // |target_widget| is not necessarily the same as the widget the header is
diff --git a/ash/frame/non_client_frame_view_ash.cc b/ash/frame/non_client_frame_view_ash.cc index 553fc8f..e4608d9 100644 --- a/ash/frame/non_client_frame_view_ash.cc +++ b/ash/frame/non_client_frame_view_ash.cc
@@ -12,7 +12,6 @@ #include "ash/public/cpp/ash_constants.h" #include "ash/public/cpp/default_frame_header.h" #include "ash/public/cpp/frame_utils.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h" #include "ash/public/cpp/tablet_mode_observer.h" #include "ash/public/cpp/window_properties.h" #include "ash/shell.h" @@ -23,7 +22,9 @@ #include "ash/wm/window_state_observer.h" #include "ash/wm/window_util.h" #include "base/bind.h" +#include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" #include "ui/aura/window_observer.h" @@ -39,6 +40,8 @@ namespace ash { +using ::chromeos::ImmersiveFullscreenController; +using ::chromeos::kImmersiveImpliedByFullscreen; using ::chromeos::WindowStateType; DEFINE_UI_CLASS_PROPERTY_KEY(NonClientFrameViewAsh*,
diff --git a/ash/frame/non_client_frame_view_ash.h b/ash/frame/non_client_frame_view_ash.h index 4f549f5..9275144 100644 --- a/ash/frame/non_client_frame_view_ash.h +++ b/ash/frame/non_client_frame_view_ash.h
@@ -19,6 +19,7 @@ namespace chromeos { class FrameCaptionButtonContainerView; +class ImmersiveFullscreenController; } namespace views { @@ -27,7 +28,6 @@ namespace ash { -class ImmersiveFullscreenController; class NonClientFrameViewAshImmersiveHelper; // A NonClientFrameView used for packaged apps, dialogs and other non-browser @@ -59,7 +59,7 @@ // NonClientFrameViewAsh does not take ownership of // |immersive_fullscreen_controller|. void InitImmersiveFullscreenControllerForView( - ImmersiveFullscreenController* immersive_fullscreen_controller); + chromeos::ImmersiveFullscreenController* immersive_fullscreen_controller); // Sets the active and inactive frame colors. Note the inactive frame color // will have some transparency added when the frame is drawn.
diff --git a/ash/frame/non_client_frame_view_ash_unittest.cc b/ash/frame/non_client_frame_view_ash_unittest.cc index d529f590..31b59f9d 100644 --- a/ash/frame/non_client_frame_view_ash_unittest.cc +++ b/ash/frame/non_client_frame_view_ash_unittest.cc
@@ -11,8 +11,6 @@ #include "ash/frame/wide_frame_view.h" #include "ash/public/cpp/ash_switches.h" #include "ash/public/cpp/default_frame_header.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h" #include "ash/public/cpp/window_properties.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" @@ -27,6 +25,8 @@ #include "base/command_line.h" #include "base/containers/flat_set.h" #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h" #include "chromeos/ui/vector_icons/vector_icons.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" @@ -50,6 +50,9 @@ namespace ash { using ::chromeos::FrameCaptionButtonContainerView; +using ::chromeos::ImmersiveFullscreenController; +using ::chromeos::ImmersiveFullscreenControllerDelegate; +using ::chromeos::ImmersiveFullscreenControllerTestApi; // A views::WidgetDelegate which uses a NonClientFrameViewAsh. class NonClientFrameViewAshTestWidgetDelegate
diff --git a/ash/frame/wide_frame_view.cc b/ash/frame/wide_frame_view.cc index 9399c90..503b3ae 100644 --- a/ash/frame/wide_frame_view.cc +++ b/ash/frame/wide_frame_view.cc
@@ -7,7 +7,6 @@ #include "ash/frame/header_view.h" #include "ash/frame/non_client_frame_view_ash.h" #include "ash/public/cpp/default_frame_header.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h" #include "ash/public/cpp/window_properties.h" #include "ash/shell.h" #include "ash/wm/overview/overview_controller.h" @@ -15,6 +14,7 @@ #include "ash/wm/wm_event.h" #include "base/metrics/user_metrics.h" #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" #include "ui/aura/window.h" #include "ui/aura/window_targeter.h" #include "ui/display/display.h" @@ -25,6 +25,8 @@ namespace ash { namespace { +using ::chromeos::ImmersiveFullscreenController; + class WideFrameTargeter : public aura::WindowTargeter { public: explicit WideFrameTargeter(HeaderView* header_view)
diff --git a/ash/frame/wide_frame_view.h b/ash/frame/wide_frame_view.h index a843bbc6..5657d0c 100644 --- a/ash/frame/wide_frame_view.h +++ b/ash/frame/wide_frame_view.h
@@ -6,20 +6,23 @@ #define ASH_FRAME_WIDE_FRAME_VIEW_H_ #include "ash/ash_export.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller_delegate.h" #include "ash/wm/overview/overview_observer.h" #include "chromeos/ui/frame/caption_buttons/caption_button_model.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_delegate.h" #include "ui/aura/window_observer.h" #include "ui/display/display_observer.h" #include "ui/views/widget/widget_delegate.h" +namespace chromeos { +class ImmersiveFullscreenController; +} + namespace views { class Widget; } namespace ash { class HeaderView; -class ImmersiveFullscreenController; // WideFrameView is used for the case where the widget's maximzed/fullscreen // doesn't cover the entire workarea/display area but the caption frame should @@ -31,17 +34,18 @@ // the target widget because ImmersiveFullscreenController is not owned by // NonClientFrameViewAsh. Investigate if we integrate this into // NonClientFrameViewAsh. -class ASH_EXPORT WideFrameView : public views::WidgetDelegateView, - public aura::WindowObserver, - public display::DisplayObserver, - public ImmersiveFullscreenControllerDelegate { +class ASH_EXPORT WideFrameView + : public views::WidgetDelegateView, + public aura::WindowObserver, + public display::DisplayObserver, + public chromeos::ImmersiveFullscreenControllerDelegate { public: explicit WideFrameView(views::Widget* target); ~WideFrameView() override; // Initialize |immersive_fullscreen_controller| so that the controller reveals // and |hides_header_| in immersive mode. - void Init(ImmersiveFullscreenController* controller); + void Init(chromeos::ImmersiveFullscreenController* controller); // Set the caption model for caption buttions on this frame. void SetCaptionButtonModel(
diff --git a/ash/public/cpp/BUILD.gn b/ash/public/cpp/BUILD.gn index fdf9769..8b23b50d 100644 --- a/ash/public/cpp/BUILD.gn +++ b/ash/public/cpp/BUILD.gn
@@ -154,15 +154,6 @@ "ime_controller_client.h", "ime_info.cc", "ime_info.h", - "immersive/immersive_context.cc", - "immersive/immersive_context.h", - "immersive/immersive_focus_watcher.cc", - "immersive/immersive_focus_watcher.h", - "immersive/immersive_fullscreen_controller.cc", - "immersive/immersive_fullscreen_controller.h", - "immersive/immersive_fullscreen_controller_delegate.h", - "immersive/immersive_revealed_lock.cc", - "immersive/immersive_revealed_lock.h", "in_session_auth_dialog_client.h", "in_session_auth_dialog_controller.cc", "in_session_auth_dialog_controller.h", @@ -403,8 +394,6 @@ source_set("test_support") { testonly = true sources = [ - "immersive/immersive_fullscreen_controller_test_api.cc", - "immersive/immersive_fullscreen_controller_test_api.h", "test/test_ambient_client.cc", "test/test_ambient_client.h", "test/test_image_downloader.cc",
diff --git a/ash/public/cpp/window_properties.cc b/ash/public/cpp/window_properties.cc index f1b6092d..2c3531a 100644 --- a/ash/public/cpp/window_properties.cc +++ b/ash/public/cpp/window_properties.cc
@@ -4,12 +4,12 @@ #include "ash/public/cpp/window_properties.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h" #include "ash/public/cpp/shelf_types.h" #include "ash/public/cpp/window_backdrop.h" #include "ash/public/cpp/window_pin_type.h" #include "chromeos/ui/base/chromeos_ui_constants.h" #include "chromeos/ui/base/window_state_type.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" #include "third_party/skia/include/core/SkRegion.h" #include "ui/aura/window.h" #include "ui/wm/core/window_properties.h" @@ -34,15 +34,6 @@ DEFINE_UI_CLASS_PROPERTY_KEY(bool, kHideInOverviewKey, false) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kHideInShelfKey, false) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kHideShelfWhenFullscreenKey, true) -DEFINE_UI_CLASS_PROPERTY_KEY(bool, kImmersiveImpliedByFullscreen, true) -DEFINE_UI_CLASS_PROPERTY_KEY(bool, kImmersiveIsActive, false) -DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(gfx::Rect, - kImmersiveTopContainerBoundsInScreen, - nullptr) -DEFINE_UI_CLASS_PROPERTY_KEY( - int, - kImmersiveWindowType, - ImmersiveFullscreenController::WindowType::WINDOW_TYPE_OTHER) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kIsDeferredTabDraggingTargetWindowKey, false) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kIsDraggingTabsKey, false) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kHideInDeskMiniViewKey, false)
diff --git a/ash/public/cpp/window_properties.h b/ash/public/cpp/window_properties.h index 6febe80..319edcb9 100644 --- a/ash/public/cpp/window_properties.h +++ b/ash/public/cpp/window_properties.h
@@ -85,25 +85,6 @@ ASH_PUBLIC_EXPORT extern const aura::WindowProperty<bool>* const kHideShelfWhenFullscreenKey; -// Whether entering fullscreen means that a window should automatically enter -// immersive mode. This is false for some client windows, such as Chrome Apps. -ASH_PUBLIC_EXPORT extern const aura::WindowProperty<bool>* const - kImmersiveImpliedByFullscreen; - -// Whether immersive is currently active (in ImmersiveFullscreenController -// parlance, "enabled"). -ASH_PUBLIC_EXPORT extern const aura::WindowProperty<bool>* const - kImmersiveIsActive; - -// The bounds of the top container in screen coordinates. -ASH_PUBLIC_EXPORT extern const aura::WindowProperty<gfx::Rect*>* const - kImmersiveTopContainerBoundsInScreen; - -// The type of window for logging immersive metrics. Type: -// ImmersiveFullscreenController::WindowType. -ASH_PUBLIC_EXPORT extern const aura::WindowProperty<int>* const - kImmersiveWindowType; - // If true, the window is the target window for the tab-dragged window. The key // is used by overview to show a highlight indication to indicate which overview // window the dragged tabs will merge into when the user releases the pointer.
diff --git a/ash/search_box/search_box_view_base.cc b/ash/search_box/search_box_view_base.cc index ac2e4fe..241f86ba 100644 --- a/ash/search_box/search_box_view_base.cc +++ b/ash/search_box/search_box_view_base.cc
@@ -349,6 +349,7 @@ if (event_type != ui::ET_KEY_PRESSED && event_type != ui::ET_KEY_RELEASED) UpdateKeyboardVisibility(); UpdateButtonsVisisbility(); + OnSearchBoxActiveChanged(active); NotifyActiveChanged(); @@ -438,6 +439,8 @@ NotifyQueryChanged(); } +void SearchBoxViewBase::OnSearchBoxActiveChanged(bool active) {} + void SearchBoxViewBase::NotifyQueryChanged() { DCHECK(delegate_); delegate_->QueryChanged(this);
diff --git a/ash/search_box/search_box_view_base.h b/ash/search_box/search_box_view_base.h index ac963e2..ccd9302 100644 --- a/ash/search_box/search_box_view_base.h +++ b/ash/search_box/search_box_view_base.h
@@ -118,6 +118,9 @@ virtual void ClearSearch(); + // Called when the search box active state changes. + virtual void OnSearchBoxActiveChanged(bool active); + protected: // Fires query change notification. void NotifyQueryChanged();
diff --git a/ash/shelf/shelf_layout_manager_unittest.cc b/ash/shelf/shelf_layout_manager_unittest.cc index 88faeb2d..3f6fc60 100644 --- a/ash/shelf/shelf_layout_manager_unittest.cc +++ b/ash/shelf/shelf_layout_manager_unittest.cc
@@ -26,7 +26,6 @@ #include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/ash_pref_names.h" #include "ash/public/cpp/ash_switches.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h" #include "ash/public/cpp/keyboard/keyboard_controller.h" #include "ash/public/cpp/keyboard/keyboard_controller_observer.h" #include "ash/public/cpp/shelf_config.h"
diff --git a/ash/shelf/test/shelf_layout_manager_test_base.cc b/ash/shelf/test/shelf_layout_manager_test_base.cc index 46eba01..1abbf42 100644 --- a/ash/shelf/test/shelf_layout_manager_test_base.cc +++ b/ash/shelf/test/shelf_layout_manager_test_base.cc
@@ -16,6 +16,7 @@ #include "ash/wm/window_state.h" #include "ash/wm/workspace_controller.h" #include "chromeos/constants/chromeos_switches.h" +#include "chromeos/ui/base/window_properties.h" #include "components/prefs/pref_service.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/client/window_parenting_client.h" @@ -27,6 +28,9 @@ namespace ash { namespace { + +using ::chromeos::kImmersiveIsActive; + ShelfWidget* GetShelfWidget() { return AshTestBase::GetPrimaryShelf()->shelf_widget(); }
diff --git a/ash/shell.h b/ash/shell.h index f47bc16d..32417ba 100644 --- a/ash/shell.h +++ b/ash/shell.h
@@ -33,6 +33,7 @@ } // namespace aura namespace chromeos { +class ImmersiveContext; class SnapController; } // namespace chromeos @@ -126,7 +127,6 @@ class HoldingSpaceController; class HomeScreenController; class ImeControllerImpl; -class ImmersiveContext; class InSessionAuthDialogControllerImpl; class KeyAccessibilityEnabler; class KeyboardBrightnessControlDelegate; @@ -693,7 +693,7 @@ std::unique_ptr<HoldingSpaceController> holding_space_controller_; std::unique_ptr<HomeScreenController> home_screen_controller_; std::unique_ptr<ImeControllerImpl> ime_controller_; - std::unique_ptr<ImmersiveContext> immersive_context_; + std::unique_ptr<chromeos::ImmersiveContext> immersive_context_; std::unique_ptr<InSessionAuthDialogControllerImpl> in_session_auth_dialog_controller_; std::unique_ptr<KeyboardBrightnessControlDelegate>
diff --git a/ash/system/holding_space/holding_space_drag_util.cc b/ash/system/holding_space/holding_space_drag_util.cc new file mode 100644 index 0000000..54682ea --- /dev/null +++ b/ash/system/holding_space/holding_space_drag_util.cc
@@ -0,0 +1,275 @@ +// 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 "ash/system/holding_space/holding_space_drag_util.h" + +#include <memory> + +#include "ash/public/cpp/holding_space/holding_space_color_provider.h" +#include "ash/public/cpp/holding_space/holding_space_image.h" +#include "ash/public/cpp/holding_space/holding_space_item.h" +#include "ash/public/cpp/rounded_image_view.h" +#include "ash/system/holding_space/holding_space_item_view.h" +#include "ash/system/tray/tray_popup_item_style.h" +#include "base/containers/adapters.h" +#include "ui/compositor/canvas_painter.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/image/image_skia.h" +#include "ui/gfx/shadow_util.h" +#include "ui/gfx/skia_paint_util.h" +#include "ui/views/border.h" +#include "ui/views/controls/label.h" +#include "ui/views/drag_utils.h" +#include "ui/views/layout/box_layout.h" +#include "ui/views/layout/layout_manager_base.h" +#include "ui/views/view.h" +#include "ui/views/widget/widget.h" + +namespace ash { +namespace holding_space_util { + +namespace { + +// Appearance. +constexpr int kDragImageItemViewCornerRadius = 8; +constexpr int kDragImageItemViewElevation = 2; +constexpr int kDragImageItemChipViewIconSize = 24; +constexpr gfx::Insets kDragImageItemChipViewInsets(0, 13); +constexpr gfx::Size kDragImageItemChipViewPreferredSize(160, 40); +constexpr int kDragImageItemChipViewSpacing = 13; +constexpr int kDragImageViewChildOffset = 8; + +// Helpers --------------------------------------------------------------------- + +#if DCHECK_IS_ON() +// Asserts that there are no `ui::Layer`s in the specified `view` hierarchy. +void AssertNoLayers(const views::View* view) { + DCHECK(!view->layer()); + for (const views::View* child : view->children()) + AssertNoLayers(child); +} +#endif // DCHECK_IS_ON() + +// Returns an empty border with space to accommodate the specified `shadow`. +std::unique_ptr<views::Border> CreateEmptyBorderForShadow( + const gfx::ShadowDetails& shadow) { + return views::CreateEmptyBorder(-gfx::ShadowValue::GetMargin(shadow.values)); +} + +// Returns the holding space items associated with the specified `views`. +std::vector<const HoldingSpaceItem*> GetHoldingSpaceItems( + const std::vector<const HoldingSpaceItemView*> views) { + std::vector<const HoldingSpaceItem*> items; + for (const HoldingSpaceItemView* view : views) + items.push_back(view->item()); + return items; +} + +// DragImageLayoutManager ------------------------------------------------------ + +// A `views::LayoutManager` which lays out its children atop each other with a +// specified `child_offset`. Note that children are painted in reverse order. +class DragImageLayoutManager : public views::LayoutManagerBase { + public: + explicit DragImageLayoutManager(int child_offset) + : child_offset_(child_offset) {} + + DragImageLayoutManager(const DragImageLayoutManager&) = delete; + DragImageLayoutManager& operator=(const DragImageLayoutManager&) = delete; + ~DragImageLayoutManager() override = default; + + private: + // views::LayoutManagerBase: + views::ProposedLayout CalculateProposedLayout( + const views::SizeBounds& size_bounds) const override { + views::ProposedLayout proposed_layout; + + int left = 0, top = 0; + for (views::View* child_view : host_view()->children()) { + const gfx::Size child_preferred_size = child_view->GetPreferredSize(); + + // Child layout. + views::ChildLayout child_layout; + child_layout.available_size = views::SizeBounds(child_preferred_size); + child_layout.bounds = gfx::Rect({left, top}, child_preferred_size); + child_layout.child_view = child_view; + child_layout.visible = true; + proposed_layout.child_layouts.push_back(std::move(child_layout)); + + // Host size. + if (proposed_layout.host_size.IsEmpty()) { + proposed_layout.host_size = child_preferred_size; + } else { + int host_width = left + child_preferred_size.width(); + int host_height = top + child_preferred_size.height(); + proposed_layout.host_size.SetToMax(gfx::Size(host_width, host_height)); + } + + left += child_offset_; + top += child_offset_; + } + + return proposed_layout; + } + + std::vector<views::View*> GetChildViewsInPaintOrder( + const views::View* host) const override { + // Paint `children` in reverse order so that earlier views paint at a higher + // z-index than later views, like a deck of cards with the first `child` + // stacked on top. + std::vector<views::View*> children; + for (views::View* child : base::Reversed(host->children())) + children.push_back(child); + return children; + } + + const int child_offset_; +}; + +// DragImageItemView ----------------------------------------------------------- + +// An abstract `views::View` which represents a single holding space item in the +// drag image for a collection of holding space item views. The main purpose of +// this view is to implement the shadow which is intentionally done without use +// of `ui::Layer`s to accommodate painting to an `SkBitmap`. +class DragImageItemView : public views::View { + public: + DragImageItemView(const DragImageItemView&) = delete; + DragImageItemView& operator=(const DragImageItemView&) = delete; + ~DragImageItemView() override = default; + + protected: + DragImageItemView() { + // Add an empty border to accommodate the shadow so that the view's content + // will be laid out within the appropriate shadow margins. + SetBorder(CreateEmptyBorderForShadow(GetShadowDetails())); + } + + private: + // views::View: + void OnPaintBackground(gfx::Canvas* canvas) override { + cc::PaintFlags flags; + flags.setAntiAlias(true); + flags.setColor(SK_ColorWHITE); + flags.setLooper(gfx::CreateShadowDrawLooper(GetShadowDetails().values)); + canvas->DrawRoundRect(GetContentsBounds(), kDragImageItemViewCornerRadius, + flags); + } + + const gfx::ShadowDetails& GetShadowDetails() const { + return gfx::ShadowDetails::Get(kDragImageItemViewElevation, + kDragImageItemViewCornerRadius); + } +}; + +// DragImageItemChipView ------------------------------------------------------- + +// A `DragImageItemView` which represents a single holding space `item` as a +// chip in the drag image for a collection of holding space item views. +class DragImageItemChipView : public DragImageItemView { + public: + explicit DragImageItemChipView(const HoldingSpaceItem* item) { + InitLayout(item); + } + + private: + void InitLayout(const HoldingSpaceItem* item) { + // NOTE: We enlarge `preferred_size` to accommodate the view's shadow. + gfx::Size preferred_size(kDragImageItemChipViewPreferredSize); + preferred_size.Enlarge(GetInsets().width(), GetInsets().height()); + SetPreferredSize(preferred_size); + + // Layout. + views::BoxLayout* layout = + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal, + kDragImageItemChipViewInsets, kDragImageItemChipViewSpacing)); + layout->set_cross_axis_alignment( + views::BoxLayout::CrossAxisAlignment::kCenter); + layout->set_main_axis_alignment( + views::BoxLayout::MainAxisAlignment::kCenter); + + // Icon. + auto* icon = AddChildView(std::make_unique<RoundedImageView>( + /*radius=*/kDragImageItemChipViewIconSize / 2, + RoundedImageView::Alignment::kCenter)); + icon->SetPreferredSize(gfx::Size(kDragImageItemChipViewIconSize, + kDragImageItemChipViewIconSize)); + icon->SetImage(item->image().image_skia(), icon->GetPreferredSize()); + + // Label. + auto* label = AddChildView(std::make_unique<views::Label>(item->text())); + label->SetElideBehavior(gfx::ElideBehavior::ELIDE_MIDDLE); + label->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT); + layout->SetFlexForView(label, 1); + + TrayPopupItemStyle(TrayPopupItemStyle::FontStyle::DETAILED_VIEW_LABEL, + /*use_unified_theme=*/false) + .SetupLabel(label); + } +}; + +// DragImageView --------------------------------------------------------------- + +// A `views::View` for use as a drag image for a collection of holding space +// item `views`. This view expects to be painted to an `SkBitmap`. +class DragImageView : public views::View { + public: + explicit DragImageView(const std::vector<const HoldingSpaceItem*>& items) { + InitLayout(items); + } + + DragImageView(const DragImageView&) = delete; + DragImageView& operator=(const DragImageView&) = delete; + ~DragImageView() override = default; + + // Paints this view to a `gfx::ImageSkia`. + gfx::ImageSkia PaintToImageSkia(float scale, bool is_pixel_canvas) { +#if DCHECK_IS_ON() + // NOTE: This method will *not* paint `ui::Layer`s, so it is expected that + // all views in this view hierarchy *not* paint to layers. + AssertNoLayers(this); +#endif // DCHECK_IS_ON() + SkBitmap bitmap; + Paint(views::PaintInfo::CreateRootPaintInfo( + ui::CanvasPainter(&bitmap, size(), scale, + /*clear_color=*/SK_ColorTRANSPARENT, is_pixel_canvas) + .context(), + size())); + return gfx::ImageSkia(gfx::ImageSkiaRep(bitmap, scale)); + } + + private: + void InitLayout(const std::vector<const HoldingSpaceItem*>& items) { + SetLayoutManager( + std::make_unique<DragImageLayoutManager>(kDragImageViewChildOffset)); + + // TODO(crbug.com/1139113): Support theming. + // TODO(crbug.com/1139113): Paint screenshot items differently. + // TODO(crbug.com/1139113): Limit number of items and add overflow badge. + for (const HoldingSpaceItem* item : items) + AddChildView(std::make_unique<DragImageItemChipView>(item)); + } +}; + +} // namespace + +// Utilities ------------------------------------------------------------------- + +gfx::ImageSkia CreateDragImage( + const std::vector<const HoldingSpaceItemView*>& views) { + if (views.empty()) + return gfx::ImageSkia(); + + const views::Widget* widget = views[0]->GetWidget(); + const float scale = views::ScaleFactorForDragFromWidget(widget); + const bool is_pixel_canvas = widget->GetCompositor()->is_pixel_canvas(); + + DragImageView drag_image_view(GetHoldingSpaceItems(views)); + drag_image_view.SetSize(drag_image_view.GetPreferredSize()); + return drag_image_view.PaintToImageSkia(scale, is_pixel_canvas); +} + +} // namespace holding_space_util +} // namespace ash
diff --git a/ash/system/holding_space/holding_space_drag_util.h b/ash/system/holding_space/holding_space_drag_util.h new file mode 100644 index 0000000..84fc0a33 --- /dev/null +++ b/ash/system/holding_space/holding_space_drag_util.h
@@ -0,0 +1,31 @@ +// 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 ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_DRAG_UTIL_H_ +#define ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_DRAG_UTIL_H_ + +#include <vector> + +namespace gfx { +class ImageSkia; +} // namespace gfx + +namespace ash { + +class HoldingSpaceItemView; + +namespace holding_space_util { + +// Returns a drag image for the specified holding space item `views`. The drag +// image consists of a stacked representation of the dragged items with the +// first item being stacked on top. Note that the drag image will paint at most +// two items with an overflow badge to represent the presence of additional drag +// items if necessary. +gfx::ImageSkia CreateDragImage( + const std::vector<const HoldingSpaceItemView*>& views); + +} // namespace holding_space_util +} // namespace ash + +#endif // ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_DRAG_UTIL_H_
diff --git a/ash/system/holding_space/holding_space_item_view_delegate.cc b/ash/system/holding_space/holding_space_item_view_delegate.cc index 1ac1c4ae..8322c6f 100644 --- a/ash/system/holding_space/holding_space_item_view_delegate.cc +++ b/ash/system/holding_space/holding_space_item_view_delegate.cc
@@ -12,12 +12,15 @@ #include "ash/public/cpp/holding_space/holding_space_model.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/strings/grit/ash_strings.h" +#include "ash/system/holding_space/holding_space_drag_util.h" #include "ash/system/holding_space/holding_space_item_view.h" #include "base/bind.h" +#include "base/i18n/rtl.h" #include "net/base/mime_util.h" #include "ui/accessibility/ax_action_data.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/base/dragdrop/drag_drop_types.h" +#include "ui/base/dragdrop/os_exchange_data_provider.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/models/simple_menu_model.h" #include "ui/views/controls/menu/menu_runner.h" @@ -234,10 +237,18 @@ holding_space_metrics::RecordItemAction( GetItems(selection), holding_space_metrics::ItemAction::kDrag); + // Drag image. + gfx::ImageSkia drag_image = holding_space_util::CreateDragImage(selection); + data->provider().SetDragImage(std::move(drag_image), + /*image_offset=*/base::i18n::IsRTL() + ? gfx::Vector2d(drag_image.width(), 0) + : gfx::Vector2d()); + + // Payload. std::vector<ui::FileInfo> filenames; for (const HoldingSpaceItemView* view : selection) { - filenames.push_back(ui::FileInfo(view->item()->file_path(), - view->item()->file_path().BaseName())); + const base::FilePath& file_path = view->item()->file_path(); + filenames.push_back(ui::FileInfo(file_path, file_path.BaseName())); } data->SetFilenames(filenames); }
diff --git a/ash/wm/immersive_context_ash.cc b/ash/wm/immersive_context_ash.cc index b003b45..4c6d054 100644 --- a/ash/wm/immersive_context_ash.cc +++ b/ash/wm/immersive_context_ash.cc
@@ -4,16 +4,18 @@ #include "ash/wm/immersive_context_ash.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h" #include "ash/shelf/shelf.h" #include "ash/shell.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" #include "ui/display/screen.h" #include "ui/views/widget/widget.h" namespace ash { +using ::chromeos::ImmersiveFullscreenController; + ImmersiveContextAsh::ImmersiveContextAsh() = default; ImmersiveContextAsh::~ImmersiveContextAsh() = default;
diff --git a/ash/wm/immersive_context_ash.h b/ash/wm/immersive_context_ash.h index 3684ccf..e2578f0 100644 --- a/ash/wm/immersive_context_ash.h +++ b/ash/wm/immersive_context_ash.h
@@ -6,19 +6,20 @@ #define ASH_WM_IMMERSIVE_CONTEXT_ASH_H_ #include "ash/ash_export.h" -#include "ash/public/cpp/immersive/immersive_context.h" #include "base/macros.h" +#include "chromeos/ui/frame/immersive/immersive_context.h" namespace ash { -class ASH_EXPORT ImmersiveContextAsh : public ImmersiveContext { +class ASH_EXPORT ImmersiveContextAsh : public chromeos::ImmersiveContext { public: ImmersiveContextAsh(); ~ImmersiveContextAsh() override; // ImmersiveContext: - void OnEnteringOrExitingImmersive(ImmersiveFullscreenController* controller, - bool entering) override; + void OnEnteringOrExitingImmersive( + chromeos::ImmersiveFullscreenController* controller, + bool entering) override; gfx::Rect GetDisplayBoundsInScreen(views::Widget* widget) override; bool DoesAnyWindowHaveCapture() override;
diff --git a/ash/wm/immersive_fullscreen_controller_unittest.cc b/ash/wm/immersive_fullscreen_controller_unittest.cc index fd32b4a..c1d55d3 100644 --- a/ash/wm/immersive_fullscreen_controller_unittest.cc +++ b/ash/wm/immersive_fullscreen_controller_unittest.cc
@@ -2,13 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" #include "ash/frame/header_view.h" #include "ash/frame/non_client_frame_view_ash.h" #include "ash/public/cpp/ash_features.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller_delegate.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h" #include "ash/public/cpp/shelf_config.h" #include "ash/public/cpp/shelf_types.h" #include "ash/root_window_controller.h" @@ -20,6 +18,8 @@ #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_state.h" #include "base/test/scoped_feature_list.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_delegate.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/client/cursor_client.h" #include "ui/aura/env.h" @@ -42,6 +42,11 @@ namespace { +using ::chromeos::ImmersiveFullscreenController; +using ::chromeos::ImmersiveFullscreenControllerDelegate; +using ::chromeos::ImmersiveFullscreenControllerTestApi; +using ::chromeos::ImmersiveRevealedLock; + class TestBubbleDialogDelegate : public views::BubbleDialogDelegateView { public: explicit TestBubbleDialogDelegate(views::View* anchor)
diff --git a/ash/wm/splitview/split_view_controller_unittest.cc b/ash/wm/splitview/split_view_controller_unittest.cc index 5ddea92..8134bf84 100644 --- a/ash/wm/splitview/split_view_controller_unittest.cc +++ b/ash/wm/splitview/split_view_controller_unittest.cc
@@ -4819,7 +4819,7 @@ const WMEvent fullscreen_event(WM_EVENT_TOGGLE_FULLSCREEN); window_state->OnWMEvent(&fullscreen_event); window_state->SetHideShelfWhenFullscreen(false); - window()->SetProperty(kImmersiveIsActive, true); + window()->SetProperty(chromeos::kImmersiveIsActive, true); shelf_layout_manager->UpdateVisibilityState(); EXPECT_TRUE(window_state->IsFullscreen()); EXPECT_FALSE(shelf_layout_manager->IsVisible());
diff --git a/ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler_unittest.cc b/ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler_unittest.cc index c369eb7..6817eb4 100644 --- a/ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler_unittest.cc +++ b/ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler_unittest.cc
@@ -4,11 +4,11 @@ #include "ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler.h" -#include "ash/public/cpp/window_properties.h" #include "ash/test/ash_test_base.h" #include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h" #include "ash/wm/window_state.h" #include "ash/wm/wm_event.h" +#include "chromeos/ui/base/window_properties.h" #include "ui/aura/window.h" namespace ash { @@ -44,7 +44,7 @@ void ToggleFullscreen(aura::Window* window, bool immersive) { WMEvent toggle_fullscreen(WM_EVENT_TOGGLE_FULLSCREEN); WindowState::Get(window)->OnWMEvent(&toggle_fullscreen); - window->SetProperty(kImmersiveIsActive, immersive); + window->SetProperty(chromeos::kImmersiveIsActive, immersive); } bool IsFullscreen(aura::Window* window) const {
diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc index d094ae1..6da6761 100644 --- a/ash/wm/window_state.cc +++ b/ash/wm/window_state.cc
@@ -52,6 +52,7 @@ namespace ash { namespace { +using ::chromeos::kImmersiveIsActive; using ::chromeos::WindowStateType; bool IsTabletModeEnabled() {
diff --git a/base/allocator/partition_allocator/page_allocator_internals_posix.h b/base/allocator/partition_allocator/page_allocator_internals_posix.h index d8a21bc..52518de 100644 --- a/base/allocator/partition_allocator/page_allocator_internals_posix.h +++ b/base/allocator/partition_allocator/page_allocator_internals_posix.h
@@ -11,6 +11,7 @@ #include "base/allocator/partition_allocator/partition_alloc_check.h" #include "base/check_op.h" #include "base/notreached.h" +#include "base/posix/eintr_wrapper.h" #include "build/build_config.h" #if defined(OS_APPLE) @@ -135,8 +136,7 @@ } #endif - void* ret = - mmap(hint, length, access_flag, map_flags, fd, 0); + void* ret = mmap(hint, length, access_flag, map_flags, fd, 0); if (ret == MAP_FAILED) { s_allocPageErrorCode = errno; ret = nullptr; @@ -159,14 +159,33 @@ void* address, size_t length, PageAccessibilityConfiguration accessibility) { - return 0 == mprotect(address, length, GetAccessFlags(accessibility)); + return 0 == + HANDLE_EINTR(mprotect(address, length, GetAccessFlags(accessibility))); } void SetSystemPagesAccessInternal( void* address, size_t length, PageAccessibilityConfiguration accessibility) { - PCHECK(!mprotect(address, length, GetAccessFlags(accessibility))); + if (!HANDLE_EINTR(mprotect(address, length, GetAccessFlags(accessibility)))) + return; + + // mprotect() failed, let's get more data on errno in crash reports. Values + // taken from man mprotect(2) on Linux: + switch (errno) { + case EACCES: + PCHECK(false); + break; + case EINVAL: + PCHECK(false); + break; + case ENOMEM: + PCHECK(false); + break; + default: + PCHECK(false); + break; + } } void FreePagesInternal(void* address, size_t length) {
diff --git a/base/win/registry.cc b/base/win/registry.cc index c317daf7..3d5f1e2 100644 --- a/base/win/registry.cc +++ b/base/win/registry.cc
@@ -8,16 +8,19 @@ #include <algorithm> #include <memory> - #include <string> #include <utility> +#include <vector> +#include "base/callback.h" #include "base/check_op.h" #include "base/notreached.h" #include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/strings/string_util_win.h" #include "base/threading/thread_restrictions.h" +#include "base/win/object_watcher.h" +#include "base/win/scoped_handle.h" #include "base/win/shlwapi.h" #include "base/win/windows_version.h" @@ -51,9 +54,10 @@ bool StartWatching(HKEY key, ChangeCallback callback); - // Implementation of ObjectWatcher::Delegate. + // ObjectWatcher::Delegate: void OnObjectSignaled(HANDLE object) override { - DCHECK(watch_event_.IsValid() && watch_event_.Get() == object); + DCHECK(watch_event_.IsValid()); + DCHECK_EQ(watch_event_.Get(), object); std::move(callback_).Run(); } @@ -74,12 +78,13 @@ if (!watch_event_.IsValid()) return false; - DWORD filter = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | - REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY; + const DWORD filter = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | + REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY; // Watch the registry key for a change of value. LONG result = - RegNotifyChangeKeyValue(key, TRUE, filter, watch_event_.Get(), TRUE); + RegNotifyChangeKeyValue(key, /*bWatchSubtree=*/TRUE, filter, + watch_event_.Get(), /*fAsynchronous=*/TRUE); if (result != ERROR_SUCCESS) { watch_event_.Close(); return false;
diff --git a/base/win/registry.h b/base/win/registry.h index 784b58b..e5769d42 100644 --- a/base/win/registry.h +++ b/base/win/registry.h
@@ -12,10 +12,8 @@ #include <vector> #include "base/base_export.h" -#include "base/callback.h" +#include "base/callback_forward.h" #include "base/macros.h" -#include "base/win/object_watcher.h" -#include "base/win/scoped_handle.h" #include "base/win/windows_types.h" namespace base {
diff --git a/build/android/pylib/utils/test_filter.py b/build/android/pylib/utils/test_filter.py index 430b4c5..6db6243 100644 --- a/build/android/pylib/utils/test_filter.py +++ b/build/android/pylib/utils/test_filter.py
@@ -50,9 +50,9 @@ '--gtest-filter-file', # New argument. '--test-launcher-filter-file', - dest='test_filter_file', type=os.path.realpath, + dest='test_filter_file', help='Path to file that contains googletest-style filter strings. ' - 'See also //testing/buildbot/filters/README.md.') + 'See also //testing/buildbot/filters/README.md.') filter_group = parser.add_mutually_exclusive_group() filter_group.add_argument( @@ -126,14 +126,16 @@ '', args.test_filter.replace('#', '.')) if args.test_filter_file: - with open(args.test_filter_file, 'r') as f: - positive_file_patterns, negative_file_patterns = ParseFilterFile(f) - if positive_file_patterns and HasPositivePatterns(test_filter): - raise ConflictingPositiveFiltersException( - 'Cannot specify positive pattern in both filter file and ' + - 'filter command line argument') - test_filter = AppendPatternsToFilter(test_filter, - positive_patterns=positive_file_patterns, - negative_patterns=negative_file_patterns) + for test_filter_file in args.test_filter_file.split(';'): + with open(test_filter_file, 'r') as f: + positive_file_patterns, negative_file_patterns = ParseFilterFile(f) + if positive_file_patterns and HasPositivePatterns(test_filter): + raise ConflictingPositiveFiltersException( + 'Cannot specify positive pattern in both filter file and ' + + 'filter command line argument') + test_filter = AppendPatternsToFilter( + test_filter, + positive_patterns=positive_file_patterns, + negative_patterns=negative_file_patterns) return test_filter
diff --git a/build/android/stacktrace/crashpad_stackwalker.py b/build/android/stacktrace/crashpad_stackwalker.py index 6be71ca..beeb6f4 100755 --- a/build/android/stacktrace/crashpad_stackwalker.py +++ b/build/android/stacktrace/crashpad_stackwalker.py
@@ -119,8 +119,7 @@ description='Fetches Crashpad dumps from a given device, ' 'walks and symbolizes the stacks.') parser.add_argument('--device', required=True, help='Device serial number') - parser.add_argument( - '--adb-path', required=True, help='Path to the "adb" command') + parser.add_argument('--adb-path', help='Path to the "adb" command') parser.add_argument( '--build-path', required=True, @@ -137,7 +136,8 @@ logging.error('Missing minidump_stackwalk executable') return 1 - devil_chromium.Initialize(adb_path=args.adb_path) + devil_chromium.Initialize(output_directory=args.build_path, + adb_path=args.adb_path) device = device_utils.DeviceUtils(args.device) device_crashpad_path = posixpath.join(args.chrome_cache_path, 'Crashpad',
diff --git a/build/android/tombstones.py b/build/android/tombstones.py index 821c31b0..33fd681 100755 --- a/build/android/tombstones.py +++ b/build/android/tombstones.py
@@ -251,16 +251,15 @@ help='Path to the adb binary.') args = parser.parse_args() - devil_chromium.Initialize(adb_path=args.adb_path) + if args.output_directory: + constants.SetOutputDirectory(args.output_directory) + + devil_chromium.Initialize(output_directory=constants.GetOutDirectory(), + adb_path=args.adb_path) denylist = (device_denylist.Denylist(args.denylist_file) if args.denylist_file else None) - if args.output_directory: - constants.SetOutputDirectory(args.output_directory) - # Do an up-front test that the output directory is known. - constants.CheckOutputDirectory() - if args.device: devices = [device_utils.DeviceUtils(args.device)] else:
diff --git a/build/build_config.h b/build/build_config.h index 2c3e81ee..c37c7429 100644 --- a/build/build_config.h +++ b/build/build_config.h
@@ -61,7 +61,11 @@ #define OS_MAC 1 #endif // defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE #elif defined(__linux__) +#if !defined(OS_CHROMEOS) +// Do not define OS_LINUX on Chrome OS build. +// The OS_CHROMEOS macro is defined in GN. #define OS_LINUX 1 +#endif // !defined(OS_CHROMEOS) // Include a system header to pull in features.h for glibc/uclibc macros. #include <unistd.h> #if defined(__GLIBC__) && !defined(__UCLIBC__)
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 6fa8428..3bd02b7e 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20201016.0.1 +0.20201016.2.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 6fa8428..3bd02b7e 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -0.20201016.0.1 +0.20201016.2.1
diff --git a/build/toolchain/win/midl.py b/build/toolchain/win/midl.py index 5483173..4fa0383 100644 --- a/build/toolchain/win/midl.py +++ b/build/toolchain/win/midl.py
@@ -57,7 +57,8 @@ # First: Type string (0x8), followed by 0x3e characters. assert contents[custom_off:custom_off + 6] == b'\x08\x00\x3e\x00\x00\x00' assert re.match( - br'Created by MIDL version 8\.\d\d\.\d{4} at ... Jan 1. ..:..:.. 2038\n', + br'Created by MIDL version 8\.\d\d\.\d{4} ' + br'at ... Jan 1. ..:..:.. 2038\n', contents[custom_off + 6:custom_off + 6 + 0x3e]) # Second: Type uint32 (0x13) storing 0x7fffffff (followed by WW / 0x57 pad) assert contents[custom_off+6+0x3e:custom_off+6+0x3e+8] == \ @@ -121,32 +122,27 @@ open(iid_file, 'wb').write(contents) -def overwrite_cls_guid_tlb(tlb_file, dynamic_guid): - # See ZapTimestamp() for a short overview of the .tlb format. The 1st - # section contains type descriptions, and the first type should be our - # coclass. It points to the type's GUID in section 6, the GUID section. +def get_tlb_contents(tlb_file): + # See ZapTimestamp() for a short overview of the .tlb format. contents = open(tlb_file, 'rb').read() assert contents[0:8] == b'MSFT\x02\x00\x01\x00' ntypes, = struct.unpack_from('<I', contents, 0x20) type_off, type_len = struct.unpack_from('<II', contents, 0x54 + 4*ntypes) - # contents is a bytestring in Python 3, but a normal string in Py2. - if sys.version_info.major == 2: - coclass = ord(contents[type_off]) - else: - coclass = contents[type_off] - assert coclass == 0x25, "expected coclass" - - guidind = struct.unpack_from('<I', contents, type_off + 0x2c)[0] guid_off, guid_len = struct.unpack_from( '<II', contents, 0x54 + 4*ntypes + 5*16) - assert guidind + 14 <= guid_len + assert guid_len % 24 == 0 + contents = array.array('B', contents) - struct.pack_into('<IHH8s', contents, guid_off + guidind, - *(dynamic_guid.fields[0:3] + (dynamic_guid.bytes[8:],))) - # The GUID is correct now, but there's also a GUID hashtable in section 5. - # Need to recreate that too. Since the hash table uses chaining, it's - # easiest to recompute it from scratch rather than trying to patch it up. + + return contents, ntypes, type_off, guid_off, guid_len + + +def recreate_guid_hashtable(contents, ntypes, guid_off, guid_len): + # This function is called after changing guids in section 6 (the "guid" + # section). This function recreates the GUID hashtable in section 5. Since the + # hash table uses chaining, it's easiest to recompute it from scratch rather + # than trying to patch it up. hashtab = [0xffffffff] * (0x80 // 4) for guidind in range(guid_off, guid_off + guid_len, 24): guidbytes, typeoff, nextguid = struct.unpack_from( @@ -161,18 +157,140 @@ '<II', contents, 0x54 + 4*ntypes + 4*16) for i, hashval in enumerate(hashtab): struct.pack_into('<I', contents, hash_off + 4*i, hashval) + + +def overwrite_cls_guid_tlb(tlb_file, dynamic_guid): + contents, ntypes, type_off, guid_off, guid_len = get_tlb_contents(tlb_file) + + # The first type should be a coclass. It points to the type's GUID in + # section 6, the GUID section. + coclass, = struct.unpack_from('<B', contents, type_off) + assert coclass == 0x25, "expected coclass" + + guidind = struct.unpack_from('<I', contents, type_off + 0x2c)[0] + assert guidind + 14 <= guid_len + struct.pack_into('<IHH8s', contents, guid_off + guidind, + *(dynamic_guid.fields[0:3] + (dynamic_guid.bytes[8:], ))) + + recreate_guid_hashtable(contents, ntypes, guid_off, guid_len) open(tlb_file, 'wb').write(contents) +# Handle a single clsid substitution where |dynamic_guid| is of the form +# "D0E1CACC-C63C-4192-94AB-BF8EAD0E3B83". def overwrite_cls_guid(h_file, iid_file, tlb_file, dynamic_guid): - # Fix up GUID in .h, _i.c, and .tlb. This currently assumes that there's - # only one coclass in the idl file, and that that's the type with the - # dynamic type. + # Fix up GUID in .h, _i.c, and .tlb. This function assumes that there is only + # one coclass in the idl file, and that that's the type with the dynamic type. overwrite_cls_guid_h(h_file, dynamic_guid) overwrite_cls_guid_iid(iid_file, dynamic_guid) overwrite_cls_guid_tlb(tlb_file, dynamic_guid) +def overwrite_guids_h(h_file, dynamic_guids): + contents = open(h_file, 'rb').read() + for key in dynamic_guids: + contents = re.sub(key, dynamic_guids[key], contents, flags=re.IGNORECASE) + open(h_file, 'wb').write(contents) + + +def get_uuid_format(guid, prefix, suffix): + formatted_uuid = '%s0x%s,0x%s,0x%s,' % (prefix, guid[0:8], guid[9:13], + guid[14:18]) + formatted_uuid += '%s0x%s,0x%s' % (prefix, guid[19:21], guid[21:23]) + for i in range(24, len(guid), 2): + formatted_uuid += ',0x' + guid[i:i + 2] + formatted_uuid += '%s%s' % (suffix, suffix) + return formatted_uuid + + +def get_uuid_format_iid_file(guid): + # Convert from "D0E1CACC-C63C-4192-94AB-BF8EAD0E3B83" to + # 0xD0E1CACC,0xC63C,0x4192,0x94,0xAB,0xBF,0x8E,0xAD,0x0E,0x3B,0x83. + return get_uuid_format(guid, '', '') + + +def overwrite_guids_iid(iid_file, dynamic_guids): + contents = open(iid_file, 'rb').read() + for key in dynamic_guids: + contents = re.sub(get_uuid_format_iid_file(key), + get_uuid_format_iid_file(dynamic_guids[key]), + contents, + flags=re.IGNORECASE) + open(iid_file, 'wb').write(contents) + + +def get_uuid_format_proxy_file(guid): + # Convert from "D0E1CACC-C63C-4192-94AB-BF8EAD0E3B83" to + # {0xD0E1CACC,0xC63C,0x4192,{0x94,0xAB,0xBF,0x8E,0xAD,0x0E,0x3B,0x83}}. + return get_uuid_format(guid, '{', '}') + + +def overwrite_guids_proxy(proxy_file, dynamic_guids): + contents = open(proxy_file, 'rb').read() + for key in dynamic_guids: + contents = re.sub(get_uuid_format_proxy_file(key), + get_uuid_format_proxy_file(dynamic_guids[key]), + contents, + flags=re.IGNORECASE) + open(proxy_file, 'wb').write(contents) + + +def getguid(contents, offset): + # Returns a guid string of the form "D0E1CACC-C63C-4192-94AB-BF8EAD0E3B83". + g0, g1, g2, g3 = struct.unpack_from('<IHH8s', contents, offset) + g3 = ''.join(['%02X' % ord(g) for g in g3]) + return '%08X-%04X-%04X-%s-%s' % (g0, g1, g2, g3[0:4], g3[4:]) + + +def setguid(contents, offset, guid): + guid = uuid.UUID(guid) + struct.pack_into('<IHH8s', contents, offset, + *(guid.fields[0:3] + (guid.bytes[8:], ))) + + +def overwrite_guids_tlb(tlb_file, dynamic_guids): + contents, ntypes, type_off, guid_off, guid_len = get_tlb_contents(tlb_file) + + for i in range(0, guid_len, 24): + current_guid = getguid(contents, guid_off + i) + for key in dynamic_guids: + if key.lower() == current_guid.lower(): + setguid(contents, guid_off + i, dynamic_guids[key]) + + recreate_guid_hashtable(contents, ntypes, guid_off, guid_len) + open(tlb_file, 'wb').write(contents) + + +# Handle multiple guid substitutions, where |dynamic_guid| is of the form +# "158428a4-6014-4978-83ba-9fad0dabe791=3d852661-c795-4d20-9b95-5561e9a1d2d9," +# "63B8FFB1-5314-48C9-9C57-93EC8BC6184B=D0E1CACC-C63C-4192-94AB-BF8EAD0E3B83". +# +# Before specifying |dynamic_guid| in the build, the IDL file is first compiled +# with "158428a4-6014-4978-83ba-9fad0dabe791" and +# "63B8FFB1-5314-48C9-9C57-93EC8BC6184B". These are the "replaceable" guids, +# i.e., guids that can be replaced in future builds. The resulting MIDL outputs +# are copied over to src\third_party\win_build_output\. +# +# Then, in the future, any changes to these guids can be accomplished by +# providing a |dynamic_guid| of the format above in the build file. These +# "dynamic" guid changes by themselves will not require the MIDL compiler and +# therefore will not require copying output over to +# src\third_party\win_build_output\. +# +# The pre-generated src\third_party\win_build_output\ files are used for +# cross-compiling on other platforms, since the MIDL compiler is Windows-only. +def overwrite_guids(h_file, iid_file, proxy_file, tlb_file, dynamic_guids): + n = len(dynamic_guids) + dynamic_guids = dynamic_guids.split(',') + dynamic_guids = dict(s.split('=') for s in dynamic_guids) + + # Fix up GUIDs in .h, _i.c, _p.c, and .tlb. + overwrite_guids_h(h_file, dynamic_guids) + overwrite_guids_iid(iid_file, dynamic_guids) + overwrite_guids_proxy(proxy_file, dynamic_guids) + overwrite_guids_tlb(tlb_file, dynamic_guids) + + def main(arch, gendir, outdir, dynamic_guid, tlb, h, dlldata, iid, proxy, clang, idl, *flags): # Copy checked-in outputs to final location. @@ -183,10 +301,13 @@ source = os.path.normpath(source) distutils.dir_util.copy_tree(source, outdir, preserve_times=False) if dynamic_guid != 'none': - overwrite_cls_guid(os.path.join(outdir, h), - os.path.join(outdir, iid), - os.path.join(outdir, tlb), - uuid.UUID(dynamic_guid)) + if '=' not in dynamic_guid: + overwrite_cls_guid(os.path.join(outdir, h), os.path.join(outdir, iid), + os.path.join(outdir, tlb), uuid.UUID(dynamic_guid)) + else: + overwrite_guids(os.path.join(outdir, h), os.path.join(outdir, iid), + os.path.join(outdir, proxy), os.path.join(outdir, tlb), + dynamic_guid) # On non-Windows, that's all we can do. if sys.platform != 'win32':
diff --git a/cc/base/math_util.cc b/cc/base/math_util.cc index d9b43f4..486974d 100644 --- a/cc/base/math_util.cc +++ b/cc/base/math_util.cc
@@ -804,6 +804,22 @@ res->EndArray(); } +void MathUtil::AddCornerRadiiToTracedValue( + const char* name, + const gfx::RRectF& rect, + base::trace_event::TracedValue* res) { + res->BeginArray(name); + res->AppendDouble(rect.GetCornerRadii(gfx::RRectF::Corner::kUpperLeft).x()); + res->AppendDouble(rect.GetCornerRadii(gfx::RRectF::Corner::kUpperLeft).y()); + res->AppendDouble(rect.GetCornerRadii(gfx::RRectF::Corner::kUpperRight).x()); + res->AppendDouble(rect.GetCornerRadii(gfx::RRectF::Corner::kUpperRight).y()); + res->AppendDouble(rect.GetCornerRadii(gfx::RRectF::Corner::kLowerRight).x()); + res->AppendDouble(rect.GetCornerRadii(gfx::RRectF::Corner::kLowerRight).y()); + res->AppendDouble(rect.GetCornerRadii(gfx::RRectF::Corner::kLowerLeft).x()); + res->AppendDouble(rect.GetCornerRadii(gfx::RRectF::Corner::kLowerLeft).y()); + res->EndArray(); +} + double MathUtil::AsDoubleSafely(double value) { return std::min(value, std::numeric_limits<double>::max()); }
diff --git a/cc/base/math_util.h b/cc/base/math_util.h index 1368c9c1..8cb8c386 100644 --- a/cc/base/math_util.h +++ b/cc/base/math_util.h
@@ -16,6 +16,7 @@ #include "ui/gfx/geometry/box_f.h" #include "ui/gfx/geometry/point3_f.h" #include "ui/gfx/geometry/point_f.h" +#include "ui/gfx/geometry/rounded_corners_f.h" #include "ui/gfx/geometry/scroll_offset.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/transform.h" @@ -303,6 +304,9 @@ static void AddToTracedValue(const char* name, const gfx::RRectF& rect, base::trace_event::TracedValue* res); + static void AddCornerRadiiToTracedValue(const char* name, + const gfx::RRectF& rect, + base::trace_event::TracedValue* res); // Returns a base::Value representation of the floating point value. // If the value is inf, returns max double/float representation.
diff --git a/cc/layers/draw_properties.h b/cc/layers/draw_properties.h index d5a0a7d8..96d7ffd 100644 --- a/cc/layers/draw_properties.h +++ b/cc/layers/draw_properties.h
@@ -11,7 +11,7 @@ #include "cc/trees/occlusion.h" #include "ui/gfx/geometry/rect.h" -#include "ui/gfx/rrect_f.h" +#include "ui/gfx/mask_filter_info.h" #include "ui/gfx/transform.h" namespace cc { @@ -45,10 +45,6 @@ // True if the layer needs to be clipped by clip_rect. bool is_clipped = false; - // If set, it makes the layer's rounded corner not trigger a render surface if - // possible. - bool is_fast_rounded_corner = false; - // This rect is a bounding box around what part of the layer is visible, in // the layer's coordinate space. gfx::Rect visible_layer_rect; @@ -61,9 +57,9 @@ // value is used to avoid unnecessarily changing GL scissor state. gfx::Rect clip_rect; - // Contains a rounded corner rect to clip this layer when drawing. This rrect - // is in the target space of the layer. - gfx::RRectF rounded_corner_bounds; + // Contains a mask information applied to the layer. The coordinates is in the + // target space of the layer. + gfx::MaskFilterInfo mask_filter_info; }; } // namespace cc
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index 9c40eed..5f3fefa8 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc
@@ -549,8 +549,8 @@ effect_tree_index() != EffectTree::kInvalidNodeId) { if (EffectNode* node = property_trees->effect_tree.Node(effect_tree_index())) { - node->rounded_corner_bounds = - gfx::RRectF(effective_clip_rect, corner_radii()); + node->mask_filter_info = gfx::MaskFilterInfo( + effective_clip_rect, corner_radii(), is_fast_rounded_corner()); node->effect_changed = true; property_trees->effect_tree.set_needs_update(true); } @@ -656,8 +656,8 @@ EffectNode* node = nullptr; if (property_trees && effect_tree_index() != EffectTree::kInvalidNodeId && (node = property_trees->effect_tree.Node(effect_tree_index()))) { - node->rounded_corner_bounds = - gfx::RRectF(EffectiveClipRect(), corner_radii); + node->mask_filter_info = gfx::MaskFilterInfo( + EffectiveClipRect(), corner_radii, is_fast_rounded_corner()); node->effect_changed = true; property_trees->effect_tree.set_needs_update(true); } else {
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index b29796f9..af70440b 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc
@@ -142,13 +142,12 @@ EffectNode* effect_node = GetEffectTree().Node(effect_tree_index_); state->SetAll(draw_properties_.target_space_transform, gfx::Rect(bounds()), draw_properties_.visible_layer_rect, - draw_properties_.rounded_corner_bounds, - draw_properties_.clip_rect, draw_properties_.is_clipped, - contents_opaque, draw_properties_.opacity, + draw_properties_.mask_filter_info, draw_properties_.clip_rect, + draw_properties_.is_clipped, contents_opaque, + draw_properties_.opacity, effect_node->HasRenderSurface() ? SkBlendMode::kSrcOver : effect_node->blend_mode, GetSortingContextId()); - state->is_fast_rounded_corner = draw_properties_.is_fast_rounded_corner; } void LayerImpl::PopulateScaledSharedQuadState(viz::SharedQuadState* state, @@ -178,13 +177,12 @@ EffectNode* effect_node = GetEffectTree().Node(effect_tree_index_); state->SetAll(scaled_draw_transform, content_rect, visible_content_rect, - draw_properties().rounded_corner_bounds, - draw_properties().clip_rect, draw_properties().is_clipped, - contents_opaque, draw_properties().opacity, + draw_properties().mask_filter_info, draw_properties().clip_rect, + draw_properties().is_clipped, contents_opaque, + draw_properties().opacity, effect_node->HasRenderSurface() ? SkBlendMode::kSrcOver : effect_node->blend_mode, GetSortingContextId()); - state->is_fast_rounded_corner = draw_properties().is_fast_rounded_corner; } bool LayerImpl::WillDraw(DrawMode draw_mode,
diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc index b483fc7..2b7d4d69 100644 --- a/cc/layers/layer_unittest.cc +++ b/cc/layers/layer_unittest.cc
@@ -1811,15 +1811,15 @@ layer_5->effect_tree_index()); EXPECT_EQ(gfx::RRectF(gfx::RectF(kClipRect), kRoundedCorners), - node_1->rounded_corner_bounds); + node_1->mask_filter_info.rounded_corner_bounds()); EXPECT_EQ(gfx::RRectF(gfx::RectF(kClipRect), kRoundedCorners), - node_2->rounded_corner_bounds); + node_2->mask_filter_info.rounded_corner_bounds()); EXPECT_EQ(gfx::RRectF(gfx::RectF(kClipRect), kRoundedCorners), - node_3->rounded_corner_bounds); + node_3->mask_filter_info.rounded_corner_bounds()); EXPECT_EQ(gfx::RRectF(gfx::RectF(kClipRect), kRoundedCorners), - node_4->rounded_corner_bounds); + node_4->mask_filter_info.rounded_corner_bounds()); EXPECT_EQ(gfx::RRectF(gfx::RectF(gfx::Rect(kLayerSize)), kRoundedCorners), - node_5->rounded_corner_bounds); + node_5->mask_filter_info.rounded_corner_bounds()); // Setting clip to layer bounds. layer_1->SetMasksToBounds(true); @@ -1850,18 +1850,18 @@ EXPECT_EQ(gfx::RRectF(gfx::RectF(gfx::IntersectRects(gfx::Rect(kLayerSize), kClipRect)), kUpdatedRoundedCorners), - node_1->rounded_corner_bounds); + node_1->mask_filter_info.rounded_corner_bounds()); EXPECT_EQ(gfx::RRectF(gfx::RectF(gfx::IntersectRects(gfx::Rect(kLayerSize), kClipRect)), kUpdatedRoundedCorners), - node_2->rounded_corner_bounds); + node_2->mask_filter_info.rounded_corner_bounds()); EXPECT_EQ(gfx::RRectF(gfx::RectF(kClipRect), kUpdatedRoundedCorners), - node_3->rounded_corner_bounds); + node_3->mask_filter_info.rounded_corner_bounds()); EXPECT_EQ(gfx::RRectF(gfx::RectF(kUpdatedClipRect), kRoundedCorners), - node_4->rounded_corner_bounds); + node_4->mask_filter_info.rounded_corner_bounds()); EXPECT_EQ( gfx::RRectF(gfx::RectF(gfx::Rect(kLayerSize)), kUpdatedRoundedCorners), - node_5->rounded_corner_bounds); + node_5->mask_filter_info.rounded_corner_bounds()); } } // namespace
diff --git a/cc/layers/render_surface_impl.cc b/cc/layers/render_surface_impl.cc index ac3f7c28..a1eb58c 100644 --- a/cc/layers/render_surface_impl.cc +++ b/cc/layers/render_surface_impl.cc
@@ -399,7 +399,7 @@ viz::SharedQuadState* shared_quad_state = render_pass->CreateAndAppendSharedQuadState(); shared_quad_state->SetAll( - draw_transform(), content_rect(), content_rect(), rounded_corner_bounds(), + draw_transform(), content_rect(), content_rect(), mask_filter_info(), draw_properties_.clip_rect, draw_properties_.is_clipped, contents_opaque, draw_properties_.draw_opacity, BlendMode(), sorting_context_id);
diff --git a/cc/layers/render_surface_impl.h b/cc/layers/render_surface_impl.h index 115b49a..0dc3766 100644 --- a/cc/layers/render_surface_impl.h +++ b/cc/layers/render_surface_impl.h
@@ -20,6 +20,7 @@ #include "components/viz/common/quads/shared_quad_state.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_f.h" +#include "ui/gfx/mask_filter_info.h" #include "ui/gfx/transform.h" namespace cc { @@ -54,11 +55,11 @@ } float draw_opacity() const { return draw_properties_.draw_opacity; } - void SetRoundedCornerRRect(const gfx::RRectF& rounded_corner_bounds) { - draw_properties_.rounded_corner_bounds = rounded_corner_bounds; + void SetMaskFilterInfo(const gfx::MaskFilterInfo& mask_filter_info) { + draw_properties_.mask_filter_info = mask_filter_info; } - const gfx::RRectF& rounded_corner_bounds() const { - return draw_properties_.rounded_corner_bounds; + const gfx::MaskFilterInfo& mask_filter_info() const { + return draw_properties_.mask_filter_info; } SkBlendMode BlendMode() const; @@ -241,10 +242,10 @@ // True if the surface needs to be clipped by clip_rect. bool is_clipped : 1; - // Contains a rounded corner rect to clip this render surface by when - // drawing. This rrect is in the target space of the render surface. The - // root render surface will never have this set. - gfx::RRectF rounded_corner_bounds; + // Contains a mask information applied to the layer. The coordinates is in + // the target space of the render surface. The root render surface will + // never have this set. + gfx::MaskFilterInfo mask_filter_info; }; DrawProperties draw_properties_;
diff --git a/cc/layers/video_layer_impl.cc b/cc/layers/video_layer_impl.cc index 3767b58a..824dd4a 100644 --- a/cc/layers/video_layer_impl.cc +++ b/cc/layers/video_layer_impl.cc
@@ -163,10 +163,10 @@ if (visible_quad_rect.IsEmpty()) return; - updater_->AppendQuads( - render_pass, frame_, transform, quad_rect, visible_quad_rect, - draw_properties().rounded_corner_bounds, clip_rect(), is_clipped(), - contents_opaque(), draw_opacity(), GetSortingContextId()); + updater_->AppendQuads(render_pass, frame_, transform, quad_rect, + visible_quad_rect, draw_properties().mask_filter_info, + clip_rect(), is_clipped(), contents_opaque(), + draw_opacity(), GetSortingContextId()); } void VideoLayerImpl::DidDraw(viz::ClientResourceProvider* resource_provider) {
diff --git a/cc/test/render_pass_test_utils.cc b/cc/test/render_pass_test_utils.cc index 3809da1..3232fdc 100644 --- a/cc/test/render_pass_test_utils.cc +++ b/cc/test/render_pass_test_utils.cc
@@ -112,8 +112,8 @@ const gfx::Rect& rect, SkColor color) { viz::SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, true, - false, 1, SkBlendMode::kSrcOver, 0); + shared_state->SetAll(gfx::Transform(), rect, rect, gfx::MaskFilterInfo(), + rect, true, false, 1, SkBlendMode::kSrcOver, 0); auto* quad = pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>(); quad->SetNew(shared_state, rect, rect, color, false); return quad; @@ -124,8 +124,8 @@ SkColor color, const gfx::Transform& transform) { viz::SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(transform, rect, rect, gfx::RRectF(), rect, false, false, - 1, + shared_state->SetAll(transform, rect, rect, gfx::MaskFilterInfo(), rect, + false, false, 1, SkBlendMode::kSrcOver, 0); auto* quad = pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>(); @@ -140,7 +140,7 @@ viz::SharedQuadState* shared_state = to_pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(gfx::Transform(), output_rect, output_rect, - gfx::RRectF(), output_rect, false, false, 1, + gfx::MaskFilterInfo(), output_rect, false, false, 1, SkBlendMode::kSrcOver, 0); auto* quad = to_pass->template CreateAndAppendDrawQuad<QuadType>(); quad->SetNew(shared_state, output_rect, output_rect, contributing_pass->id, 0, @@ -170,8 +170,9 @@ gfx::Rect output_rect = contributing_pass->output_rect; viz::SharedQuadState* shared_state = to_pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(transform, output_rect, output_rect, gfx::RRectF(), - output_rect, false, false, 1, blend_mode, 0); + shared_state->SetAll(transform, output_rect, output_rect, + gfx::MaskFilterInfo(), output_rect, false, false, 1, + blend_mode, 0); auto* quad = to_pass->CreateAndAppendDrawQuad<viz::AggregatedRenderPassDrawQuad>(); gfx::Size arbitrary_nonzero_size(1, 1); @@ -217,8 +218,8 @@ viz::SharedQuadState* shared_state = to_pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, false, - false, 1, SkBlendMode::kSrcOver, 0); + shared_state->SetAll(gfx::Transform(), rect, rect, gfx::MaskFilterInfo(), + rect, false, false, 1, SkBlendMode::kSrcOver, 0); auto* debug_border_quad = to_pass->CreateAndAppendDrawQuad<viz::DebugBorderDrawQuad>(); @@ -278,8 +279,8 @@ viz::SharedQuadState* shared_state2 = to_pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, false, - false, 1, SkBlendMode::kSrcOver, 0); + shared_state->SetAll(gfx::Transform(), rect, rect, gfx::MaskFilterInfo(), + rect, false, false, 1, SkBlendMode::kSrcOver, 0); auto* tile_quad = to_pass->CreateAndAppendDrawQuad<viz::TileDrawQuad>(); tile_quad->SetNew(shared_state2, rect, visible_rect, needs_blending, @@ -394,8 +395,8 @@ viz::SharedQuadState* shared_state = to_pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, false, - false, 1, SkBlendMode::kSrcOver, 0); + shared_state->SetAll(gfx::Transform(), rect, rect, gfx::MaskFilterInfo(), + rect, false, false, 1, SkBlendMode::kSrcOver, 0); viz::DebugBorderDrawQuad* debug_border_quad = to_pass->CreateAndAppendDrawQuad<viz::DebugBorderDrawQuad>(); @@ -455,8 +456,8 @@ viz::SharedQuadState* shared_state2 = to_pass->CreateAndAppendSharedQuadState(); - shared_state2->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, - false, false, 1, SkBlendMode::kSrcOver, 0); + shared_state2->SetAll(gfx::Transform(), rect, rect, gfx::MaskFilterInfo(), + rect, false, false, 1, SkBlendMode::kSrcOver, 0); viz::TileDrawQuad* tile_quad = to_pass->CreateAndAppendDrawQuad<viz::TileDrawQuad>();
diff --git a/cc/test/render_pass_test_utils.h b/cc/test/render_pass_test_utils.h index 54a8d59..0c4b5001 100644 --- a/cc/test/render_pass_test_utils.h +++ b/cc/test/render_pass_test_utils.h
@@ -72,8 +72,8 @@ const gfx::Rect& rect, SkColor color) { viz::SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, false, - false, 1, SkBlendMode::kSrcOver, 0); + shared_state->SetAll(gfx::Transform(), rect, rect, gfx::MaskFilterInfo(), + rect, false, false, 1, SkBlendMode::kSrcOver, 0); auto* quad = pass->template CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>(); quad->SetNew(shared_state, rect, rect, color, false);
diff --git a/cc/trees/draw_properties_unittest.cc b/cc/trees/draw_properties_unittest.cc index cd040c96..d461d6a 100644 --- a/cc/trees/draw_properties_unittest.cc +++ b/cc/trees/draw_properties_unittest.cc
@@ -8122,12 +8122,12 @@ UpdateMainDrawProperties(); CommitAndActivate(); - EXPECT_FALSE( - GetRenderSurfaceImpl(child_1)->rounded_corner_bounds().IsEmpty()); - EXPECT_FALSE( - GetRenderSurfaceImpl(child_2)->rounded_corner_bounds().IsEmpty()); - EXPECT_FALSE( - GetRenderSurfaceImpl(child_3)->rounded_corner_bounds().IsEmpty()); + EXPECT_TRUE( + GetRenderSurfaceImpl(child_1)->mask_filter_info().HasRoundedCorners()); + EXPECT_TRUE( + GetRenderSurfaceImpl(child_2)->mask_filter_info().HasRoundedCorners()); + EXPECT_TRUE( + GetRenderSurfaceImpl(child_3)->mask_filter_info().HasRoundedCorners()); } } // namespace
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc index 1e007fd..e7537c57 100644 --- a/cc/trees/draw_property_utils.cc +++ b/cc/trees/draw_property_utils.cc
@@ -706,27 +706,25 @@ layer->clip_tree_index(), target_node->id); } -std::pair<gfx::RRectF, bool> GetRoundedCornerRRect( - const PropertyTrees* property_trees, - int effect_tree_index, - bool for_render_surface) { - static const std::pair<gfx::RRectF, bool> kEmptyRoundedCornerInfo( - gfx::RRectF(), false); +gfx::MaskFilterInfo GetMaskFilterInfo(const PropertyTrees* property_trees, + int effect_tree_index, + bool for_render_surface) { + static const gfx::MaskFilterInfo kEmptyMaskFilterInfo; const EffectTree* effect_tree = &property_trees->effect_tree; const EffectNode* effect_node = effect_tree->Node(effect_tree_index); const int target_id = effect_node->target_id; - // Return empty rrect if this node has a render surface but the function call - // was made for a non render surface. + // Return empty mask info if this node has a render surface but the function + // call was made for a non render surface. if (effect_node->HasRenderSurface() && !for_render_surface) - return kEmptyRoundedCornerInfo; + return kEmptyMaskFilterInfo; // Traverse the parent chain up to the render target to find a node which has // a rounded corner bounds set. const EffectNode* node = effect_node; bool found_rounded_corner = false; while (node) { - if (!node->rounded_corner_bounds.IsEmpty()) { + if (node->mask_filter_info.HasRoundedCorners()) { found_rounded_corner = true; break; } @@ -749,17 +747,16 @@ // While traversing up the parent chain we did not find any node with a // rounded corner. if (!node || !found_rounded_corner) - return kEmptyRoundedCornerInfo; + return kEmptyMaskFilterInfo; gfx::Transform to_target; if (!property_trees->GetToTarget(node->transform_id, target_id, &to_target)) - return kEmptyRoundedCornerInfo; + return kEmptyMaskFilterInfo; - auto result = - std::make_pair(node->rounded_corner_bounds, node->is_fast_rounded_corner); + auto result = node->mask_filter_info; - if (!to_target.TransformRRectF(&result.first)) - return kEmptyRoundedCornerInfo; + if (!result.Transform(to_target)) + return kEmptyMaskFilterInfo; return result; } @@ -839,10 +836,9 @@ SetSurfaceDrawOpacity(property_trees->effect_tree, render_surface); SetSurfaceDrawTransform(property_trees, render_surface); - render_surface->SetRoundedCornerRRect( - GetRoundedCornerRRect(property_trees, render_surface->EffectTreeIndex(), - /*for_render_surface*/ true) - .first); + render_surface->SetMaskFilterInfo( + GetMaskFilterInfo(property_trees, render_surface->EffectTreeIndex(), + /*for_render_surface=*/true)); render_surface->SetScreenSpaceTransform( property_trees->ToScreenSpaceTransformWithoutSurfaceContentsScale( render_surface->TransformTreeIndex(), @@ -1142,12 +1138,10 @@ layer, property_trees->transform_tree, property_trees->effect_tree); layer->draw_properties().screen_space_transform_is_animating = transform_node->to_screen_is_potentially_animated; - auto rounded_corner_info = - GetRoundedCornerRRect(property_trees, layer->effect_tree_index(), - /*from_render_surface*/ false); - layer->draw_properties().rounded_corner_bounds = rounded_corner_info.first; - layer->draw_properties().is_fast_rounded_corner = - rounded_corner_info.second; + auto mask_filter_info = + GetMaskFilterInfo(property_trees, layer->effect_tree_index(), + /*from_render_surface=*/false); + layer->draw_properties().mask_filter_info = mask_filter_info; } // Compute effects and determine if render surfaces have contributing layers
diff --git a/cc/trees/effect_node.cc b/cc/trees/effect_node.cc index de8b74ca..0bf427a56 100644 --- a/cc/trees/effect_node.cc +++ b/cc/trees/effect_node.cc
@@ -34,7 +34,6 @@ has_masking_child(false), effect_changed(false), subtree_has_copy_request(false), - is_fast_rounded_corner(false), node_or_ancestor_has_filters(false), affected_by_backdrop_filter(false), render_surface_reason(RenderSurfaceReason::kNone), @@ -60,8 +59,7 @@ backdrop_filters == other.backdrop_filters && backdrop_filter_bounds == other.backdrop_filter_bounds && backdrop_mask_element_id == other.backdrop_mask_element_id && - rounded_corner_bounds == other.rounded_corner_bounds && - is_fast_rounded_corner == other.is_fast_rounded_corner && + mask_filter_info == other.mask_filter_info && node_or_ancestor_has_filters == other.node_or_ancestor_has_filters && affected_by_backdrop_filter == other.affected_by_backdrop_filter && // The specific reason is just for tracing/testing/debugging, so just @@ -158,12 +156,18 @@ if (!backdrop_filters.IsEmpty()) value->SetString("backdrop_filters", backdrop_filters.ToString()); value->SetDouble("backdrop_filter_quality", backdrop_filter_quality); - value->SetBoolean("is_fast_rounded_corner", is_fast_rounded_corner); value->SetBoolean("node_or_ancestor_has_filters", node_or_ancestor_has_filters); - if (!rounded_corner_bounds.IsEmpty()) { - MathUtil::AddToTracedValue("rounded_corner_bounds", rounded_corner_bounds, + if (!mask_filter_info.IsEmpty()) { + MathUtil::AddToTracedValue("mask_filter_bounds", mask_filter_info.bounds(), value); + if (mask_filter_info.HasRoundedCorners()) { + MathUtil::AddCornerRadiiToTracedValue( + "mask_filter_rounded_corner_raii", + mask_filter_info.rounded_corner_bounds(), value); + value->SetBoolean("mask_filter_is_fast_rounded_corner", + mask_filter_info.is_fast_rounded_corner()); + } } value->SetString("blend_mode", SkBlendMode_Name(blend_mode)); value->SetBoolean("cache_render_surface", cache_render_surface);
diff --git a/cc/trees/effect_node.h b/cc/trees/effect_node.h index 4834773c..e3b05ee 100644 --- a/cc/trees/effect_node.h +++ b/cc/trees/effect_node.h
@@ -11,6 +11,7 @@ #include "third_party/skia/include/core/SkBlendMode.h" #include "ui/gfx/geometry/point_f.h" #include "ui/gfx/geometry/size_f.h" +#include "ui/gfx/mask_filter_info.h" #include "ui/gfx/rrect_f.h" namespace base { @@ -80,9 +81,10 @@ // image. ElementId backdrop_mask_element_id; - // Bounds of rounded corner rrect in the space of the transform node - // associated with this effect node. - gfx::RRectF rounded_corner_bounds; + // The mask filter information applied to this effect node. The coordinates of + // in the mask info is in the space of the transform node associated with this + // effect node. + gfx::MaskFilterInfo mask_filter_info; SkBlendMode blend_mode; @@ -127,9 +129,6 @@ // frame. Needed in order to compute damage rect. bool effect_changed : 1; bool subtree_has_copy_request : 1; - // If set, the effect node tries to not trigger a render surface due to it - // having a rounded corner. - bool is_fast_rounded_corner : 1; // If the node or it's parent has the filters, it sets to true. bool node_or_ancestor_has_filters : 1; // All node in the subtree starting from the containing render surface, and
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 4d646ef..49e9d29 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -1053,9 +1053,9 @@ viz::SharedQuadState* shared_quad_state = target_render_pass->CreateAndAppendSharedQuadState(); shared_quad_state->SetAll(gfx::Transform(), root_target_rect, - root_target_rect, gfx::RRectF(), root_target_rect, - false, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, sorting_context_id); + root_target_rect, gfx::MaskFilterInfo(), + root_target_rect, false, are_contents_opaque, + opacity, SkBlendMode::kSrcOver, sorting_context_id); for (gfx::Rect screen_space_rect : fill_region) { gfx::Rect visible_screen_space_rect = screen_space_rect;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index fa6ac027..99ed46b5f 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -18117,8 +18117,8 @@ // Add rounded corners to the layer, which are unable to be hit tested by the // simple quad-based logic. - CreateEffectNode(rounded_frame_layer).rounded_corner_bounds = - gfx::RRectF(25, 25, 50, 50, 5); + CreateEffectNode(rounded_frame_layer).mask_filter_info = + gfx::MaskFilterInfo(gfx::RRectF(25, 25, 50, 50, 5), false); UpdateDrawProperties(host_impl_->active_tree());
diff --git a/cc/trees/occlusion_tracker.cc b/cc/trees/occlusion_tracker.cc index 7a6bf206..b3ed41e 100644 --- a/cc/trees/occlusion_tracker.cc +++ b/cc/trees/occlusion_tracker.cc
@@ -350,7 +350,7 @@ if (layer->Is3dSorted()) return; - if (!layer->draw_properties().rounded_corner_bounds.IsEmpty()) + if (!layer->draw_properties().mask_filter_info.IsEmpty()) return; SimpleEnclosedRegion opaque_layer_region = layer->VisibleOpaqueRegion();
diff --git a/cc/trees/occlusion_tracker_unittest.cc b/cc/trees/occlusion_tracker_unittest.cc index c2dafbd..9f347c7b 100644 --- a/cc/trees/occlusion_tracker_unittest.cc +++ b/cc/trees/occlusion_tracker_unittest.cc
@@ -924,8 +924,8 @@ filters.Append(FilterOperation::CreateOpacityFilter(0.5f)); GetEffectNode(opacity_layer)->filters = filters; - CreateEffectNode(rounded_corner_layer).rounded_corner_bounds = - gfx::RRectF(1, 2, 3, 4, 5, 6); + CreateEffectNode(rounded_corner_layer).mask_filter_info = + gfx::MaskFilterInfo(gfx::RRectF(1, 2, 3, 4, 5, 6), false); this->CalcDrawEtc(); EXPECT_TRUE(rounded_corner_layer->contributes_to_drawn_render_surface());
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc index a4a770d1..c188896f 100644 --- a/cc/trees/property_tree.cc +++ b/cc/trees/property_tree.cc
@@ -1137,7 +1137,7 @@ const EffectNode* effect_node = Node(effect_id); for (; effect_node->id != kContentsRootNodeId; effect_node = Node(effect_node->parent_id)) { - if (!effect_node->rounded_corner_bounds.IsEmpty() || + if (!effect_node->mask_filter_info.IsEmpty() || effect_node->has_masking_child) return true; }
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc index ab2eb2f..3a4b6cf 100644 --- a/cc/trees/property_tree_builder.cc +++ b/cc/trees/property_tree_builder.cc
@@ -7,7 +7,9 @@ #include <stddef.h> #include <map> +#include <memory> #include <set> +#include <utility> #include "base/auto_reset.h" #include "cc/base/math_util.h" @@ -165,10 +167,6 @@ !layer->clip_rect().IsEmpty(); } -gfx::RRectF RoundedCornerBounds(Layer* layer) { - return gfx::RRectF(layer->EffectiveClipRect(), layer->corner_radii()); -} - void PropertyTreeBuilderContext::AddClipNodeIfNeeded( const DataForRecursion& data_from_ancestor, Layer* layer, @@ -491,8 +489,9 @@ // This is currently in the local space of the layer and hence in an invalid // space. Once we have the associated transform node for this effect node, // we will update this to the transform node's coordinate space. - node->rounded_corner_bounds = RoundedCornerBounds(layer); - node->is_fast_rounded_corner = layer->is_fast_rounded_corner(); + node->mask_filter_info = + gfx::MaskFilterInfo(layer->EffectiveClipRect(), layer->corner_radii(), + layer->is_fast_rounded_corner()); } if (!is_root) { @@ -557,7 +556,8 @@ EffectNode* effect_node = effect_tree_.Node(data_for_children->effect_tree_parent); - const bool has_rounded_corner = !effect_node->rounded_corner_bounds.IsEmpty(); + const bool has_rounded_corner = + effect_node->mask_filter_info.HasRoundedCorners(); // Having a rounded corner should trigger a transform node. if (has_rounded_corner)
diff --git a/cc/trees/property_tree_builder_unittest.cc b/cc/trees/property_tree_builder_unittest.cc index 243de40..9e8baa2 100644 --- a/cc/trees/property_tree_builder_unittest.cc +++ b/cc/trees/property_tree_builder_unittest.cc
@@ -859,7 +859,8 @@ // Since this effect node has no descendants that draw and no descendant that // has a rounded corner, it does not need a render surface. const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); - gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; + gfx::RRectF rounded_corner_bounds_1 = + effect_node->mask_filter_info.rounded_corner_bounds(); EXPECT_FALSE(effect_node->HasRenderSurface()); EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), kRoundedCorner1Radius); @@ -869,7 +870,8 @@ // Since this node has descendants with roudned corners, it needs a render // surface. It also has 2 descendants that draw. effect_node = GetEffectNode(rounded_corner_layer_2.get()); - gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; + gfx::RRectF rounded_corner_bounds_2 = + effect_node->mask_filter_info.rounded_corner_bounds(); EXPECT_TRUE(effect_node->HasRenderSurface()); EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), kRoundedCorner2Radius); @@ -879,7 +881,8 @@ // Since this node has a descendant that has a rounded corner, it will trigger // the creation of a render surface. effect_node = GetEffectNode(rounded_corner_layer_3.get()); - gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds; + gfx::RRectF rounded_corner_bounds_3 = + effect_node->mask_filter_info.rounded_corner_bounds(); EXPECT_TRUE(effect_node->HasRenderSurface()); EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(), kRoundedCorner3Radius); @@ -889,7 +892,8 @@ // Since this node has no descendants that draw nor any descendant that has a // rounded corner, it does not need a render surface. effect_node = GetEffectNode(rounded_corner_layer_4.get()); - gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds; + gfx::RRectF rounded_corner_bounds_4 = + effect_node->mask_filter_info.rounded_corner_bounds(); EXPECT_FALSE(effect_node->HasRenderSurface()); EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(), kRoundedCorner4Radius); @@ -918,7 +922,8 @@ // scale factor is 1.6 thus giving the target space origin of [24, 24]. The // corner radius is also scaled by a factor of 1.6. const gfx::RRectF actual_rrect_1 = - rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds; + rounded_corner_layer_1_impl->draw_properties() + .mask_filter_info.rounded_corner_bounds(); gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; bounds_in_target_space.Scale(kDeviceScale); EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space); @@ -931,13 +936,16 @@ // scale factor is 1.6 thus giving the target space origin of [64, 64]. The // corner radius is also scaled by a factor of 1.6. const gfx::RRectF actual_self_rrect_2 = - rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds; + rounded_corner_layer_2_impl->draw_properties() + .mask_filter_info.rounded_corner_bounds(); EXPECT_TRUE(actual_self_rrect_2.IsEmpty()); bounds_in_target_space = kRoundedCornerLayer2Bound; bounds_in_target_space.Scale(kDeviceScale); const gfx::RRectF actual_render_target_rrect_2 = - rounded_corner_layer_2_impl->render_target()->rounded_corner_bounds(); + rounded_corner_layer_2_impl->render_target() + ->mask_filter_info() + .rounded_corner_bounds(); EXPECT_EQ(actual_render_target_rrect_2.rect(), bounds_in_target_space); EXPECT_FLOAT_EQ(actual_render_target_rrect_2.GetSimpleRadius(), kRoundedCorner2Radius * kDeviceScale); @@ -948,7 +956,8 @@ // device scale factor is 1.6 thus giving the target space origin of [64, 88]. // The corner radius is also scaled by a factor of 1.6 * transform scale. const gfx::RRectF actual_self_rrect_3 = - rounded_corner_layer_3_impl->draw_properties().rounded_corner_bounds; + rounded_corner_layer_3_impl->draw_properties() + .mask_filter_info.rounded_corner_bounds(); EXPECT_TRUE(actual_self_rrect_3.IsEmpty()); bounds_in_target_space = kRoundedCornerLayer3Bound; @@ -960,7 +969,9 @@ bounds_in_target_space.set_size(transformed_size); const gfx::RRectF actual_render_target_rrect_3 = - rounded_corner_layer_3_impl->render_target()->rounded_corner_bounds(); + rounded_corner_layer_3_impl->render_target() + ->mask_filter_info() + .rounded_corner_bounds(); EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space); EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(), kRoundedCorner3Radius * kDeviceScale * kRoundedCorner3Scale); @@ -972,7 +983,8 @@ // rigin of [3.2, 3.2]. // The corner radius is also scaled by a factor of 3.2. const gfx::RRectF actual_rrect_4 = - rounded_corner_layer_4_impl->draw_properties().rounded_corner_bounds; + rounded_corner_layer_4_impl->draw_properties() + .mask_filter_info.rounded_corner_bounds(); bounds_in_target_space = kRoundedCornerLayer4Bound; bounds_in_target_space.Scale(kDeviceScale * kRoundedCorner3Scale); EXPECT_EQ(actual_rrect_4.rect(), bounds_in_target_space); @@ -1042,7 +1054,8 @@ // that has a rounded corner before the render surface, it does not need a // render surface. const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); - gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; + gfx::RRectF rounded_corner_bounds_1 = + effect_node->mask_filter_info.rounded_corner_bounds(); EXPECT_FALSE(effect_node->HasRenderSurface()); EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), kRoundedCorner1Radius); @@ -1052,7 +1065,8 @@ // Since this effect node has no descendants that draw and no descendant that // has a rounded corner, it does not need a render surface. effect_node = GetEffectNode(rounded_corner_layer_2.get()); - gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; + gfx::RRectF rounded_corner_bounds_2 = + effect_node->mask_filter_info.rounded_corner_bounds(); EXPECT_FALSE(effect_node->HasRenderSurface()); EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), kRoundedCorner2Radius); @@ -1077,7 +1091,8 @@ // scale factor is 1.6 thus giving the target space origin of [96, 0]. The // corner radius is also scaled by a factor of 1.6. const gfx::RRectF actual_rrect_1 = - rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds; + rounded_corner_layer_1_impl->draw_properties() + .mask_filter_info.rounded_corner_bounds(); gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; bounds_in_target_space.Scale(kDeviceScale); EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space); @@ -1088,7 +1103,8 @@ // The render target for this layer is |render_surface|. // The offset from the origin of the render target is [0, 0]. const gfx::RRectF actual_rrect_2 = - rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds; + rounded_corner_layer_2_impl->draw_properties() + .mask_filter_info.rounded_corner_bounds(); bounds_in_target_space = kRoundedCornerLayer2Bound; bounds_in_target_space.Scale(kDeviceScale); EXPECT_EQ(actual_rrect_2.rect(), bounds_in_target_space); @@ -1157,7 +1173,8 @@ // Since this effect node has 1 descendant with a rounded corner without a // render surface along the chain, it need a render surface. const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); - gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; + gfx::RRectF rounded_corner_bounds_1 = + effect_node->mask_filter_info.rounded_corner_bounds(); EXPECT_TRUE(effect_node->HasRenderSurface()); EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), kRoundedCorner1Radius); @@ -1167,7 +1184,8 @@ // Since this effect node has no descendants that draw and no descendant that // has a rounded corner, it does not need a render surface. effect_node = GetEffectNode(rounded_corner_layer_2.get()); - gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; + gfx::RRectF rounded_corner_bounds_2 = + effect_node->mask_filter_info.rounded_corner_bounds(); EXPECT_FALSE(effect_node->HasRenderSurface()); EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), kRoundedCorner2Radius); @@ -1192,13 +1210,16 @@ // scale factor is 1.6 thus giving the target space origin of [0, 96]. The // corner radius is also scaled by a factor of 1.6. const gfx::RRectF actual_self_rrect_1 = - rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds; + rounded_corner_layer_1_impl->draw_properties() + .mask_filter_info.rounded_corner_bounds(); EXPECT_TRUE(actual_self_rrect_1.IsEmpty()); gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; bounds_in_target_space.Scale(kDeviceScale); const gfx::RRectF actual_render_target_rrect_1 = - rounded_corner_layer_1_impl->render_target()->rounded_corner_bounds(); + rounded_corner_layer_1_impl->render_target() + ->mask_filter_info() + .rounded_corner_bounds(); EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space); EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(), kRoundedCorner1Radius * kDeviceScale); @@ -1207,7 +1228,8 @@ // The render target for this layer is |render_surface|. // The offset from the origin of the render target is [0, 0]. const gfx::RRectF actual_rrect_2 = - rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds; + rounded_corner_layer_2_impl->draw_properties() + .mask_filter_info.rounded_corner_bounds(); bounds_in_target_space = kRoundedCornerLayer2Bound; bounds_in_target_space.Scale(kDeviceScale); EXPECT_EQ(actual_rrect_2.rect(), bounds_in_target_space); @@ -1297,9 +1319,10 @@ // surface even though it has 2 layers in the subtree that draws content. const EffectNode* effect_node = GetEffectNode(fast_rounded_corner_layer.get()); - gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; + gfx::RRectF rounded_corner_bounds_1 = + effect_node->mask_filter_info.rounded_corner_bounds(); EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_TRUE(effect_node->is_fast_rounded_corner); + EXPECT_TRUE(effect_node->mask_filter_info.is_fast_rounded_corner()); EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), kRoundedCorner1Radius); EXPECT_EQ(rounded_corner_bounds_1.rect(), @@ -1307,9 +1330,10 @@ // Since this node has 2 descendants that draw, it will have a rounded corner. effect_node = GetEffectNode(rounded_corner_layer.get()); - gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; + gfx::RRectF rounded_corner_bounds_2 = + effect_node->mask_filter_info.rounded_corner_bounds(); EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FALSE(effect_node->mask_filter_info.is_fast_rounded_corner()); EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), kRoundedCorner2Radius); EXPECT_EQ(rounded_corner_bounds_2.rect(), @@ -1336,7 +1360,8 @@ // The offset from the origin of the render target is [0, 0] and the device // scale factor is 1.6. const gfx::RRectF actual_rrect_1 = - fast_rounded_corner_layer_impl->draw_properties().rounded_corner_bounds; + fast_rounded_corner_layer_impl->draw_properties() + .mask_filter_info.rounded_corner_bounds(); gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; bounds_in_target_space.Scale(kDeviceScale); EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space); @@ -1347,9 +1372,9 @@ // This should have the same rounded corner boudns as fast rounded corner // layer. const gfx::RRectF layer_1_rrect = - layer_1_impl->draw_properties().rounded_corner_bounds; + layer_1_impl->draw_properties().mask_filter_info.rounded_corner_bounds(); const gfx::RRectF layer_2_rrect = - layer_2_impl->draw_properties().rounded_corner_bounds; + layer_2_impl->draw_properties().mask_filter_info.rounded_corner_bounds(); EXPECT_EQ(actual_rrect_1, layer_1_rrect); EXPECT_EQ(actual_rrect_1, layer_2_rrect); @@ -1359,13 +1384,16 @@ // scale factor is 1.6 thus giving the target space origin of [64, 64]. The // corner radius is also scaled by a factor of 1.6. const gfx::RRectF actual_self_rrect_2 = - rounded_corner_layer_impl->draw_properties().rounded_corner_bounds; + rounded_corner_layer_impl->draw_properties() + .mask_filter_info.rounded_corner_bounds(); EXPECT_TRUE(actual_self_rrect_2.IsEmpty()); bounds_in_target_space = kRoundedCornerLayer2Bound; bounds_in_target_space.Scale(kDeviceScale); const gfx::RRectF actual_render_target_rrect_2 = - rounded_corner_layer_impl->render_target()->rounded_corner_bounds(); + rounded_corner_layer_impl->render_target() + ->mask_filter_info() + .rounded_corner_bounds(); EXPECT_EQ(actual_render_target_rrect_2.rect(), bounds_in_target_space); EXPECT_FLOAT_EQ(actual_render_target_rrect_2.GetSimpleRadius(), kRoundedCorner2Radius * kDeviceScale); @@ -1373,9 +1401,9 @@ // Layer 3 and layer 4 should have no rounded corner bounds set as their // parent is a render surface. const gfx::RRectF layer_3_rrect = - layer_3_impl->draw_properties().rounded_corner_bounds; + layer_3_impl->draw_properties().mask_filter_info.rounded_corner_bounds(); const gfx::RRectF layer_4_rrect = - layer_4_impl->draw_properties().rounded_corner_bounds; + layer_4_impl->draw_properties().mask_filter_info.rounded_corner_bounds(); EXPECT_TRUE(layer_3_rrect.IsEmpty()); EXPECT_TRUE(layer_4_rrect.IsEmpty()); } @@ -1462,9 +1490,10 @@ // Since this layer has a descendant that has rounded corner, this node will // require a render surface. const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); - gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; + gfx::RRectF rounded_corner_bounds_1 = + effect_node->mask_filter_info.rounded_corner_bounds(); EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FALSE(effect_node->mask_filter_info.is_fast_rounded_corner()); EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), kRoundedCorner1Radius); EXPECT_EQ(rounded_corner_bounds_1.rect(), @@ -1473,9 +1502,10 @@ // Since this layer has no descendant with rounded corner or drawable, it will // not have a render surface. effect_node = GetEffectNode(fast_rounded_corner_layer_2.get()); - gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; + gfx::RRectF rounded_corner_bounds_2 = + effect_node->mask_filter_info.rounded_corner_bounds(); EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_TRUE(effect_node->is_fast_rounded_corner); + EXPECT_TRUE(effect_node->mask_filter_info.is_fast_rounded_corner()); EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), kRoundedCorner2Radius); EXPECT_EQ(rounded_corner_bounds_2.rect(), @@ -1484,9 +1514,10 @@ // Since this layer has 1 descendant with a rounded corner, it should have a // render surface. effect_node = GetEffectNode(rounded_corner_layer_3.get()); - gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds; + gfx::RRectF rounded_corner_bounds_3 = + effect_node->mask_filter_info.rounded_corner_bounds(); EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FALSE(effect_node->mask_filter_info.is_fast_rounded_corner()); EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(), kRoundedCorner3Radius); EXPECT_EQ(rounded_corner_bounds_3.rect(), @@ -1494,9 +1525,10 @@ // Since this layer no descendants, it would no thave a render pass. effect_node = GetEffectNode(rounded_corner_layer_4.get()); - gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds; + gfx::RRectF rounded_corner_bounds_4 = + effect_node->mask_filter_info.rounded_corner_bounds(); EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FALSE(effect_node->mask_filter_info.is_fast_rounded_corner()); EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(), kRoundedCorner4Radius); EXPECT_EQ(rounded_corner_bounds_4.rect(), @@ -1523,13 +1555,16 @@ // The offset from the origin of the render target is [5, 5] and the device // scale factor is 1.6 giving a total offset of [8, 8]. const gfx::RRectF actual_self_rrect_1 = - rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds; + rounded_corner_layer_impl_1->draw_properties() + .mask_filter_info.rounded_corner_bounds(); EXPECT_TRUE(actual_self_rrect_1.IsEmpty()); gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; bounds_in_target_space.Scale(kDeviceScale); const gfx::RRectF actual_render_target_rrect_1 = - rounded_corner_layer_impl_1->render_target()->rounded_corner_bounds(); + rounded_corner_layer_impl_1->render_target() + ->mask_filter_info() + .rounded_corner_bounds(); EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space); EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(), kRoundedCorner1Radius * kDeviceScale); @@ -1539,7 +1574,8 @@ // The offset from the origin of the render target is [0, 0] and the device // scale factor is 1.6. The corner radius is also scaled by a factor of 1.6. const gfx::RRectF actual_self_rrect_2 = - fast_rounded_corner_layer_impl_2->draw_properties().rounded_corner_bounds; + fast_rounded_corner_layer_impl_2->draw_properties() + .mask_filter_info.rounded_corner_bounds(); bounds_in_target_space = kRoundedCornerLayer2Bound; bounds_in_target_space.Scale(kDeviceScale); EXPECT_EQ(actual_self_rrect_2.rect(), bounds_in_target_space); @@ -1552,13 +1588,16 @@ // scale factor is 1.6 thus giving the target space origin of [64, 64]. The // corner radius is also scaled by a factor of 1.6. const gfx::RRectF actual_self_rrect_3 = - rounded_corner_layer_impl_3->draw_properties().rounded_corner_bounds; + rounded_corner_layer_impl_3->draw_properties() + .mask_filter_info.rounded_corner_bounds(); EXPECT_TRUE(actual_self_rrect_3.IsEmpty()); bounds_in_target_space = kRoundedCornerLayer3Bound; bounds_in_target_space.Scale(kDeviceScale); const gfx::RRectF actual_render_target_rrect_3 = - rounded_corner_layer_impl_3->render_target()->rounded_corner_bounds(); + rounded_corner_layer_impl_3->render_target() + ->mask_filter_info() + .rounded_corner_bounds(); EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space); EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(), kRoundedCorner3Radius * kDeviceScale); @@ -1569,7 +1608,8 @@ // scale factor is 1.6 thus giving the target space origin of [48, 0]. The // corner radius is also scaled by a factor of 1.6. const gfx::RRectF actual_self_rrect_4 = - rounded_corner_layer_impl_4->draw_properties().rounded_corner_bounds; + rounded_corner_layer_impl_4->draw_properties() + .mask_filter_info.rounded_corner_bounds(); bounds_in_target_space = kRoundedCornerLayer4Bound; bounds_in_target_space.Scale(kDeviceScale); EXPECT_EQ(actual_self_rrect_4.rect(), bounds_in_target_space); @@ -1658,9 +1698,10 @@ // surface. const EffectNode* effect_node = GetEffectNode(fast_rounded_corner_layer_1.get()); - gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; + gfx::RRectF rounded_corner_bounds_1 = + effect_node->mask_filter_info.rounded_corner_bounds(); EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_TRUE(effect_node->is_fast_rounded_corner); + EXPECT_TRUE(effect_node->mask_filter_info.is_fast_rounded_corner()); EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), kRoundedCorner1Radius); EXPECT_EQ(rounded_corner_bounds_1.rect(), @@ -1669,9 +1710,10 @@ // Since this layer has no descendant with rounded corner or drawable, it will // not have a render surface. effect_node = GetEffectNode(rounded_corner_layer_1.get()); - gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; + gfx::RRectF rounded_corner_bounds_2 = + effect_node->mask_filter_info.rounded_corner_bounds(); EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FALSE(effect_node->mask_filter_info.is_fast_rounded_corner()); EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), kRoundedCorner2Radius); EXPECT_EQ(rounded_corner_bounds_2.rect(), @@ -1680,9 +1722,10 @@ // Since this layer has a descendant with rounded corner, it should have a // render surface. effect_node = GetEffectNode(rounded_corner_layer_2.get()); - gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds; + gfx::RRectF rounded_corner_bounds_3 = + effect_node->mask_filter_info.rounded_corner_bounds(); EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FALSE(effect_node->mask_filter_info.is_fast_rounded_corner()); EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(), kRoundedCorner3Radius); EXPECT_EQ(rounded_corner_bounds_3.rect(), @@ -1690,9 +1733,10 @@ // Since this layer has no descendant, it does not need a render surface. effect_node = GetEffectNode(rounded_corner_layer_3.get()); - gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds; + gfx::RRectF rounded_corner_bounds_4 = + effect_node->mask_filter_info.rounded_corner_bounds(); EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FALSE(effect_node->mask_filter_info.is_fast_rounded_corner()); EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(), kRoundedCorner4Radius); EXPECT_EQ(rounded_corner_bounds_4.rect(), @@ -1719,14 +1763,16 @@ // The offset from the origin of the render target is [5, 5] and the device // scale factor is 1.6. const gfx::RRectF actual_self_rrect_1 = - fast_rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds; + fast_rounded_corner_layer_impl_1->draw_properties() + .mask_filter_info.rounded_corner_bounds(); EXPECT_TRUE(actual_self_rrect_1.IsEmpty()); gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; bounds_in_target_space.Scale(kDeviceScale); const gfx::RRectF actual_render_target_rrect_1 = fast_rounded_corner_layer_impl_1->render_target() - ->rounded_corner_bounds(); + ->mask_filter_info() + .rounded_corner_bounds(); EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space); EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(), kRoundedCorner1Radius * kDeviceScale); @@ -1736,7 +1782,8 @@ // The offset from the origin of the render target is [0, 0] and the device // scale factor is 1.6. The corner radius is also scaled by a factor of 1.6. const gfx::RRectF actual_self_rrect_2 = - rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds; + rounded_corner_layer_impl_1->draw_properties() + .mask_filter_info.rounded_corner_bounds(); bounds_in_target_space = kRoundedCornerLayer2Bound; bounds_in_target_space.Scale(kDeviceScale); EXPECT_EQ(actual_self_rrect_2.rect(), bounds_in_target_space); @@ -1749,13 +1796,16 @@ // scale factor is 1.6 thus giving the target space origin of [8, 8]. The // corner radius is also scaled by a factor of 1.6. const gfx::RRectF actual_self_rrect_3 = - rounded_corner_layer_impl_2->draw_properties().rounded_corner_bounds; + rounded_corner_layer_impl_2->draw_properties() + .mask_filter_info.rounded_corner_bounds(); EXPECT_TRUE(actual_self_rrect_3.IsEmpty()); bounds_in_target_space = kRoundedCornerLayer3Bound; bounds_in_target_space.Scale(kDeviceScale); const gfx::RRectF actual_render_target_rrect_3 = - rounded_corner_layer_impl_2->render_target()->rounded_corner_bounds(); + rounded_corner_layer_impl_2->render_target() + ->mask_filter_info() + .rounded_corner_bounds(); EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space); EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(), kRoundedCorner3Radius * kDeviceScale); @@ -1766,7 +1816,8 @@ // scale factor is 1.6 thus giving the target space origin of [0, 8]. The // corner radius is also scaled by a factor of 1.6. const gfx::RRectF actual_self_rrect_4 = - rounded_corner_layer_impl_3->draw_properties().rounded_corner_bounds; + rounded_corner_layer_impl_3->draw_properties() + .mask_filter_info.rounded_corner_bounds(); bounds_in_target_space = kRoundedCornerLayer4Bound; bounds_in_target_space.Scale(kDeviceScale); EXPECT_EQ(actual_self_rrect_4.rect(), bounds_in_target_space);
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index 6571383c..d497a5e 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -1369,6 +1369,10 @@ ] } + if (is_linux || is_chromeos) { + public_deps += [ "//chrome/browser/resources:webui_js_exception_resources" ] + } + if (!is_android && !is_chromeos) { public_deps += [ "//chrome/browser/resources:profile_picker_resources",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 760e114..72685ff2 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -208,6 +208,7 @@ "java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/sharing/TwaSharingController.java", "java/src/org/chromium/chrome/browser/browserservices/ui/SharedActivityCoordinator.java", "java/src/org/chromium/chrome/browser/browserservices/ui/controller/CurrentPageVerifier.java", + "java/src/org/chromium/chrome/browser/browserservices/ui/controller/DisclosureController.java", "java/src/org/chromium/chrome/browser/browserservices/ui/controller/EmptyVerifier.java", "java/src/org/chromium/chrome/browser/browserservices/ui/controller/Verifier.java", "java/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/ClientAppDataRecorder.java",
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayIntegrationTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayIntegrationTest.java index 40de2ae..1f000ba 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayIntegrationTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayIntegrationTest.java
@@ -6,6 +6,7 @@ import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; +import static androidx.test.espresso.assertion.ViewAssertions.matches; import static androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription; import static androidx.test.espresso.matcher.ViewMatchers.withText; @@ -15,12 +16,15 @@ import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.checkElementExists; import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.checkElementOnScreen; +import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.getBitmapFromView; import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.startAutofillAssistant; import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.tapElement; import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntil; import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntilViewMatchesCondition; import android.support.test.InstrumentationRegistry; +import android.view.View; +import android.view.ViewGroup; import androidx.test.filters.MediumTest; @@ -30,13 +34,19 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.chrome.autofill_assistant.R; import org.chromium.chrome.browser.autofill_assistant.proto.ActionProto; +import org.chromium.chrome.browser.autofill_assistant.proto.BitmapDrawableProto; import org.chromium.chrome.browser.autofill_assistant.proto.ChipProto; +import org.chromium.chrome.browser.autofill_assistant.proto.ClientDimensionProto; +import org.chromium.chrome.browser.autofill_assistant.proto.ClientSettingsProto; import org.chromium.chrome.browser.autofill_assistant.proto.ConfigureUiStateProto; import org.chromium.chrome.browser.autofill_assistant.proto.ConfigureUiStateProto.OverlayBehavior; +import org.chromium.chrome.browser.autofill_assistant.proto.DrawableProto; import org.chromium.chrome.browser.autofill_assistant.proto.ElementAreaProto; import org.chromium.chrome.browser.autofill_assistant.proto.ElementAreaProto.Rectangle; import org.chromium.chrome.browser.autofill_assistant.proto.FocusElementProto; +import org.chromium.chrome.browser.autofill_assistant.proto.OverlayImageProto; import org.chromium.chrome.browser.autofill_assistant.proto.PromptProto; import org.chromium.chrome.browser.autofill_assistant.proto.PromptProto.Choice; import org.chromium.chrome.browser.autofill_assistant.proto.SelectorProto; @@ -432,6 +442,61 @@ assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_four"), is(true)); } + /** + * Tests that an image works with an overlay + */ + @Test + @MediumTest + public void testShowImageOnOverlay() throws Exception { + String redDotBase64Url = + "data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; + int imageSize = 50; + ClientSettingsProto clientSettings = + (ClientSettingsProto) ClientSettingsProto.newBuilder() + .setOverlayImage( + OverlayImageProto.newBuilder() + .setImageDrawable(DrawableProto.newBuilder().setBitmap( + BitmapDrawableProto.newBuilder() + .setUrl(redDotBase64Url) + .setWidth(ClientDimensionProto.newBuilder() + .setDp(imageSize)) + .setHeight(ClientDimensionProto.newBuilder() + .setDp(imageSize)))) + .setImageSize( + ClientDimensionProto.newBuilder().setDp(imageSize))) + .build(); + + AutofillAssistantTestScript script = new AutofillAssistantTestScript( + (SupportedScriptProto) SupportedScriptProto.newBuilder() + .setPath("autofill_assistant_target_website.html") + .setPresentation(PresentationProto.newBuilder().setAutostart(true).setChip( + ChipProto.newBuilder().setText("Done"))) + .build(), + new ArrayList<>()); + AutofillAssistantTestService testService = + new AutofillAssistantTestService(Collections.singletonList(script), clientSettings); + startAutofillAssistant(mTestRule.getActivity(), testService); + + ViewGroup chromeCoordinatorView = mTestRule.getActivity().findViewById(R.id.coordinator); + View scrim = mTestRule.getActivity() + .getRootUiCoordinatorForTesting() + .getScrimCoordinator() + .getViewForTesting(); + + onView(is(scrim)).check(matches(isCompletelyDisplayed())); + int image_center_x = scrim.getWidth() / 2; + int yTopContentOffset = mTestRule.getActivity() + .getRootUiCoordinatorForTesting() + .getBrowserControlsManager() + .getContentOffset(); + int image_center_y = yTopContentOffset + imageSize / 2; + + // Testing that central pixel of overlay image is different from (0,0) pixel + waitUntil(() + -> getBitmapFromView(scrim).getPixel(image_center_x, image_center_y) + != getBitmapFromView(scrim).getPixel(0, 0)); + } + private void runScript(AutofillAssistantTestScript script) { AutofillAssistantTestService testService = new AutofillAssistantTestService(Collections.singletonList(script));
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java index 7a9e736..b97e0ea 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java
@@ -12,6 +12,7 @@ import android.content.Context; import android.graphics.Bitmap; +import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.Typeface; import android.graphics.drawable.ColorDrawable; @@ -718,6 +719,22 @@ return result.getString(0); } + /** + * Converts a view into a bitmap. + */ + public static Bitmap getBitmapFromView(View view) { + Bitmap resultBitmap = + Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888); + Drawable backgroundDrawable = view.getBackground(); + if (backgroundDrawable == null) { + return resultBitmap; + } + Canvas canvas = new Canvas(resultBitmap); + backgroundDrawable.draw(canvas); + view.draw(canvas); + return resultBitmap; + } + private static String getElementSelectorString(String[] elementIds) { StringBuilder builder = new StringBuilder(); builder.append("document");
diff --git a/chrome/android/features/cablev2_authenticator/java/src/org/chromium/chrome/browser/webauth/authenticator/CableAuthenticatorUI.java b/chrome/android/features/cablev2_authenticator/java/src/org/chromium/chrome/browser/webauth/authenticator/CableAuthenticatorUI.java index e099c99..eab2cfe4 100644 --- a/chrome/android/features/cablev2_authenticator/java/src/org/chromium/chrome/browser/webauth/authenticator/CableAuthenticatorUI.java +++ b/chrome/android/features/cablev2_authenticator/java/src/org/chromium/chrome/browser/webauth/authenticator/CableAuthenticatorUI.java
@@ -173,8 +173,8 @@ } @Override - public void onDestroy() { - super.onDestroy(); + public void onStop() { + super.onStop(); mAuthenticator.close(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/DisclosureController.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/DisclosureController.java new file mode 100644 index 0000000..8a739871 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/DisclosureController.java
@@ -0,0 +1,96 @@ +// 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.browserservices.ui.controller; + +import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_EVENTS_CALLBACK; +import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_FIRST_TIME; +import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_SCOPE; +import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_STATE; +import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_STATE_DISMISSED_BY_USER; +import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_STATE_NOT_SHOWN; +import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_STATE_SHOWN; +import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.PACKAGE_NAME; + +import androidx.annotation.CallSuper; +import androidx.annotation.Nullable; + +import org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel; +import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; +import org.chromium.chrome.browser.lifecycle.NativeInitObserver; + +/** + * Contains common implementation between WebappDisclosureController and + * TrustedWebActivityDisclosureController. + */ +public abstract class DisclosureController + implements NativeInitObserver, TrustedWebActivityModel.DisclosureEventsCallback { + private final TrustedWebActivityModel mModel; + + public DisclosureController(TrustedWebActivityModel model, + ActivityLifecycleDispatcher lifecycleDispatcher, String packageName) { + mModel = model; + + model.set(DISCLOSURE_EVENTS_CALLBACK, this); + model.set(PACKAGE_NAME, packageName); + + lifecycleDispatcher.register(this); + } + + @Override + public void onFinishNativeInitialization() { + // We want to show disclosure ASAP, which is limited by SnackbarManager requiring + // native. + if (shouldShowInCurrentState()) { + showIfNeeded(); + } + } + + @Override + @CallSuper + public void onDisclosureAccepted() { + mModel.set(DISCLOSURE_STATE, DISCLOSURE_STATE_DISMISSED_BY_USER); + } + + @Override + @CallSuper + public void onDisclosureShown() { + mModel.set(DISCLOSURE_FIRST_TIME, false); + } + + protected boolean shouldShowInCurrentState() { + return false; + } + + /** Shows the disclosure if it is not already showing and hasn't been accepted. */ + protected void showIfNeeded() { + if (!isShowing() && shouldShowDisclosure()) { + showDisclosure(); + } + } + + protected abstract boolean shouldShowDisclosure(); + + /** Is this the first time the user has seen the disclosure? */ + protected abstract boolean isFirstTime(); + + protected void showDisclosure() { + mModel.set(DISCLOSURE_FIRST_TIME, isFirstTime()); + mModel.set(DISCLOSURE_STATE, DISCLOSURE_STATE_SHOWN); + } + + /** Dismisses the disclosure if it is showing. */ + protected void dismiss() { + if (isShowing()) { + mModel.set(DISCLOSURE_STATE, DISCLOSURE_STATE_NOT_SHOWN); + } + } + protected boolean isShowing() { + return mModel.get(DISCLOSURE_STATE) == DISCLOSURE_STATE_SHOWN; + } + + protected void setDisclosureScope(@Nullable String scope) { + mModel.set(DISCLOSURE_SCOPE, scope); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityDisclosureController.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityDisclosureController.java index 6c1c5a6..b122380 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityDisclosureController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityDisclosureController.java
@@ -4,23 +4,14 @@ package org.chromium.chrome.browser.browserservices.ui.controller.trustedwebactivity; -import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_EVENTS_CALLBACK; -import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_FIRST_TIME; -import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_SCOPE; -import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_STATE; -import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_STATE_DISMISSED_BY_USER; -import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_STATE_NOT_SHOWN; -import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_STATE_SHOWN; -import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.PACKAGE_NAME; - import org.chromium.chrome.browser.browserservices.BrowserServicesStore; import org.chromium.chrome.browser.browserservices.TrustedWebActivityUmaRecorder; import org.chromium.chrome.browser.browserservices.ui.controller.CurrentPageVerifier; import org.chromium.chrome.browser.browserservices.ui.controller.CurrentPageVerifier.VerificationState; import org.chromium.chrome.browser.browserservices.ui.controller.CurrentPageVerifier.VerificationStatus; +import org.chromium.chrome.browser.browserservices.ui.controller.DisclosureController; import org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; -import org.chromium.chrome.browser.lifecycle.NativeInitObserver; import javax.inject.Inject; @@ -28,10 +19,8 @@ * Controls when Trusted Web Activity disclosure should be shown and hidden, reacts to interaction * with it. */ -public class TrustedWebActivityDisclosureController - implements NativeInitObserver, TrustedWebActivityModel.DisclosureEventsCallback { +public class TrustedWebActivityDisclosureController extends DisclosureController { private final BrowserServicesStore mBrowserServicesStore; - private final TrustedWebActivityModel mModel; private final CurrentPageVerifier mCurrentPageVerifier; private final TrustedWebActivityUmaRecorder mRecorder; private final ClientPackageNameProvider mClientPackageNameProvider; @@ -41,23 +30,20 @@ TrustedWebActivityModel model, ActivityLifecycleDispatcher lifecycleDispatcher, CurrentPageVerifier currentPageVerifier, TrustedWebActivityUmaRecorder recorder, ClientPackageNameProvider clientPackageNameProvider) { + super(model, lifecycleDispatcher, clientPackageNameProvider.get()); mBrowserServicesStore = browserServicesStore; - mModel = model; mCurrentPageVerifier = currentPageVerifier; mRecorder = recorder; mClientPackageNameProvider = clientPackageNameProvider; - model.set(DISCLOSURE_EVENTS_CALLBACK, this); - model.set(PACKAGE_NAME, mClientPackageNameProvider.get()); currentPageVerifier.addVerificationObserver(this::onVerificationStatusChanged); - lifecycleDispatcher.register(this); } private void onVerificationStatusChanged() { if (shouldShowInCurrentState()) { - mModel.set(DISCLOSURE_SCOPE, mCurrentPageVerifier.getState().scope); + setDisclosureScope(mCurrentPageVerifier.getState().scope); showIfNeeded(); } else { - mModel.set(DISCLOSURE_SCOPE, null); + setDisclosureScope(null); dismiss(); } } @@ -67,57 +53,32 @@ mRecorder.recordDisclosureAccepted(); mBrowserServicesStore.setUserAcceptedTwaDisclosureForPackage( mClientPackageNameProvider.get()); - mModel.set(DISCLOSURE_STATE, DISCLOSURE_STATE_DISMISSED_BY_USER); + super.onDisclosureAccepted(); } @Override public void onDisclosureShown() { + mRecorder.recordDisclosureShown(); mBrowserServicesStore.setUserSeenTwaDisclosureForPackage(mClientPackageNameProvider.get()); - mModel.set(DISCLOSURE_FIRST_TIME, false); + super.onDisclosureShown(); } - /** Shows the disclosure if it is not already showing and hasn't been accepted. */ - private void showIfNeeded() { - if (!isShowing() && !wasDismissed()) { - mRecorder.recordDisclosureShown(); - mModel.set(DISCLOSURE_FIRST_TIME, isFirstTime()); - mModel.set(DISCLOSURE_STATE, DISCLOSURE_STATE_SHOWN); - } - } - - /** Dismisses the disclosure if it is showing. */ - private void dismiss() { - if (isShowing()) { - mModel.set(DISCLOSURE_STATE, DISCLOSURE_STATE_NOT_SHOWN); - } - } - - /** Has a disclosure been dismissed for this client package before? */ - private boolean wasDismissed() { - return mBrowserServicesStore.hasUserAcceptedTwaDisclosureForPackage( + @Override + protected boolean shouldShowDisclosure() { + /** Has a disclosure been dismissed for this client package before? */ + return !mBrowserServicesStore.hasUserAcceptedTwaDisclosureForPackage( mClientPackageNameProvider.get()); } - /** Is this the first time the user has seen the disclosure? */ - private boolean isFirstTime() { + @Override + protected boolean isFirstTime() { return !mBrowserServicesStore.hasUserSeenTwaDisclosureForPackage( mClientPackageNameProvider.get()); } @Override - public void onFinishNativeInitialization() { - // We want to show disclosure ASAP, which is limited by SnackbarManager requiring native. - if (shouldShowInCurrentState()) { - showIfNeeded(); - } - } - - private boolean shouldShowInCurrentState() { + protected boolean shouldShowInCurrentState() { VerificationState state = mCurrentPageVerifier.getState(); return state != null && state.status != VerificationStatus.FAILURE; } - - public boolean isShowing() { - return mModel.get(DISCLOSURE_STATE) == DISCLOSURE_STATE_SHOWN; - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/webapps/WebappDisclosureController.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/webapps/WebappDisclosureController.java index 15dba99..7bf3864c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/webapps/WebappDisclosureController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/webapps/WebappDisclosureController.java
@@ -4,24 +4,16 @@ package org.chromium.chrome.browser.browserservices.ui.controller.webapps; -import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_EVENTS_CALLBACK; -import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_STATE; -import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_STATE_DISMISSED_BY_USER; -import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_STATE_SHOWN; -import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.PACKAGE_NAME; - import androidx.annotation.Nullable; import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; +import org.chromium.chrome.browser.browserservices.ui.controller.DisclosureController; import org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel; import org.chromium.chrome.browser.dependency_injection.ActivityScope; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; -import org.chromium.chrome.browser.lifecycle.NativeInitObserver; -import org.chromium.chrome.browser.webapps.WebApkExtras; import org.chromium.chrome.browser.webapps.WebappDataStorage; import org.chromium.chrome.browser.webapps.WebappDeferredStartupWithStorageHandler; -import org.chromium.chrome.browser.webapps.WebappExtras; import org.chromium.chrome.browser.webapps.WebappRegistry; import org.chromium.components.webapk.lib.common.WebApkConstants; @@ -37,26 +29,16 @@ * next time the app is opened if it hasn't been acknowledged. */ @ActivityScope -public class WebappDisclosureController - implements NativeInitObserver, TrustedWebActivityModel.DisclosureEventsCallback { +public class WebappDisclosureController extends DisclosureController { private final BrowserServicesIntentDataProvider mIntentDataProvider; - private final TrustedWebActivityModel mModel; @Inject public WebappDisclosureController(ChromeActivity<?> activity, BrowserServicesIntentDataProvider intentDataProvider, TrustedWebActivityModel model, WebappDeferredStartupWithStorageHandler deferredStartupWithStorageHandler, ActivityLifecycleDispatcher lifecycleDispatcher) { + super(model, lifecycleDispatcher, intentDataProvider.getClientPackageName()); mIntentDataProvider = intentDataProvider; - mModel = model; - - model.set(DISCLOSURE_EVENTS_CALLBACK, this); - WebApkExtras webApkExtras = mIntentDataProvider.getWebApkExtras(); - if (webApkExtras != null && webApkExtras.webApkPackageName != null) { - model.set(PACKAGE_NAME, webApkExtras.webApkPackageName); - } - - lifecycleDispatcher.register(this); deferredStartupWithStorageHandler.addTask((storage, didCreateStorage) -> { if (activity.isActivityFinishingOrDestroyed()) return; @@ -65,76 +47,62 @@ }); } - public void onDeferredStartupWithStorage( + void onDeferredStartupWithStorage( @Nullable WebappDataStorage storage, boolean didCreateStorage) { - if (didCreateStorage) { - // Set force == true to indicate that we need to show a privacy disclosure for the newly + if (didCreateStorage && storage != null) { + // SetShowDisclosure to indicate that we need to show a privacy disclosure for the newly // installed unbound WebAPKs which have no storage yet. We can't simply default to a // showing if the storage has a default value as we don't want to show this disclosure // for pre-existing unbound WebAPKs. - maybeShowDisclosure(storage, true /* force */); - } - } - - @Override - public void onFinishNativeInitialization() { - WebappExtras webappExtras = mIntentDataProvider.getWebappExtras(); - WebappDataStorage storage = WebappRegistry.getInstance().getWebappDataStorage( - mIntentDataProvider.getWebappExtras().id); - if (storage != null) { - maybeShowDisclosure(storage, false /* force */); + storage.setShowDisclosure(); + if (shouldShowInCurrentState()) { + showIfNeeded(); + } } } @Override public void onDisclosureAccepted() { - WebappExtras webappExtras = mIntentDataProvider.getWebappExtras(); WebappDataStorage storage = WebappRegistry.getInstance().getWebappDataStorage( mIntentDataProvider.getWebappExtras().id); - if (storage != null) { - storage.clearShowDisclosure(); - } - mModel.set(DISCLOSURE_STATE, DISCLOSURE_STATE_DISMISSED_BY_USER); - } + assert storage != null; - @Override - public void onDisclosureShown() {} - - /** - * Shows the disclosure informing the user the Webapp is running in Chrome. - * @param storage Storage for the Webapp. - * @param force Whether to force showing the Snackbar (if no storage is available on start). - */ - private void maybeShowDisclosure(WebappDataStorage storage, boolean force) { - if (storage == null) return; - - // If forced we set the bit to show the disclosure. This persists to future instances. - if (force) storage.setShowDisclosure(); - - if (!isShowing() && shouldShowDisclosure(storage)) { - mModel.set(DISCLOSURE_STATE, DISCLOSURE_STATE_SHOWN); - } + storage.clearShowDisclosure(); + super.onDisclosureAccepted(); } /** * Restricts showing to unbound WebAPKs that haven't dismissed the disclosure. - * @param storage Storage for the Webapp. * @return boolean indicating whether to show the privacy disclosure. */ - private boolean shouldShowDisclosure(WebappDataStorage storage) { - // Show only if the correct flag is set. - if (!storage.shouldShowDisclosure()) { + @Override + protected boolean shouldShowDisclosure() { + // Only show disclosure for unbound WebAPKs. + if (mIntentDataProvider.getClientPackageName() == null + || mIntentDataProvider.getClientPackageName().startsWith( + WebApkConstants.WEBAPK_PACKAGE_PREFIX)) { return false; } - // Show for unbound WebAPKs. - WebApkExtras webApkExtras = mIntentDataProvider.getWebApkExtras(); - return webApkExtras != null && webApkExtras.webApkPackageName != null - && !webApkExtras.webApkPackageName.startsWith( - WebApkConstants.WEBAPK_PACKAGE_PREFIX); + WebappDataStorage storage = WebappRegistry.getInstance().getWebappDataStorage( + mIntentDataProvider.getWebappExtras().id); + if (storage == null) return false; + + // Show only if the correct flag is set. + return storage.shouldShowDisclosure(); } - public boolean isShowing() { - return mModel.get(DISCLOSURE_STATE) == DISCLOSURE_STATE_SHOWN; + @Override + protected boolean isFirstTime() { + // TODO(crbug.com/1128675): isFirstTime is used for showing notification disclosure for + // TWAs, not used in Webapk for now. + return false; + } + + @Override + protected boolean shouldShowInCurrentState() { + // TODO(crbug.com/1128675): TWA hides snackbar when move out of verified origin, we should + // do the same for WebApk. + return true; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java index e962c16..fa611a0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
@@ -105,7 +105,7 @@ if (mOverviewLayout != null) { mOverviewLayout.setTabContentManager(manager); } - mTabContentManagerSupplier.removeObserver(this); + tabContentManagerSupplier.removeObserver(this); } });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/homepage/HomepageManager.java b/chrome/android/java/src/org/chromium/chrome/browser/homepage/HomepageManager.java index d477d25..3f30323f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/homepage/HomepageManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/homepage/HomepageManager.java
@@ -12,9 +12,6 @@ import org.chromium.base.ObserverList; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; -import org.chromium.chrome.browser.flags.CachedFeatureFlags; -import org.chromium.chrome.browser.flags.ChromeFeatureList; -import org.chromium.chrome.browser.homepage.settings.HomepageMetricsEnums.HomeButtonPreferenceState; import org.chromium.chrome.browser.homepage.settings.HomepageMetricsEnums.HomepageLocationType; import org.chromium.chrome.browser.ntp.NewTabPage; import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomizations; @@ -175,9 +172,6 @@ */ public void setPrefHomepageEnabled(boolean enabled) { mSharedPreferencesManager.writeBoolean(ChromePreferenceKeys.HOMEPAGE_ENABLED, enabled); - RecordHistogram.recordBooleanHistogram( - "Settings.ShowHomeButtonPreferenceStateChanged", enabled); - recordHomeButtonPreferenceState(); notifyHomepageUpdated(); } @@ -238,7 +232,6 @@ } if (wasUseDefaultUri != useDefaultUri) { - recordHomepageIsCustomized(!useDefaultUri); mSharedPreferencesManager.writeBoolean( ChromePreferenceKeys.HOMEPAGE_USE_DEFAULT_URI, useDefaultUri); } @@ -253,31 +246,6 @@ } /** - * Get the homepage button preference state. - */ - public static void recordHomeButtonPreferenceState() { - if (!CachedFeatureFlags.isEnabled(ChromeFeatureList.HOMEPAGE_LOCATION_POLICY)) { - RecordHistogram.recordBooleanHistogram( - "Settings.ShowHomeButtonPreferenceState", HomepageManager.isHomepageEnabled()); - return; - } - - int state = HomeButtonPreferenceState.USER_DISABLED; - if (HomepagePolicyManager.isHomepageManagedByPolicy()) { - state = HomeButtonPreferenceState.MANAGED_ENABLED; - } else if (isHomepageEnabled()) { - state = HomeButtonPreferenceState.USER_ENABLED; - } - - RecordHistogram.recordEnumeratedHistogram("Settings.ShowHomeButtonPreferenceStateManaged", - state, HomeButtonPreferenceState.NUM_ENTRIES); - } - - public static void recordHomepageIsCustomized(boolean isCustomized) { - RecordHistogram.recordBooleanHistogram("Settings.HomePageIsCustomized", isCustomized); - } - - /** * Record histogram "Settings.Homepage.LocationType" with the current homepage location type. */ public static void recordHomepageLocationTypeIfEnabled() { @@ -320,11 +288,6 @@ @Override public void onHomepagePolicyUpdate() { notifyHomepageUpdated(); - - boolean isPolicyEnabled = HomepagePolicyManager.isHomepageManagedByPolicy(); - if (isPolicyEnabled) { - recordHomepageIsCustomized(false); - } } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/HomepageMetricsEnums.java b/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/HomepageMetricsEnums.java index 2d95728..ea2ce2d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/HomepageMetricsEnums.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/HomepageMetricsEnums.java
@@ -16,25 +16,6 @@ private HomepageMetricsEnums() {} /** - * Possible states for HomeButton. Used for Histogram - * Settings.ShowHomeButtonPreferenceStateManaged. Currently {@link - * HomeButtonPreferenceState.MANAGED_DISABLED } is not used. - * - * These values are persisted to logs, and should therefore never be renumbered nor reused. - */ - @IntDef({HomeButtonPreferenceState.USER_DISABLED, HomeButtonPreferenceState.USER_ENABLED, - HomeButtonPreferenceState.MANAGED_DISABLED, HomeButtonPreferenceState.MANAGED_ENABLED}) - @Retention(RetentionPolicy.SOURCE) - public @interface HomeButtonPreferenceState { - int USER_DISABLED = 0; - int USER_ENABLED = 1; - int MANAGED_DISABLED = 2; - int MANAGED_ENABLED = 3; - - int NUM_ENTRIES = 4; - } - - /** * Possible location type for homepage. Used for Histogram "Settings.Homepage.LocationType" * recorded in {@link HomepageManager#recordHomepageLocationType()}. *
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java index acbdea0..c611668 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java
@@ -342,8 +342,6 @@ deferredStartupHandler.addDeferredTask(new Runnable() { @Override public void run() { - HomepageManager.recordHomeButtonPreferenceState(); - HomepageManager.recordHomepageIsCustomized(HomepageManager.isHomepageCustomized()); HomepageManager.recordHomepageLocationTypeIfEnabled(); } });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java index 143e75e..5ef015b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java
@@ -7,7 +7,6 @@ import android.content.Context; import androidx.annotation.IntDef; -import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import org.chromium.base.metrics.RecordUserAction; @@ -66,8 +65,6 @@ private static final int RECENTLY_CLOSED_MAX_TAB_COUNT = 5; - private static @Nullable @PromoState Integer sPromoStateForTests; - private static RecentlyClosedTabManager sRecentlyClosedTabManagerForTests; private final Profile mProfile; @@ -362,10 +359,6 @@ */ @PromoState int getPromoType() { - if (sPromoStateForTests != null) { - return sPromoStateForTests; - } - if (!mSignInManager.getIdentityManager().hasPrimaryAccount()) { if (!mSignInManager.isSignInAllowed()) { return PromoState.PROMO_NONE; @@ -445,16 +438,6 @@ }); } - /** - * Forces the promo state to a particular value for testing purposes. - * @param promoState The promo state to which the manager will be set to. - * TODO(https://crbug.com/1123478): Create a different method to enforce promo state. - */ - @VisibleForTesting - static void forcePromoStateForTests(@Nullable @PromoState Integer promoState) { - sPromoStateForTests = promoState; - } - @VisibleForTesting public static void setRecentlyClosedTabManagerForTests(RecentlyClosedTabManager manager) { sRecentlyClosedTabManagerForTests = manager;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentAppService.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentAppService.java index 2f2e458..3f514a9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentAppService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentAppService.java
@@ -46,6 +46,12 @@ mFactories.add(factory); } + /** Resets the instance, used by //clank tests. */ + @VisibleForTesting + public void resetForTest() { + sInstance = null; + } + // PaymentAppFactoryInterface implementation. @Override public void create(PaymentAppFactoryDelegate delegate) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialog.java index 4d7b810..0b04684a2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialog.java
@@ -107,22 +107,36 @@ mConfirmImportOption.setRadioButtonGroup(radioGroup); mKeepSeparateOption.setRadioButtonGroup(radioGroup); - SigninManager signinManager = IdentityServicesProvider.get().getSigninManager( - Profile.getLastUsedRegularProfile()); + boolean isManagedAccount = IdentityServicesProvider.get() + .getSigninManager(Profile.getLastUsedRegularProfile()) + .getManagementDomain() + != null; + final AlertDialog alertDialog = + new AlertDialog.Builder(getActivity(), R.style.Theme_Chromium_AlertDialog) + .setPositiveButton(R.string.continue_button, this) + .setNegativeButton(R.string.cancel, this) + .setView(v) + .create(); + // For non-managed accounts, the confirmation button starts out disabled, since none of the + // options are chosen by default. + alertDialog.setOnShowListener(dialog + -> alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(isManagedAccount)); + // If the account is managed, disallow merging information. - if (signinManager.getManagementDomain() != null) { + if (isManagedAccount) { mKeepSeparateOption.setChecked(true); mConfirmImportOption.setOnClickListener( view -> ManagedPreferencesUtils.showManagedByAdministratorToast(getActivity())); } else { - mConfirmImportOption.setChecked(true); + // The confirmation button gets enabled as soon as either of the radio button options + // was selected. + mConfirmImportOption.setOnCheckedChangeListener(radioButton + -> alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true)); + mKeepSeparateOption.setOnCheckedChangeListener(radioButton + -> alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true)); } - return new AlertDialog.Builder(getActivity(), R.style.Theme_Chromium_AlertDialog) - .setPositiveButton(R.string.continue_button, this) - .setNegativeButton(R.string.cancel, this) - .setView(v) - .create(); + return alertDialog; } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountConsistencyPromoAction.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountConsistencyPromoAction.java index 4bbea88f..21ce1ae 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountConsistencyPromoAction.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountConsistencyPromoAction.java
@@ -31,6 +31,7 @@ AccountConsistencyPromoAction.DISMISSED_OTHER, AccountConsistencyPromoAction.AUTH_ERROR_SHOWN, AccountConsistencyPromoAction.GENERIC_ERROR_SHOWN, + AccountConsistencyPromoAction.DISMISSED_BUTTON, }) @Retention(RetentionPolicy.SOURCE) public @interface AccountConsistencyPromoAction { @@ -109,5 +110,10 @@ */ int GENERIC_ERROR_SHOWN = 13; - int MAX = 14; + /** + * User has dismissed the promo by tapping on the dismissal button in the bottom sheet. + */ + int DISMISSED_BUTTON = 14; + + int MAX = 15; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetMediator.java index 415ded2..48673df 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetMediator.java
@@ -7,6 +7,7 @@ import android.accounts.Account; import android.content.Context; import android.text.TextUtils; +import android.view.View.OnClickListener; import androidx.annotation.Nullable; @@ -50,8 +51,13 @@ mProfileDataCache = new ProfileDataCache( context, context.getResources().getDimensionPixelSize(R.dimen.user_picture_size)); - mModel = AccountPickerBottomSheetProperties.createModel(this::onSelectedAccountClicked, - this::onContinueAsClicked, dismissBottomSheetRunnable); + OnClickListener onDismissClicked = v -> { + AccountPickerDelegate.recordAccountConsistencyPromoAction( + AccountConsistencyPromoAction.DISMISSED_BUTTON); + dismissBottomSheetRunnable.run(); + }; + mModel = AccountPickerBottomSheetProperties.createModel( + this::onSelectedAccountClicked, this::onContinueAsClicked, onDismissClicked); mProfileDataCache.addObserver(mProfileDataSourceObserver); mAccountManagerFacade = AccountManagerFacadeProvider.getInstance();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetProperties.java index 2e2e7ade..455e2180 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetProperties.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetProperties.java
@@ -130,12 +130,12 @@ * state {@link ViewState#NO_ACCOUNTS}. */ static PropertyModel createModel(Runnable onSelectedAccountClicked, - Runnable onContinueAsClicked, Runnable onDismissClicked) { + Runnable onContinueAsClicked, OnClickListener onDismissClicked) { return new PropertyModel.Builder(ALL_KEYS) .with(ON_SELECTED_ACCOUNT_CLICKED, v -> onSelectedAccountClicked.run()) .with(SELECTED_ACCOUNT_DATA, null) .with(ON_CONTINUE_AS_CLICKED, v -> onContinueAsClicked.run()) - .with(ON_DISMISS_CLICKED, v -> onDismissClicked.run()) + .with(ON_DISMISS_CLICKED, onDismissClicked) .with(VIEW_STATE, ViewState.NO_ACCOUNTS) .build(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java index 83b9815..24fe0cb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java
@@ -498,16 +498,6 @@ mNativeProfileSyncServiceAndroid, ProfileSyncService.this); } - /** - * Turns on encryption of all data types. This only takes effect after sync configuration is - * completed and setChosenDataTypes() is invoked. - */ - public void enableEncryptEverything() { - assert isEngineInitialized(); - ProfileSyncServiceJni.get().enableEncryptEverything( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this); - } - public void setEncryptionPassphrase(String passphrase) { assert isEngineInitialized(); ProfileSyncServiceJni.get().setEncryptionPassphrase( @@ -675,8 +665,6 @@ long nativeProfileSyncServiceAndroid, ProfileSyncService caller); boolean isTransportStateActive( long nativeProfileSyncServiceAndroid, ProfileSyncService caller); - void enableEncryptEverything( - long nativeProfileSyncServiceAndroid, ProfileSyncService caller); boolean isPassphraseRequiredForPreferredDataTypes( long nativeProfileSyncServiceAndroid, ProfileSyncService caller); boolean isTrustedVaultKeyRequired(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java index 2838a12..c437801 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java
@@ -525,7 +525,6 @@ // If the engine was shut down since the dialog was opened, do nothing. return; } - mProfileSyncService.enableEncryptEverything(); mProfileSyncService.setEncryptionPassphrase(passphrase); // Save the current state of data types - this tells the sync engine to // apply our encryption configuration changes.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java index a6c2c32..ff1412d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java
@@ -11,6 +11,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.NativeMethods; +import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabLaunchType; @@ -214,20 +215,26 @@ private static void flushTabSwitchLatencyMetric(boolean perceived) { if (sTabSwitchStartTime <= 0) return; final long ms = SystemClock.uptimeMillis() - sTabSwitchStartTime; + String baseHistogram; switch (sTabSelectionType) { case TabSelectionType.FROM_CLOSE: - TabModelJniBridgeJni.get().logFromCloseMetric(ms, perceived); + baseHistogram = "Tabs.SwitchFromCloseLatency"; break; case TabSelectionType.FROM_EXIT: - TabModelJniBridgeJni.get().logFromExitMetric(ms, perceived); + baseHistogram = "Tabs.SwitchFromExitLatency"; break; case TabSelectionType.FROM_NEW: - TabModelJniBridgeJni.get().logFromNewMetric(ms, perceived); + baseHistogram = "Tabs.SwitchFromNewLatency"; break; case TabSelectionType.FROM_USER: - TabModelJniBridgeJni.get().logFromUserMetric(ms, perceived); + baseHistogram = "Tabs.SwitchFromUserLatency"; break; + default: + assert false; + return; } + String histogramSuffix = perceived ? "_Perceived" : "_Actual"; + RecordHistogram.recordTimesHistogram(baseHistogram + histogramSuffix, ms); } @NativeMethods @@ -238,11 +245,5 @@ long nativeTabModelJniBridge, TabModelJniBridge caller); void destroy(long nativeTabModelJniBridge, TabModelJniBridge caller); void tabAddedToModel(long nativeTabModelJniBridge, TabModelJniBridge caller, Tab tab); - - // Methods for tab switch latency metrics. - void logFromCloseMetric(long ms, boolean perceived); - void logFromExitMetric(long ms, boolean perceived); - void logFromNewMetric(long ms, boolean perceived); - void logFromUserMetric(long ms, boolean perceived); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinatorPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinatorPhone.java index 3d21e38..8f7be496 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinatorPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinatorPhone.java
@@ -4,13 +4,9 @@ package org.chromium.chrome.browser.toolbar.top; -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; import android.view.View; import android.view.ViewStub; - import androidx.annotation.Nullable; - import org.chromium.chrome.R; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.incognito.IncognitoUtils; @@ -129,71 +125,7 @@ if (mTabSwitcherModeToolbar != null) { mTabSwitcherModeToolbar.setTabModelSelector(selector); } - } - /** - * @param provider The provider used to determine incognito state. - */ - void setIncognitoStateProvider(IncognitoStateProvider provider) { - mIncognitoStateProvider = provider; - if (mTabSwitcherModeToolbar != null) { - mTabSwitcherModeToolbar.setIncognitoStateProvider(provider); - } - } - - /** Called when accessibility status changes. */ - void onAccessibilityStatusChanged(boolean enabled) { - mAccessibilityEnabled = enabled; - if (mTabSwitcherModeToolbar != null) { - mTabSwitcherModeToolbar.onAccessibilityStatusChanged(enabled); - } - } - - void setTabSwitcherToolbarVisibility(boolean shouldShowTabSwitcherToolbar) { - if (mTabSwitcherModeToolbar == null - || (mTabSwitcherModeToolbar.getVisibility() == View.VISIBLE) - == shouldShowTabSwitcherToolbar) { - return; - } - - final float targetAlpha = shouldShowTabSwitcherToolbar ? 1.0f : 0.0f; - mTabSwitcherModeToolbar.animate() - .alpha(targetAlpha) - .setDuration(TopToolbarCoordinator.TAB_SWITCHER_MODE_NORMAL_ANIMATION_DURATION_MS) - .setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animation) { - if (shouldShowTabSwitcherToolbar) { - mTabSwitcherModeToolbar.setVisibility(View.VISIBLE); - } - } - - @Override - public void onAnimationEnd(Animator animation) { - if (!shouldShowTabSwitcherToolbar) { - mTabSwitcherModeToolbar.setVisibility(View.GONE); - } - } - }); - } - - private void initializeTabSwitcherToolbar() { - mTabSwitcherModeToolbar = (TabSwitcherModeTTPhone) mTabSwitcherToolbarStub.inflate(); - mMenuButtonCoordinator.setMenuButton( - mTabSwitcherModeToolbar.findViewById(R.id.menu_button_wrapper)); - - // It's expected that these properties are set by the time the tab switcher is entered. - assert mTabSwitcherListener != null; - mTabSwitcherModeToolbar.setOnTabSwitcherClickHandler(mTabSwitcherListener); - - assert mNewTabListener != null; - mTabSwitcherModeToolbar.setOnNewTabClickHandler(mNewTabListener); - - assert mTabCountProvider != null; - mTabSwitcherModeToolbar.setTabCountProvider(mTabCountProvider); - - assert mTabModelSelector != null; - mTabSwitcherModeToolbar.setTabModelSelector(mTabModelSelector); if (isNewTabVariationEnabled()) { mTabModelObserver = new TabModelObserver() { @Override @@ -216,17 +148,64 @@ private void updateIncognitoTabsCount() { int incognitoTabsCount = mTabModelSelector.getModel(true).getCount(); - mTabSwitcherModeToolbar.onIncognitoTabsCountChanged(incognitoTabsCount); + if (mTabSwitcherModeToolbar != null) { + mTabSwitcherModeToolbar.onIncognitoTabsCountChanged(incognitoTabsCount); + } } }; TabModel incognitoTabModel = mTabModelSelector.getModel(true); incognitoTabModel.addObserver(mTabModelObserver); - mTabSwitcherModeToolbar.onIncognitoTabsCountChanged(incognitoTabModel.getCount()); + if (mTabSwitcherModeToolbar != null) { + mTabSwitcherModeToolbar.onIncognitoTabsCountChanged(incognitoTabModel.getCount()); + } } + } + + /** + * @param provider The provider used to determine incognito state. + */ + void setIncognitoStateProvider(IncognitoStateProvider provider) { + mIncognitoStateProvider = provider; + if (mTabSwitcherModeToolbar != null) { + mTabSwitcherModeToolbar.setIncognitoStateProvider(provider); + } + } + + /** Called when accessibility status changes. */ + void onAccessibilityStatusChanged(boolean enabled) { + mAccessibilityEnabled = enabled; + if (mTabSwitcherModeToolbar != null) { + mTabSwitcherModeToolbar.onAccessibilityStatusChanged(enabled); + } + } + + private void initializeTabSwitcherToolbar() { + mTabSwitcherModeToolbar = (TabSwitcherModeTTPhone) mTabSwitcherToolbarStub.inflate(); + mMenuButtonCoordinator.setMenuButton( + mTabSwitcherModeToolbar.findViewById(R.id.menu_button_wrapper)); + + // It's expected that these properties are set by the time the tab switcher is entered. + assert mTabSwitcherListener != null; + mTabSwitcherModeToolbar.setOnTabSwitcherClickHandler(mTabSwitcherListener); + + assert mNewTabListener != null; + mTabSwitcherModeToolbar.setOnNewTabClickHandler(mNewTabListener); + + assert mTabCountProvider != null; + mTabSwitcherModeToolbar.setTabCountProvider(mTabCountProvider); + + assert mTabModelSelector != null; + mTabSwitcherModeToolbar.setTabModelSelector(mTabModelSelector); assert mIncognitoStateProvider != null; mTabSwitcherModeToolbar.setIncognitoStateProvider(mIncognitoStateProvider); + if (isNewTabVariationEnabled()) { + int incognitoTabsCount = + mTabModelSelector == null ? 0 : mTabModelSelector.getModel(true).getCount(); + mTabSwitcherModeToolbar.onIncognitoTabsCountChanged(incognitoTabsCount); + } + if (mAccessibilityEnabled) { mTabSwitcherModeToolbar.onAccessibilityStatusChanged(mAccessibilityEnabled); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java index fde8a1a5..2e35f4c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java
@@ -66,6 +66,15 @@ @Override @Nullable + public String getClientPackageName() { + if (mWebApkExtras != null) { + return mWebApkExtras.webApkPackageName; + } + return null; + } + + @Override + @Nullable public String getUrlToLoad() { return mWebappExtras.url; }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java index 80e8a31..c6badbf69 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java
@@ -51,7 +51,6 @@ import org.chromium.base.test.params.ParameterizedRunner; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.FlakyTest; @@ -259,7 +258,6 @@ @Test @SmallTest - @DisableIf.Build(sdk_is_less_than = 21, message = "crbug.com/807807") public void testAddBookmark() { mActivityTestRule.loadUrl(mTestPage); // Check partner bookmarks are lazily loaded. @@ -290,7 +288,6 @@ @Test @SmallTest - @DisableIf.Build(sdk_is_less_than = 21, message = "crbug.com/807807") public void testAddBookmarkSnackbar() { mActivityTestRule.loadUrl(mTestPage); // Check partner bookmarks are lazily loaded. @@ -323,7 +320,6 @@ @Test @SmallTest - @DisableIf.Build(sdk_is_less_than = 21, message = "crbug.com/807807") public void testAddBookmarkToOtherFolder() { mActivityTestRule.loadUrl(mTestPage); readPartnerBookmarks();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/homepage/HomepagePolicyIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/homepage/HomepagePolicyIntegrationTest.java index da2279b..ffc54c8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/homepage/HomepagePolicyIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/homepage/HomepagePolicyIntegrationTest.java
@@ -28,7 +28,6 @@ import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; -import org.chromium.chrome.browser.homepage.settings.HomepageMetricsEnums.HomeButtonPreferenceState; import org.chromium.chrome.browser.homepage.settings.HomepageMetricsEnums.HomepageLocationType; import org.chromium.chrome.browser.homepage.settings.HomepageSettings; import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; @@ -67,9 +66,6 @@ public static final String TEST_URL = "http://127.0.0.1:8000/foo.html"; public static final String GOOGLE_HTML = "/chrome/test/data/android/google.html"; - private static final String METRICS_HOME_BUTTON_STATE_ENUM = - "Settings.ShowHomeButtonPreferenceStateManaged"; - private static final String METRICS_HOMEPAGE_IS_CUSTOMIZED = "Settings.HomePageIsCustomized"; private static final String METRICS_HOMEPAGE_LOCATION_TYPE = "Settings.Homepage.LocationType"; private EmbeddedTestServer mTestServer; @@ -119,18 +115,6 @@ SharedPreferencesManager.getInstance().readString( ChromePreferenceKeys.HOMEPAGE_LOCATION_POLICY, "")); - // METRICS_HOMEPAGE_IS_CUSTOMIZED Should be collected twice it is called in: - // 1. ProcessInitializationHandler#handleDeferredStartupTasksInitialization; - // 2. HomepageManager#onHomepagePolicyUpdate, which will be called when native initialized. - Assert.assertEquals( - "Settings.HomepageIsCustomized should be recorded twice when policy enabled", 2, - RecordHistogram.getHistogramTotalCountForTesting(METRICS_HOMEPAGE_IS_CUSTOMIZED)); - - // METRICS_HOME_BUTTON_STATE_ENUM should be collected once in deferred start up tasks. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - METRICS_HOME_BUTTON_STATE_ENUM, HomeButtonPreferenceState.MANAGED_ENABLED)); - // METRICS_HOMEPAGE_LOCATION_TYPE is recorded once in deferred start up tasks. Assert.assertEquals("Settings.Homepage.LocationType should record POLICY_OTHER once.", 1, RecordHistogram.getHistogramValueCountForTesting(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RecentTabsPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RecentTabsPageTest.java index cc9c05c9..5e4a9a38 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RecentTabsPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RecentTabsPageTest.java
@@ -4,7 +4,6 @@ package org.chromium.chrome.browser.ntp; -import android.accounts.Account; import android.app.Activity; import android.view.View; @@ -21,12 +20,14 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.ChromeRenderTestRule; import org.chromium.chrome.test.util.RecentTabsPageTestUtils; +import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule; import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.components.signin.test.util.FakeProfileDataSource; @@ -74,7 +75,6 @@ @After public void tearDown() { leaveRecentTabsPage(); - RecentTabsManager.forcePromoStateForTests(null); RecentTabsManager.setRecentlyClosedTabManagerForTests(null); } @@ -100,9 +100,8 @@ @LargeTest @Feature("RenderTest") public void testPersonalizedSigninPromoInRecentTabsPage() throws Exception { - Account account = mAccountManagerTestRule.addTestAccountThenSigninAndEnableSync(); - RecentTabsManager.forcePromoStateForTests( - RecentTabsManager.PromoState.PROMO_SIGNIN_PERSONALIZED); + mAccountManagerTestRule.addAccount(mAccountManagerTestRule.createProfileDataFromName( + AccountManagerTestRule.TEST_ACCOUNT_EMAIL)); mPage = loadRecentTabsPage(); mRenderTestRule.render(mPage.getView(), "personalized_signin_promo_recent_tabs_page"); } @@ -110,10 +109,9 @@ @Test @LargeTest @Feature("RenderTest") + @Features.EnableFeatures({ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY}) public void testPersonalizedSyncPromoInRecentTabsPage() throws Exception { - Account account = mAccountManagerTestRule.addTestAccountThenSigninAndEnableSync(); - RecentTabsManager.forcePromoStateForTests( - RecentTabsManager.PromoState.PROMO_SYNC_PERSONALIZED); + mAccountManagerTestRule.addTestAccountThenSignin(); mPage = loadRecentTabsPage(); mRenderTestRule.render(mPage.getView(), "personalized_sync_promo_recent_tabs_page"); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java index ac4d893b..4c56d8e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java
@@ -418,20 +418,6 @@ } @Test - @LargeTest - @Feature({"RenderTest"}) - @Features.EnableFeatures({ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY}) - public void testSyncPromoView() throws Exception { - mSyncTestRule.setUpAccountAndSignInForTesting(); - launchSettingsActivity(); - - Preference syncPromoPreference = mMainSettings.findPreference(MainSettings.PREF_SYNC_PROMO); - CriteriaHelper.pollUiThread(() -> syncPromoPreference.isVisible()); - View syncPromoView = mMainSettings.getView().findViewById(R.id.signin_promo_view_container); - mRenderTestRule.render(syncPromoView, "main_settings_sync_promo"); - } - - @Test @SmallTest public void testRemoveSettings() { // Disable night mode
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/FakeProfileSyncService.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/FakeProfileSyncService.java index 7077c961..6f138237 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/FakeProfileSyncService.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/FakeProfileSyncService.java
@@ -128,11 +128,6 @@ } @Override - public void enableEncryptEverything() { - mEncryptEverythingEnabled = true; - } - - @Override public boolean canSyncFeatureStart() { return mCanSyncFeatureStart; } @@ -149,4 +144,8 @@ public void setRequiresClientUpgrade(boolean requiresClientUpgrade) { mRequiresClientUpgrade = requiresClientUpgrade; } + + public void setEncryptEverythingEnabled(boolean encryptEverythingEnabled) { + mEncryptEverythingEnabled = encryptEverythingEnabled; + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncErrorCardPreferenceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncErrorCardPreferenceTest.java index a5ae71c..7f560b4b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncErrorCardPreferenceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncErrorCardPreferenceTest.java
@@ -24,6 +24,7 @@ import org.chromium.base.test.params.ParameterAnnotations; import org.chromium.base.test.params.ParameterizedRunner; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.chrome.R; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -49,6 +50,7 @@ @ParameterAnnotations.UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) @Features.EnableFeatures(ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY) +@DisabledTest(message = "https://crbug.com/1139399") public class SyncErrorCardPreferenceTest { // FakeProfileDataSource is required to create the ProfileDataCache entry with sync_error badge // for Sync error card. @@ -211,7 +213,7 @@ public void testSyncErrorCardForTrustedVaultKey(boolean nightModeEnabled) throws Exception { mFakeProfileSyncService.setEngineInitialized(true); mFakeProfileSyncService.setTrustedVaultKeyRequiredForPreferredDataTypes(true); - mFakeProfileSyncService.enableEncryptEverything(); + mFakeProfileSyncService.setEncryptEverythingEnabled(true); when(mAndroidSyncSettingsMock.doesMasterSyncSettingAllowChromeSync()).thenReturn(true); mAccountManagerTestRule.addTestAccountThenSigninAndEnableSync(mFakeProfileSyncService); TestThreadUtils.runOnUiThreadBlocking(
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/controller/webapps/WebappDisclosureControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/controller/webapps/WebappDisclosureControllerTest.java index 05b9e86..8f8ad69 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/controller/webapps/WebappDisclosureControllerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/controller/webapps/WebappDisclosureControllerTest.java
@@ -101,6 +101,7 @@ // Simulates the case that shows the disclosure when finish native initialization. storage.setShowDisclosure(); + assertTrue(storage.shouldShowDisclosure()); controller.onFinishNativeInitialization(); assertSnackbarShown();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialogTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialogTest.java index f7654436..8c9e89940 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialogTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialogTest.java
@@ -68,6 +68,7 @@ @Test public void testPositiveButtonWhenAccountIsNotManaged() { AlertDialog alertDialog = getConfirmImportSyncDataDialog(); + alertDialog.findViewById(R.id.sync_confirm_import_choice).performClick(); alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).performClick(); verify(mMockListener).onConfirm(false); } @@ -91,6 +92,7 @@ @Test public void testListenerOnCancelNotCalledOnDismissWhenButtonClicked() { AlertDialog dialog = getConfirmImportSyncDataDialog(); + dialog.findViewById(R.id.sync_confirm_import_choice).performClick(); dialog.getButton(AlertDialog.BUTTON_POSITIVE).performClick(); dialog.dismiss(); verify(mMockListener, never()).onCancel();
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index 44a71eca..34bfc543 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -1622,6 +1622,9 @@ <message name="IDS_SETTINGS_MOUSE_TITLE" desc="In Device Settings, the title of the mouse settings subpage."> Mouse </message> + <message name="IDS_SETTINGS_POINTING_STICK_TITLE" desc="In Device Settings, the title of the pointing stick settings subpage. In most cases this will just be 'TrackPoint', the brand name of the pointing sticks used on Chromebooks."> + TrackPoint + </message> <message name="IDS_SETTINGS_TOUCHPAD_TITLE" desc="In Device Settings, the title of the touchpad settings subpage."> Touchpad </message>
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_POINTING_STICK_TITLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_POINTING_STICK_TITLE.png.sha1 new file mode 100644 index 0000000..2ab527c --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_POINTING_STICK_TITLE.png.sha1
@@ -0,0 +1 @@ +ec6fb452c11f3dd8c97d90f63bc1e614c5633d32 \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 022ad2e5..b08cbe760 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1267,6 +1267,12 @@ "predictors/resource_prefetch_predictor.h", "predictors/resource_prefetch_predictor_tables.cc", "predictors/resource_prefetch_predictor_tables.h", + "prefetch/search_prefetch/field_trial_settings.cc", + "prefetch/search_prefetch/field_trial_settings.h", + "prefetch/search_prefetch/search_prefetch_service.cc", + "prefetch/search_prefetch/search_prefetch_service.h", + "prefetch/search_prefetch/search_prefetch_service_factory.cc", + "prefetch/search_prefetch/search_prefetch_service_factory.h", "prefs/browser_prefs.cc", "prefs/browser_prefs.h", "prefs/chrome_command_line_pref_store.cc",
diff --git a/chrome/browser/android/autofill_assistant/lite_service_bridge.cc b/chrome/browser/android/autofill_assistant/lite_service_bridge.cc index 18bef3e..7bfd29ea 100644 --- a/chrome/browser/android/autofill_assistant/lite_service_bridge.cc +++ b/chrome/browser/android/autofill_assistant/lite_service_bridge.cc
@@ -48,15 +48,17 @@ } ServerUrlFetcher url_fetcher{ServerUrlFetcher::GetDefaultServerUrl()}; + auto request_sender = std::make_unique<ServiceRequestSender>( + web_contents->GetBrowserContext(), /* access_token_fetcher = */ nullptr, + std::make_unique<NativeURLLoaderFactory>(), + ApiKeyFetcher().GetAPIKey(chrome::GetChannel()), + /* auth_enabled = */ false, /* disable_auth_if_no_access_token = */ true); + return reinterpret_cast<jlong>(new LiteService( - std::make_unique<ServiceImpl>( - ApiKeyFetcher().GetAPIKey(chrome::GetChannel()), - url_fetcher.GetSupportsScriptEndpoint(), - url_fetcher.GetNextActionsEndpoint(), - web_contents->GetBrowserContext(), - std::make_unique<EmptyClientContext>(), - /* access_token_fetcher = */ nullptr, - /* auth_enabled = */ false), + std::make_unique<ServiceImpl>(std::move(request_sender), + url_fetcher.GetSupportsScriptEndpoint(), + url_fetcher.GetNextActionsEndpoint(), + std::make_unique<EmptyClientContext>()), base::android::ConvertJavaStringToUTF8(env, jtrigger_script_path), base::BindOnce(&OnFinished, base::android::ScopedJavaGlobalRef<jobject>( java_lite_service)),
diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browser/android/bookmarks/bookmark_bridge.cc index 22330d0..ff4fd75 100644 --- a/chrome/browser/android/bookmarks/bookmark_bridge.cc +++ b/chrome/browser/android/bookmarks/bookmark_bridge.cc
@@ -741,6 +741,7 @@ // why this is called with an uneditable node. // See https://crbug.com/981172. if (!IsEditable(node)) { + LOG(ERROR) << "Deleting non editable bookmark, type:" << type; NOTREACHED(); return; }
diff --git a/chrome/browser/android/history/history_deletion_bridge.cc b/chrome/browser/android/history/history_deletion_bridge.cc index 5427200..bbc944af 100644 --- a/chrome/browser/android/history/history_deletion_bridge.cc +++ b/chrome/browser/android/history/history_deletion_bridge.cc
@@ -24,6 +24,17 @@ return reinterpret_cast<intptr_t>(new HistoryDeletionBridge(jobj)); } +// static +history::DeletionInfo HistoryDeletionBridge::SanitizeDeletionInfo( + const history::DeletionInfo& deletion_info) { + std::vector<history::URLRow> sanitized_rows; + for (auto row : deletion_info.deleted_rows()) { + if (!row.url().is_empty() && row.url().is_valid()) + sanitized_rows.push_back(row); + } + return history::DeletionInfo::ForUrls(sanitized_rows, {}); +} + HistoryDeletionBridge::HistoryDeletionBridge(const JavaRef<jobject>& jobj) : jobj_(ScopedJavaGlobalRef<jobject>(jobj)), profile_(ProfileManager::GetLastUsedProfile()->GetOriginalProfile()) { @@ -47,6 +58,7 @@ const history::DeletionInfo& deletion_info) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); JNIEnv* env = base::android::AttachCurrentThread(); + history::DeletionInfo sanitized_info = SanitizeDeletionInfo(deletion_info); Java_HistoryDeletionBridge_onURLsDeleted( - env, jobj_, CreateHistoryDeletionInfo(env, &deletion_info)); + env, jobj_, CreateHistoryDeletionInfo(env, &sanitized_info)); }
diff --git a/chrome/browser/android/history/history_deletion_bridge.h b/chrome/browser/android/history/history_deletion_bridge.h index 0edddc61..a6e49e8 100644 --- a/chrome/browser/android/history/history_deletion_bridge.h +++ b/chrome/browser/android/history/history_deletion_bridge.h
@@ -25,6 +25,12 @@ void OnURLsDeleted(history::HistoryService* history_service, const history::DeletionInfo& deletion_info) override; + // Sanitize the DeletionInfo of empty/invalid urls before passing to java. + // Fix for empty java strings being passed to the content capture service + // (crbug.com/1136486). + static history::DeletionInfo SanitizeDeletionInfo( + const history::DeletionInfo& deletion_info); + private: ~HistoryDeletionBridge() override;
diff --git a/chrome/browser/android/history/history_deletion_bridge_unittest.cc b/chrome/browser/android/history/history_deletion_bridge_unittest.cc new file mode 100644 index 0000000..4e881bf8 --- /dev/null +++ b/chrome/browser/android/history/history_deletion_bridge_unittest.cc
@@ -0,0 +1,30 @@ +// 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/android/history/history_deletion_bridge.h" + +#include "base/time/time.h" +#include "components/history/core/browser/history_types.h" +#include "components/history/core/browser/url_row.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +TEST(HistoryDeletionBridge, TestSanitizeDeletionInfo) { + history::DeletionInfo info = history::DeletionInfo::ForUrls( + {history::URLResult(GURL("https://google.com/"), base::Time()), + history::URLResult(GURL("https://google.com/foo"), base::Time()), + history::URLResult(GURL("htt\\invalido\\gle.com"), base::Time()), + history::URLResult(GURL(""), base::Time())}, + {}); + + std::vector<GURL> expected = {GURL("https://google.com/"), + GURL("https://google.com/foo")}; + std::vector<history::URLRow> actual = + HistoryDeletionBridge::SanitizeDeletionInfo(info).deleted_rows(); + EXPECT_EQ(expected.size(), actual.size()); + + for (auto row : actual) + EXPECT_NE(expected.end(), + std::find(expected.begin(), expected.end(), row.url())); +}
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index b8bf5229..d986e54 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -223,6 +223,7 @@ "//chromeos/timezone", "//chromeos/tpm", "//chromeos/ui/base", + "//chromeos/ui/frame", "//components/arc", "//components/arc/media_session", "//components/arc/mojom:mojom_traits", @@ -3860,6 +3861,7 @@ "//chromeos/system", "//chromeos/tpm", "//chromeos/tpm:test_support", + "//chromeos/ui/frame:test_support", "//components/arc", "//components/arc:arc_test_support", "//components/arc:notification_test_support",
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc index 8cfebf0c..34d6e4a0d 100644 --- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
@@ -24,7 +24,6 @@ #include "ash/public/cpp/default_frame_header.h" #include "ash/public/cpp/desks_helper.h" #include "ash/public/cpp/frame_header.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h" #include "ash/public/cpp/login_screen.h" #include "ash/public/cpp/metrics_util.h" #include "ash/public/cpp/overview_test_api.h" @@ -123,6 +122,7 @@ #include "chromeos/services/machine_learning/public/cpp/service_connection.h" #include "chromeos/settings/cros_settings_names.h" #include "chromeos/ui/base/window_properties.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" #include "components/arc/arc_prefs.h" #include "components/arc/metrics/arc_metrics_constants.h" #include "components/policy/core/browser/policy_conversions.h" @@ -3622,7 +3622,7 @@ } // Frame information - auto* immersive_controller = ash::ImmersiveFullscreenController::Get( + auto* immersive_controller = chromeos::ImmersiveFullscreenController::Get( views::Widget::GetWidgetForNativeWindow(window)); if (immersive_controller) { // The widget that hosts the immersive frame can be different from the
diff --git a/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc b/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc index 0d8f2b5d1..f001c09 100644 --- a/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc +++ b/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc
@@ -169,6 +169,8 @@ // Since this number is divided by the result of the sysconf(_SC_CLK_TCK) // syscall, we need it to be 0 to avoid flaky tests, constexpr uint32_t kFakeIdleTime = 0; +constexpr uint64_t kFakeUserTime = 789; +constexpr uint64_t kFakeSystemTime = 4680; constexpr char kFakeCStateName[] = "fake_c_state_name"; constexpr uint64_t kFakeTimeInStateSinceLastBoot = 87; // CPU Temperature test values: @@ -538,7 +540,7 @@ std::vector<cros_healthd::LogicalCpuInfoPtr> logical_cpus; logical_cpus.push_back(cros_healthd::LogicalCpuInfo::New( kFakeMaxClockSpeed, kFakeScalingMaxFrequency, kFakeScalingCurFrequency, - kFakeIdleTime, CreateCStateInfo())); + kFakeUserTime, kFakeSystemTime, kFakeIdleTime, CreateCStateInfo())); return logical_cpus; }
diff --git a/chrome/browser/chromeos/scoped_test_system_nss_key_slot_mixin.cc b/chrome/browser/chromeos/scoped_test_system_nss_key_slot_mixin.cc index 7c5cb6e..103d76b 100644 --- a/chrome/browser/chromeos/scoped_test_system_nss_key_slot_mixin.cc +++ b/chrome/browser/chromeos/scoped_test_system_nss_key_slot_mixin.cc
@@ -4,25 +4,44 @@ #include "chrome/browser/chromeos/scoped_test_system_nss_key_slot_mixin.h" +#include <memory> + #include "base/bind.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/logging.h" +#include "base/path_service.h" #include "base/run_loop.h" +#include "chrome/common/chrome_paths.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" +#include "crypto/nss_util.h" +#include "crypto/nss_util_internal.h" +#include "crypto/scoped_nss_types.h" #include "crypto/scoped_test_system_nss_key_slot.h" #include "testing/gtest/include/gtest/gtest.h" namespace chromeos { +namespace { + +// Returns a subdirectory under the user data directory (which is not cleared +// after pre-tests). +base::FilePath GetNssDbTestDir() { + base::FilePath nss_db_subdir; + base::PathService::Get(chrome::DIR_USER_DATA, &nss_db_subdir); + nss_db_subdir = nss_db_subdir.AppendASCII("nss_db_subdir"); + return nss_db_subdir; +} + +} // namespace + ScopedTestSystemNSSKeySlotMixin::ScopedTestSystemNSSKeySlotMixin( InProcessBrowserTestMixinHost* host) : InProcessBrowserTestMixin(host) {} ScopedTestSystemNSSKeySlotMixin::~ScopedTestSystemNSSKeySlotMixin() = default; -PK11SlotInfo* ScopedTestSystemNSSKeySlotMixin::slot() { - return scoped_test_system_nss_key_slot_->slot(); -} - void ScopedTestSystemNSSKeySlotMixin::SetUpOnMainThread() { bool system_slot_initialized_successfully = false; base::RunLoop loop; @@ -48,14 +67,36 @@ void ScopedTestSystemNSSKeySlotMixin::InitializeOnIo(bool* out_success) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - scoped_test_system_nss_key_slot_ = - std::make_unique<crypto::ScopedTestSystemNSSKeySlot>(); - *out_success = scoped_test_system_nss_key_slot_->ConstructedSuccessfully(); + + crypto::EnsureNSSInit(); + // NSS is allowed to do IO on the current thread since dispatching + // to a dedicated thread would still have the affect of blocking + // the current thread, due to NSS's internal locking requirements + base::ScopedAllowBlockingForTesting allow_blocking; + + base::FilePath nss_db_subdir = GetNssDbTestDir(); + ASSERT_TRUE(base::CreateDirectory(nss_db_subdir)); + + const char kTestDescription[] = "Test DB"; + slot_ = crypto::OpenSoftwareNSSDB(nss_db_subdir, kTestDescription); + *out_success = !!slot_; + + if (slot_) { + crypto::SetSystemKeySlotForTesting( + crypto::ScopedPK11Slot(PK11_ReferenceSlot(slot_.get()))); + } } void ScopedTestSystemNSSKeySlotMixin::DestroyOnIo() { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - scoped_test_system_nss_key_slot_.reset(); + + crypto::SetSystemKeySlotForTesting(nullptr); + + if (slot_) { + SECStatus status = SECMOD_CloseUserDB(slot_.get()); + if (status != SECSuccess) + PLOG(ERROR) << "SECMOD_CloseUserDB failed: " << PORT_GetError(); + } } } // namespace chromeos
diff --git a/chrome/browser/chromeos/scoped_test_system_nss_key_slot_mixin.h b/chrome/browser/chromeos/scoped_test_system_nss_key_slot_mixin.h index 2793c90..4031a9f 100644 --- a/chrome/browser/chromeos/scoped_test_system_nss_key_slot_mixin.h +++ b/chrome/browser/chromeos/scoped_test_system_nss_key_slot_mixin.h
@@ -6,18 +6,20 @@ #define CHROME_BROWSER_CHROMEOS_SCOPED_TEST_SYSTEM_NSS_KEY_SLOT_MIXIN_H_ #include <pk11pub.h> + #include <memory> #include "chrome/test/base/mixin_based_in_process_browser_test.h" - -namespace crypto { -class ScopedTestSystemNSSKeySlot; -} +#include "crypto/scoped_nss_types.h" namespace chromeos { -// Owns a persistent NSS software database in a temporary directory and the +// Owns a persistent NSS software database in the user directory and the // association of the system slot with this database. +// Note: The database is persisted in the user data directory +// (chrome::DIR_USER_DATA) so it persists between PRE_ and non-PRE_ tests. This +// allows simulating browser restarts after doing some operations on the +// database without losing its state. // // This mixin performs the blocking initialization/destruction in the // {SetUp|TearDown}OnMainThread methods. @@ -30,14 +32,7 @@ const ScopedTestSystemNSSKeySlotMixin&) = delete; ~ScopedTestSystemNSSKeySlotMixin() override; - crypto::ScopedTestSystemNSSKeySlot* scoped_test_system_nss_key_slot() { - return scoped_test_system_nss_key_slot_.get(); - } - const crypto::ScopedTestSystemNSSKeySlot* scoped_test_system_nss_key_slot() - const { - return scoped_test_system_nss_key_slot_.get(); - } - PK11SlotInfo* slot(); + PK11SlotInfo* slot() { return slot_.get(); } void SetUpOnMainThread() override; void TearDownOnMainThread() override; @@ -46,8 +41,7 @@ void InitializeOnIo(bool* out_success); void DestroyOnIo(); - std::unique_ptr<crypto::ScopedTestSystemNSSKeySlot> - scoped_test_system_nss_key_slot_; + crypto::ScopedPK11Slot slot_; }; } // namespace chromeos
diff --git a/chrome/browser/download/android/BUILD.gn b/chrome/browser/download/android/BUILD.gn index 9eb6e8d..607ac29 100644 --- a/chrome/browser/download/android/BUILD.gn +++ b/chrome/browser/download/android/BUILD.gn
@@ -16,6 +16,7 @@ "java/src/org/chromium/chrome/browser/download/DownloadFilter.java", "java/src/org/chromium/chrome/browser/download/DownloadInfo.java", "java/src/org/chromium/chrome/browser/download/DownloadLaterMetrics.java", + "java/src/org/chromium/chrome/browser/download/DownloadLocationDialogMetrics.java", "java/src/org/chromium/chrome/browser/download/DownloadManagerBridge.java", "java/src/org/chromium/chrome/browser/download/DownloadStartupUtils.java", "java/src/org/chromium/chrome/browser/download/DownloadStatus.java",
diff --git a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DownloadDialogBridge.java b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DownloadDialogBridge.java index 7b5cceb..f2a7ab3 100644 --- a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DownloadDialogBridge.java +++ b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DownloadDialogBridge.java
@@ -232,6 +232,12 @@ @Override public void onDownloadLocationDialogComplete(String returnedPath) { mSuggestedPath = returnedPath; + + if (mLocationDialogType == DownloadLocationDialogType.LOCATION_SUGGESTION) { + boolean isSelected = !mSuggestedPath.equals(getDownloadDefaultDirectory()); + DownloadLocationDialogMetrics.recordDownloadLocationSuggestionChoice(isSelected); + } + // The location dialog is triggered automatically, complete the flow. if (!mEditLocation) { onComplete();
diff --git a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DownloadLocationDialogMetrics.java b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DownloadLocationDialogMetrics.java new file mode 100644 index 0000000..5a738bf --- /dev/null +++ b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DownloadLocationDialogMetrics.java
@@ -0,0 +1,23 @@ +// 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.download; + +import org.chromium.base.metrics.RecordHistogram; + +/** + * Class that contains helper functions for download location download feature metrics recording. + */ +public final class DownloadLocationDialogMetrics { + private DownloadLocationDialogMetrics() {} + + /** + * Records the user choice on the locaction suggestion spinner. + * @param isChosen The user choice, true if the user chooses the suggestion. + */ + public static void recordDownloadLocationSuggestionChoice(boolean isSelected) { + RecordHistogram.recordBooleanHistogram( + "MobileDownload.Location.Dialog.SuggestionSelected", isSelected); + } +}
diff --git a/chrome/browser/lookalikes/lookalike_url_blocking_page.cc b/chrome/browser/lookalikes/lookalike_url_blocking_page.cc index 6d7c101d..aa0af3df 100644 --- a/chrome/browser/lookalikes/lookalike_url_blocking_page.cc +++ b/chrome/browser/lookalikes/lookalike_url_blocking_page.cc
@@ -30,6 +30,7 @@ const GURL& request_url, ukm::SourceId source_id, LookalikeUrlMatchType match_type, + bool is_signed_exchange, std::unique_ptr< security_interstitials::SecurityInterstitialControllerClient> controller_client) @@ -39,7 +40,8 @@ std::move(controller_client)), safe_url_(safe_url), source_id_(source_id), - match_type_(match_type) { + match_type_(match_type), + is_signed_exchange_(is_signed_exchange) { controller()->metrics_helper()->RecordUserDecision(MetricsHelper::SHOW); controller()->metrics_helper()->RecordUserInteraction( MetricsHelper::TOTAL_VISITS);
diff --git a/chrome/browser/lookalikes/lookalike_url_blocking_page.h b/chrome/browser/lookalikes/lookalike_url_blocking_page.h index f82f292..d7281e9 100644 --- a/chrome/browser/lookalikes/lookalike_url_blocking_page.h +++ b/chrome/browser/lookalikes/lookalike_url_blocking_page.h
@@ -32,6 +32,7 @@ const GURL& request_url, ukm::SourceId source_id, LookalikeUrlMatchType match_type, + bool is_signed_exchange, std::unique_ptr< security_interstitials::SecurityInterstitialControllerClient> controller); @@ -42,6 +43,8 @@ security_interstitials::SecurityInterstitialPage::TypeID GetTypeForTesting() override; + bool is_signed_exchange_for_testing() const { return is_signed_exchange_; } + protected: // SecurityInterstitialPage implementation: void CommandReceived(const std::string& command) override; @@ -59,6 +62,9 @@ const GURL safe_url_; ukm::SourceId source_id_; LookalikeUrlMatchType match_type_; + // True if the throttle encountered a response with + // is_signed_exchange_inner_response flag. Only checked in tests. + const bool is_signed_exchange_; DISALLOW_COPY_AND_ASSIGN(LookalikeUrlBlockingPage); };
diff --git a/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc b/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc index 4f9db24d..fe25266 100644 --- a/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc +++ b/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc
@@ -143,8 +143,9 @@ web_contents, url, safe_url); std::unique_ptr<LookalikeUrlBlockingPage> blocking_page( - new LookalikeUrlBlockingPage(web_contents, safe_url, url, source_id, - match_type, std::move(controller))); + new LookalikeUrlBlockingPage( + web_contents, safe_url, url, source_id, match_type, + handle->IsSignedExchangeInnerResponse(), std::move(controller))); base::Optional<std::string> error_page_contents = blocking_page->GetHTMLContents(); @@ -225,6 +226,28 @@ first_is_lookalike = false; } + // Allow signed exchange cache URLs such as + // https://example-com.site.test/package.sxg. + // Navigation throttles see signed exchanges as a redirect chain where + // Url 0: Cache URL (i.e. outer URL) + // Url 1: URL of the sgx package + // Url 2: Inner URL (the URL whose contents the sgx package contains) + // + // We want to allow lookalike cache URLs but not lookalike inner URLs, so we + // make an exception for this condition. + // TODO(meacer): Confirm that the assumption about cache URL being the 1st + // and inner URL being the last URL in the redirect chain is correct. + // + // Note that the signed exchange logic can still redirect the initial + // navigation to the fallback URL even if SGX checks fail (invalid cert, + // missing headers etc, see crbug.com/874323 for an example). Such navigations + // are not considered SGX navigations and IsSignedExchangeInnerResponse() + // will return false. We treat such navigations as simple redirects. + if (first_is_lookalike && + navigation_handle()->IsSignedExchangeInnerResponse()) { + first_is_lookalike = false; + } + if (!first_is_lookalike && !last_is_lookalike) { return content::NavigationThrottle::PROCEED; }
diff --git a/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc b/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc index 11d5c763..8aacc0be 100644 --- a/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc +++ b/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/bind.h" +#include "base/path_service.h" #include "base/strings/pattern.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -28,20 +29,26 @@ #include "chrome/test/base/ui_test_utils.h" #include "components/lookalikes/core/features.h" #include "components/lookalikes/core/lookalike_url_util.h" +#include "components/network_session_configurator/common/network_switches.h" #include "components/security_interstitials/content/security_interstitial_page.h" #include "components/security_interstitials/content/security_interstitial_tab_helper.h" #include "components/security_interstitials/core/metrics_helper.h" #include "components/ukm/test_ukm_recorder.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_features.h" +#include "content/public/common/content_paths.h" #include "content/public/test/browser_test.h" +#include "content/public/test/content_mock_cert_verifier.h" #include "content/public/test/signed_exchange_browser_test_helper.h" #include "content/public/test/test_navigation_observer.h" +#include "net/cert/mock_cert_verifier.h" #include "net/dns/mock_host_resolver.h" +#include "net/test/cert_test_util.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" #include "services/metrics/public/cpp/ukm_builders.h" #include "services/metrics/public/cpp/ukm_source.h" +#include "services/network/public/cpp/network_switches.h" #include "ui/base/window_open_disposition.h" namespace { @@ -281,7 +288,8 @@ Browser* browser, const GURL& navigated_url, const GURL& expected_suggested_url, - NavigationSuggestionEvent expected_event) { + NavigationSuggestionEvent expected_event, + bool expect_signed_exchange = false) { base::HistogramTester histograms; history::HistoryService* const history_service = @@ -290,6 +298,14 @@ ui_test_utils::WaitForHistoryToLoad(history_service); LoadAndCheckInterstitialAt(browser, navigated_url); + + if (expect_signed_exchange) { + LookalikeUrlBlockingPage* interstitial = + static_cast<LookalikeUrlBlockingPage*>(GetCurrentInterstitial( + browser->tab_strip_model()->GetActiveWebContents())); + EXPECT_TRUE(interstitial->is_signed_exchange_for_testing()); + } + SendInterstitialCommandSync(browser, SecurityInterstitialCommand::CMD_DONT_PROCEED); EXPECT_EQ(expected_suggested_url, @@ -1293,18 +1309,56 @@ embedded_test_server()->GetURL("example.net", "/")); } +scoped_refptr<net::X509Certificate> LoadCertificate() { + constexpr char kCertFileName[] = "prime256v1-sha256-google-com.public.pem"; + + base::ScopedAllowBlockingForTesting allow_io; + base::FilePath dir_path; + base::PathService::Get(content::DIR_TEST_DATA, &dir_path); + dir_path = dir_path.Append(FILE_PATH_LITERAL("sxg")); + + return net::CreateCertificateChainFromFile( + dir_path, kCertFileName, net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE); +} + // Tests for Signed Exchanges. class LookalikeUrlNavigationThrottleSignedExchangeBrowserTest : public LookalikeUrlNavigationThrottleBrowserTest { public: - void SetUpOnMainThread() override { - sxg_test_helper_.SetUp(); + LookalikeUrlNavigationThrottleSignedExchangeBrowserTest() { + net::EmbeddedTestServer::RegisterTestCerts(); + } - embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data"); - embedded_test_server()->RegisterRequestMonitor(base::BindRepeating( + void SetUpCommandLine(base::CommandLine* command_line) override { + // HTTPS server only serves a valid cert for localhost, so this is needed + // to load pages from other hosts without an error. + command_line->AppendSwitch(switches::kIgnoreCertificateErrors); + mock_cert_verifier_.SetUpCommandLine(command_line); + } + + void SetUpInProcessBrowserTestFixture() override { + mock_cert_verifier_.SetUpInProcessBrowserTestFixture(); + } + + void TearDownInProcessBrowserTestFixture() override { + mock_cert_verifier_.TearDownInProcessBrowserTestFixture(); + } + + void SetUp() override { + sxg_test_helper_.SetUp(); + LookalikeUrlNavigationThrottleBrowserTest::SetUp(); + } + + void SetUpOnMainThread() override { + https_server_.AddDefaultHandlers( + base::FilePath(FILE_PATH_LITERAL("content/test/data"))); + https_server_.ServeFilesFromSourceDirectory("content/test/data"); + https_server_.RegisterRequestMonitor(base::BindRepeating( &LookalikeUrlNavigationThrottleSignedExchangeBrowserTest:: MonitorRequest, base::Unretained(this))); + ASSERT_TRUE(https_server_.Start()); + LookalikeUrlNavigationThrottleBrowserTest::SetUpOnMainThread(); } @@ -1319,8 +1373,34 @@ return it->second.find("application/signed-exchange") != std::string::npos; } + void InstallMockCert() { + sxg_test_helper_.InstallMockCert(mock_cert_verifier_.mock_cert_verifier()); + + // Make the MockCertVerifier treat the certificate + // "prime256v1-sha256-google-com.public.pem" as valid for + // "google-com.example.org". + scoped_refptr<net::X509Certificate> original_cert = LoadCertificate(); + net::CertVerifyResult dummy_result; + dummy_result.verified_cert = original_cert; + dummy_result.cert_status = net::OK; + dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED; + dummy_result.ocsp_result.revocation_status = + net::OCSPRevocationStatus::GOOD; + mock_cert_verifier_.mock_cert_verifier()->AddResultForCertAndHost( + original_cert, "google-com.example.org", dummy_result, net::OK); + } + + void InstallMockCertChainInterceptor() { + sxg_test_helper_.InstallMockCertChainInterceptor(); + sxg_test_helper_.InstallUrlInterceptor( + GURL("https://google-com.example.org/cert.msg"), + "content/test/data/sxg/google-com.example.org.public.pem.cbor"); + } + protected: + net::EmbeddedTestServer https_server_{net::EmbeddedTestServer::TYPE_HTTPS}; content::SignedExchangeBrowserTestHelper sxg_test_helper_; + content::ContentMockCertVerifier mock_cert_verifier_; private: void MonitorRequest(const net::test_server::HttpRequest& request) { @@ -1337,7 +1417,8 @@ INSTANTIATE_TEST_SUITE_P( All, LookalikeUrlNavigationThrottleSignedExchangeBrowserTest, - testing::Combine(testing::Bool(), testing::Bool())); + testing::Combine(testing::Bool() /* target_embedding_enabled */, + testing::Bool() /* punycode_interstitial_enabled */)); // Navigates to a 127.0.0.1 URL that serves a signed exchange for // google-com.example.org. This navigation should be blocked by the target @@ -1346,47 +1427,117 @@ // code). Testing an ETLD+1 such as googlé.com would require generating a custom // cert. IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleSignedExchangeBrowserTest, - SignedExchange_ShouldBlockTarget) { + InnerUrlIsLookalike_ShouldBlock) { if (!target_embedding_enabled()) { return; } + InstallMockCert(); + InstallMockCertChainInterceptor(); + sxg_test_helper_.InstallUrlInterceptor( GURL("https://google-com.example.org/test/"), "content/test/data/sxg/fallback.html"); const GURL kNavigatedUrl = - embedded_test_server()->GetURL("/sxg/google-com.example.org_test.sxg"); + https_server_.GetURL("/sxg/google-com.example.org_test.sxg"); const GURL kExpectedSuggestedUrl("https://google.com"); TestMetricsRecordedAndInterstitialShown( browser(), kNavigatedUrl, kExpectedSuggestedUrl, - NavigationSuggestionEvent::kMatchTargetEmbedding); + NavigationSuggestionEvent::kMatchTargetEmbedding, + true /* expect_signed_exchange */); // Check that the SXG file was handled as a Signed Exchange. ASSERT_TRUE(HadSignedExchangeInAcceptHeader(kNavigatedUrl)); } -// Navigates to a lookalike URL that serves a signed exchange for -// test.example.org. This should also be blocked by the lookalike interstitial, -// even though the URL that serves the signed exchange is never visible to -// the user. +// Navigates to a lookalike URL (google-com.test.com) that serves a signed +// exchange for test.example.org. This should not be blocked. IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleSignedExchangeBrowserTest, - SignedExchange_ShouldBlockCacheUrl) { + OuterUrlIsLookalike_ShouldNotBlock) { if (!target_embedding_enabled()) { return; } + + InstallMockCert(); + InstallMockCertChainInterceptor(); + const GURL kSgxTargetUrl("https://test.example.org/test/"); sxg_test_helper_.InstallUrlInterceptor(kSgxTargetUrl, "content/test/data/sxg/fallback.html"); - const GURL kNavigatedUrl = embedded_test_server()->GetURL( + const GURL kNavigatedUrl = https_server_.GetURL( "google-com.test.com", "/sxg/test.example.org_test.sxg"); - const GURL kExpectedSuggestedUrl = - embedded_test_server()->GetURL("google.com", "/"); + + TestInterstitialNotShown(browser(), kNavigatedUrl); + + // Check that the SXG file was handled as a Signed Exchange. + // MonitorRequest() sees kNavigatedUrl with an IP address instead of + // domain name, so check it instead. + const GURL kResolvedNavigatedUrl = + https_server_.GetURL("/sxg/test.example.org_test.sxg"); + ASSERT_TRUE(HadSignedExchangeInAcceptHeader(kResolvedNavigatedUrl)); +} + +// Navigates to a lookalike URL (google-com.test.com) that serves a signed +// exchange for test.example.org. This should not be blocked. +IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleSignedExchangeBrowserTest, + OuterUrlIsLookalikeButNotSignedExchange_ShouldNotBlock) { + if (!target_embedding_enabled()) { + return; + } + + InstallMockCert(); + InstallMockCertChainInterceptor(); + + const GURL kSgxTargetUrl("https://test.example.org/test/"); + sxg_test_helper_.InstallUrlInterceptor(kSgxTargetUrl, + "content/test/data/sxg/fallback.html"); + const GURL kSgxCacheUrl = https_server_.GetURL( + "google-com.test.com", "/sxg/test.example.org_test.sxg"); + const GURL kNavigatedUrl = embedded_test_server()->GetURL( + "apple-com.site.com", "/server-redirect?" + kSgxCacheUrl.spec()); + + TestInterstitialNotShown(browser(), kNavigatedUrl); + + // Check that the SXG file was handled as a Signed Exchange. + // MonitorRequest() sees kNavigatedUrl with an IP address instead of + // domain name, so check it instead. + const GURL kResolvedNavigatedUrl = + https_server_.GetURL("/sxg/test.example.org_test.sxg"); + ASSERT_TRUE(HadSignedExchangeInAcceptHeader(kResolvedNavigatedUrl)); +} + +// Navigates to a lookalike URL (google-com.test.com) that serves a signed +// exchange for google-com.example.org. +// Both the outer URL (i.e. cache) and the inner URL are lookalikes so this +// should be blocked. +IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleSignedExchangeBrowserTest, + InnerAndOuterUrlsAreLookalikes_ShouldBlock) { + if (!target_embedding_enabled()) { + return; + } + InstallMockCert(); + InstallMockCertChainInterceptor(); + + sxg_test_helper_.InstallUrlInterceptor( + GURL("https://google-com.example.org/test/"), + "content/test/data/sxg/fallback.html"); + const GURL kNavigatedUrl = https_server_.GetURL( + "google-com.test.com", "/sxg/google-com.example.org_test.sxg"); + const GURL kExpectedSuggestedUrl("https://google.com"); TestMetricsRecordedAndInterstitialShown( browser(), kNavigatedUrl, kExpectedSuggestedUrl, - NavigationSuggestionEvent::kMatchTargetEmbedding); + NavigationSuggestionEvent::kMatchTargetEmbedding, + true /* expect_signed_exchange */); - // Check that no SXG response was handled. - ASSERT_FALSE(HadSignedExchangeInAcceptHeader(kNavigatedUrl)); - ASSERT_FALSE(HadSignedExchangeInAcceptHeader(kSgxTargetUrl)); + // Check that the SXG file was handled as a Signed Exchange. + // MonitorRequest() sees kNavigatedUrl with an IP address instead of + // domain name, so check it instead. + const GURL kResolvedNavigatedUrl = + https_server_.GetURL("/sxg/google-com.example.org_test.sxg"); + ASSERT_TRUE(HadSignedExchangeInAcceptHeader(kResolvedNavigatedUrl)); } + +// TODO(meacer): Add a test for a failed SGX response. It should be treated +// as a normal redirect. In fact, InnerAndOuterUrlsLookalikes_ShouldBlock +// is actually testing this right now, fix it.
diff --git a/chrome/browser/media/router/providers/cast/app_activity.cc b/chrome/browser/media/router/providers/cast/app_activity.cc index 1a7989d..09f89c1 100644 --- a/chrome/browser/media/router/providers/cast/app_activity.cc +++ b/chrome/browser/media/router/providers/cast/app_activity.cc
@@ -13,6 +13,7 @@ #include "base/stl_util.h" #include "chrome/browser/media/router/providers/cast/cast_activity_manager.h" #include "chrome/browser/media/router/providers/cast/cast_session_client.h" +#include "components/cast_channel/enum_table.h" #include "url/origin.h" using blink::mojom::PresentationConnectionCloseReason; @@ -111,7 +112,10 @@ if (session) { media_controller_->SetSession(*session); base::Value status_request(base::Value::Type::DICTIONARY); - status_request.SetKey("type", base::Value("MEDIA_GET_STATUS")); + status_request.SetStringKey( + "type", cast_util::EnumToString< + cast_channel::V2MessageType, + cast_channel::V2MessageType::kMediaGetStatus>()); message_handler_->SendMediaRequest(cast_channel_id(), status_request, media_controller_->sender_id(), session->transport_id());
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index 5f0c303..ff3e40d 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -931,6 +931,9 @@ { key::kPhoneHubTaskContinuationAllowed, chromeos::multidevice_setup::kPhoneHubTaskContinuationAllowedPrefName, base::Value::Type::BOOLEAN }, + { key::kWifiSyncAndroidAllowed, + chromeos::multidevice_setup::kWifiSyncAllowedPrefName, + base::Value::Type::BOOLEAN }, { key::kCaptivePortalAuthenticationIgnoresProxy, prefs::kCaptivePortalAuthenticationIgnoresProxy, base::Value::Type::BOOLEAN },
diff --git a/chrome/browser/prefetch/search_prefetch/field_trial_settings.cc b/chrome/browser/prefetch/search_prefetch/field_trial_settings.cc new file mode 100644 index 0000000..e556dc6 --- /dev/null +++ b/chrome/browser/prefetch/search_prefetch/field_trial_settings.cc
@@ -0,0 +1,12 @@ +// 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/prefetch/search_prefetch/field_trial_settings.h" + +const base::Feature kSearchPrefetchService{"SearchPrefecthService", + base::FEATURE_DISABLED_BY_DEFAULT}; + +bool SearchPrefetchServiceIsEnabled() { + return base::FeatureList::IsEnabled(kSearchPrefetchService); +}
diff --git a/chrome/browser/prefetch/search_prefetch/field_trial_settings.h b/chrome/browser/prefetch/search_prefetch/field_trial_settings.h new file mode 100644 index 0000000..b9fb4e0 --- /dev/null +++ b/chrome/browser/prefetch/search_prefetch/field_trial_settings.h
@@ -0,0 +1,14 @@ +// 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_PREFETCH_SEARCH_PREFETCH_FIELD_TRIAL_SETTINGS_H_ +#define CHROME_BROWSER_PREFETCH_SEARCH_PREFETCH_FIELD_TRIAL_SETTINGS_H_ + +#include "base/feature_list.h" + +extern const base::Feature kSearchPrefetchService; + +bool SearchPrefetchServiceIsEnabled(); + +#endif // CHROME_BROWSER_PREFETCH_SEARCH_PREFETCH_FIELD_TRIAL_SETTINGS_H_
diff --git a/chrome/browser/prefetch/search_prefetch/search_prefetch_service.cc b/chrome/browser/prefetch/search_prefetch/search_prefetch_service.cc new file mode 100644 index 0000000..33a898c --- /dev/null +++ b/chrome/browser/prefetch/search_prefetch/search_prefetch_service.cc
@@ -0,0 +1,14 @@ +// 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/prefetch/search_prefetch/search_prefetch_service.h" + +#include "chrome/browser/profiles/profile.h" + +SearchPrefetchService::SearchPrefetchService(Profile* profile) + : profile_(profile) { + DCHECK(!profile_->IsOffTheRecord()); +} + +SearchPrefetchService::~SearchPrefetchService() = default;
diff --git a/chrome/browser/prefetch/search_prefetch/search_prefetch_service.h b/chrome/browser/prefetch/search_prefetch/search_prefetch_service.h new file mode 100644 index 0000000..ed61519 --- /dev/null +++ b/chrome/browser/prefetch/search_prefetch/search_prefetch_service.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 CHROME_BROWSER_PREFETCH_SEARCH_PREFETCH_SEARCH_PREFETCH_SERVICE_H_ +#define CHROME_BROWSER_PREFETCH_SEARCH_PREFETCH_SEARCH_PREFETCH_SERVICE_H_ + +#include "components/keyed_service/core/keyed_service.h" + +class Profile; + +class SearchPrefetchService : public KeyedService { + public: + explicit SearchPrefetchService(Profile* profile); + ~SearchPrefetchService() override; + + private: + Profile* profile_; +}; + +#endif // CHROME_BROWSER_PREFETCH_SEARCH_PREFETCH_SEARCH_PREFETCH_SERVICE_H_
diff --git a/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc b/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc new file mode 100644 index 0000000..0ce8b1f --- /dev/null +++ b/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc
@@ -0,0 +1,52 @@ +// 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 "base/test/scoped_feature_list.h" +#include "chrome/browser/prefetch/search_prefetch/field_trial_settings.h" +#include "chrome/browser/prefetch/search_prefetch/search_prefetch_service.h" +#include "chrome/browser/prefetch/search_prefetch/search_prefetch_service_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" + +class SearchPrefetchServiceDisabledBrowserTest : public InProcessBrowserTest { + public: + SearchPrefetchServiceDisabledBrowserTest() { + feature_list_.InitAndDisableFeature(kSearchPrefetchService); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceDisabledBrowserTest, + ServiceNotCreatedWhenDisabled) { + EXPECT_EQ(nullptr, + SearchPrefetchServiceFactory::GetForProfile(browser()->profile())); +} + +class SearchPrefetchServiceEnabledBrowserTest : public InProcessBrowserTest { + public: + SearchPrefetchServiceEnabledBrowserTest() { + feature_list_.InitAndEnableFeature(kSearchPrefetchService); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest, + ServiceNotCreatedWhenIncognito) { + EXPECT_EQ(nullptr, SearchPrefetchServiceFactory::GetForProfile( + browser()->profile()->GetPrimaryOTRProfile())); +} + +IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceEnabledBrowserTest, + ServiceCreatedWhenFeatureEnabled) { + EXPECT_NE(nullptr, + SearchPrefetchServiceFactory::GetForProfile(browser()->profile())); +}
diff --git a/chrome/browser/prefetch/search_prefetch/search_prefetch_service_factory.cc b/chrome/browser/prefetch/search_prefetch/search_prefetch_service_factory.cc new file mode 100644 index 0000000..5c7c53e1 --- /dev/null +++ b/chrome/browser/prefetch/search_prefetch/search_prefetch_service_factory.cc
@@ -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. + +#include "chrome/browser/prefetch/search_prefetch/search_prefetch_service_factory.h" + +#include "chrome/browser/prefetch/search_prefetch/field_trial_settings.h" +#include "chrome/browser/prefetch/search_prefetch/search_prefetch_service.h" +#include "chrome/browser/profiles/profile.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "content/public/browser/browser_context.h" + +// static +SearchPrefetchService* SearchPrefetchServiceFactory::GetForProfile( + Profile* profile) { + if (SearchPrefetchServiceIsEnabled()) { + return static_cast<SearchPrefetchService*>( + GetInstance()->GetServiceForBrowserContext(profile, true)); + } + return nullptr; +} + +// static +SearchPrefetchServiceFactory* SearchPrefetchServiceFactory::GetInstance() { + static base::NoDestructor<SearchPrefetchServiceFactory> factory; + return factory.get(); +} + +SearchPrefetchServiceFactory::SearchPrefetchServiceFactory() + : BrowserContextKeyedServiceFactory( + "SearchPrefetchService", + BrowserContextDependencyManager::GetInstance()) {} + +SearchPrefetchServiceFactory::~SearchPrefetchServiceFactory() = default; + +KeyedService* SearchPrefetchServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + Profile* profile = Profile::FromBrowserContext(context); + return new SearchPrefetchService(profile); +}
diff --git a/chrome/browser/prefetch/search_prefetch/search_prefetch_service_factory.h b/chrome/browser/prefetch/search_prefetch/search_prefetch_service_factory.h new file mode 100644 index 0000000..c8bdbacd --- /dev/null +++ b/chrome/browser/prefetch/search_prefetch/search_prefetch_service_factory.h
@@ -0,0 +1,44 @@ +// 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_PREFETCH_SEARCH_PREFETCH_SEARCH_PREFETCH_SERVICE_FACTORY_H_ +#define CHROME_BROWSER_PREFETCH_SEARCH_PREFETCH_SEARCH_PREFETCH_SERVICE_FACTORY_H_ + +#include "base/macros.h" +#include "base/no_destructor.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +namespace content { +class BrowserContext; +} // namespace content + +class SearchPrefetchService; +class Profile; + +// LazyInstance that owns all SearchPrefetchServices and associates them +// with Profiles. +class SearchPrefetchServiceFactory : public BrowserContextKeyedServiceFactory { + public: + // Gets the SearchPrefetchService for the profile. + // + // Returns null if the features if not enabled or incognito. + static SearchPrefetchService* GetForProfile(Profile* profile); + + // Gets the LazyInstance that owns all SearchPrefetchService(s). + static SearchPrefetchServiceFactory* GetInstance(); + + private: + friend base::NoDestructor<SearchPrefetchServiceFactory>; + + SearchPrefetchServiceFactory(); + ~SearchPrefetchServiceFactory() override; + + // BrowserContextKeyedServiceFactory: + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; + + DISALLOW_COPY_AND_ASSIGN(SearchPrefetchServiceFactory); +}; + +#endif // CHROME_BROWSER_PREFETCH_SEARCH_PREFETCH_SEARCH_PREFETCH_SERVICE_FACTORY_H_
diff --git a/chrome/browser/reading_list/android/reading_list_manager_impl.cc b/chrome/browser/reading_list/android/reading_list_manager_impl.cc index 27385a5..10dd4749 100644 --- a/chrome/browser/reading_list/android/reading_list_manager_impl.cc +++ b/chrome/browser/reading_list/android/reading_list_manager_impl.cc
@@ -114,7 +114,13 @@ if (root_.get() == node) return true; - return Get(node->url()); + // Not recursive since there is only one level of children. + for (const auto& child : root_->children()) { + if (node == child.get()) + return true; + } + + return false; } void ReadingListManagerImpl::Delete(const GURL& url) {
diff --git a/chrome/browser/reading_list/android/reading_list_manager_impl_unittest.cc b/chrome/browser/reading_list/android/reading_list_manager_impl_unittest.cc index e0a97cc..612ed88 100644 --- a/chrome/browser/reading_list/android/reading_list_manager_impl_unittest.cc +++ b/chrome/browser/reading_list/android/reading_list_manager_impl_unittest.cc
@@ -8,6 +8,7 @@ #include <string> #include <utility> +#include "base/guid.h" #include "base/strings/utf_string_conversions.h" #include "base/test/simple_test_clock.h" #include "chrome/browser/reading_list/android/reading_list_manager.h" @@ -141,6 +142,11 @@ node = manager()->GetNodeByID(12345); EXPECT_FALSE(node); EXPECT_FALSE(manager()->IsReadingListBookmark(node)); + + // Node with the same URL but not in the tree. + auto node_same_url = + std::make_unique<BookmarkNode>(0, base::GenerateGUID(), url); + EXPECT_FALSE(manager()->IsReadingListBookmark(node_same_url.get())); } // Verifies Add() the same URL twice will not invalidate returned pointers, and
diff --git a/chrome/browser/resources/BUILD.gn b/chrome/browser/resources/BUILD.gn index 788683f..407faa9 100644 --- a/chrome/browser/resources/BUILD.gn +++ b/chrome/browser/resources/BUILD.gn
@@ -60,6 +60,9 @@ if (is_win || is_android || is_linux || is_chromeos) { deps += [ "sandbox_internals:closure_compile" ] } + if (is_linux || is_chromeos) { + deps += [ "webui_js_exception:closure_compile" ] + } if (is_chromeos) { deps += [ "chromeos:closure_compile", @@ -663,9 +666,23 @@ if (enable_webui_tab_strip) { grit("tab_strip_resources") { - source = "tab_strip/tab_strip_resources.grd" + grit_flags = [ + "-E", + "root_gen_dir=" + rebase_path(root_gen_dir, root_build_dir), + "-E", + "root_src_dir=" + rebase_path("//", root_build_dir), + ] + defines = chrome_grit_defines - deps = [ "tab_strip:web_components" ] + + # These arguments are needed since the grd is generated at build time. + enable_input_discovery_for_gn_analyze = false + defines += [ "SHARED_INTERMEDIATE_DIR=" + + rebase_path(root_gen_dir, root_build_dir) ] + tab_strip_gen_dir = "$root_gen_dir/chrome/browser/resources/tab_strip" + source = "$tab_strip_gen_dir/tab_strip_resources.grd" + deps = [ "//chrome/browser/resources/tab_strip:build_grd" ] + outputs = [ "grit/tab_strip_resources.h", "grit/tab_strip_resources_map.cc", @@ -673,10 +690,33 @@ "tab_strip_resources.pak", ] output_dir = "$root_gen_dir/chrome" + } +} + +if (is_linux || is_chromeos) { + grit("webui_js_exception_resources") { + if (optimize_webui) { + source = "webui_js_exception/webui_js_exception_resources_vulcanized.grd" + deps = [ "//chrome/browser/resources/webui_js_exception:build" ] + } else { + source = "webui_js_exception/webui_js_exception_resources.grd" + deps = + [ "//chrome/browser/resources/webui_js_exception:webui_js_exception" ] + } + grit_flags = [ "-E", "root_gen_dir=" + rebase_path(root_gen_dir, root_build_dir), ] + + defines = chrome_grit_defines + outputs = [ + "grit/webui_js_exception_resources.h", + "grit/webui_js_exception_resources_map.cc", + "grit/webui_js_exception_resources_map.h", + "webui_js_exception_resources.pak", + ] + output_dir = "$root_gen_dir/chrome" } }
diff --git a/chrome/browser/resources/chromeos/login/sync_consent.html b/chrome/browser/resources/chromeos/login/sync_consent.html index ed3c9546..21712caf 100644 --- a/chrome/browser/resources/chromeos/login/sync_consent.html +++ b/chrome/browser/resources/chromeos/login/sync_consent.html
@@ -89,7 +89,8 @@ <!-- "Chrome OS settings sync" --> <div class="overview-list-item layout horizontal center"> - <img class="overview-list-item-icon" src="images/settings_gear.svg" width="24" height="24"> + <img class="overview-list-item-icon" src="images/settings_gear.svg" + width="24" height="24" aria-hidden="true"> <div class="flex layout vertical center-justified"> <div role="heading" aria-level="2" class="overview-list-item-title" id="osSyncName" consent-description> [[i18nDynamic(locale, 'syncConsentScreenOsSyncName')]] @@ -102,7 +103,8 @@ <!-- "Chrome browser sync" --> <div class="overview-list-item layout horizontal center"> - <img class="overview-list-item-icon" src="images/browser_sync.svg" width="24" height="24"> + <img class="overview-list-item-icon" src="images/browser_sync.svg" + width="24" height="24" aria-hidden="true"> <div class="flex layout vertical center-justified"> <div role="heading" aria-level="2" class="overview-list-item-title" consent-description id="browserSyncName">
diff --git a/chrome/browser/resources/chromeos/login/user_creation.html b/chrome/browser/resources/chromeos/login/user_creation.html index c29afed4..4e1eccd6 100644 --- a/chrome/browser/resources/chromeos/login/user_creation.html +++ b/chrome/browser/resources/chromeos/login/user_creation.html
@@ -11,6 +11,9 @@ <template> <style include="oobe-dialog-host"> cr-card-radio-button { + /* Removes the highlight that appears on tap. It has sharp + * corners, which don't match the rounded corners of the card. */ + -webkit-tap-highlight-color: transparent; border-radius: 16px; height: 210px; margin-bottom: 20px;
diff --git a/chrome/browser/resources/safe_browsing/README.md b/chrome/browser/resources/safe_browsing/README.md index 4b6f8f2..a446ae9 100644 --- a/chrome/browser/resources/safe_browsing/README.md +++ b/chrome/browser/resources/safe_browsing/README.md
@@ -16,7 +16,7 @@ * Wait 1-3 day for this to run on Canary to verify it doesn't crash Chrome. * In a synced checkout, run the following to generate protos for all platforms and push them to GCS. Replace the arg with your build directory: - * % `chrome/browser/resources/safe_browsing/push_file_type_proto.py -d + * % `components/safe_browsing/core/resources/push_file_type_proto.py -d out-gn/Debug` * It will ask you to double check its actions before proceeding. It will fail if you're not a member of @@ -42,7 +42,7 @@ * **Upload** the new version of the file types. * In a synced checkout, run the following to generate protos for all platforms and push them to GCS. Replace the arg with your build directory: - * % `chrome/browser/resources/safe_browsing/push_file_type_proto.py -d + * % `components/safe_browsing/core/resources/push_file_type_proto.py -d out-gn/Debug` * Create a new cohort. * Under _Cohorts_, click _Manage_, then _Create Subcohort_ of Auto.
diff --git a/chrome/browser/resources/settings/a11y_page/a11y_page.html b/chrome/browser/resources/settings/a11y_page/a11y_page.html index 44d8b67..c050e22 100644 --- a/chrome/browser/resources/settings/a11y_page/a11y_page.html +++ b/chrome/browser/resources/settings/a11y_page/a11y_page.html
@@ -27,7 +27,7 @@ </template> </template> <template is="dom-if" if="[[!captionSettingsOpensExternally_]]"> - <cr-link-row class="first" + <cr-link-row class="first" id="captions" label="$i18n{captionsTitle}" on-click="onCaptionsClick_" role-description="$i18n{subpageArrowRoleDescription}">
diff --git a/chrome/browser/resources/settings/a11y_page/captions_subpage.html b/chrome/browser/resources/settings/a11y_page/captions_subpage.html index f6e0e9e..ae06ffa 100644 --- a/chrome/browser/resources/settings/a11y_page/captions_subpage.html +++ b/chrome/browser/resources/settings/a11y_page/captions_subpage.html
@@ -156,7 +156,7 @@ pref="{{prefs.accessibility.captions.live_caption_enabled}}" on-change="onA11yLiveCaptionChange_" label="$i18n{captionsEnableLiveCaptionTitle}" - sub-label="$i18n{captionsEnableLiveCaptionSubtitle}"> + sub-label="[[enableLiveCaptionSubtitle_]]"> </settings-toggle-button> </div> </template>
diff --git a/chrome/browser/resources/settings/a11y_page/captions_subpage.js b/chrome/browser/resources/settings/a11y_page/captions_subpage.js index 7dd750267..c4d29e2 100644 --- a/chrome/browser/resources/settings/a11y_page/captions_subpage.js +++ b/chrome/browser/resources/settings/a11y_page/captions_subpage.js
@@ -6,6 +6,7 @@ * @fileoverview 'settings-captions' is a component for showing captions * settings subpage (chrome://settings/captions). */ + (function() { Polymer({ @@ -175,6 +176,17 @@ return loadTimeData.getBoolean('enableLiveCaption'); }, }, + + /** + * The subtitle to display under the Live Caption heading. Generally, this + * is a generic subtitle describing the feature. While the SODA model is + * being downloading, this displays the download progress. + * @private + */ + enableLiveCaptionSubtitle_: { + type: String, + value: loadTimeData.getString('captionsEnableLiveCaptionSubtitle'), + }, }, /** @private {?settings.FontsBrowserProxy} */ @@ -188,6 +200,11 @@ /** @override */ ready() { this.browserProxy_.fetchFontsData().then(this.setFontsData_.bind(this)); + + this.addWebUIListener( + 'enable-live-caption-subtitle-changed', + this.onEnableLiveCaptionSubtitleChanged_.bind(this)); + chrome.send('captionsSubpageReady'); }, /** @@ -288,5 +305,14 @@ chrome.metricsPrivate.recordBoolean( 'Accessibility.LiveCaption.ToggleEnabled', a11yLiveCaptionOn); }, + + /** + * @private + * @param {!string} enableLiveCaptionSubtitle The message sent from the webui + * to be displayed as a subtitle to Live Captions. + */ + onEnableLiveCaptionSubtitleChanged_(enableLiveCaptionSubtitle) { + this.enableLiveCaptionSubtitle_ = enableLiveCaptionSubtitle; + }, }); })();
diff --git a/chrome/browser/resources/settings/chromeos/bluetooth_page/bluetooth_device_list_item.js b/chrome/browser/resources/settings/chromeos/bluetooth_page/bluetooth_device_list_item.js index e9d7c096..1a9cf089 100644 --- a/chrome/browser/resources/settings/chromeos/bluetooth_page/bluetooth_device_list_item.js +++ b/chrome/browser/resources/settings/chromeos/bluetooth_page/bluetooth_device_list_item.js
@@ -126,16 +126,22 @@ * @private */ getAriaLabel_(device) { - // We need to turn the device name and type into a single localized string. + // We need to turn the device name, connection status and type into a single + // localized string. // The possible device type enum values can be seen here: // https://developer.chrome.com/apps/bluetooth#type-Device. // The localization id is computed dynamically to avoid maintaining a // mapping from the enum string value to the localization id. // if device.type is not defined, we fall back to an unknown device string. const deviceName = this.getDeviceName_(device); - return (device.type) ? + const deviceStatus = this.getConnectionStatusText_(device); + + const a11ydeviceNameAndType = (device.type) ? this.i18n('bluetoothDeviceType_' + device.type, deviceName) : this.i18n('bluetoothDeviceType_unknown', deviceName); + return this.i18n( + 'bluetoothDeviceWithConnectionStatus', a11ydeviceNameAndType, + deviceStatus); }, /**
diff --git a/chrome/browser/resources/settings/chromeos/device_page/pointers.html b/chrome/browser/resources/settings/chromeos/device_page/pointers.html index a58258f..5c781ea9 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/pointers.html +++ b/chrome/browser/resources/settings/chromeos/device_page/pointers.html
@@ -36,9 +36,9 @@ } </style> <div id="mouse" hidden$="[[!showMouseSection_]]"> - <!-- Subsection title only appears if both mouse and touchpad exist. --> - <h2 hidden$="[[!hasTouchpad]]">$i18n{mouseTitle}</h2> - <div class$="[[getSubsectionClass_(showMouseSection_, hasTouchpad)]]"> + <!-- Subsection title only appears if multiple sections are visible. --> + <h2 hidden$="[[!showHeadings_]]">$i18n{mouseTitle}</h2> + <div class$="[[subsectionClass_]]"> <!-- Do not change the mouse button pref before the mouse is released. See crbug.com/686949 --> <div class="settings-box"> @@ -108,10 +108,19 @@ </div> </div> </div> + <template is="dom-if" if="[[separatePointingStickSettings_]]"> + <div id="pointingStick" hidden$="[[!hasPointingStick]]"> + <!-- Subsection title only appears if multiple sections are visible. --> + <h2 hidden$="[[!showHeadings_]]">$i18n{pointingStickTitle}</h2> + <div class$="[[subsectionClass_]]"> + (Settings not implemented yet) + </div> + </div> + </template> <div id="touchpad" hidden$="[[!hasTouchpad]]"> - <!-- Subsection title only appears if both mouse and touchpad exist. --> - <h2 hidden$="[[!showMouseSection_]]">$i18n{touchpadTitle}</h2> - <div class$="[[getSubsectionClass_(showMouseSection_, hasTouchpad)]]"> + <!-- Subsection title only appears if multiple sections are visible. --> + <h2 hidden$="[[!showHeadings_]]">$i18n{touchpadTitle}</h2> + <div class$="[[subsectionClass_]]"> <settings-toggle-button id="enableTapToClick" pref="{{prefs.settings.touchpad.enable_tap_to_click}}" label="$i18n{touchpadTapToClickEnabledLabel}"
diff --git a/chrome/browser/resources/settings/chromeos/device_page/pointers.js b/chrome/browser/resources/settings/chromeos/device_page/pointers.js index 065a483..88d4767e 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/pointers.js +++ b/chrome/browser/resources/settings/chromeos/device_page/pointers.js
@@ -51,7 +51,20 @@ */ showMouseSection_: { type: Boolean, - computed: 'computeShowMouseSection_(hasMouse, hasPointingStick)', + computed: 'computeShowMouseSection_(separatePointingStickSettings_, ' + + 'hasMouse, hasPointingStick)', + }, + + showHeadings_: { + type: Boolean, + computed: 'computeShowHeadings_(separatePointingStickSettings_, ' + + 'hasMouse, hasPointingStick, hasTouchpad)', + }, + + subsectionClass_: { + type: String, + computed: 'computeSubsectionClass_(separatePointingStickSettings_, ' + + 'hasMouse, hasPointingStick, hasTouchpad)', }, /** @@ -90,6 +103,18 @@ }, /** + * TODO(crbug.com/1114828): Remove this conditional once the feature is + * launched. + * @private + */ + separatePointingStickSettings_: { + type: Boolean, + value() { + return loadTimeData.getBoolean('separatePointingStickSettings'); + }, + }, + + /** * Used by DeepLinkingBehavior to focus this page's deep links. * @type {!Set<!chromeos.settings.mojom.Setting>} */ @@ -112,11 +137,49 @@ }, /** + * @param {boolean} separateSettings * @param {boolean} hasMouse * @param {boolean} hasPointingStick */ - computeShowMouseSection_(hasMouse, hasPointingStick) { - return hasMouse || hasPointingStick; + computeShowMouseSection_(separateSettings, hasMouse, hasPointingStick) { + return separateSettings ? hasMouse : hasMouse || hasPointingStick; + }, + + /** + * Headings should only be visible if more than one subsection is present. + * @param {boolean} separateSettings + * @param {boolean} hasMouse + * @param {boolean} hasPointingStick + * @param {boolean} hasTouchpad + * @return {boolean} + * @private + */ + computeShowHeadings_( + separateSettings, hasMouse, hasPointingStick, hasTouchpad) { + if (!separateSettings) { + return (hasMouse || hasPointingStick) && hasTouchpad; + } + const sectionVisibilities = [hasMouse, hasPointingStick, hasTouchpad]; + // Count the number of true values in sectionVisibilities. + const numVisibleSections = sectionVisibilities.filter(x => x).length; + return numVisibleSections > 1; + }, + + /** + * Mouse, pointing stick, and touchpad sections are only subsections if more + * than one is present. + * @param {boolean} separateSettings + * @param {boolean} hasMouse + * @param {boolean} hasPointingStick + * @param {boolean} hasTouchpad + * @return {string} + * @private + */ + computeSubsectionClass_( + separateSettings, hasMouse, hasPointingStick, hasTouchpad) { + const subsections = this.computeShowHeadings_( + separateSettings, hasMouse, hasPointingStick, hasTouchpad); + return subsections ? 'subsection' : ''; }, /** @@ -133,17 +196,6 @@ }, /** - * Mouse and touchpad sections are only subsections if they are both present. - * @param {boolean} showMouseSection - * @param {boolean} hasTouchpad - * @return {string} - * @private - */ - getSubsectionClass_(showMouseSection, hasTouchpad) { - return showMouseSection && hasTouchpad ? 'subsection' : ''; - }, - - /** * @param {!Event} event * @private */
diff --git a/chrome/browser/resources/settings/people_page/sync_browser_proxy.js b/chrome/browser/resources/settings/people_page/sync_browser_proxy.js index 97f632a..1524971 100644 --- a/chrome/browser/resources/settings/people_page/sync_browser_proxy.js +++ b/chrome/browser/resources/settings/people_page/sync_browser_proxy.js
@@ -199,6 +199,8 @@ * @param {!settings.SyncPrefs} syncPrefs * @return {!Promise<!settings.PageStatus>} */ + // TODO(crbug.com/1139060): Use a clear signature which doesn't rely on + // syncPrefs. setSyncEncryption(syncPrefs) {} /**
diff --git a/chrome/browser/resources/settings/people_page/sync_encryption_options.js b/chrome/browser/resources/settings/people_page/sync_encryption_options.js index ae8e9e8..98d8f48 100644 --- a/chrome/browser/resources/settings/people_page/sync_encryption_options.js +++ b/chrome/browser/resources/settings/people_page/sync_encryption_options.js
@@ -139,7 +139,7 @@ chrome.metricsPrivate.recordUserAction('Sync_SaveNewPassphraseClicked'); // Might happen within the transient time between the request to // |setSyncEncryption| and receiving the response. - if (this.syncPrefs.encryptAllData) { + if (this.syncPrefs.setNewPassphrase) { return; } // If a new password has been entered but it is invalid, do not send the @@ -148,7 +148,6 @@ return; } - this.syncPrefs.encryptAllData = true; this.syncPrefs.setNewPassphrase = true; this.syncPrefs.passphrase = this.passphrase_;
diff --git a/chrome/browser/resources/tab_strip/BUILD.gn b/chrome/browser/resources/tab_strip/BUILD.gn index 93030f62..0707412 100644 --- a/chrome/browser/resources/tab_strip/BUILD.gn +++ b/chrome/browser/resources/tab_strip/BUILD.gn
@@ -3,7 +3,68 @@ # found in the LICENSE file. import("//third_party/closure_compiler/compile_js.gni") +import("//tools/grit/preprocess_grit.gni") import("//tools/polymer/html_to_js.gni") +import("//ui/webui/resources/tools/generate_grd.gni") + +preprocess_folder = "preprocessed" +preprocess_manifest = "preprocessed_manifest.json" +preprocess_gen_manifest = "preprocessed_gen_manifest.json" + +generate_grd("build_grd") { + grd_prefix = "tab_strip" + out_grd = "$target_gen_dir/${grd_prefix}_resources.grd" + input_files = [ + "alert_indicators/picture_in_picture_alt.svg", + "alert_indicators/serial_port.svg", + "alert_indicators/tab_audio_muting_rounded.svg", + "alert_indicators/tab_audio_rounded.svg", + "alert_indicators/tab_bluetooth_connected.svg", + "alert_indicators/tab_hid_connected.svg", + "alert_indicators/tab_media_capturing_with_arrow.svg", + "alert_indicators/tab_media_recording.svg", + "alert_indicators/tab_usb_connected.svg", + "alert_indicators/vr_headset.svg", + "tab_strip.html", + ] + input_files_base_dir = rebase_path(".", "//") + + deps = [ + ":preprocess", + ":preprocess_generated", + ] + manifest_files = [ + "$target_gen_dir/$preprocess_manifest", + "$target_gen_dir/$preprocess_gen_manifest", + ] +} + +preprocess_grit("preprocess") { + in_folder = "./" + out_folder = "$target_gen_dir/$preprocess_folder" + out_manifest = "$target_gen_dir/$preprocess_manifest" + in_files = [ + "custom_element.js", + "drag_manager.js", + "tab_strip_embedder_proxy.js", + "tab_swiper.js", + "tabs_api_proxy.js", + ] +} + +preprocess_grit("preprocess_generated") { + deps = [ ":web_components" ] + in_folder = target_gen_dir + out_folder = "$target_gen_dir/$preprocess_folder" + out_manifest = "$target_gen_dir/$preprocess_gen_manifest" + in_files = [ + "alert_indicator.js", + "alert_indicators.js", + "tab_group.js", + "tab_list.js", + "tab.js", + ] +} js_type_check("closure_compile") { uses_js_modules = true
diff --git a/chrome/browser/resources/tab_strip/tab_strip_resources.grd b/chrome/browser/resources/tab_strip/tab_strip_resources.grd deleted file mode 100644 index 7f8d71a..0000000 --- a/chrome/browser/resources/tab_strip/tab_strip_resources.grd +++ /dev/null
@@ -1,113 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<grit latest_public_release="0" current_release="1" output_all_resource_defines="false"> - <outputs> - <output filename="grit/tab_strip_resources.h" type="rc_header"> - <emit emit_type='prepend'></emit> - </output> - <output filename="grit/tab_strip_resources_map.cc" - type="resource_file_map_source" /> - <output filename="grit/tab_strip_resources_map.h" - type="resource_map_header" /> - <output filename="tab_strip_resources.pak" type="data_package" /> - </outputs> - <release seq="1"> - <structures> - <structure - name="IDR_TAB_STRIP_HTML" - file="tab_strip.html" - type="chrome_html" - preprocess="true"/> - <structure - name="IDR_TAB_STRIP_TABS_API_PROXY_JS" - file="tabs_api_proxy.js" - type="chrome_html"/> - <structure - name="IDR_TAB_STRIP_CUSTOM_ELEMENT_JS" - file="custom_element.js" - type="chrome_html"/> - <structure - name="IDR_TAB_STRIP_TAB_GROUP_JS" - file="${root_gen_dir}/chrome/browser/resources/tab_strip/tab_group.js" - use_base_dir="false" - type="chrome_html"/> - <structure - name="IDR_TAB_STRIP_TAB_LIST_JS" - file="${root_gen_dir}/chrome/browser/resources/tab_strip/tab_list.js" - use_base_dir="false" - type="chrome_html" - preprocess="true"/> - <structure - name="IDR_TAB_STRIP_TAB_JS" - file="${root_gen_dir}/chrome/browser/resources/tab_strip/tab.js" - use_base_dir="false" - type="chrome_html"/> - <structure - name="IDR_TAB_STRIP_ALERT_INDICATOR_JS" - file="${root_gen_dir}/chrome/browser/resources/tab_strip/alert_indicator.js" - use_base_dir="false" - type="chrome_html"/> - <structure - name="IDR_TAB_STRIP_ALERT_INDICATORS_JS" - file="${root_gen_dir}/chrome/browser/resources/tab_strip/alert_indicators.js" - use_base_dir="false" - type="chrome_html"/> - <structure - name="IDR_TAB_STRIP_EMBEDDER_PROXY_JS" - file="tab_strip_embedder_proxy.js" - type="chrome_html"/> - <structure - name="IDR_TAB_STRIP_TAB_SWIPER_JS" - file="tab_swiper.js" - type="chrome_html"/> - <structure - name="IDR_TAB_STRIP_DRAG_MANAGER_JS" - file="drag_manager.js" - type="chrome_html" - preprocess="true"/> - </structures> - - <includes> - <!-- Alert indicators --> - <include - name="IDR_TAB_STRIP_PICTURE_IN_PICTURE_ALT_SVG" - file="alert_indicators/picture_in_picture_alt.svg" - type="BINDATA" /> - <include - name="IDR_TAB_STRIP_SERIAL_PORT_SVG" - file="alert_indicators/serial_port.svg" - type="BINDATA" /> - <include - name="IDR_TAB_STRIP_TAB_AUDIO_MUTING_ROUNDED_SVG" - file="alert_indicators/tab_audio_muting_rounded.svg" - type="BINDATA" /> - <include - name="IDR_TAB_STRIP_TAB_AUDIO_ROUNDED_SVG" - file="alert_indicators/tab_audio_rounded.svg" - type="BINDATA" /> - <include - name="IDR_TAB_STRIP_TAB_BLUETOOTH_CONNECTED_SVG" - file="alert_indicators/tab_bluetooth_connected.svg" - type="BINDATA" /> - <include - name="IDR_TAB_STRIP_TAB_HID_CONNECTED_SVG" - file="alert_indicators/tab_hid_connected.svg" - type="BINDATA" /> - <include - name="IDR_TAB_STRIP_TAB_MEDIA_CAPTURING_WITH_ARROW_SVG" - file="alert_indicators/tab_media_capturing_with_arrow.svg" - type="BINDATA" /> - <include - name="IDR_TAB_STRIP_TAB_MEDIA_RECORING_SVG" - file="alert_indicators/tab_media_recording.svg" - type="BINDATA" /> - <include - name="IDR_TAB_STRIP_TAB_USB_CONNECTED_SVG" - file="alert_indicators/tab_usb_connected.svg" - type="BINDATA" /> - <include - name="IDR_TAB_STRIP_VR_HEADSET_SVG" - file="alert_indicators/vr_headset.svg" - type="BINDATA" /> - </includes> - </release> -</grit>
diff --git a/chrome/browser/resources/webui_js_exception/BUILD.gn b/chrome/browser/resources/webui_js_exception/BUILD.gn new file mode 100644 index 0000000..c62fa2f --- /dev/null +++ b/chrome/browser/resources/webui_js_exception/BUILD.gn
@@ -0,0 +1,54 @@ +# 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/browser/resources/optimize_webui.gni") +import("//third_party/closure_compiler/compile_js.gni") +import("//tools/grit/grit_rule.gni") +import("//ui/webui/webui_features.gni") + +js_library("webui_js_exception") { +} + +if (optimize_webui) { + grit("flattened_resources") { + source = "webui_js_exception_resources.grd" + + deps = [ ":webui_js_exception" ] + + grit_flags = [ + "-E", + "root_gen_dir=" + rebase_path(root_gen_dir, root_build_dir), + ] + + outputs = [ + "grit/webui_js_exception_resources.h", + "grit/webui_js_exception_resources_map.cc", + "grit/webui_js_exception_resources_map.h", + "webui_js_exception_resources.pak", + ] + output_dir = "$root_gen_dir/chrome/browser/resources/webui_js_exception" + } + + unpak("unpak") { + pak_file = "webui_js_exception_resources.pak" + out_folder = "unpak" + deps = [ ":flattened_resources" ] + } + + optimize_webui("build") { + host = "webui_js_exception" + input = rebase_path("$target_gen_dir/unpak", root_build_dir) + deps = [ + ":unpak", + "//ui/webui/resources:modulize", + ] + js_module_in_files = [ "webui_js_exception.js" ] + js_out_files = [ "webui_js_exception.rollup.js" ] + excludes = [ "chrome://resources/js/cr.m.js" ] + } +} + +js_type_check("closure_compile") { + deps = [ ":webui_js_exception" ] +}
diff --git a/chrome/browser/resources/webui_js_exception/webui_js_exception.html b/chrome/browser/resources/webui_js_exception/webui_js_exception.html new file mode 100644 index 0000000..180d788 --- /dev/null +++ b/chrome/browser/resources/webui_js_exception/webui_js_exception.html
@@ -0,0 +1,25 @@ +<!doctype html> +<html> + <head> + <meta charset="utf-8"> + <!-- Title is not localized since this is just a debugging page --> + <title>WebUI JS Exception Page</title> + <style> + html, + body { + height: 100%; + overflow: hidden; + } + + body { + margin: 0; + } + </style> + </head> + <body> + <!-- Text not localized since this is just a debugging page --> + This page generates a JavaScript exception on load and then another 3 + seconds later. + <script type="module" src="webui_js_exception.js"></script> + </body> +</html>
diff --git a/chrome/browser/resources/webui_js_exception/webui_js_exception.js b/chrome/browser/resources/webui_js_exception/webui_js_exception.js new file mode 100644 index 0000000..685521c --- /dev/null +++ b/chrome/browser/resources/webui_js_exception/webui_js_exception.js
@@ -0,0 +1,45 @@ +// 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 This JavaScript throws an unhandled exception on page load, and + * then another 3 seconds later. + * + * Note that function names and error text are referenced in integration tests + * (particularly tast tests); do not change them without updating the tests. + */ + +/** + * Throws an exception when called. This throws the "after 3 seconds" exception. + */ +function throwExceptionAfterTimeoutFunction() { + throwExceptionAfterTimeoutInner(); +} + +/** + * Throws an exception when called. This is a separate function from + * throwExceptionAfterTimeoutFunction() so that we get an interesting stack. + */ +function throwExceptionAfterTimeoutInner() { + throw new Error('WebUI JS Exception: timeout expired'); +} + +/** + * Throws an exception when called. This throws the "during page load" + * exception. + */ +function throwExceptionDuringPageLoadFunction() { + throwExceptionDuringPageLoadInner(); +} + +/** + * Throws an exception when called. This is a separate function from + * throwExceptionDuringPageLoadFunction() so that we get an interesting stack. + */ +function throwExceptionDuringPageLoadInner() { + throw new Error('WebUI JS Exception: exception on page load'); +} + +setTimeout(throwExceptionAfterTimeoutFunction, 3000); +throwExceptionDuringPageLoadFunction();
diff --git a/chrome/browser/resources/webui_js_exception/webui_js_exception_resources.grd b/chrome/browser/resources/webui_js_exception/webui_js_exception_resources.grd new file mode 100644 index 0000000..9946d94 --- /dev/null +++ b/chrome/browser/resources/webui_js_exception/webui_js_exception_resources.grd
@@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<grit latest_public_release="0" current_release="1" output_all_resource_defines="false"> + <outputs> + <output filename="grit/webui_js_exception_resources.h" type="rc_header"> + <emit emit_type='prepend'></emit> + </output> + <output filename="grit/webui_js_exception_resources_map.cc" + type="resource_file_map_source" /> + <output filename="grit/webui_js_exception_resources_map.h" + type="resource_map_header" /> + <output filename="webui_js_exception_resources.pak" type="data_package" /> + </outputs> + <release seq="1"> + <structures> + <structure name="IDR_WEBUI_JS_EXCEPTION_UI_WEBUI_JS_EXCEPTION_JS" + file="webui_js_exception.js" type="chrome_html" compress="false" /> + <structure name="IDR_WEBUI_JS_EXCEPTION_UI_WEBUI_JS_EXCEPTION_HTML" + file="webui_js_exception.html" type="chrome_html" compress="false" /> + </structures> + </release> +</grit>
diff --git a/chrome/browser/resources/webui_js_exception/webui_js_exception_resources_vulcanized.grd b/chrome/browser/resources/webui_js_exception/webui_js_exception_resources_vulcanized.grd new file mode 100644 index 0000000..e410c66 --- /dev/null +++ b/chrome/browser/resources/webui_js_exception/webui_js_exception_resources_vulcanized.grd
@@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<grit latest_public_release="0" current_release="1" output_all_resource_defines="false"> + <outputs> + <output filename="grit/webui_js_exception_resources.h" type="rc_header"> + <emit emit_type='prepend'></emit> + </output> + <output filename="grit/webui_js_exception_resources_map.cc" + type="resource_map_source" /> + <output filename="grit/webui_js_exception_resources_map.h" + type="resource_map_header" /> + <output filename="webui_js_exception_resources.pak" type="data_package" /> + </outputs> + <release seq="1"> + <includes> + <include name="IDR_WEBUI_JS_EXCEPTION_UI_WEBUI_JS_EXCEPTION_ROLLUP_JS" + file="${root_gen_dir}/chrome/browser/resources/webui_js_exception/webui_js_exception.rollup.js" + use_base_dir="false" type="BINDATA" /> + <include name="IDR_WEBUI_JS_EXCEPTION_UI_WEBUI_JS_EXCEPTION_HTML" + file="webui_js_exception.html" preprocess="true" type="BINDATA" /> + </includes> + </release> +</grit>
diff --git a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc index e6277e89..d3df33d 100644 --- a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc +++ b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
@@ -342,6 +342,12 @@ if (g_browser_process->profile_manager()) g_browser_process->profile_manager()->RemoveObserver(this); + + for (const auto& profile_and_context : profiles_) { + Profile* profile = profile_and_context.first; + if (profile) + profile->RemoveObserver(this); + } } std::unique_ptr<IncidentReceiver> @@ -478,6 +484,28 @@ BeginDownloadCollection(); } +void IncidentReportingService::OnProfileWillBeDestroyed(Profile* profile) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + profile->RemoveObserver(this); + + auto it = profiles_.find(profile); + DCHECK(it != profiles_.end()); + + // Take ownership of the context. + std::unique_ptr<ProfileContext> context = std::move(it->second); + + // TODO(grt): Persist incidents for upload on future profile load. + + // Remove the association with this profile context from all pending uploads. + for (const auto& upload : uploads_) + upload->profiles_to_state.erase(context.get()); + + // Forget about this profile. Incidents not yet sent for upload are lost. + // No new incidents will be accepted for it. + profiles_.erase(it); +} + std::unique_ptr<LastDownloadFinder> IncidentReportingService::CreateDownloadFinder( const LastDownloadFinder::LastDownloadCallback& callback) { @@ -502,8 +530,11 @@ IncidentReportingService::ProfileContext* IncidentReportingService::GetOrCreateProfileContext(Profile* profile) { std::unique_ptr<ProfileContext>& context = profiles_[profile]; - if (!context) + if (!context) { context = std::make_unique<ProfileContext>(); + if (profile) + profile->AddObserver(this); + } return context.get(); }
diff --git a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h index 0c170b3..037a06c 100644 --- a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h +++ b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h
@@ -74,7 +74,8 @@ // the initial incident. Finally, already-reported incidents are pruned and any // remaining are uploaded in an incident report. // Lives on the UI thread. -class IncidentReportingService : public ProfileManagerObserver { +class IncidentReportingService : public ProfileManagerObserver, + public ProfileObserver { public: explicit IncidentReportingService(SafeBrowsingService* safe_browsing_service); @@ -107,6 +108,9 @@ // ProfileManagerObserver: void OnProfileAdded(Profile* profile) override; + // ProfileObserver: + void OnProfileWillBeDestroyed(Profile* profile) override; + protected: // A pointer to a function that populates a protobuf with environment data. typedef void (*CollectEnvironmentDataFn)(
diff --git a/chrome/browser/safe_browsing/incident_reporting/last_download_finder.cc b/chrome/browser/safe_browsing/incident_reporting/last_download_finder.cc index 0e70841a..0c587165 100644 --- a/chrome/browser/safe_browsing/incident_reporting/last_download_finder.cc +++ b/chrome/browser/safe_browsing/incident_reporting/last_download_finder.cc
@@ -236,6 +236,8 @@ LastDownloadFinder::~LastDownloadFinder() { g_browser_process->profile_manager()->RemoveObserver(this); + for (const auto& state : profile_states_) + state.first->RemoveObserver(this); } // static @@ -278,6 +280,8 @@ if (profile_states_.count(profile)) return; + profile->AddObserver(this); + // Initiate a metadata search. As with IncidentReportingService, it's assumed // that all passed profiles will outlive |this|. profile_states_[profile] = WAITING_FOR_METADATA; @@ -361,6 +365,7 @@ void LastDownloadFinder::RemoveProfileAndReportIfDone( std::map<Profile*, ProfileWaitState>::iterator iter) { DCHECK(iter != profile_states_.end()); + iter->first->RemoveObserver(this); profile_states_.erase(iter); // Finish processing if all results are in. @@ -400,6 +405,13 @@ SearchInProfile(profile); } +void LastDownloadFinder::OnProfileWillBeDestroyed(Profile* profile) { + // |profile| may not be present in the set of profiles. + auto iter = profile_states_.find(profile); + DCHECK(iter != profile_states_.end()); + RemoveProfileAndReportIfDone(iter); +} + void LastDownloadFinder::OnHistoryServiceLoaded( history::HistoryService* history_service) { for (const auto& pair : profile_states_) {
diff --git a/chrome/browser/safe_browsing/incident_reporting/last_download_finder.h b/chrome/browser/safe_browsing/incident_reporting/last_download_finder.h index cf4f652b..804b9f8 100644 --- a/chrome/browser/safe_browsing/incident_reporting/last_download_finder.h +++ b/chrome/browser/safe_browsing/incident_reporting/last_download_finder.h
@@ -15,6 +15,7 @@ #include "base/memory/weak_ptr.h" #include "base/scoped_observer.h" #include "chrome/browser/profiles/profile_manager_observer.h" +#include "chrome/browser/profiles/profile_observer.h" #include "chrome/browser/safe_browsing/incident_reporting/download_metadata_manager.h" #include "components/history/core/browser/download_row.h" #include "components/history/core/browser/history_service.h" @@ -31,6 +32,7 @@ // any on-the-record profile with history that participates in safe browsing // extended reporting. class LastDownloadFinder : public ProfileManagerObserver, + public ProfileObserver, public history::HistoryServiceObserver { public: typedef base::Callback<void( @@ -101,6 +103,9 @@ // ProfileManagerObserver: void OnProfileAdded(Profile* profile) override; + // ProfileObserver: + void OnProfileWillBeDestroyed(Profile* profile) override; + // history::HistoryServiceObserver: void OnHistoryServiceLoaded(history::HistoryService* service) override; void HistoryServiceBeingDeleted(
diff --git a/chrome/browser/sync/profile_sync_service_android.cc b/chrome/browser/sync/profile_sync_service_android.cc index d790875..301624cf0 100644 --- a/chrome/browser/sync/profile_sync_service_android.cc +++ b/chrome/browser/sync/profile_sync_service_android.cc
@@ -278,13 +278,6 @@ return sync_service_->GetUserSettings()->IsEncryptEverythingEnabled(); } -void ProfileSyncServiceAndroid::EnableEncryptEverything( - JNIEnv* env, - const JavaParamRef<jobject>& obj) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - sync_service_->GetUserSettings()->EnableEncryptEverything(); -} - jboolean ProfileSyncServiceAndroid::IsPassphraseRequiredForPreferredDataTypes( JNIEnv* env, const JavaParamRef<jobject>& obj) {
diff --git a/chrome/browser/sync/profile_sync_service_android.h b/chrome/browser/sync/profile_sync_service_android.h index 28dbd24..50d8921 100644 --- a/chrome/browser/sync/profile_sync_service_android.h +++ b/chrome/browser/sync/profile_sync_service_android.h
@@ -87,8 +87,6 @@ jboolean IsEncryptEverythingEnabled( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); - void EnableEncryptEverything(JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj); jboolean IsPassphraseRequiredForPreferredDataTypes( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
diff --git a/chrome/browser/sync/profile_sync_service_factory.cc b/chrome/browser/sync/profile_sync_service_factory.cc index 8b3b7aa..e1dc8ce5 100644 --- a/chrome/browser/sync/profile_sync_service_factory.cc +++ b/chrome/browser/sync/profile_sync_service_factory.cc
@@ -47,19 +47,14 @@ #include "chrome/common/buildflags.h" #include "chrome/common/channel_info.h" #include "components/autofill/core/browser/personal_data_manager.h" -#include "components/autofill/core/common/autofill_features.h" -#include "components/browser_sync/browser_sync_switches.h" -#include "components/invalidation/impl/invalidation_switches.h" #include "components/invalidation/impl/profile_identity_provider.h" #include "components/invalidation/impl/profile_invalidation_provider.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/network_time/network_time_tracker.h" -#include "components/password_manager/core/common/password_manager_features.h" #include "components/sync/driver/profile_sync_service.h" #include "components/sync/driver/sync_driver_switches.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" #include "content/public/browser/network_service_instance.h" #include "content/public/browser/storage_partition.h" #include "extensions/buildflags/buildflags.h" @@ -190,7 +185,8 @@ : std::make_unique<browser_sync::ChromeSyncClient>(profile); init_params.sync_client = std::move(sync_client); - init_params.network_time_update_callback = base::Bind(&UpdateNetworkTime); + init_params.network_time_update_callback = + base::BindRepeating(&UpdateNetworkTime); init_params.url_loader_factory = content::BrowserContext::GetDefaultStoragePartition(profile) ->GetURLLoaderFactoryForBrowserProcess(); @@ -198,11 +194,6 @@ content::GetNetworkConnectionTracker(); init_params.channel = chrome::GetChannel(); init_params.debug_identifier = profile->GetDebugName(); - init_params.autofill_enable_account_wallet_storage = - base::FeatureList::IsEnabled( - autofill::features::kAutofillEnableAccountWalletStorage); - init_params.enable_passwords_account_storage = base::FeatureList::IsEnabled( - password_manager::features::kEnablePasswordsAccountStorage); bool local_sync_backend_enabled = false;
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index c9226f8..1daa9fb 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -306,13 +306,6 @@ "webui/webui_util.h", ] - if (is_win || is_mac) { - sources += [ - "webui/settings/captions_handler.cc", - "webui/settings/captions_handler.h", - ] - } - if (safe_browsing_mode == 1) { sources += [ "webui/reset_password/reset_password_ui.cc", @@ -1563,6 +1556,13 @@ deps += [ "//ui/base/ime/linux" ] } + if (!is_chromeos) { + sources += [ + "webui/settings/captions_handler.cc", + "webui/settings/captions_handler.h", + ] + } + if (!toolkit_views) { sources += [ "media_router/cloud_services_dialog.cc" ] } @@ -2443,6 +2443,8 @@ "webui/settings/chromeos/bluetooth_section.h", "webui/settings/chromeos/calculator/size_calculator.cc", "webui/settings/chromeos/calculator/size_calculator.h", + "webui/settings/chromeos/captions_handler.cc", + "webui/settings/chromeos/captions_handler.h", "webui/settings/chromeos/change_picture_handler.cc", "webui/settings/chromeos/change_picture_handler.h", "webui/settings/chromeos/constants/constants_util.cc", @@ -3294,6 +3296,8 @@ "webui/certificate_viewer_ui.h", "webui/certificate_viewer_webui.cc", "webui/certificate_viewer_webui.h", + "webui/webui_js_exception/webui_js_exception_ui.cc", + "webui/webui_js_exception/webui_js_exception_ui.h", ] if (use_aura) { deps += [ "//third_party/fontconfig" ]
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index 3bb7730..d145aec 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -3999,7 +3999,7 @@ <message name="IDS_CABLEV2_ACTIVITY_TITLE" desc="The label of the Activity for using your phone as a security key. A 'security key' in this context is generally a small USB device that is used for logging into websites. This feature allows Chrome on an Android phone to act as a security key. A user may see it in Android permissions prompts (see screenshot)."> - Google <ph name="APP_NAME">%1$s<ex>Chrome</ex></ph> as a Security Key + Google Chrome as a Security Key </message> <!-- QR Code -->
diff --git a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc index 1932583..2f3290a 100644 --- a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc +++ b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc
@@ -203,61 +203,6 @@ TabModel::BroadcastSessionRestoreComplete(); } -inline static base::TimeDelta GetTimeDelta(jlong ms) { - return base::TimeDelta::FromMilliseconds(static_cast<int64_t>(ms)); -} - -void JNI_TabModelJniBridge_LogFromCloseMetric( - JNIEnv* env, - jlong ms, - jboolean perceived) { - if (perceived) { - UMA_HISTOGRAM_TIMES("Tabs.SwitchFromCloseLatency_Perceived", - GetTimeDelta(ms)); - } else { - UMA_HISTOGRAM_TIMES("Tabs.SwitchFromCloseLatency_Actual", - GetTimeDelta(ms)); - } -} - -void JNI_TabModelJniBridge_LogFromExitMetric( - JNIEnv* env, - jlong ms, - jboolean perceived) { - if (perceived) { - UMA_HISTOGRAM_TIMES("Tabs.SwitchFromExitLatency_Perceived", - GetTimeDelta(ms)); - } else { - UMA_HISTOGRAM_TIMES("Tabs.SwitchFromExitLatency_Actual", - GetTimeDelta(ms)); - } -} - -void JNI_TabModelJniBridge_LogFromNewMetric(JNIEnv* env, - jlong ms, - jboolean perceived) { - if (perceived) { - UMA_HISTOGRAM_TIMES("Tabs.SwitchFromNewLatency_Perceived", - GetTimeDelta(ms)); - } else { - UMA_HISTOGRAM_TIMES("Tabs.SwitchFromNewLatency_Actual", - GetTimeDelta(ms)); - } -} - -void JNI_TabModelJniBridge_LogFromUserMetric( - JNIEnv* env, - jlong ms, - jboolean perceived) { - if (perceived) { - UMA_HISTOGRAM_TIMES("Tabs.SwitchFromUserLatency_Perceived", - GetTimeDelta(ms)); - } else { - UMA_HISTOGRAM_TIMES("Tabs.SwitchFromUserLatency_Actual", - GetTimeDelta(ms)); - } -} - TabModelJniBridge::~TabModelJniBridge() { TabModelList::RemoveTabModel(this); }
diff --git a/chrome/browser/ui/ash/accelerator_commands_browsertest.cc b/chrome/browser/ui/ash/accelerator_commands_browsertest.cc index e839496..540dad32 100644 --- a/chrome/browser/ui/ash/accelerator_commands_browsertest.cc +++ b/chrome/browser/ui/ash/accelerator_commands_browsertest.cc
@@ -5,7 +5,6 @@ #include "ash/accelerators/accelerator_commands.h" #include "ash/public/cpp/test/shell_test_api.h" -#include "ash/public/cpp/window_properties.h" #include "base/command_line.h" #include "base/macros.h" #include "build/build_config.h" @@ -18,6 +17,7 @@ #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" +#include "chromeos/ui/base/window_properties.h" #include "content/public/test/browser_test.h" #include "extensions/browser/app_window/app_window.h" #include "extensions/browser/app_window/native_app_window.h" @@ -34,7 +34,7 @@ namespace { bool IsInImmersive(aura::Window* window) { - return window->GetProperty(ash::kImmersiveIsActive); + return window->GetProperty(chromeos::kImmersiveIsActive); } } // namespace
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_client_impl_browsertest.cc b/chrome/browser/ui/ash/holding_space/holding_space_client_impl_browsertest.cc index c2864c0..666d3e6 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_client_impl_browsertest.cc +++ b/chrome/browser/ui/ash/holding_space/holding_space_client_impl_browsertest.cc
@@ -100,7 +100,8 @@ } // Verifies that `HoldingSpaceClient::OpenDownloads()` works as intended. -IN_PROC_BROWSER_TEST_F(HoldingSpaceClientImplTest, OpenDownloads) { +// TODO(crbug.com/1139299): Flaky. +IN_PROC_BROWSER_TEST_F(HoldingSpaceClientImplTest, DISABLED_OpenDownloads) { ASSERT_TRUE(HoldingSpaceController::Get()); auto* holding_space_client = HoldingSpaceController::Get()->client();
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc index 729dd66..41fcd29 100644 --- a/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc +++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc
@@ -325,6 +325,7 @@ region->op(gfx::RectToSkIRect(input_rect), SkRegion::kUnion_Op); } shape_ = std::move(region); + OnWidgetHasHitTestMaskChanged(); widget()->SetShape(shape() ? std::make_unique<ShapeRects>(*shape_rects_) : nullptr); widget()->OnSizeConstraintsChanged();
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc index f42f0dd..37ff38a3 100644 --- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc +++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc
@@ -10,7 +10,6 @@ #include "ash/frame/non_client_frame_view_ash.h" #include "ash/public/cpp/app_types.h" #include "ash/public/cpp/ash_switches.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h" #include "ash/public/cpp/shelf_types.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/tablet_mode.h" @@ -31,7 +30,9 @@ #include "chrome/common/chrome_features.h" #include "chrome/common/extensions/extension_constants.h" #include "chromeos/ui/base/chromeos_ui_constants.h" +#include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/base/window_state_type.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" #include "components/session_manager/core/session_manager.h" #include "extensions/browser/app_window/app_delegate.h" #include "extensions/common/constants.h" @@ -90,12 +91,12 @@ window->SetProperty(aura::client::kAppType, static_cast<int>(ash::AppType::CHROME_APP)); window->SetProperty( - ash::kImmersiveWindowType, + chromeos::kImmersiveWindowType, static_cast<int>( - ash::ImmersiveFullscreenController::WINDOW_TYPE_PACKAGED_APP)); + chromeos::ImmersiveFullscreenController::WINDOW_TYPE_PACKAGED_APP)); // Fullscreen doesn't always imply immersive mode (see // ShouldEnableImmersive()). - window->SetProperty(ash::kImmersiveImpliedByFullscreen, false); + window->SetProperty(chromeos::kImmersiveImpliedByFullscreen, false); // TODO(https://crbug.com/997480): Determine if all non-resizable windows // should have this behavior, or just the feedback app. if (app_window->extension_id() == extension_misc::kFeedbackExtensionId) { @@ -438,12 +439,13 @@ } bool ChromeNativeAppWindowViewsAuraAsh::IsImmersiveModeEnabled() const { - return GetWidget()->GetNativeWindow()->GetProperty(ash::kImmersiveIsActive); + return GetWidget()->GetNativeWindow()->GetProperty( + chromeos::kImmersiveIsActive); } gfx::Rect ChromeNativeAppWindowViewsAuraAsh::GetTopContainerBoundsInScreen() { gfx::Rect* bounds = GetWidget()->GetNativeWindow()->GetProperty( - ash::kImmersiveTopContainerBoundsInScreen); + chromeos::kImmersiveTopContainerBoundsInScreen); return bounds ? *bounds : gfx::Rect(); } @@ -546,7 +548,7 @@ } void ChromeNativeAppWindowViewsAuraAsh::UpdateImmersiveMode() { - ash::ImmersiveFullscreenController::EnableForWidget( + chromeos::ImmersiveFullscreenController::EnableForWidget( widget(), ShouldEnableImmersiveMode()); }
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash_browsertest.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash_browsertest.cc index 8a18f76..4ddddc94 100644 --- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash_browsertest.cc +++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash_browsertest.cc
@@ -4,9 +4,7 @@ #include "chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h" #include "ash/public/cpp/test/shell_test_api.h" -#include "ash/public/cpp/window_properties.h" #include "base/macros.h" #include "base/run_loop.h" #include "base/scoped_observer.h" @@ -17,6 +15,8 @@ #include "chrome/test/base/interactive_test_utils.h" #include "chromeos/login/login_state/login_state.h" #include "chromeos/login/login_state/scoped_test_public_session_login_state.h" +#include "chromeos/ui/base/window_properties.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" #include "content/public/test/browser_test.h" #include "extensions/browser/app_window/app_window.h" #include "extensions/test/extension_test_message_listener.h" @@ -66,7 +66,7 @@ bool IsImmersiveActive() { return window()->widget()->GetNativeWindow()->GetProperty( - ash::kImmersiveIsActive); + chromeos::kImmersiveIsActive); } ChromeNativeAppWindowViewsAuraAsh* window() {
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc index 814bb0b0d..89b4065 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
@@ -7,7 +7,6 @@ #include "ash/public/cpp/ash_switches.h" #include "ash/public/cpp/default_frame_header.h" #include "ash/public/cpp/frame_header.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h" #include "ash/public/cpp/shelf_test_api.h" #include "ash/public/cpp/split_view_test_api.h" #include "ash/public/cpp/test/shell_test_api.h" @@ -74,6 +73,7 @@ #include "chrome/test/base/ui_test_utils.h" #include "chromeos/ui/base/chromeos_ui_constants.h" #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h" #include "components/account_id/account_id.h" #include "components/autofill/core/common/password_form.h" #include "components/keep_alive_registry/keep_alive_types.h" @@ -481,7 +481,7 @@ BrowserView::SetDisableRevealerDelayForTesting(true); - ash::ImmersiveFullscreenControllerTestApi( + chromeos::ImmersiveFullscreenControllerTestApi( static_cast<ImmersiveModeControllerAsh*>( BrowserView::GetBrowserViewForBrowser(browser()) ->immersive_mode_controller()) @@ -680,7 +680,7 @@ ASSERT_TRUE(browser->is_type_app()); BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); - ash::ImmersiveFullscreenControllerTestApi( + chromeos::ImmersiveFullscreenControllerTestApi( static_cast<ImmersiveModeControllerAsh*>( browser_view->immersive_mode_controller()) ->controller())
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc index 9818063..6ff5b686 100644 --- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc +++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h" -#include "ash/public/cpp/immersive/immersive_revealed_lock.h" #include "ash/public/cpp/tablet_mode.h" #include "ash/public/cpp/window_properties.h" #include "base/macros.h" @@ -14,6 +13,8 @@ #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/top_container_view.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" +#include "chromeos/ui/base/window_properties.h" +#include "chromeos/ui/frame/immersive/immersive_revealed_lock.h" #include "content/public/browser/web_contents.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window_targeter.h" @@ -30,27 +31,27 @@ namespace { // Converts from ImmersiveModeController::AnimateReveal to -// ash::ImmersiveFullscreenController::AnimateReveal. -ash::ImmersiveFullscreenController::AnimateReveal +// chromeos::ImmersiveFullscreenController::AnimateReveal. +chromeos::ImmersiveFullscreenController::AnimateReveal ToImmersiveFullscreenControllerAnimateReveal( ImmersiveModeController::AnimateReveal animate_reveal) { switch (animate_reveal) { case ImmersiveModeController::ANIMATE_REVEAL_YES: - return ash::ImmersiveFullscreenController::ANIMATE_REVEAL_YES; + return chromeos::ImmersiveFullscreenController::ANIMATE_REVEAL_YES; case ImmersiveModeController::ANIMATE_REVEAL_NO: - return ash::ImmersiveFullscreenController::ANIMATE_REVEAL_NO; + return chromeos::ImmersiveFullscreenController::ANIMATE_REVEAL_NO; } NOTREACHED(); - return ash::ImmersiveFullscreenController::ANIMATE_REVEAL_NO; + return chromeos::ImmersiveFullscreenController::ANIMATE_REVEAL_NO; } class ImmersiveRevealedLockAsh : public ImmersiveRevealedLock { public: - explicit ImmersiveRevealedLockAsh(ash::ImmersiveRevealedLock* lock) + explicit ImmersiveRevealedLockAsh(chromeos::ImmersiveRevealedLock* lock) : lock_(lock) {} private: - std::unique_ptr<ash::ImmersiveRevealedLock> lock_; + std::unique_ptr<chromeos::ImmersiveRevealedLock> lock_; DISALLOW_COPY_AND_ASSIGN(ImmersiveRevealedLockAsh); }; @@ -69,11 +70,11 @@ observed_windows_.Add(browser_view_->GetNativeWindow()); browser_view_->GetNativeWindow()->SetProperty( - ash::kImmersiveWindowType, + chromeos::kImmersiveWindowType, static_cast<int>( browser_view_->browser()->deprecated_is_app() - ? ash::ImmersiveFullscreenController::WINDOW_TYPE_HOSTED_APP - : ash::ImmersiveFullscreenController::WINDOW_TYPE_BROWSER)); + ? chromeos::ImmersiveFullscreenController::WINDOW_TYPE_HOSTED_APP + : chromeos::ImmersiveFullscreenController::WINDOW_TYPE_BROWSER)); } void ImmersiveModeControllerAsh::SetEnabled(bool enabled) { @@ -86,8 +87,8 @@ ->fullscreen_controller()); } - ash::ImmersiveFullscreenController::EnableForWidget(browser_view_->frame(), - enabled); + chromeos::ImmersiveFullscreenController::EnableForWidget( + browser_view_->frame(), enabled); } bool ImmersiveModeControllerAsh::IsEnabled() const { @@ -143,7 +144,7 @@ // Enable immersive mode if the widget is activated. Do not disable immersive // mode if the widget deactivates, but is not minimized. - ash::ImmersiveFullscreenController::EnableForWidget( + chromeos::ImmersiveFullscreenController::EnableForWidget( browser_view_->frame(), active || !widget->IsMinimized()); }
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.h b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.h index 0950ed91..303c25bd 100644 --- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.h +++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.h
@@ -7,27 +7,27 @@ #include <memory> -#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller_delegate.h" #include "base/macros.h" #include "base/scoped_observer.h" #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" #include "chrome/browser/ui/exclusive_access/fullscreen_observer.h" #include "chrome/browser/ui/views/frame/immersive_mode_controller.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_delegate.h" #include "ui/aura/window.h" #include "ui/aura/window_observer.h" #include "ui/gfx/geometry/rect.h" class ImmersiveModeControllerAsh : public ImmersiveModeController, - public ash::ImmersiveFullscreenControllerDelegate, + public chromeos::ImmersiveFullscreenControllerDelegate, public FullscreenObserver, public aura::WindowObserver { public: ImmersiveModeControllerAsh(); ~ImmersiveModeControllerAsh() override; - ash::ImmersiveFullscreenController* controller() { return &controller_; } + chromeos::ImmersiveFullscreenController* controller() { return &controller_; } // ImmersiveModeController overrides: void Init(BrowserView* browser_view) override; @@ -65,7 +65,7 @@ intptr_t old) override; void OnWindowDestroying(aura::Window* window) override; - ash::ImmersiveFullscreenController controller_; + chromeos::ImmersiveFullscreenController controller_; BrowserView* browser_view_ = nullptr;
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc index 6a3e4574..37b21a24 100644 --- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc +++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h" #include "ash/public/cpp/test/shell_test_api.h" #include "base/macros.h" #include "base/test/test_mock_time_task_runner.h" @@ -26,6 +25,7 @@ #include "chrome/test/base/ui_test_utils.h" #include "chrome/test/permissions/permission_request_manager_test_api.h" #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h" #include "content/public/test/browser_test.h" #include "content/public/test/content_mock_cert_verifier.h" #include "net/cert/mock_cert_verifier.h" @@ -71,7 +71,7 @@ // Disable animations in immersive fullscreen before we show the window, // which triggers an animation. - ash::ImmersiveFullscreenControllerTestApi( + chromeos::ImmersiveFullscreenControllerTestApi( static_cast<ImmersiveModeControllerAsh*>(controller_)->controller()) .SetupForTest();
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc index 5abe576..8bc2966c 100644 --- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc +++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h" #include "ash/public/cpp/window_pin_type.h" #include "ash/public/cpp/window_properties.h" #include "ash/root_window_controller.h" @@ -27,6 +26,7 @@ #include "chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h" #include "ui/aura/window.h" #include "ui/base/pointer/touch_ui_controller.h" #include "ui/events/event.h" @@ -46,7 +46,7 @@ browser()->window()->Show(); controller_ = browser_view()->immersive_mode_controller(); - ash::ImmersiveFullscreenControllerTestApi( + chromeos::ImmersiveFullscreenControllerTestApi( static_cast<ImmersiveModeControllerAsh*>(controller_)->controller()) .SetupForTest(); }
diff --git a/chrome/browser/ui/views/frame/webui_tab_strip_interactive_uitest.cc b/chrome/browser/ui/views/frame/webui_tab_strip_interactive_uitest.cc index 152bc701..d80480a 100644 --- a/chrome/browser/ui/views/frame/webui_tab_strip_interactive_uitest.cc +++ b/chrome/browser/ui/views/frame/webui_tab_strip_interactive_uitest.cc
@@ -22,8 +22,8 @@ #include "ui/views/controls/webview/webview.h" #if defined(OS_CHROMEOS) -#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h" #endif // defined(OS_CHROMEOS) class WebUITabStripInteractiveTest : public InProcessBrowserTest { @@ -138,8 +138,8 @@ BrowserView* const browser_view = BrowserView::GetBrowserViewForBrowser(browser()); - ash::ImmersiveFullscreenControllerTestApi immersive_test_api( - ash::ImmersiveFullscreenController::Get(browser_view->GetWidget())); + chromeos::ImmersiveFullscreenControllerTestApi immersive_test_api( + chromeos::ImmersiveFullscreenController::Get(browser_view->GetWidget())); immersive_test_api.SetupForTest(); ImmersiveModeController* const immersive_mode_controller =
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc index 30e1b14..3b5dc3b 100644 --- a/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
@@ -23,8 +23,8 @@ #include "ui/views/test/widget_test.h" #if defined(OS_CHROMEOS) -#include "ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h" #include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h" #endif #if defined(OS_MAC) @@ -176,7 +176,7 @@ ImmersiveModeController* immersive_controller = browser_view->immersive_mode_controller(); - ash::ImmersiveFullscreenControllerTestApi( + chromeos::ImmersiveFullscreenControllerTestApi( static_cast<ImmersiveModeControllerAsh*>(immersive_controller) ->controller()) .SetupForTest();
diff --git a/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc b/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc index 347239e1..f02929c4 100644 --- a/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc +++ b/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc
@@ -104,18 +104,6 @@ return false; } -void AccountChooserDialogView::ButtonPressed(views::Button* sender, - const ui::Event& event) { - CredentialsItemView* view = static_cast<CredentialsItemView*>(sender); - // On Mac the button click event may be dispatched after the dialog was - // hidden. Thus, the controller can be null. - if (controller_) { - controller_->OnChooseCredentials( - *view->form(), - password_manager::CredentialType::CREDENTIAL_TYPE_PASSWORD); - } -} - void AccountChooserDialogView::InitWindow() { SetLayoutManager(std::make_unique<views::FillLayout>()); @@ -129,7 +117,10 @@ const auto titles = GetCredentialLabelsForAccountChooser(*form); auto* credential_view = list_view->AddChildView(std::make_unique<CredentialsItemView>( - this, titles.first, titles.second, form.get(), + base::BindRepeating( + &AccountChooserDialogView::CredentialsItemPressed, + base::Unretained(this), base::Unretained(form.get())), + titles.first, titles.second, form.get(), content::BrowserContext::GetDefaultStoragePartition( Profile::FromBrowserContext(web_contents_->GetBrowserContext())) ->GetURLLoaderFactoryForBrowserProcess() @@ -148,6 +139,16 @@ scroll_view->ClipHeightTo(0, kMaxVisibleItems * item_height); } +void AccountChooserDialogView::CredentialsItemPressed( + const autofill::PasswordForm* form) { + // On Mac the button click event may be dispatched after the dialog was + // hidden. Thus, the controller can be null. + if (controller_) { + controller_->OnChooseCredentials( + *form, password_manager::CredentialType::CREDENTIAL_TYPE_PASSWORD); + } +} + AccountChooserPrompt* CreateAccountChooserPromptView( CredentialManagerDialogController* controller, content::WebContents* web_contents) {
diff --git a/chrome/browser/ui/views/passwords/account_chooser_dialog_view.h b/chrome/browser/ui/views/passwords/account_chooser_dialog_view.h index f48d5cf6..32ae645a 100644 --- a/chrome/browser/ui/views/passwords/account_chooser_dialog_view.h +++ b/chrome/browser/ui/views/passwords/account_chooser_dialog_view.h
@@ -8,7 +8,10 @@ #include "base/macros.h" #include "chrome/browser/ui/passwords/password_dialog_prompts.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" -#include "ui/views/controls/button/button.h" + +namespace autofill { +struct PasswordForm; +} namespace content { class WebContents; @@ -17,7 +20,6 @@ class CredentialManagerDialogController; class AccountChooserDialogView : public views::BubbleDialogDelegateView, - public views::ButtonListener, public AccountChooserPrompt { public: AccountChooserDialogView(CredentialManagerDialogController* controller, @@ -38,12 +40,11 @@ // DialogDelegate: bool Accept() override; - // ButtonListener: - void ButtonPressed(views::Button* sender, const ui::Event& event) override; - // Sets up the child views. void InitWindow(); + void CredentialsItemPressed(const autofill::PasswordForm* form); + // A weak pointer to the controller. CredentialManagerDialogController* controller_; content::WebContents* web_contents_;
diff --git a/chrome/browser/ui/views/passwords/credentials_item_view.cc b/chrome/browser/ui/views/passwords/credentials_item_view.cc index b4fff3b7..642e3e9 100644 --- a/chrome/browser/ui/views/passwords/credentials_item_view.cc +++ b/chrome/browser/ui/views/passwords/credentials_item_view.cc
@@ -56,14 +56,14 @@ } // namespace CredentialsItemView::CredentialsItemView( - views::ButtonListener* button_listener, + PressedCallback callback, const base::string16& upper_text, const base::string16& lower_text, const autofill::PasswordForm* form, network::mojom::URLLoaderFactory* loader_factory, int upper_text_style, int lower_text_style) - : Button(button_listener), form_(form) { + : Button(std::move(callback)) { SetNotifyEnterExitOnChild(true); views::BoxLayout* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( @@ -83,10 +83,10 @@ DCHECK(image.Width() >= kAvatarImageSize && image.Height() >= kAvatarImageSize); UpdateAvatar(image.AsImageSkia()); - if (form_->icon_url.is_valid()) { + if (form->icon_url.is_valid()) { // Fetch the actual avatar. AccountAvatarFetcher* fetcher = new AccountAvatarFetcher( - form_->icon_url, weak_ptr_factory_.GetWeakPtr()); + form->icon_url, weak_ptr_factory_.GetWeakPtr()); fetcher->Start(loader_factory); } AddChildView(std::move(image_view)); @@ -121,9 +121,9 @@ lower_label_ = text_container->AddChildView(std::move(lower_label)); } - if (form_->is_public_suffix_match) { + if (form->is_public_suffix_match) { info_icon_ = AddChildView(std::make_unique<views::TooltipIcon>( - base::UTF8ToUTF16(form_->url.GetOrigin().spec()))); + base::UTF8ToUTF16(form->url.GetOrigin().spec()))); } if (!upper_text.empty() && !lower_text.empty())
diff --git a/chrome/browser/ui/views/passwords/credentials_item_view.h b/chrome/browser/ui/views/passwords/credentials_item_view.h index c2747f0..be7fddc 100644 --- a/chrome/browser/ui/views/passwords/credentials_item_view.h +++ b/chrome/browser/ui/views/passwords/credentials_item_view.h
@@ -34,7 +34,7 @@ class CredentialsItemView : public AccountAvatarFetcherDelegate, public views::Button { public: - CredentialsItemView(views::ButtonListener* button_listener, + CredentialsItemView(PressedCallback callback, const base::string16& upper_text, const base::string16& lower_text, const autofill::PasswordForm* form, @@ -47,8 +47,6 @@ // to the view. If |store| is kProfileStore, removes any existing icon. void SetStoreIndicatorIcon(autofill::PasswordForm::Store store); - const autofill::PasswordForm* form() const { return form_; } - // AccountAvatarFetcherDelegate: void UpdateAvatar(const gfx::ImageSkia& image) override; @@ -58,8 +56,6 @@ // views::View: void OnPaintBackground(gfx::Canvas* canvas) override; - const autofill::PasswordForm* const form_; - views::ImageView* image_view_; // Optional right-aligned icon to distinguish account store credentials and
diff --git a/chrome/browser/ui/views/passwords/password_auto_sign_in_view.cc b/chrome/browser/ui/views/passwords/password_auto_sign_in_view.cc index 79c215f..96bbe57 100644 --- a/chrome/browser/ui/views/passwords/password_auto_sign_in_view.cc +++ b/chrome/browser/ui/views/passwords/password_auto_sign_in_view.cc
@@ -43,7 +43,7 @@ CredentialsItemView* credential = AddChildView(std::make_unique<CredentialsItemView>( - nullptr, + views::Button::PressedCallback(), l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_AUTO_SIGNIN_TITLE_MD), form.username_value, &form, content::BrowserContext::GetDefaultStoragePartition(
diff --git a/chrome/browser/ui/views/passwords/password_items_view.cc b/chrome/browser/ui/views/passwords/password_items_view.cc index 69dad05..2e02647d 100644 --- a/chrome/browser/ui/views/passwords/password_items_view.cc +++ b/chrome/browser/ui/views/passwords/password_items_view.cc
@@ -46,9 +46,6 @@ namespace { -constexpr int kDeleteButtonTag = 1; -constexpr int kUndoButtonTag = 2; - // Column set identifiers for displaying or undoing removal of credentials. // All of them allocate space differently. enum PasswordItemsViewColumnSetType { @@ -139,7 +136,7 @@ // An entry for each credential. Relays delete/undo actions associated with // this password row to parent dialog. -class PasswordItemsView::PasswordRow : public views::ButtonListener { +class PasswordItemsView::PasswordRow { public: PasswordRow(PasswordItemsView* parent, const autofill::PasswordForm* password_form); @@ -152,8 +149,8 @@ void AddPasswordRow(views::GridLayout* layout, PasswordItemsViewColumnSetType type_id); - // views::ButtonListener: - void ButtonPressed(views::Button* sender, const ui::Event& event) override; + void DeleteButtonPressed(); + void UndoButtonPressed(); PasswordItemsView* const parent_; const autofill::PasswordForm* const password_form_; @@ -184,8 +181,9 @@ views::style::CONTEXT_DIALOG_BODY_TEXT)) ->SetHorizontalAlignment(gfx::ALIGN_LEFT); auto* undo_button = layout->AddView(std::make_unique<views::MdTextButton>( - this, l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_UNDO))); - undo_button->set_tag(kUndoButtonTag); + base::BindRepeating(&PasswordRow::UndoButtonPressed, + base::Unretained(this)), + l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_UNDO))); undo_button->SetFocusForPlatform(); undo_button->SetTooltipText(l10n_util::GetStringFUTF16( IDS_MANAGE_PASSWORDS_UNDO_TOOLTIP, GetDisplayUsername(*password_form_))); @@ -233,22 +231,28 @@ separator->SetCanProcessEventsWithinSubtree(false); } - auto* delete_button = layout->AddView( - views::CreateVectorImageButtonWithNativeTheme(this, kTrashCanIcon)); - delete_button->set_tag(kDeleteButtonTag); + auto* delete_button = + layout->AddView(views::CreateVectorImageButtonWithNativeTheme( + base::BindRepeating(&PasswordRow::DeleteButtonPressed, + base::Unretained(this)), + kTrashCanIcon)); delete_button->SetFocusForPlatform(); delete_button->SetTooltipText(l10n_util::GetStringFUTF16( IDS_MANAGE_PASSWORDS_DELETE, GetDisplayUsername(*password_form_))); } -void PasswordItemsView::PasswordRow::ButtonPressed(views::Button* sender, - const ui::Event& event) { - DCHECK(sender->tag() == kDeleteButtonTag || sender->tag() == kUndoButtonTag); - deleted_ = sender->tag() == kDeleteButtonTag; +void PasswordItemsView::PasswordRow::DeleteButtonPressed() { + deleted_ = true; parent_->NotifyPasswordFormAction( *password_form_, - deleted_ ? PasswordBubbleControllerBase::PasswordAction::kRemovePassword - : PasswordBubbleControllerBase::PasswordAction::kAddPassword); + PasswordBubbleControllerBase::PasswordAction::kRemovePassword); +} + +void PasswordItemsView::PasswordRow::UndoButtonPressed() { + deleted_ = false; + parent_->NotifyPasswordFormAction( + *password_form_, + PasswordBubbleControllerBase::PasswordAction::kAddPassword); } PasswordItemsView::PasswordItemsView(content::WebContents* web_contents, @@ -259,7 +263,14 @@ controller_(PasswordsModelDelegateFromWebContents(web_contents)) { SetButtons(ui::DIALOG_BUTTON_OK); SetExtraView(std::make_unique<views::MdTextButton>( - this, + base::BindRepeating( + [](PasswordItemsView* items) { + items->controller_.OnManageClicked( + password_manager::ManagePasswordsReferrer:: + kManagePasswordsBubble); + items->CloseBubble(); + }, + base::Unretained(this)), l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_MANAGE_PASSWORDS_BUTTON))); if (controller_.local_credentials().empty()) { @@ -341,13 +352,6 @@ return gfx::Size(width, GetHeightForWidth(width)); } -void PasswordItemsView::ButtonPressed(views::Button* sender, - const ui::Event& event) { - controller_.OnManageClicked( - password_manager::ManagePasswordsReferrer::kManagePasswordsBubble); - CloseBubble(); -} - void PasswordItemsView::OnFaviconReady(const gfx::Image& favicon) { if (!favicon.IsEmpty()) { favicon_ = favicon;
diff --git a/chrome/browser/ui/views/passwords/password_items_view.h b/chrome/browser/ui/views/passwords/password_items_view.h index 5ef440c..d262d05 100644 --- a/chrome/browser/ui/views/passwords/password_items_view.h +++ b/chrome/browser/ui/views/passwords/password_items_view.h
@@ -12,14 +12,12 @@ #include "chrome/browser/ui/passwords/bubble_controllers/items_bubble_controller.h" #include "chrome/browser/ui/views/passwords/password_bubble_view_base.h" #include "components/autofill/core/common/password_form.h" -#include "ui/views/controls/button/button.h" #include "ui/views/view.h" // A dialog for managing stored password and federated login information for a // specific site. A user can remove managed credentials for the site via this // dialog. -class PasswordItemsView : public PasswordBubbleViewBase, - public views::ButtonListener { +class PasswordItemsView : public PasswordBubbleViewBase { public: PasswordItemsView(content::WebContents* web_contents, views::View* anchor_view); @@ -41,9 +39,6 @@ bool ShouldShowCloseButton() const override; gfx::Size CalculatePreferredSize() const override; - // views::ButtonListener: - void ButtonPressed(views::Button* sender, const ui::Event& event) override; - // Called when the favicon is loaded. If |favicon| isn't empty, it sets // |favicon_| and invokes RecreateLayout(). void OnFaviconReady(const gfx::Image& favicon);
diff --git a/chrome/browser/ui/views/passwords/password_save_unsynced_credentials_locally_view.cc b/chrome/browser/ui/views/passwords/password_save_unsynced_credentials_locally_view.cc index 78d4849..8a2ecb98 100644 --- a/chrome/browser/ui/views/passwords/password_save_unsynced_credentials_locally_view.cc +++ b/chrome/browser/ui/views/passwords/password_save_unsynced_credentials_locally_view.cc
@@ -54,16 +54,6 @@ return &controller_; } -void PasswordSaveUnsyncedCredentialsLocallyView::ButtonPressed( - views::Button* sender, - const ui::Event&) { - auto* checkbox = static_cast<views::Checkbox*>(sender); - num_selected_checkboxes_ += checkbox->GetChecked() ? 1 : -1; - GetOkButton()->SetState(num_selected_checkboxes_ - ? views::Button::ButtonState::STATE_NORMAL - : views::Button::ButtonState::STATE_DISABLED); -} - const PasswordBubbleControllerBase* PasswordSaveUnsyncedCredentialsLocallyView::GetController() const { return &controller_; @@ -90,8 +80,11 @@ for (const autofill::PasswordForm& form : controller_.unsynced_credentials()) { auto* row_view = AddChildView(std::make_unique<views::View>()); - auto* checkbox = row_view->AddChildView( - std::make_unique<views::Checkbox>(base::string16(), this)); + auto* checkbox = row_view->AddChildView(std::make_unique<views::Checkbox>( + base::string16(), views::Button::PressedCallback())); + checkbox->set_callback(base::BindRepeating( + &PasswordSaveUnsyncedCredentialsLocallyView::ButtonPressed, + base::Unretained(this), base::Unretained(checkbox))); checkbox->SetBorder(views::CreateEmptyBorder( 0, 0, 0, /*right=*/ ChromeLayoutProvider::Get()->GetDistanceMetric( @@ -112,6 +105,14 @@ } } +void PasswordSaveUnsyncedCredentialsLocallyView::ButtonPressed( + views::Checkbox* checkbox) { + num_selected_checkboxes_ += checkbox->GetChecked() ? 1 : -1; + GetOkButton()->SetState(num_selected_checkboxes_ + ? views::Button::ButtonState::STATE_NORMAL + : views::Button::ButtonState::STATE_DISABLED); +} + void PasswordSaveUnsyncedCredentialsLocallyView::OnSaveClicked() { std::vector<bool> was_credential_selected; for (const auto* checkbox : checkboxes_) {
diff --git a/chrome/browser/ui/views/passwords/password_save_unsynced_credentials_locally_view.h b/chrome/browser/ui/views/passwords/password_save_unsynced_credentials_locally_view.h index 81e56e114..e30f348 100644 --- a/chrome/browser/ui/views/passwords/password_save_unsynced_credentials_locally_view.h +++ b/chrome/browser/ui/views/passwords/password_save_unsynced_credentials_locally_view.h
@@ -13,7 +13,6 @@ #include "chrome/browser/ui/views/passwords/password_bubble_view_base.h" #include "components/autofill/core/common/password_form.h" #include "content/public/browser/web_contents.h" -#include "ui/views/controls/button/button.h" #include "ui/views/controls/button/checkbox.h" #include "ui/views/view.h" @@ -21,8 +20,7 @@ // to the user account. By clicking the save button, the user can save those // passwords locally. class PasswordSaveUnsyncedCredentialsLocallyView - : public PasswordBubbleViewBase, - public views::ButtonListener { + : public PasswordBubbleViewBase { public: PasswordSaveUnsyncedCredentialsLocallyView(content::WebContents* web_contents, views::View* anchor_view); @@ -33,15 +31,14 @@ PasswordBubbleControllerBase* GetController() override; const PasswordBubbleControllerBase* GetController() const override; - // views::ButtonListener overrides. - void ButtonPressed(views::Button* sender, const ui::Event&) override; - // LocationBarBubbleDelegateView overrides. bool ShouldShowCloseButton() const override; gfx::Size CalculatePreferredSize() const override; void CreateLayout(); + void ButtonPressed(views::Checkbox* checkbox); + void OnSaveClicked(); SaveUnsyncedCredentialsLocallyBubbleController controller_;
diff --git a/chrome/browser/ui/views/passwords/password_save_update_view.cc b/chrome/browser/ui/views/passwords/password_save_update_view.cc index e62db143..0cf6b33a 100644 --- a/chrome/browser/ui/views/passwords/password_save_update_view.cc +++ b/chrome/browser/ui/views/passwords/password_save_update_view.cc
@@ -157,9 +157,9 @@ } std::unique_ptr<views::ToggleImageButton> CreatePasswordViewButton( - views::ButtonListener* listener, + views::Button::PressedCallback callback, bool are_passwords_revealed) { - auto button = std::make_unique<views::ToggleImageButton>(listener); + auto button = std::make_unique<views::ToggleImageButton>(std::move(callback)); button->SetFocusForPlatform(); button->SetInstallFocusRingOnFocus(true); button->SetRequestFocusOnPress(true); @@ -276,7 +276,8 @@ SetLayoutManager(std::make_unique<views::FillLayout>()); const auto titles = GetCredentialLabelsForAccountChooser(password_form); AddChildView(std::make_unique<CredentialsItemView>( - nullptr, titles.first, titles.second, &password_form, + views::Button::PressedCallback(), titles.first, + titles.second, &password_form, content::BrowserContext::GetDefaultStoragePartition( controller_.GetProfile()) ->GetURLLoaderFactoryForBrowserProcess() @@ -293,7 +294,11 @@ &PasswordSaveUpdateView::OnContentChanged, base::Unretained(this))); std::unique_ptr<views::ToggleImageButton> password_view_button = - CreatePasswordViewButton(this, are_passwords_revealed_); + CreatePasswordViewButton( + base::BindRepeating( + &PasswordSaveUpdateView::TogglePasswordVisibility, + base::Unretained(this)), + are_passwords_revealed_); views::GridLayout* layout = SetLayoutManager(std::make_unique<views::GridLayout>()); @@ -338,12 +343,6 @@ return true; } -void PasswordSaveUpdateView::ButtonPressed(views::Button* sender, - const ui::Event& event) { - DCHECK(sender == password_view_button_); - TogglePasswordVisibility(); -} - gfx::Size PasswordSaveUpdateView::CalculatePreferredSize() const { const int width = ChromeLayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_BUBBLE_PREFERRED_WIDTH) -
diff --git a/chrome/browser/ui/views/passwords/password_save_update_view.h b/chrome/browser/ui/views/passwords/password_save_update_view.h index 78620ed3d..87f108d 100644 --- a/chrome/browser/ui/views/passwords/password_save_update_view.h +++ b/chrome/browser/ui/views/passwords/password_save_update_view.h
@@ -7,7 +7,6 @@ #include "chrome/browser/ui/passwords/bubble_controllers/save_update_bubble_controller.h" #include "chrome/browser/ui/views/passwords/password_bubble_view_base.h" -#include "ui/views/controls/button/button.h" #include "ui/views/view.h" namespace views { @@ -20,8 +19,7 @@ // A view offering the user the ability to save or update credentials (depending // on |is_update_bubble|). Contains a username and password field, along with a // "Save"/"Update" button and a "Never"/"Nope" button. -class PasswordSaveUpdateView : public PasswordBubbleViewBase, - public views::ButtonListener { +class PasswordSaveUpdateView : public PasswordBubbleViewBase { public: PasswordSaveUpdateView(content::WebContents* web_contents, views::View* anchor_view, @@ -36,9 +34,6 @@ PasswordBubbleControllerBase* GetController() override; const PasswordBubbleControllerBase* GetController() const override; - // views::ButtonListener: - void ButtonPressed(views::Button* sender, const ui::Event& event) override; - // PasswordBubbleViewBase: gfx::Size CalculatePreferredSize() const override; views::View* GetInitiallyFocusedView() override;
diff --git a/chrome/browser/ui/views/passwords/password_save_update_with_account_store_view.cc b/chrome/browser/ui/views/passwords/password_save_update_with_account_store_view.cc index 3318c019..9612985 100644 --- a/chrome/browser/ui/views/passwords/password_save_update_with_account_store_view.cc +++ b/chrome/browser/ui/views/passwords/password_save_update_with_account_store_view.cc
@@ -194,9 +194,9 @@ } std::unique_ptr<views::ToggleImageButton> CreatePasswordViewButton( - views::ButtonListener* listener, + views::Button::PressedCallback callback, bool are_passwords_revealed) { - auto button = std::make_unique<views::ToggleImageButton>(listener); + auto button = std::make_unique<views::ToggleImageButton>(std::move(callback)); button->SetFocusForPlatform(); button->SetInstallFocusRingOnFocus(true); button->SetRequestFocusOnPress(true); @@ -402,16 +402,15 @@ if (destination_dropdown) AddChildView(std::move(destination_dropdown)); - std::pair<base::string16, base::string16> titles = - GetCredentialLabelsForAccountChooser(password_form); - CredentialsItemView* credential_view = new CredentialsItemView( - nullptr, titles.first, titles.second, &password_form, - content::BrowserContext::GetDefaultStoragePartition( - controller_.GetProfile()) - ->GetURLLoaderFactoryForBrowserProcess() - .get()); - credential_view->SetEnabled(false); - AddChildView(credential_view); + const auto titles = GetCredentialLabelsForAccountChooser(password_form); + AddChildView(std::make_unique<CredentialsItemView>( + views::Button::PressedCallback(), titles.first, + titles.second, &password_form, + content::BrowserContext::GetDefaultStoragePartition( + controller_.GetProfile()) + ->GetURLLoaderFactoryForBrowserProcess() + .get())) + ->SetEnabled(false); } else { std::unique_ptr<views::EditableCombobox> username_dropdown = CreateUsernameEditableCombobox(password_form); @@ -424,7 +423,11 @@ &PasswordSaveUpdateWithAccountStoreView::OnContentChanged, base::Unretained(this))); std::unique_ptr<views::ToggleImageButton> password_view_button = - CreatePasswordViewButton(this, are_passwords_revealed_); + CreatePasswordViewButton( + base::BindRepeating(&PasswordSaveUpdateWithAccountStoreView:: + TogglePasswordVisibility, + base::Unretained(this)), + are_passwords_revealed_); // Set up layout: SetLayoutManager(std::make_unique<AutoResizingLayout>()); views::View* root_view = AddChildView(std::make_unique<views::View>()); @@ -518,14 +521,6 @@ return &controller_; } -void PasswordSaveUpdateWithAccountStoreView::ButtonPressed( - views::Button* sender, - const ui::Event& event) { - DCHECK(sender); - DCHECK(sender == password_view_button_); - TogglePasswordVisibility(); -} - void PasswordSaveUpdateWithAccountStoreView::DestinationChanged() { bool is_account_store_selected = destination_dropdown_->GetSelectedIndex() == 0;
diff --git a/chrome/browser/ui/views/passwords/password_save_update_with_account_store_view.h b/chrome/browser/ui/views/passwords/password_save_update_with_account_store_view.h index cd8e9465..0ea3aba 100644 --- a/chrome/browser/ui/views/passwords/password_save_update_with_account_store_view.h +++ b/chrome/browser/ui/views/passwords/password_save_update_with_account_store_view.h
@@ -7,7 +7,6 @@ #include "chrome/browser/ui/passwords/bubble_controllers/save_update_with_account_store_bubble_controller.h" #include "chrome/browser/ui/views/passwords/password_bubble_view_base.h" -#include "ui/views/controls/button/button.h" #include "ui/views/layout/animating_layout_manager.h" #include "ui/views/view.h" @@ -31,7 +30,6 @@ // button. class PasswordSaveUpdateWithAccountStoreView : public PasswordBubbleViewBase, - public views::ButtonListener, public views::WidgetObserver, public views::AnimatingLayoutManager::Observer { public: @@ -60,9 +58,6 @@ PasswordBubbleControllerBase* GetController() override; const PasswordBubbleControllerBase* GetController() const override; - // views::ButtonListener: - void ButtonPressed(views::Button* sender, const ui::Event& event) override; - // views::WidgetObserver: void OnWidgetDestroying(views::Widget* widget) override;
diff --git a/chrome/browser/ui/views/profiles/avatar_toolbar_button_delegate.cc b/chrome/browser/ui/views/profiles/avatar_toolbar_button_delegate.cc index b4f5bc98..8106d518 100644 --- a/chrome/browser/ui/views/profiles/avatar_toolbar_button_delegate.cc +++ b/chrome/browser/ui/views/profiles/avatar_toolbar_button_delegate.cc
@@ -265,7 +265,7 @@ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, base::BindOnce(&AvatarToolbarButtonDelegate::OnIdentityAnimationTimeout, - weak_ptr_factory_.GetWeakPtr()), + weak_ptr_factory_.GetWeakPtr(), user_identity.account_id), kIdentityAnimationDuration); } @@ -386,7 +386,17 @@ avatar_toolbar_button_->UpdateIcon(); } -void AvatarToolbarButtonDelegate::OnIdentityAnimationTimeout() { +void AvatarToolbarButtonDelegate::OnIdentityAnimationTimeout( + CoreAccountId account_id) { + CoreAccountInfo user_identity = + IdentityManagerFactory::GetForProfile(profile_)->GetPrimaryAccountInfo( + signin::ConsentLevel::kNotRequired); + // If another account is signed-in then the one that initiated this animation, + // don't hide it. There's one more pending OnIdentityAnimationTimeout() that + // will properly hide it after the proper delay. + if (!user_identity.IsEmpty() && user_identity.account_id != account_id) + return; + DCHECK_EQ(identity_animation_state_, IdentityAnimationState::kShowingUntilTimeout); identity_animation_state_ =
diff --git a/chrome/browser/ui/views/profiles/avatar_toolbar_button_delegate.h b/chrome/browser/ui/views/profiles/avatar_toolbar_button_delegate.h index 89ab666..d18a83d6 100644 --- a/chrome/browser/ui/views/profiles/avatar_toolbar_button_delegate.h +++ b/chrome/browser/ui/views/profiles/avatar_toolbar_button_delegate.h
@@ -95,8 +95,8 @@ // Initiates showing the identity. void OnUserIdentityChanged(); + void OnIdentityAnimationTimeout(CoreAccountId account_id); // Called after the user interacted with the button or after some timeout. - void OnIdentityAnimationTimeout(); void MaybeHideIdentityAnimation(); void HideHighlightAnimation();
diff --git a/chrome/browser/ui/views/read_later/read_later_button.cc b/chrome/browser/ui/views/read_later/read_later_button.cc index 00b2f4d..89027e6 100644 --- a/chrome/browser/ui/views/read_later/read_later_button.cc +++ b/chrome/browser/ui/views/read_later/read_later_button.cc
@@ -29,6 +29,7 @@ GetViewAccessibility().OverrideHasPopup(ax::mojom::HasPopup::kMenu); button_controller()->set_notify_action( views::ButtonController::NotifyAction::kOnPress); + SetHorizontalAlignment(gfx::ALIGN_LEFT); // We don't want to use ToolbarButton::SetHighlight here because it adds a // border around the button. LabelButton::SetText(l10n_util::GetStringUTF16(IDS_READ_LATER_TITLE));
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc index b0891c30..88a6c75 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -82,7 +82,6 @@ #if defined(OS_CHROMEOS) #include "ash/public/cpp/ash_switches.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h" #include "ash/public/cpp/split_view_test_api.h" #include "ash/public/cpp/test/shell_test_api.h" #include "ash/public/cpp/window_properties.h" @@ -94,6 +93,7 @@ #include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" #include "chrome/browser/web_applications/test/test_system_web_app_installation.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h" #include "content/public/common/service_names.mojom.h" #include "ui/aura/client/cursor_client.h" #include "ui/aura/client/screen_position_client.h" @@ -3851,7 +3851,7 @@ BrowserView* browser_view2 = BrowserView::GetBrowserViewForBrowser(browser2); ImmersiveModeController* immersive_controller2 = browser_view2->immersive_mode_controller(); - ash::ImmersiveFullscreenControllerTestApi( + chromeos::ImmersiveFullscreenControllerTestApi( static_cast<ImmersiveModeControllerAsh*>(immersive_controller2) ->controller()) .SetupForTest();
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.cc b/chrome/browser/ui/views/translate/translate_bubble_view.cc index 1c738c4..34911e3d 100644 --- a/chrome/browser/ui/views/translate/translate_bubble_view.cc +++ b/chrome/browser/ui/views/translate/translate_bubble_view.cc
@@ -246,48 +246,6 @@ model_->ShowError(error_type_); } -void TranslateBubbleView::ButtonPressed(views::Button* sender, - const ui::Event& event) { - switch (static_cast<ButtonID>(sender->GetID())) { - case BUTTON_ID_DONE: { - ConfirmAdvancedOptions(); - break; - } - case BUTTON_ID_TRY_AGAIN: { - model_->Translate(); - translate::ReportUiAction(translate::TRY_AGAIN_BUTTON_CLICKED); - break; - } - case BUTTON_ID_ALWAYS_TRANSLATE: { - views::Checkbox* always_checkbox = GetAlwaysTranslateCheckbox(); - DCHECK(always_checkbox); - should_always_translate_ = always_checkbox->GetChecked(); - // In the tab UI the always translate button should apply immediately - // except for in an advanced view. - if (GetViewState() != TranslateBubbleModel::VIEW_STATE_SOURCE_LANGUAGE) { - model_->SetAlwaysTranslate(should_always_translate_); - } - translate::ReportUiAction(should_always_translate_ - ? translate::ALWAYS_TRANSLATE_CHECKED - : translate::ALWAYS_TRANSLATE_UNCHECKED); - break; - } - case BUTTON_ID_OPTIONS_MENU: { - ShowOptionsMenu(sender); - break; - } - case BUTTON_ID_CLOSE: { - translate::ReportUiAction(translate::CLOSE_BUTTON_CLICKED); - GetWidget()->Close(); - break; - } - case BUTTON_ID_RESET: { - ResetLanguage(); - break; - } - } -} - views::View* TranslateBubbleView::GetInitiallyFocusedView() { return GetCurrentView()->GetNextFocusableView(); } @@ -601,6 +559,17 @@ translate::ReportUiAction(translate::TARGET_LANGUAGE_MENU_CLICKED); } +void TranslateBubbleView::AlwaysTranslatePressed() { + should_always_translate_ = GetAlwaysTranslateCheckbox()->GetChecked(); + translate::ReportUiAction(should_always_translate_ + ? translate::ALWAYS_TRANSLATE_CHECKED + : translate::ALWAYS_TRANSLATE_UNCHECKED); + // In the tab UI the always translate button should apply immediately + // except for in an advanced view. + if (GetViewState() != TranslateBubbleModel::VIEW_STATE_SOURCE_LANGUAGE) + model_->SetAlwaysTranslate(should_always_translate_); +} + void TranslateBubbleView::UpdateChildVisibilities() { // Update the state of the always translate checkbox if (advanced_always_translate_checkbox_) @@ -679,7 +648,8 @@ l10n_util::GetStringFUTF16( IDS_TRANSLATE_BUBBLE_ALWAYS_TRANSLATE_LANG, model_->GetLanguageNameAt(model_->GetOriginalLanguageIndex())), - this); + base::BindRepeating(&TranslateBubbleView::AlwaysTranslatePressed, + base::Unretained(this))); before_always_translate_checkbox->SetID(BUTTON_ID_ALWAYS_TRANSLATE); always_translate_checkbox_ = view->AddChildView(std::move(before_always_translate_checkbox)); @@ -724,8 +694,11 @@ std::unique_ptr<views::View> TranslateBubbleView::CreateViewError() { auto translate_options_button = std::make_unique<views::MdTextButtonWithDownArrow>( - this, + views::Button::PressedCallback(), l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_OPTIONS_MENU_BUTTON)); + translate_options_button->set_callback(base::BindRepeating( + &TranslateBubbleView::ShowOptionsMenu, base::Unretained(this), + base::Unretained(translate_options_button.get()))); translate_options_button->SetID(BUTTON_ID_OPTIONS_MENU); translate_options_button->SetRequestFocusOnPress(true); return CreateViewErrorNoTitle(std::move(translate_options_button)); @@ -783,7 +756,13 @@ views::GridLayout::kFixedSize, provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL)); auto try_again_button = std::make_unique<views::MdTextButton>( - this, l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRY_AGAIN)); + base::BindRepeating( + [](TranslateBubbleModel* model) { + translate::ReportUiAction(translate::TRY_AGAIN_BUTTON_CLICKED); + model->Translate(); + }, + base::Unretained(model_.get())), + l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRY_AGAIN)); try_again_button->SetID(BUTTON_ID_TRY_AGAIN); layout->AddView(std::move(try_again_button)); @@ -819,7 +798,9 @@ model_->GetLanguageNameAt(model_->GetOriginalLanguageIndex()); if (!is_in_incognito_window_ && !original_language.empty()) { advanced_always_translate_checkbox = std::make_unique<views::Checkbox>( - l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_ALWAYS), this); + l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_ALWAYS), + base::BindRepeating(&TranslateBubbleView::AlwaysTranslatePressed, + base::Unretained(this))); advanced_always_translate_checkbox->SetID(BUTTON_ID_ALWAYS_TRANSLATE); } @@ -828,7 +809,9 @@ source_language_combobox_ = source_language_combobox.get(); auto advanced_done_button = std::make_unique<views::MdTextButton>( - this, l10n_util::GetStringUTF16(IDS_DONE)); + base::BindRepeating(&TranslateBubbleView::ConfirmAdvancedOptions, + base::Unretained(this)), + l10n_util::GetStringUTF16(IDS_DONE)); advanced_done_button->SetID(BUTTON_ID_DONE); advanced_done_button->SetIsDefault(true); advanced_done_button_source_ = advanced_done_button.get(); @@ -860,7 +843,9 @@ target_language_combobox_ = target_language_combobox.get(); auto advanced_done_button = std::make_unique<views::MdTextButton>( - this, l10n_util::GetStringUTF16(IDS_DONE)); + base::BindRepeating(&TranslateBubbleView::ConfirmAdvancedOptions, + base::Unretained(this)), + l10n_util::GetStringUTF16(IDS_DONE)); advanced_done_button->SetID(BUTTON_ID_DONE); advanced_done_button->SetIsDefault(true); advanced_done_button_target_ = advanced_done_button.get(); @@ -995,7 +980,9 @@ layout->SkipColumns(1); auto advanced_reset_button = std::make_unique<views::MdTextButton>( - this, l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_RESET)); + base::BindRepeating(&TranslateBubbleView::ResetLanguage, + base::Unretained(this)), + l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_RESET)); advanced_reset_button->SetID(BUTTON_ID_RESET); layout->AddView(std::move(advanced_reset_button)); layout->AddView(std::move(advanced_done_button)); @@ -1019,7 +1006,11 @@ std::unique_ptr<views::Button> TranslateBubbleView::CreateOptionsMenuButton() { // Three dots options menu button auto tab_translate_options_button = - views::CreateVectorImageButtonWithNativeTheme(this, kBrowserToolsIcon); + views::CreateVectorImageButtonWithNativeTheme( + views::Button::PressedCallback(), kBrowserToolsIcon); + tab_translate_options_button->set_callback(base::BindRepeating( + &TranslateBubbleView::ShowOptionsMenu, base::Unretained(this), + base::Unretained(tab_translate_options_button.get()))); InstallCircleHighlightPathGenerator(tab_translate_options_button.get()); tab_translate_options_button->SetFocusForPlatform(); tab_translate_options_button->SetAccessibleName( @@ -1031,7 +1022,13 @@ } std::unique_ptr<views::Button> TranslateBubbleView::CreateCloseButton() { - auto close_button = views::BubbleFrameView::CreateCloseButton(this); + auto close_button = + views::BubbleFrameView::CreateCloseButton(base::BindRepeating( + [](View* view) { + translate::ReportUiAction(translate::CLOSE_BUTTON_CLICKED); + view->GetWidget()->Close(); + }, + base::Unretained(this))); close_button->SetVisible(true); close_button->SetID(BUTTON_ID_CLOSE); return close_button;
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.h b/chrome/browser/ui/views/translate/translate_bubble_view.h index 440325d..65ded91 100644 --- a/chrome/browser/ui/views/translate/translate_bubble_view.h +++ b/chrome/browser/ui/views/translate/translate_bubble_view.h
@@ -24,7 +24,6 @@ #include "components/translate/core/common/translate_errors.h" #include "content/public/browser/web_contents_observer.h" #include "ui/base/models/simple_menu_model.h" -#include "ui/views/controls/button/button.h" #include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" #include "ui/views/controls/menu/menu_runner.h" @@ -42,7 +41,6 @@ } // namespace views class TranslateBubbleView : public LocationBarBubbleDelegateView, - public views::ButtonListener, public ui::SimpleMenuModel::Delegate, public views::TabbedPaneListener { public: @@ -90,9 +88,6 @@ gfx::Size CalculatePreferredSize() const override; void OnWidgetClosing(views::Widget* widget) override; - // views::ButtonListener: - void ButtonPressed(views::Button* source, const ui::Event& event) override; - // ui::SimpleMenuModel::Delegate: bool IsCommandIdChecked(int command_id) const override; bool IsCommandIdEnabled(int command_id) const override; @@ -107,7 +102,7 @@ private: enum ButtonID { - BUTTON_ID_DONE, + BUTTON_ID_DONE = 1, BUTTON_ID_TRY_AGAIN, BUTTON_ID_ALWAYS_TRANSLATE, BUTTON_ID_OPTIONS_MENU, @@ -165,6 +160,8 @@ void SourceLanguageChanged(); void TargetLanguageChanged(); + void AlwaysTranslatePressed(); + // Updates the visibilities of child views according to the current view type. void UpdateChildVisibilities();
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view_unittest.cc b/chrome/browser/ui/views/translate/translate_bubble_view_unittest.cc index 8e3b849..09cbdd54f 100644 --- a/chrome/browser/ui/views/translate/translate_bubble_view_unittest.cc +++ b/chrome/browser/ui/views/translate/translate_bubble_view_unittest.cc
@@ -27,6 +27,7 @@ #include "ui/views/controls/button/menu_button.h" #include "ui/views/controls/combobox/combobox.h" #include "ui/views/controls/styled_label.h" +#include "ui/views/test/button_test_api.h" #include "ui/views/widget/widget.h" namespace { @@ -189,12 +190,10 @@ } void PressButton(TranslateBubbleView::ButtonID id) { - views::LabelButton button(nullptr, base::ASCIIToUTF16("hello")); - button.SetID(id); - - bubble_->ButtonPressed(&button, - ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, - ui::DomCode::ENTER, ui::EF_NONE)); + views::Button* button = + static_cast<views::Button*>(bubble_->GetViewByID(id)); + views::test::ButtonTestApi(button).NotifyClick(ui::KeyEvent( + ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::DomCode::ENTER, ui::EF_NONE)); } void TearDown() override { @@ -207,12 +206,7 @@ bool denial_button_clicked() { return mock_model_->translation_declined_; } void TriggerOptionsMenu() { - views::Button* button = static_cast<views::Button*>( - bubble_->GetViewByID(TranslateBubbleView::BUTTON_ID_OPTIONS_MENU)); - LOG(INFO) << button->GetID(); - bubble_->ButtonPressed(button, - ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, - ui::DomCode::ENTER, ui::EF_NONE)); + PressButton(TranslateBubbleView::BUTTON_ID_OPTIONS_MENU); } ui::SimpleMenuModel* options_menu_model() { @@ -283,7 +277,6 @@ EXPECT_FALSE(bubble_->always_translate_checkbox_->GetChecked()); // Click the checkbox. The state is saved. - bubble_->always_translate_checkbox_->SetChecked(true); PressButton(TranslateBubbleView::BUTTON_ID_ALWAYS_TRANSLATE); EXPECT_TRUE(mock_model_->should_always_translate_); EXPECT_EQ(1, mock_model_->set_always_translate_called_count_); @@ -327,7 +320,6 @@ EXPECT_FALSE(bubble_->advanced_always_translate_checkbox_->GetChecked()); // Click the checkbox. The state is not saved yet. - bubble_->advanced_always_translate_checkbox_->SetChecked(true); PressButton(TranslateBubbleView::BUTTON_ID_ALWAYS_TRANSLATE); EXPECT_FALSE(mock_model_->should_always_translate_); EXPECT_EQ(0, mock_model_->set_always_translate_called_count_);
diff --git a/chrome/browser/ui/views/web_apps/web_app_ash_interactive_ui_test.cc b/chrome/browser/ui/views/web_apps/web_app_ash_interactive_ui_test.cc index 636a319..1811ce7e 100644 --- a/chrome/browser/ui/views/web_apps/web_app_ash_interactive_ui_test.cc +++ b/chrome/browser/ui/views/web_apps/web_app_ash_interactive_ui_test.cc
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h" #include "chrome/browser/ui/exclusive_access/exclusive_access_test.h" @@ -14,6 +13,7 @@ #include "chrome/browser/ui/web_applications/web_app_controller_browsertest.h" #include "chrome/common/web_application_info.h" #include "chrome/test/base/interactive_test_utils.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h" #include "content/public/test/browser_test.h" class WebAppAshInteractiveUITest : public web_app::WebAppControllerBrowserTest { @@ -31,7 +31,7 @@ browser_view_ = BrowserView::GetBrowserViewForBrowser(browser); controller_ = browser_view_->immersive_mode_controller(); - ash::ImmersiveFullscreenControllerTestApi( + chromeos::ImmersiveFullscreenControllerTestApi( static_cast<ImmersiveModeControllerAsh*>(controller_)->controller()) .SetupForTest(); WebAppFrameToolbarView::DisableAnimationForTesting();
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index 3c5ab4f..e53282f 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -230,6 +230,10 @@ #include "chrome/browser/ui/webui/app_launcher_page_ui.h" #endif +#if defined(OS_LINUX) || defined(OS_CHROMEOS) +#include "chrome/browser/ui/webui/webui_js_exception/webui_js_exception_ui.h" +#endif + #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) #include "chrome/browser/ui/sync/sync_promo_ui.h" #include "chrome/browser/ui/webui/browser_switch/browser_switch_ui.h" @@ -751,6 +755,10 @@ } #endif // !defined(OFFICIAL_BUILD) #endif // defined(OS_CHROMEOS) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) + if (url.host_piece() == chrome::kChromeUIWebUIJsExceptionHost) + return &NewWebUI<WebUIJsExceptionUI>; +#endif #if defined(OS_ANDROID) if (url.host_piece() == chrome::kChromeUIExploreSitesInternalsHost && !profile->IsOffTheRecord())
diff --git a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc index f0f6eca3..5d25311 100644 --- a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc +++ b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
@@ -273,7 +273,7 @@ } return std::make_unique<LookalikeUrlBlockingPage>( web_contents, safe_url, request_url, ukm::kInvalidSourceId, - LookalikeUrlMatchType::kNone, + LookalikeUrlMatchType::kNone, false, std::make_unique<LookalikeUrlControllerClient>(web_contents, request_url, safe_url)); }
diff --git a/chrome/browser/ui/webui/settings/accessibility_main_handler.cc b/chrome/browser/ui/webui/settings/accessibility_main_handler.cc index 5b6d2119..4a5a81f 100644 --- a/chrome/browser/ui/webui/settings/accessibility_main_handler.cc +++ b/chrome/browser/ui/webui/settings/accessibility_main_handler.cc
@@ -5,7 +5,6 @@ #include "chrome/browser/ui/webui/settings/accessibility_main_handler.h" #include <utility> -#include <vector> #include "base/bind.h" #include "base/values.h" @@ -19,57 +18,9 @@ #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" -#if !defined(OS_CHROMEOS) -#include "base/check_op.h" -#include "base/numerics/ranges.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/component_updater/soda_component_installer.h" -#include "chrome/browser/component_updater/soda_en_us_component_installer.h" -#include "chrome/browser/component_updater/soda_ja_jp_component_installer.h" -#include "chrome/common/pref_names.h" -#include "chrome/grit/chromium_strings.h" -#include "chrome/grit/generated_resources.h" -#include "components/prefs/pref_service.h" -#include "components/update_client/crx_update_item.h" -#include "content/public/browser/browser_accessibility_state.h" -#include "ui/base/l10n/l10n_util.h" - -namespace { - -int GetDownloadProgress( - std::unordered_map<std::string, update_client::CrxUpdateItem> - downloading_components) { - int total_bytes = 0; - int downloaded_bytes = 0; - - for (auto component : downloading_components) { - if (component.second.downloaded_bytes >= 0 && - component.second.total_bytes > 0) { - downloaded_bytes += component.second.downloaded_bytes; - total_bytes += component.second.total_bytes; - } - } - - if (total_bytes == 0) - return -1; - - DCHECK_LE(downloaded_bytes, total_bytes); - return 100 * - base::ClampToRange(double{downloaded_bytes} / total_bytes, 0.0, 1.0); -} - -} // namespace - -#endif // !defined(OS_CHROMEOS) - namespace settings { -#if defined(OS_CHROMEOS) AccessibilityMainHandler::AccessibilityMainHandler() = default; -#else -AccessibilityMainHandler::AccessibilityMainHandler(PrefService* prefs) - : prefs_(prefs) {} -#endif // defined(OS_CHROMEOS) AccessibilityMainHandler::~AccessibilityMainHandler() = default; @@ -92,16 +43,12 @@ base::BindRepeating( &AccessibilityMainHandler::OnAccessibilityStatusChanged, base::Unretained(this))); -#else - component_updater_observer_.Add(g_browser_process->component_updater()); #endif // defined(OS_CHROMEOS) } void AccessibilityMainHandler::OnJavascriptDisallowed() { #if defined(OS_CHROMEOS) accessibility_subscription_.reset(); -#else - component_updater_observer_.RemoveAll(); #endif // defined(OS_CHROMEOS) } @@ -139,54 +86,6 @@ SendScreenReaderStateChanged(); } } -#else -void AccessibilityMainHandler::OnEvent(Events event, const std::string& id) { - if (id != component_updater::SODAComponentInstallerPolicy::GetExtensionId() && - id != component_updater::SodaEnUsComponentInstallerPolicy:: - GetExtensionId() && - id != - component_updater::SodaJaJpComponentInstallerPolicy::GetExtensionId()) - return; - - switch (event) { - case Events::COMPONENT_UPDATE_FOUND: - case Events::COMPONENT_UPDATE_READY: - case Events::COMPONENT_WAIT: - case Events::COMPONENT_UPDATE_DOWNLOADING: - case Events::COMPONENT_UPDATE_UPDATING: { - update_client::CrxUpdateItem item; - g_browser_process->component_updater()->GetComponentDetails(id, &item); - downloading_components_[id] = item; - const int progress = GetDownloadProgress(downloading_components_); - // When GetDownloadProgress returns -1, do nothing. It returns -1 when the - // downloaded or total bytes is unknown. - if (progress != -1) { - FireWebUIListener( - "enable-live-caption-subtitle-changed", - base::Value(l10n_util::GetStringFUTF16Int( - IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_PROGRESS, - progress))); - } - } break; - case Events::COMPONENT_UPDATED: - case Events::COMPONENT_NOT_UPDATED: - FireWebUIListener( - "enable-live-caption-subtitle-changed", - base::Value(l10n_util::GetStringUTF16( - IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_COMPLETE))); - break; - case Events::COMPONENT_UPDATE_ERROR: - prefs_->SetBoolean(prefs::kLiveCaptionEnabled, false); - FireWebUIListener( - "enable-live-caption-subtitle-changed", - base::Value(l10n_util::GetStringUTF16( - IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_ERROR))); - break; - case Events::COMPONENT_CHECKING_FOR_UPDATES: - // Do nothing. - break; - } -} #endif // defined(OS_CHROMEOS) } // namespace settings
diff --git a/chrome/browser/ui/webui/settings/accessibility_main_handler.h b/chrome/browser/ui/webui/settings/accessibility_main_handler.h index f0007018..ebc1f51b 100644 --- a/chrome/browser/ui/webui/settings/accessibility_main_handler.h +++ b/chrome/browser/ui/webui/settings/accessibility_main_handler.h
@@ -6,43 +6,28 @@ #define CHROME_BROWSER_UI_WEBUI_SETTINGS_ACCESSIBILITY_MAIN_HANDLER_H_ #include <memory> -#include <string> #include "base/macros.h" #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" -#include "components/update_client/crx_update_item.h" #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" -#else -#include "base/scoped_observer.h" -#include "components/component_updater/component_updater_service.h" #endif // defined(OS_CHROMEOS) namespace base { class ListValue; } -class PrefService; - namespace settings { // Settings handler for the main accessibility settings page, // chrome://settings/accessibility. -// TODO(1055150) Implement the SODA download progress handling on ChromeOS and -// remove the ChromeOS-only class declaration. -#if defined(OS_CHROMEOS) class AccessibilityMainHandler : public ::settings::SettingsPageUIHandler { public: AccessibilityMainHandler(); -#else -class AccessibilityMainHandler : public ::settings::SettingsPageUIHandler, - public component_updater::ServiceObserver { - public: - explicit AccessibilityMainHandler(PrefService* prefs); -#endif // defined(OS_CHROMEOS) - ~AccessibilityMainHandler() override; + AccessibilityMainHandler(const AccessibilityMainHandler&) = delete; + AccessibilityMainHandler& operator=(const AccessibilityMainHandler&) = delete; // SettingsPageUIHandler implementation. void RegisterMessages() override; @@ -61,19 +46,7 @@ std::unique_ptr<chromeos::AccessibilityStatusSubscription> accessibility_subscription_; -#else - // component_updater::ServiceObserver: - void OnEvent(Events event, const std::string& id) override; - - std::unordered_map<std::string, update_client::CrxUpdateItem> - downloading_components_; - PrefService* prefs_; - ScopedObserver<component_updater::ComponentUpdateService, - component_updater::ComponentUpdateService::Observer> - component_updater_observer_{this}; #endif // defined(OS_CHROMEOS) - - DISALLOW_COPY_AND_ASSIGN(AccessibilityMainHandler); }; } // namespace settings
diff --git a/chrome/browser/ui/webui/settings/captions_handler.cc b/chrome/browser/ui/webui/settings/captions_handler.cc index f91f2fdd..4533f31 100644 --- a/chrome/browser/ui/webui/settings/captions_handler.cc +++ b/chrome/browser/ui/webui/settings/captions_handler.cc
@@ -5,30 +5,134 @@ #include "chrome/browser/ui/webui/settings/captions_handler.h" #include "base/bind.h" -#include "base/bind_helpers.h" -#include "chrome/browser/accessibility/caption_settings_dialog.h" +#include "base/check_op.h" +#include "base/numerics/ranges.h" +#include "base/values.h" +#include "build/build_config.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/component_updater/soda_component_installer.h" +#include "chrome/browser/component_updater/soda_en_us_component_installer.h" +#include "chrome/browser/component_updater/soda_ja_jp_component_installer.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/pref_names.h" +#include "chrome/grit/chromium_strings.h" +#include "chrome/grit/generated_resources.h" +#include "components/prefs/pref_service.h" +#include "components/update_client/crx_update_item.h" #include "content/public/browser/web_ui.h" +#include "ui/base/l10n/l10n_util.h" + +#if defined(OS_WIN) || defined(OS_MAC) +#include "chrome/browser/accessibility/caption_settings_dialog.h" +#endif + +namespace { + +int GetDownloadProgress(std::map<std::string, update_client::CrxUpdateItem> + downloading_components) { + int total_bytes = 0; + int downloaded_bytes = 0; + + for (auto component : downloading_components) { + if (component.second.downloaded_bytes >= 0 && + component.second.total_bytes > 0) { + downloaded_bytes += component.second.downloaded_bytes; + total_bytes += component.second.total_bytes; + } + } + + if (total_bytes == 0) + return -1; + + DCHECK_LE(downloaded_bytes, total_bytes); + return 100 * + base::ClampToRange(double{downloaded_bytes} / total_bytes, 0.0, 1.0); +} + +} // namespace namespace settings { -CaptionsHandler::CaptionsHandler() {} +CaptionsHandler::CaptionsHandler(PrefService* prefs) : prefs_(prefs) {} -CaptionsHandler::~CaptionsHandler() {} +CaptionsHandler::~CaptionsHandler() = default; void CaptionsHandler::RegisterMessages() { web_ui()->RegisterMessageCallback( "openSystemCaptionsDialog", base::BindRepeating(&CaptionsHandler::HandleOpenSystemCaptionsDialog, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "captionsSubpageReady", + base::BindRepeating(&CaptionsHandler::HandleCaptionsSubpageReady, + base::Unretained(this))); } -void CaptionsHandler::OnJavascriptAllowed() {} +void CaptionsHandler::OnJavascriptAllowed() { + component_updater_observer_.Add(g_browser_process->component_updater()); +} -void CaptionsHandler::OnJavascriptDisallowed() {} +void CaptionsHandler::OnJavascriptDisallowed() { + component_updater_observer_.RemoveAll(); +} + +void CaptionsHandler::HandleCaptionsSubpageReady(const base::ListValue* args) { + AllowJavascript(); +} void CaptionsHandler::HandleOpenSystemCaptionsDialog( const base::ListValue* args) { +#if defined(OS_WIN) || defined(OS_MAC) captions::CaptionSettingsDialog::ShowCaptionSettingsDialog(); +#endif +} + +void CaptionsHandler::OnEvent(Events event, const std::string& id) { + if (id != component_updater::SODAComponentInstallerPolicy::GetExtensionId() && + id != component_updater::SodaEnUsComponentInstallerPolicy:: + GetExtensionId() && + id != + component_updater::SodaJaJpComponentInstallerPolicy::GetExtensionId()) + return; + + switch (event) { + case Events::COMPONENT_UPDATE_FOUND: + case Events::COMPONENT_UPDATE_READY: + case Events::COMPONENT_WAIT: + case Events::COMPONENT_UPDATE_DOWNLOADING: + case Events::COMPONENT_UPDATE_UPDATING: { + update_client::CrxUpdateItem item; + g_browser_process->component_updater()->GetComponentDetails(id, &item); + downloading_components_[id] = item; + const int progress = GetDownloadProgress(downloading_components_); + // When GetDownloadProgress returns -1, do nothing. It returns -1 when the + // downloaded or total bytes is unknown. + if (progress != -1) { + FireWebUIListener( + "enable-live-caption-subtitle-changed", + base::Value(l10n_util::GetStringFUTF16Int( + IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_PROGRESS, + progress))); + } + } break; + case Events::COMPONENT_UPDATED: + case Events::COMPONENT_NOT_UPDATED: + FireWebUIListener( + "enable-live-caption-subtitle-changed", + base::Value(l10n_util::GetStringUTF16( + IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_COMPLETE))); + break; + case Events::COMPONENT_UPDATE_ERROR: + prefs_->SetBoolean(prefs::kLiveCaptionEnabled, false); + FireWebUIListener( + "enable-live-caption-subtitle-changed", + base::Value(l10n_util::GetStringUTF16( + IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_ERROR))); + break; + case Events::COMPONENT_CHECKING_FOR_UPDATES: + // Do nothing. + break; + } } } // namespace settings
diff --git a/chrome/browser/ui/webui/settings/captions_handler.h b/chrome/browser/ui/webui/settings/captions_handler.h index 28ea30d..4203cc6c 100644 --- a/chrome/browser/ui/webui/settings/captions_handler.h +++ b/chrome/browser/ui/webui/settings/captions_handler.h
@@ -5,18 +5,32 @@ #ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CAPTIONS_HANDLER_H_ #define CHROME_BROWSER_UI_WEBUI_SETTINGS_CAPTIONS_HANDLER_H_ +#include <map> +#include <string> + #include "base/macros.h" -#include "build/build_config.h" +#include "base/scoped_observer.h" #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" +#include "components/component_updater/component_updater_service.h" + +class PrefService; + +namespace update_client { +struct CrxUpdateItem; +} namespace settings { -// UI handler for Chrome caption settings subpage on operating systems other -// than Chrome OS and Linux. -class CaptionsHandler : public SettingsPageUIHandler { +// Settings handler for the captions settings page, chrome://settings/captions, +// and for caption settings on the main accessibility page, +// chrome://settings/accessibility, on non-ChromeOS desktop browsers. +class CaptionsHandler : public ::settings::SettingsPageUIHandler, + public component_updater::ServiceObserver { public: - CaptionsHandler(); + explicit CaptionsHandler(PrefService* prefs); ~CaptionsHandler() override; + CaptionsHandler(const CaptionsHandler&) = delete; + CaptionsHandler& operator=(const CaptionsHandler&) = delete; // SettingsPageUIHandler overrides: void RegisterMessages() override; @@ -24,9 +38,17 @@ void OnJavascriptDisallowed() override; private: + void HandleCaptionsSubpageReady(const base::ListValue* args); void HandleOpenSystemCaptionsDialog(const base::ListValue* args); - DISALLOW_COPY_AND_ASSIGN(CaptionsHandler); + // component_updater::ServiceObserver: + void OnEvent(Events event, const std::string& id) override; + + std::map<std::string, update_client::CrxUpdateItem> downloading_components_; + PrefService* prefs_; + ScopedObserver<component_updater::ComponentUpdateService, + component_updater::ComponentUpdateService::Observer> + component_updater_observer_{this}; }; } // namespace settings
diff --git a/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc b/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc index e0df357..7378aa0 100644 --- a/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/speech/extension_api/tts_engine_extension_observer.h" #include "chrome/browser/ui/webui/settings/accessibility_main_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h" +#include "chrome/browser/ui/webui/settings/chromeos/captions_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/font_handler.h" #include "chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h" @@ -591,6 +592,7 @@ web_ui->AddMessageHandler(std::make_unique<::settings::TtsHandler>()); web_ui->AddMessageHandler( std::make_unique<::settings::FontHandler>(profile())); + web_ui->AddMessageHandler(std::make_unique<CaptionsHandler>()); } int AccessibilitySection::GetSectionNameMessageId() const {
diff --git a/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc b/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc index 819a030b..24211de 100644 --- a/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc
@@ -159,6 +159,8 @@ {"bluetoothRemove", IDS_SETTINGS_BLUETOOTH_REMOVE}, {"bluetoothPrimaryUserControlled", IDS_SETTINGS_BLUETOOTH_PRIMARY_USER_CONTROLLED}, + {"bluetoothDeviceWithConnectionStatus", + IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_AND_CONNECTION_STATUS}, {"bluetoothDeviceType_computer", IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_COMPUTER}, {"bluetoothDeviceType_phone",
diff --git a/chrome/browser/ui/webui/settings/chromeos/captions_handler.cc b/chrome/browser/ui/webui/settings/chromeos/captions_handler.cc new file mode 100644 index 0000000..833793db --- /dev/null +++ b/chrome/browser/ui/webui/settings/chromeos/captions_handler.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/captions_handler.h" + +#include "base/bind_helpers.h" +#include "content/public/browser/web_ui.h" + +namespace chromeos { +namespace settings { + +CaptionsHandler::CaptionsHandler() = default; + +CaptionsHandler::~CaptionsHandler() = default; + +void CaptionsHandler::RegisterMessages() { + // TODO(crbug.com/1111002): Show download progress of SODA component in the + // Live Caption subtitle. + web_ui()->RegisterMessageCallback("captionsSubpageReady", base::DoNothing()); +} + +} // namespace settings +} // namespace chromeos
diff --git a/chrome/browser/ui/webui/settings/chromeos/captions_handler.h b/chrome/browser/ui/webui/settings/chromeos/captions_handler.h new file mode 100644 index 0000000..542ceeb --- /dev/null +++ b/chrome/browser/ui/webui/settings/chromeos/captions_handler.h
@@ -0,0 +1,30 @@ +// 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_CAPTIONS_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CAPTIONS_HANDLER_H_ + +#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" + +namespace chromeos { +namespace settings { + +// Settings handler for the captions settings page on ChromeOS. +class CaptionsHandler : public ::settings::SettingsPageUIHandler { + public: + CaptionsHandler(); + ~CaptionsHandler() override; + CaptionsHandler(const CaptionsHandler&) = delete; + CaptionsHandler& operator=(const CaptionsHandler&) = delete; + + // SettingsPageUIHandler overrides: + void RegisterMessages() override; + void OnJavascriptAllowed() override {} + void OnJavascriptDisallowed() override {} +}; + +} // namespace settings +} // namespace chromeos + +#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CAPTIONS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_section.cc b/chrome/browser/ui/webui/settings/chromeos/device_section.cc index 978d34f..506de1f 100644 --- a/chrome/browser/ui/webui/settings/chromeos/device_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/device_section.cc
@@ -15,6 +15,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/chromeos/login/demo_mode/demo_session.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/webui/settings/chromeos/device_display_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.h" @@ -1133,6 +1134,7 @@ content::WebUIDataSource* html_source) { static constexpr webui::LocalizedString kPointersStrings[] = { {"mouseTitle", IDS_SETTINGS_MOUSE_TITLE}, + {"pointingStickTitle", IDS_SETTINGS_POINTING_STICK_TITLE}, {"touchpadTitle", IDS_SETTINGS_TOUCHPAD_TITLE}, {"mouseAndTouchpadTitle", IDS_SETTINGS_MOUSE_AND_TOUCHPAD_TITLE}, {"touchpadTapToClickEnabledLabel", @@ -1166,6 +1168,9 @@ html_source->AddBoolean( "allowScrollSettings", base::FeatureList::IsEnabled(::chromeos::features::kAllowScrollSettings)); + html_source->AddBoolean( + "separatePointingStickSettings", + base::FeatureList::IsEnabled(::features::kSeparatePointingStickSettings)); } } // namespace settings
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc index 753c611..137aea3 100644 --- a/chrome/browser/ui/webui/settings/people_handler.cc +++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -80,7 +80,6 @@ SyncConfigInfo(); ~SyncConfigInfo(); - bool encrypt_all; bool sync_everything; syncer::UserSelectableTypeSet selected_types; bool payments_integration_enabled; @@ -93,8 +92,7 @@ } SyncConfigInfo::SyncConfigInfo() - : encrypt_all(false), - sync_everything(false), + : sync_everything(false), payments_integration_enabled(false), set_new_passphrase(false) {} @@ -133,12 +131,6 @@ config->selected_types.Put(type); } - // Encryption settings. - if (!result->GetBoolean("encryptAllData", &config->encrypt_all)) { - DLOG(ERROR) << "GetConfiguration() not passed a value for encryptAllData"; - return false; - } - // Passphrase settings. if (result->GetString("passphrase", &config->passphrase) && !config->passphrase.empty() && @@ -551,21 +543,15 @@ return; } - // Don't allow "encrypt all" if the SyncService doesn't allow it. - // The UI is hidden, but the user may have enabled it e.g. by fiddling with - // the web inspector. - if (!service->GetUserSettings()->IsEncryptEverythingAllowed()) { - configuration.encrypt_all = false; + if (service->GetUserSettings()->IsEncryptEverythingAllowed()) { + ProfileMetrics::LogProfileSyncInfo(ProfileMetrics::SYNC_ENCRYPT); + } else { + // Don't allow "encrypt all" if the SyncService doesn't allow it. + // The UI is hidden, but the user may have enabled it e.g. by fiddling with + // the web inspector. configuration.set_new_passphrase = false; } - // Note: Data encryption will not occur until configuration is complete - // (when the PSS receives its CONFIGURE_DONE notification from the sync - // engine), so the user still has a chance to cancel out of the operation - // if (for example) some kind of passphrase error is encountered. - if (configuration.encrypt_all) - service->GetUserSettings()->EnableEncryptEverything(); - bool passphrase_failed = false; if (!configuration.passphrase.empty()) { // We call IsPassphraseRequired() here (instead of @@ -611,8 +597,6 @@ ResolveJavascriptCallback(*callback_id, base::Value(kConfigurePageStatus)); } - if (configuration.encrypt_all) - ProfileMetrics::LogProfileSyncInfo(ProfileMetrics::SYNC_ENCRYPT); if (!configuration.set_new_passphrase && !configuration.passphrase.empty()) ProfileMetrics::LogProfileSyncInfo(ProfileMetrics::SYNC_PASSPHRASE); }
diff --git a/chrome/browser/ui/webui/settings/people_handler_unittest.cc b/chrome/browser/ui/webui/settings/people_handler_unittest.cc index ba703de..abd46e7 100644 --- a/chrome/browser/ui/webui/settings/people_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/people_handler_unittest.cc
@@ -1094,9 +1094,6 @@ list_args.AppendString(args); EXPECT_CALL(*mock_sync_service_->GetMockUserSettings(), - EnableEncryptEverything()) - .Times(0); - EXPECT_CALL(*mock_sync_service_->GetMockUserSettings(), SetEncryptionPassphrase(_)) .Times(0);
diff --git a/chrome/browser/ui/webui/settings/settings_ui.cc b/chrome/browser/ui/webui/settings/settings_ui.cc index 7f2c3259..c266e474 100644 --- a/chrome/browser/ui/webui/settings/settings_ui.cc +++ b/chrome/browser/ui/webui/settings/settings_ui.cc
@@ -31,7 +31,6 @@ #include "chrome/browser/ui/webui/settings/accessibility_main_handler.h" #include "chrome/browser/ui/webui/settings/appearance_handler.h" #include "chrome/browser/ui/webui/settings/browser_lifetime_handler.h" -#include "chrome/browser/ui/webui/settings/captions_handler.h" #include "chrome/browser/ui/webui/settings/downloads_handler.h" #include "chrome/browser/ui/webui/settings/extension_control_handler.h" #include "chrome/browser/ui/webui/settings/font_handler.h" @@ -119,6 +118,7 @@ #else // !defined(OS_CHROMEOS) #include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/ui/webui/customize_themes/chrome_customize_themes_handler.h" +#include "chrome/browser/ui/webui/settings/captions_handler.h" #include "chrome/browser/ui/webui/settings/settings_default_browser_handler.h" #include "chrome/browser/ui/webui/settings/settings_manage_profile_handler.h" #include "chrome/browser/ui/webui/settings/system_handler.h" @@ -181,12 +181,7 @@ CreateForProfile(profile)); #endif -#if defined(OS_CHROMEOS) AddSettingsPageUIHandler(std::make_unique<AccessibilityMainHandler>()); -#else - AddSettingsPageUIHandler( - std::make_unique<AccessibilityMainHandler>(profile->GetPrefs())); -#endif // defined(OS_CHROMEOS) AddSettingsPageUIHandler(std::make_unique<BrowserLifetimeHandler>()); AddSettingsPageUIHandler( std::make_unique<ClearBrowsingDataHandler>(web_ui, profile)); @@ -225,13 +220,11 @@ AddSettingsPageUIHandler( std::make_unique<SecurityKeysBioEnrollmentHandler>()); -#if defined(OS_WIN) || defined(OS_MAC) - AddSettingsPageUIHandler(std::make_unique<CaptionsHandler>()); -#endif - #if defined(OS_CHROMEOS) InitBrowserSettingsWebUIHandlers(); #else + AddSettingsPageUIHandler( + std::make_unique<CaptionsHandler>(profile->GetPrefs())); AddSettingsPageUIHandler(std::make_unique<DefaultBrowserHandler>()); AddSettingsPageUIHandler(std::make_unique<ManageProfileHandler>(profile)); AddSettingsPageUIHandler(std::make_unique<SystemHandler>());
diff --git a/chrome/browser/ui/webui/tab_strip/tab_strip_ui.cc b/chrome/browser/ui/webui/tab_strip/tab_strip_ui.cc index fe50b4d..e8d9e91 100644 --- a/chrome/browser/ui/webui/tab_strip/tab_strip_ui.cc +++ b/chrome/browser/ui/webui/tab_strip/tab_strip_ui.cc
@@ -45,11 +45,9 @@ Profile* profile = Profile::FromWebUI(web_ui); content::WebUIDataSource* html_source = content::WebUIDataSource::Create(chrome::kChromeUITabStripHost); - std::string generated_path = - "@out_folder@/gen/chrome/browser/resources/tab_strip/"; webui::SetupWebUIDataSource( html_source, base::make_span(kTabStripResources, kTabStripResourcesSize), - generated_path, IDR_TAB_STRIP_HTML); + "", IDR_TAB_STRIP_TAB_STRIP_HTML); html_source->AddString("tabIdDataType", kWebUITabIdDataType); html_source->AddString("tabGroupIdDataType", kWebUITabGroupIdDataType);
diff --git a/chrome/browser/ui/webui/webui_js_exception/webui_js_exception_ui.cc b/chrome/browser/ui/webui/webui_js_exception/webui_js_exception_ui.cc new file mode 100644 index 0000000..d06afb9 --- /dev/null +++ b/chrome/browser/ui/webui/webui_js_exception/webui_js_exception_ui.cc
@@ -0,0 +1,62 @@ +// 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/webui_js_exception/webui_js_exception_ui.h" + +#include <ios> + +#include "base/feature_list.h" +#include "base/logging.h" +#include "build/build_config.h" +#include "build/buildflag.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/webui_util.h" +#include "chrome/common/buildflags.h" +#include "chrome/common/webui_url_constants.h" +#include "chrome/grit/webui_js_exception_resources.h" +#include "chrome/grit/webui_js_exception_resources_map.h" +#include "content/public/browser/web_ui_data_source.h" +#include "content/public/common/content_features.h" + +#if !BUILDFLAG(OPTIMIZE_WEBUI) +namespace { +constexpr char kGeneratedPath[] = + "@out_folder@/gen/chrome/browser/resources/webui_js_exception/"; +} // namespace +#endif // !BUILDFLAG(OPTIMIZE_WEBUI) + +WebUIJsExceptionUI::WebUIJsExceptionUI(content::WebUI* web_ui) + : content::WebUIController(web_ui) { +#if !defined(OS_WIN) && !defined(OS_FUCHSIA) + VLOG(3) << std::boolalpha << "chrome://webuijsexception loading. " + << "Experiment state: send javascript errors is " + << base::FeatureList::IsEnabled( + features::kSendWebUIJavaScriptErrorReports) + << " and send to prod is " + << features::kWebUIJavaScriptErrorReportsSendToProductionParam.Get(); +#else + VLOG(3) << std::boolalpha << "chrome://webuijsexception loading."; +#endif + + content::WebUIDataSource* source = + content::WebUIDataSource::Create(chrome::kChromeUIWebUIJsExceptionHost); +#if BUILDFLAG(OPTIMIZE_WEBUI) + webui::SetupBundledWebUIDataSource( + source, "webui_js_exception.js", + IDR_WEBUI_JS_EXCEPTION_UI_WEBUI_JS_EXCEPTION_ROLLUP_JS, + IDR_WEBUI_JS_EXCEPTION_UI_WEBUI_JS_EXCEPTION_HTML); +#else // if !BUILDFLAG(OPTIMIZE_WEBUI) + webui::SetupWebUIDataSource( + source, + base::make_span(kWebuiJsExceptionResources, + kWebuiJsExceptionResourcesSize), + kGeneratedPath, IDR_WEBUI_JS_EXCEPTION_UI_WEBUI_JS_EXCEPTION_HTML); +#endif // !BUILDFLAG(OPTIMIZE_WEBUI) + Profile* profile = Profile::FromWebUI(web_ui); + content::WebUIDataSource::Add(profile, source); +} + +WebUIJsExceptionUI::~WebUIJsExceptionUI() = default; + +WEB_UI_CONTROLLER_TYPE_IMPL(WebUIJsExceptionUI)
diff --git a/chrome/browser/ui/webui/webui_js_exception/webui_js_exception_ui.h b/chrome/browser/ui/webui/webui_js_exception/webui_js_exception_ui.h new file mode 100644 index 0000000..d49f35a5 --- /dev/null +++ b/chrome/browser/ui/webui/webui_js_exception/webui_js_exception_ui.h
@@ -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. + +#ifndef CHROME_BROWSER_UI_WEBUI_WEBUI_JS_EXCEPTION_WEBUI_JS_EXCEPTION_UI_H_ +#define CHROME_BROWSER_UI_WEBUI_WEBUI_JS_EXCEPTION_WEBUI_JS_EXCEPTION_UI_H_ + +#include "content/public/browser/web_ui_controller.h" + +// The WebUI that controls chrome://webuijsexception. +class WebUIJsExceptionUI : public content::WebUIController { + public: + explicit WebUIJsExceptionUI(content::WebUI* web_ui); + ~WebUIJsExceptionUI() override; + WebUIJsExceptionUI(const WebUIJsExceptionUI&) = delete; + WebUIJsExceptionUI& operator=(const WebUIJsExceptionUI&) = delete; + + private: + WEB_UI_CONTROLLER_TYPE_DECL(); +}; + +#endif // CHROME_BROWSER_UI_WEBUI_WEBUI_JS_EXCEPTION_WEBUI_JS_EXCEPTION_UI_H_
diff --git a/chrome/browser/video_tutorials/internal/config.cc b/chrome/browser/video_tutorials/internal/config.cc index e9ee89a..ed1de3f0 100644 --- a/chrome/browser/video_tutorials/internal/config.cc +++ b/chrome/browser/video_tutorials/internal/config.cc
@@ -11,13 +11,14 @@ namespace video_tutorials { // Default base URL string for the server. -constexpr char kDefaultBaseURL[] = "https://chromeupboarding-pa.googleapis.com"; +constexpr char kDefaultBaseURL[] = + "https://staging-gsaprototype-pa.sandbox.googleapis.com"; // Default URL string for GetTutorials RPC. constexpr char kDefaultGetTutorialsPath[] = "/v1/videotutorials"; // Hindi is the default locale. -constexpr char kDefaultPreferredLocale[] = "hi"; +constexpr char kDefaultPreferredLocale[] = "en"; // Finch parameter key for base server URL to retrieve the tutorials. constexpr char kBaseURLKey[] = "base_url";
diff --git a/chrome/browser/video_tutorials/internal/config_unittest.cc b/chrome/browser/video_tutorials/internal/config_unittest.cc index 1d292e1..4c0c0bd 100644 --- a/chrome/browser/video_tutorials/internal/config_unittest.cc +++ b/chrome/browser/video_tutorials/internal/config_unittest.cc
@@ -29,8 +29,9 @@ base::test::ScopedFeatureList feature_list; feature_list.InitAndEnableFeature(features::kVideoTutorials); EXPECT_EQ(Config::GetTutorialsServerURL().spec(), - "https://chromeupboarding-pa.googleapis.com/v1/videotutorials"); - EXPECT_EQ(Config::GetDefaultPreferredLocale(), "hi"); + "https://staging-gsaprototype-pa.sandbox.googleapis.com/v1/" + "videotutorials"); + EXPECT_EQ(Config::GetDefaultPreferredLocale(), "en"); } } // namespace video_tutorials
diff --git a/chrome/browser/video_tutorials/internal/tutorial_manager_impl_unittest.cc b/chrome/browser/video_tutorials/internal/tutorial_manager_impl_unittest.cc index 734bed7b..56e99772 100644 --- a/chrome/browser/video_tutorials/internal/tutorial_manager_impl_unittest.cc +++ b/chrome/browser/video_tutorials/internal/tutorial_manager_impl_unittest.cc
@@ -161,6 +161,7 @@ auto languages = manager()->GetSupportedLanguages(); EXPECT_EQ(languages.size(), 2u); + manager()->SetPreferredLocale("hi"); GetTutorials(); EXPECT_EQ(last_results().size(), 2u); } @@ -171,6 +172,7 @@ tutorial_store->InitStoreData("hi", groups); CreateTutorialManager(std::move(tutorial_store)); + manager()->SetPreferredLocale("hi"); auto languages = manager()->GetSupportedLanguages(); EXPECT_EQ(languages.size(), 2u); GetTutorials();
diff --git a/chrome/browser/video_tutorials/internal/tutorial_service_impl.cc b/chrome/browser/video_tutorials/internal/tutorial_service_impl.cc index 0c10699f..6caca4f 100644 --- a/chrome/browser/video_tutorials/internal/tutorial_service_impl.cc +++ b/chrome/browser/video_tutorials/internal/tutorial_service_impl.cc
@@ -20,7 +20,9 @@ PrefService* pref_service) : tutorial_manager_(std::move(tutorial_manager)), tutorial_fetcher_(std::move(tutorial_fetcher)), - pref_service_(pref_service) {} + pref_service_(pref_service) { + StartFetchIfNecessary(); +} TutorialServiceImpl::~TutorialServiceImpl() = default; @@ -61,7 +63,8 @@ void TutorialServiceImpl::OnFetchFinished( bool success, std::unique_ptr<std::string> response_body) { - // TODO(shaktisahu): Save tutorials to the database. + pref_service_->SetTime(kLastUpdatedTimeKey, base::Time::Now()); + if (!success || !response_body) return;
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 79a5b52..0c57458 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-master-1602827193-4287d7521da41bae907bcfa87edebb4158ef284f.profdata +chrome-linux-master-1602849330-e626db1a42614bd1b3dbd5e4d956205e419c269d.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 359e973..26ad8fb 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-master-1602827193-a11ab02463ee64ac6dd1eb410ceea8e9dc281351.profdata +chrome-mac-master-1602849330-a9b7aee9583f24ea33d238dab5bbe64a57e40269.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index ad65eeb..5654285 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-master-1602795589-2bd353ec3fee304a6bd3887aca77b7d3fb1210e3.profdata +chrome-win32-master-1602838722-3d3847c86317a9aa85069273b7be64c1533b4e7a.profdata
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni index 9323a774..683f931 100644 --- a/chrome/chrome_paks.gni +++ b/chrome/chrome_paks.gni
@@ -221,6 +221,10 @@ ] } } + if (is_linux || is_chromeos) { + sources += [ "$root_gen_dir/chrome/webui_js_exception_resources.pak" ] + deps += [ "//chrome/browser/resources:webui_js_exception_resources" ] + } if (!is_android && !is_chromeos) { sources += [ "$root_gen_dir/chrome/profile_picker_resources.pak",
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc index 9012476..2f6f4f4 100644 --- a/chrome/common/webui_url_constants.cc +++ b/chrome/common/webui_url_constants.cc
@@ -338,6 +338,11 @@ } #endif // defined(OS_CHROMEOS) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) +const char kChromeUIWebUIJsExceptionHost[] = "webuijsexception"; +const char kChromeUIWebUIJsExceptionURL[] = "chrome://webuijsexception/"; +#endif + #if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \ defined(OS_CHROMEOS) const char kChromeUIDiscardsHost[] = "discards"; @@ -609,6 +614,9 @@ content::kChromeUIGpuJavaCrashURL, kChromeUIJavaCrashURL, #endif +#if defined(OS_LINUX) || defined(OS_CHROMEOS) + kChromeUIWebUIJsExceptionURL, +#endif kChromeUIQuitURL, kChromeUIRestartURL}; const size_t kNumberOfChromeDebugURLs = base::size(kChromeDebugURLs);
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h index bc28c1b..c57f9936 100644 --- a/chrome/common/webui_url_constants.h +++ b/chrome/common/webui_url_constants.h
@@ -291,6 +291,11 @@ #endif // defined(OS_CHROMEOS) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) +extern const char kChromeUIWebUIJsExceptionHost[]; +extern const char kChromeUIWebUIJsExceptionURL[]; +#endif + #if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \ defined(OS_CHROMEOS) extern const char kChromeUIDiscardsHost[];
diff --git a/chrome/installer/setup/user_hive_visitor_unittest.cc b/chrome/installer/setup/user_hive_visitor_unittest.cc index 70bbb0f..a614c5e 100644 --- a/chrome/installer/setup/user_hive_visitor_unittest.cc +++ b/chrome/installer/setup/user_hive_visitor_unittest.cc
@@ -7,6 +7,7 @@ #include <vector> #include "base/bind.h" +#include "base/callback.h" #include "base/macros.h" #include "base/strings/string16.h" #include "base/win/registry.h"
diff --git a/chrome/installer/util/beacons.cc b/chrome/installer/util/beacons.cc index ee2c1bb..4bbbb71 100644 --- a/chrome/installer/util/beacons.cc +++ b/chrome/installer/util/beacons.cc
@@ -6,6 +6,7 @@ #include <stdint.h> +#include "base/notreached.h" #include "base/win/registry.h" #include "base/win/win_util.h" #include "chrome/install_static/install_details.h"
diff --git a/chrome/installer/util/install_util.cc b/chrome/installer/util/install_util.cc index 45a89af7..5647b0e 100644 --- a/chrome/installer/util/install_util.cc +++ b/chrome/installer/util/install_util.cc
@@ -13,10 +13,13 @@ #include <algorithm> #include <iterator> +#include "base/check.h" +#include "base/check_op.h" #include "base/command_line.h" #include "base/files/file_util.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" +#include "base/notreached.h" #include "base/path_service.h" #include "base/process/launch.h" #include "base/stl_util.h"
diff --git a/chrome/installer/util/registry_entry.cc b/chrome/installer/util/registry_entry.cc index b4bf253..7e5c8ff 100644 --- a/chrome/installer/util/registry_entry.cc +++ b/chrome/installer/util/registry_entry.cc
@@ -5,6 +5,7 @@ #include "chrome/installer/util/registry_entry.h" #include "base/check.h" +#include "base/numerics/safe_conversions.h" #include "base/strings/string_util.h" #include "base/win/registry.h" #include "chrome/installer/util/work_item.h"
diff --git a/chrome/installer/util/registry_key_backup.cc b/chrome/installer/util/registry_key_backup.cc index c10d476..8909cb4 100644 --- a/chrome/installer/util/registry_key_backup.cc +++ b/chrome/installer/util/registry_key_backup.cc
@@ -11,6 +11,7 @@ #include <utility> #include <vector> +#include "base/check.h" #include "base/logging.h" #include "base/win/registry.h"
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 31b5dee..25ebf2f 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1215,6 +1215,7 @@ "../browser/portal/portal_recently_audible_browsertest.cc", "../browser/predictors/loading_predictor_browsertest.cc", "../browser/prefetch/prefetch_browsertest.cc", + "../browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc", "../browser/prefs/pref_functional_browsertest.cc", "../browser/prefs/pref_service_browsertest.cc", "../browser/prefs/tracked/pref_hash_browsertest.cc", @@ -2817,7 +2818,10 @@ "../browser/policy/cloud/chrome_browser_cloud_management_browsertest.cc", ] - deps += [ "//components/crash/content/browser/error_reporting:mock_crash_endpoint" ] + deps += [ + "//chromeos/ui/frame:test_support", + "//components/crash/content/browser/error_reporting:mock_crash_endpoint", + ] } else { # !is_chromeos sources -= [ "../browser/invalidation/profile_invalidation_provider_factory_browsertest.cc", @@ -3786,6 +3790,7 @@ "../browser/android/explore_sites/ntp_json_fetcher_unittest.cc", "../browser/android/explore_sites/record_site_click_task_unittest.cc", "../browser/android/favicon_helper_unittest.cc", + "../browser/android/history/history_deletion_bridge_unittest.cc", "../browser/android/history_report/data_observer_unittest.cc", "../browser/android/history_report/delta_file_backend_leveldb_unittest.cc", "../browser/android/history_report/delta_file_commons_unittest.cc", @@ -6595,6 +6600,7 @@ deps += [ "//chrome/browser/media/router:test_support", "//chromeos/dbus", + "//chromeos/ui/frame:test_support", ] sources -= [ "../browser/ui/signin_view_controller_interactive_uitest.cc" ]
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index a7c2739..3cbb9fc 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -4983,6 +4983,16 @@ ] }, + "WifiSyncAndroidAllowed": { + "os": ["chromeos"], + "policy_pref_mapping_test": [ + { + "policies": { "WifiSyncAndroidAllowed": false }, + "prefs": { "wifi_sync.allowed": {} } + } + ] + }, + "SmartLockSigninAllowed": { "os": ["chromeos"], "policy_pref_mapping_test": [
diff --git a/chrome/test/data/webui/chromeos/diagnostics/realtime_cpu_chart_test.js b/chrome/test/data/webui/chromeos/diagnostics/realtime_cpu_chart_test.js index 40170d2e..07b162f 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/realtime_cpu_chart_test.js +++ b/chrome/test/data/webui/chromeos/diagnostics/realtime_cpu_chart_test.js
@@ -62,12 +62,44 @@ return initializeRealtimeCpuChart(user, system).then(() => { const svg = realtimeCpuChartElement.$$('#chart'); const boundary = realtimeCpuChartElement.$$('#defClip>rect'); + + // Chart area boundary must fit within svg. assertGT( Number(svg.getAttribute('width')), Number(boundary.getAttribute('width'))); assertGT( Number(svg.getAttribute('height')), Number(boundary.getAttribute('height'))); + + const chartGroup = realtimeCpuChartElement.$$('#chartGroup'); + + // Margins are in effect. + assertEquals( + `translate(${realtimeCpuChartElement.margin_.left},${ + realtimeCpuChartElement.margin_.top})`, + chartGroup.getAttribute('transform')); + }); + }); + + test('InitializePlot', () => { + const user = 10; + const system = 30; + return initializeRealtimeCpuChart(user, system).then(() => { + // yAxis is drawn. + assertTrue(!!realtimeCpuChartElement.$$('#gridLines>path.domain')); + + // Correct number of yAxis ticks drawn. + assertEquals( + 3, + realtimeCpuChartElement.shadowRoot + .querySelectorAll('#gridLines>g.tick') + .length); + + // Plot lines are drawn. + assertTrue(!!realtimeCpuChartElement.$$('#plotGroup>path.user-line') + .getAttribute('d')); + assertTrue(!!realtimeCpuChartElement.$$('#plotGroup>path.system-line') + .getAttribute('d')); }); }); });
diff --git a/chrome/test/data/webui/chromeos/diagnostics/routine_result_entry_test.js b/chrome/test/data/webui/chromeos/diagnostics/routine_result_entry_test.js index f7ef766..979dd69 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/routine_result_entry_test.js +++ b/chrome/test/data/webui/chromeos/diagnostics/routine_result_entry_test.js
@@ -5,6 +5,9 @@ // TODO(jimmyxgong): Use es6 module for mojo binding (crbug/1004256). import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; import 'chrome://diagnostics/routine_result_entry.js'; + +import {RoutineName, RoutineResult, StandardRoutineResult} from 'chrome://diagnostics/diagnostics_types.js'; +import {ExecutionProgress, ResultStatusItem} from 'chrome://diagnostics/routine_list_executor.js'; import {flushTasks} from 'chrome://test/test_util.m.js'; suite('RoutineResultEntryTest', () => { @@ -33,6 +36,71 @@ return flushTasks(); } + /** + * Updates the item in the element. + * @param {!ResultStatusItem} item + * @return {!Promise} + */ + function updateItem(item) { + routineResultEntryElement.item = item; + return flushTasks(); + } + + /** + * Initializes the entry then updates the item. + * @param {!ResultStatusItem} item + * @return {!Promise} + */ + function initializeEntryWithItem(item) { + return initializeRoutineResultEntry().then(() => { + return updateItem(item); + }); + } + + /** + * Creates a result status item without a final result. + * @param {!RoutineName} routine + * @param {!ExecutionProgress} progress + * @return {!ResultStatusItem} + */ + function createIncompleteStatus(routine, progress) { + let status = new ResultStatusItem(routine); + status.progress = progress; + return status; + } + + /** + * Creates a completed result status item with a result. + * @param {!RoutineName} routine + * @param {!RoutineResult} result + * @return {!ResultStatusItem} + */ + function createCompletedStatus(routine, result) { + let status = createIncompleteStatus(routine, ExecutionProgress.kCompleted); + status.result = result; + return status; + } + + /** + * Returns the routine name element text content. + * @return {string} + */ + function getNameText() { + const name = routineResultEntryElement.$$('#routine'); + assertTrue(!!name); + return name.textContent.trim(); + } + + /** + * Returns the status element text content. + * @return {string} + */ + function getStatusText() { + const status = routineResultEntryElement.$$('#status'); + assertTrue(!!status); + return status.textContent.trim(); + } + test('ElementRendered', () => { return initializeRoutineResultEntry().then(() => { // Verify the element rendered. @@ -40,4 +108,54 @@ assertTrue(!!div); }); }); + + test('NotStartedTest', () => { + const item = createIncompleteStatus( + RoutineName.kCpuStress, ExecutionProgress.kNotStarted); + return initializeEntryWithItem(item).then(() => { + // TODO(zentaro): Localize the test. + assertEquals(getNameText(), 'kCpuStress'); + + // Status should be empty if the test is not started. + assertEquals(getStatusText(), ''); + }); + }); + + test('RunningTest', () => { + const item = createIncompleteStatus( + RoutineName.kCpuStress, ExecutionProgress.kRunning); + return initializeEntryWithItem(item).then(() => { + // TODO(zentaro): Localize the test. + assertEquals(getNameText(), 'kCpuStress'); + + // Status should be running. + assertEquals(getStatusText(), 'kRunning'); + }); + }); + + test('PassedTest', () => { + const item = createCompletedStatus( + RoutineName.kCpuStress, + {simple_result: StandardRoutineResult.kTestPassed}); + return initializeEntryWithItem(item).then(() => { + // TODO(zentaro): Localize the test. + assertEquals(getNameText(), 'kCpuStress'); + + // Status should show the passed result. + assertEquals(getStatusText(), 'kTestPassed'); + }); + }); + + test('FailedTest', () => { + const item = createCompletedStatus( + RoutineName.kCpuStress, + {simple_result: StandardRoutineResult.kTestFailed}); + return initializeEntryWithItem(item).then(() => { + // TODO(zentaro): Localize the test. + assertEquals(getNameText(), 'kCpuStress'); + + // Status should show the passed result. + assertEquals(getStatusText(), 'kTestFailed'); + }); + }); });
diff --git a/chrome/test/data/webui/settings/chromeos/device_page_tests.js b/chrome/test/data/webui/settings/chromeos/device_page_tests.js index 4995bea..4a5e2c03 100644 --- a/chrome/test/data/webui/settings/chromeos/device_page_tests.js +++ b/chrome/test/data/webui/settings/chromeos/device_page_tests.js
@@ -10,6 +10,7 @@ Keyboard: 'keyboard', NightLight: 'night light', Pointers: 'pointers', + PointingStick: 'pointing stick', Power: 'power', Storage: 'storage', Stylus: 'stylus', @@ -740,6 +741,101 @@ }); }); + suite(assert(TestNames.PointingStick), function() { + // TODO(crbug.com/1114828): merge this suite into the Pointers one when + // the flag is removed. + let pointersPage; + + setup(function() { + // We have to set separatePointingStickSettings here so it's in effect + // when the template is rendered. + loadTimeData.overrideValues({separatePointingStickSettings: true}); + return showAndGetDeviceSubpage('pointers', settings.routes.POINTERS) + .then(function(page) { + pointersPage = page; + }); + }); + + test('subpage responds to pointer attach/detach', function() { + const assertElementVisible = (element) => { + assertNotEquals(element, null, 'element should exist'); + // offsetWidth and offsetHeight reflect more ways that an element + // could be hidden than checking the hidden attribute directly. + assertTrue( + element.offsetWidth > 0 && element.offsetHeight > 0, + 'element should be visible'); + }; + + const assertElementHidden = (element) => { + assertNotEquals(element, null, 'element should exist'); + assertTrue( + element.offsetWidth === 0 && element.offsetHeight === 0, + 'element should be hidden'); + }; + + assertEquals( + settings.routes.POINTERS, + settings.Router.getInstance().getCurrentRoute()); + assertElementVisible(pointersPage.$$('#mouse')); + assertElementVisible(pointersPage.$$('#mouse h2')); + assertElementVisible(pointersPage.$$('#pointingStick')); + assertElementVisible(pointersPage.$$('#pointingStick h2')); + assertElementVisible(pointersPage.$$('#touchpad')); + assertElementVisible(pointersPage.$$('#touchpad h2')); + + cr.webUIListenerCallback('has-touchpad-changed', false); + assertEquals( + settings.routes.POINTERS, + settings.Router.getInstance().getCurrentRoute()); + assertElementVisible(pointersPage.$$('#mouse')); + assertElementVisible(pointersPage.$$('#mouse h2')); + assertElementVisible(pointersPage.$$('#pointingStick')); + assertElementVisible(pointersPage.$$('#pointingStick h2')); + assertElementHidden(pointersPage.$$('#touchpad')); + assertElementHidden(pointersPage.$$('#touchpad h2')); + + cr.webUIListenerCallback('has-pointing-stick-changed', false); + assertEquals( + settings.routes.POINTERS, + settings.Router.getInstance().getCurrentRoute()); + assertElementVisible(pointersPage.$$('#mouse')); + assertElementHidden(pointersPage.$$('#mouse h2')); + assertElementHidden(pointersPage.$$('#pointingStick')); + assertElementHidden(pointersPage.$$('#pointingStick h2')); + assertElementHidden(pointersPage.$$('#touchpad')); + assertElementHidden(pointersPage.$$('#touchpad h2')); + + cr.webUIListenerCallback('has-mouse-changed', false); + assertEquals( + settings.routes.DEVICE, + settings.Router.getInstance().getCurrentRoute()); + assertElementHidden(devicePage.$$('#main #pointersRow')); + + cr.webUIListenerCallback('has-touchpad-changed', true); + assertElementVisible(devicePage.$$('#main #pointersRow')); + return showAndGetDeviceSubpage('pointers', settings.routes.POINTERS) + .then(function(page) { + assertElementHidden(page.$$('#mouse')); + assertElementHidden(page.$$('#mouse h2')); + assertElementHidden(page.$$('#pointingStick')); + assertElementHidden(page.$$('#pointingStick h2')); + assertElementVisible(page.$$('#touchpad')); + assertElementHidden(page.$$('#touchpad h2')); + + cr.webUIListenerCallback('has-mouse-changed', true); + assertEquals( + settings.routes.POINTERS, + settings.Router.getInstance().getCurrentRoute()); + assertElementVisible(page.$$('#mouse')); + assertElementVisible(page.$$('#mouse h2')); + assertElementHidden(page.$$('#pointingStick')); + assertElementHidden(page.$$('#pointingStick h2')); + assertElementVisible(page.$$('#touchpad')); + assertElementVisible(page.$$('#touchpad h2')); + }); + }); + }); + suite(assert(TestNames.Keyboard), function() { const name = k => `prefs.settings.language.${k}.value`; const get = k => devicePage.get(name(k));
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js index 41c8ccc..2cfeb7c 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -687,6 +687,10 @@ mocha.grep(assert(device_page_tests.TestNames.Pointers)).run(); }); +TEST_F('OSSettingsDevicePageTest', 'PointersWithPointingStickTest', () => { + mocha.grep(assert(device_page_tests.TestNames.PointingStick)).run(); +}); + TEST_F('OSSettingsDevicePageTest', 'PowerTest', () => { mocha.grep(assert(device_page_tests.TestNames.Power)).run(); });
diff --git a/chrome/test/data/webui/settings/people_page_sync_page_test.js b/chrome/test/data/webui/settings/people_page_sync_page_test.js index 8f09e01b..624cd363 100644 --- a/chrome/test/data/webui/settings/people_page_sync_page_test.js +++ b/chrome/test/data/webui/settings/people_page_sync_page_test.js
@@ -335,8 +335,6 @@ assertFalse(passphraseInput.invalid); assertTrue(passphraseConfirmationInput.invalid); - - assertFalse(syncPage.syncPrefs.encryptAllData); }); test('CreatingPassphraseValidPassphrase', function() { @@ -354,15 +352,15 @@ passphraseConfirmationInput.value = 'foo'; saveNewPassphrase.click(); - function verifyPrefs(prefs) { - const expected = getSyncAllPrefs(); - expected.setNewPassphrase = true; - expected.passphrase = 'foo'; - expected.encryptAllData = true; - assertEquals(JSON.stringify(expected), JSON.stringify(prefs)); + function verifySetSyncEncryption(args) { + assertTrue(args.setNewPassphrase); + assertEquals('foo', args.passphrase); - expected.fullEncryptionBody = 'Encrypted with custom passphrase'; - webUIListenerCallback('sync-prefs-changed', expected); + // Fake backend response. + const newPrefs = getSyncAllPrefs(); + newPrefs.fullEncryptionBody = 'Encrypted with custom passphrase'; + newPrefs.encryptAllData = true; + webUIListenerCallback('sync-prefs-changed', newPrefs); flush(); @@ -378,7 +376,8 @@ assertEquals(-1, encryptWithPassphrase.$.button.tabIndex); }); } - return browserProxy.whenCalled('setSyncEncryption').then(verifyPrefs); + return browserProxy.whenCalled('setSyncEncryption') + .then(verifySetSyncEncryption); }); test('RadioBoxesHiddenWhenPassphraseRequired', function() { @@ -432,16 +431,10 @@ assertTrue(!!submitExistingPassphrase); submitExistingPassphrase.click(); - return browserProxy.whenCalled('setSyncEncryption').then(function(prefs) { - const expected = getSyncAllPrefs(); - expected.setNewPassphrase = false; - expected.passphrase = 'wrong'; - expected.encryptAllData = true; - expected.passphraseRequired = true; - assertEquals(JSON.stringify(expected), JSON.stringify(prefs)); - - flush(); - + return browserProxy.whenCalled('setSyncEncryption').then(function(args) { + assertFalse(args.setNewPassphrase); + assertEquals('wrong', args.passphrase); + assertTrue(args.passphraseRequired); assertTrue(existingPassphraseInput.invalid); }); }); @@ -462,14 +455,12 @@ assertTrue(!!submitExistingPassphrase); submitExistingPassphrase.click(); - return browserProxy.whenCalled('setSyncEncryption').then(function(prefs) { - const expected = getSyncAllPrefs(); - expected.setNewPassphrase = false; - expected.passphrase = 'right'; - expected.encryptAllData = true; - expected.passphraseRequired = true; - assertEquals(JSON.stringify(expected), JSON.stringify(prefs)); + return browserProxy.whenCalled('setSyncEncryption').then(function(args) { + assertFalse(args.setNewPassphrase); + assertEquals('right', args.passphrase); + assertTrue(args.passphraseRequired); + // Fake backend response. const newPrefs = getSyncAllPrefs(); newPrefs.encryptAllData = true; webUIListenerCallback('sync-prefs-changed', newPrefs);
diff --git a/chrome/updater/app/server/win/BUILD.gn b/chrome/updater/app/server/win/BUILD.gn index 5506d9d..7cc50e2 100644 --- a/chrome/updater/app/server/win/BUILD.gn +++ b/chrome/updater/app/server/win/BUILD.gn
@@ -4,10 +4,14 @@ import("//build/toolchain/win/midl.gni") +UpdaterClass_replaceable_uuid = "158428a4-6014-4978-83ba-9fad0dabe791" +IUpdater_replaceable_uuid = "63B8FFB1-5314-48C9-9C57-93EC8BC6184B" + # TODO(crbug.com/1099904): this CLSID needs to be regenerated for every build. # TODO(crbug.com/1099904): we need to use an indirection mechanism for the # common GUIDs in the SxS versions. -updater_clsid = "158428a4-6014-4978-83ba-9fad0dabe791" +updater_clsid = "3d852661-c795-4d20-9b95-5561e9a1d2d9" +IUPDATER_IID = "D0E1CACC-C63C-4192-94AB-BF8EAD0E3B83" action("generate_updater_idl") { script = "//build/util/version.py" @@ -17,14 +21,17 @@ args = [ "-e", - "UPDATER_CLSID='$updater_clsid'", + "$UpdaterClass_replaceable_uuid='$updater_clsid'", + "-e", + "$IUpdater_replaceable_uuid='$IUPDATER_IID'", rebase_path(inputs[0], root_build_dir), rebase_path(outputs[0], root_build_dir), ] } midl("updater_idl_idl") { - dynamic_guid = updater_clsid + dynamic_guid = "$UpdaterClass_replaceable_uuid=$updater_clsid," + + "$IUpdater_replaceable_uuid=$IUPDATER_IID" deps = [ ":generate_updater_idl" ] header_file = "updater_idl.h" sources = get_target_outputs(":generate_updater_idl") @@ -33,7 +40,7 @@ "IUPDATESTATE_IID=46ACF70B-AC13-406D-B53B-B2C4BF091FF6", "ICOMPLETESTATUS_IID=2FCD14AF-B645-4351-8359-E80A0E202A0B", "IUPDATEROBSERVER_IID=7B416CFD-4216-4FD6-BD83-7C586054676E", - "IUPDATER_IID=63B8FFB1-5314-48C9-9C57-93EC8BC6184B", + "IUPDATER_IID=$IUPDATER_IID", "IUPDATERCONTROL_IID=526DA036-9BD3-4697-865A-DA12D37DFFCA", "UPDATER_LIB_UUID=69464FF0-D9EC-4037-A35F-8AE4358106CC", "ICURRENTSTATE_IID=247954F9-9EDC-4E68-8CC3-150C2B89EADF",
diff --git a/chrome/updater/app/server/win/updater_idl.template b/chrome/updater/app/server/win/updater_idl.template index 4122276..322e973 100644 --- a/chrome/updater/app/server/win/updater_idl.template +++ b/chrome/updater/app/server/win/updater_idl.template
@@ -257,7 +257,7 @@ [ object, dual, - uuid(IUPDATER_IID), + uuid(@63B8FFB1-5314-48C9-9C57-93EC8BC6184B@), helpstring("IUpdater Interface"), pointer_default(unique) ] @@ -298,7 +298,7 @@ // single 'coclass' definition. Any other coclasses need to be defined in // constants.h/cc. [ - uuid(@UPDATER_CLSID@), + uuid(@158428a4-6014-4978-83ba-9fad0dabe791@), helpstring("Updater Class") ] coclass UpdaterClass
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index 7dafa85..d56d66e 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -511,6 +511,12 @@ <message name="IDS_DIAGNOSTICS_CPU_USAGE_LABEL" desc="The label for the percentage of CPU that is currently being used." translateable="false"> Currently using </message> + <message name="IDS_DIAGNOSTICS_CPU_USAGE_SYSTEM_LABEL" desc="The label for the percentage of CPU that is currently being used by the system." translateable="false"> + System + </message> + <message name="IDS_DIAGNOSTICS_CPU_USAGE_USER_LABEL" desc="The label for the percentage of CPU that is currently being used by the user." translateable="false"> + User + </message> <message name="IDS_DIAGNOSTICS_CPU_TEMPERATURE_LABEL" desc="The label for the current CPU temperature." translateable="false"> Temperature </message>
diff --git a/chromeos/components/cdm_factory_daemon/chromeos_cdm_factory.cc b/chromeos/components/cdm_factory_daemon/chromeos_cdm_factory.cc index f258083..b9d1c91 100644 --- a/chromeos/components/cdm_factory_daemon/chromeos_cdm_factory.cc +++ b/chromeos/components/cdm_factory_daemon/chromeos_cdm_factory.cc
@@ -73,6 +73,9 @@ if (!platform_verification_) { frame_interfaces_->BindEmbedderReceiver(mojo::GenericPendingReceiver( platform_verification_.BindNewPipeAndPassReceiver())); + platform_verification_.set_disconnect_handler( + base::BindOnce(&ChromeOsCdmFactory::OnVerificationMojoConnectionError, + weak_factory_.GetWeakPtr())); } platform_verification_->IsVerifiedAccessEnabled(base::BindOnce( &ChromeOsCdmFactory::OnVerifiedAccessEnabled, weak_factory_.GetWeakPtr(), @@ -147,7 +150,7 @@ if (!remote_factory_) { remote_factory_.Bind(std::move(remote_factory)); remote_factory_.set_disconnect_handler( - base::BindOnce(&ChromeOsCdmFactory::OnMojoConnectionError, + base::BindOnce(&ChromeOsCdmFactory::OnFactoryMojoConnectionError, weak_factory_.GetWeakPtr())); } @@ -202,9 +205,14 @@ FROM_HERE, base::BindOnce(std::move(cdm_created_cb), std::move(cdm), "")); } -void ChromeOsCdmFactory::OnMojoConnectionError() { +void ChromeOsCdmFactory::OnFactoryMojoConnectionError() { DVLOG(1) << __func__; remote_factory_.reset(); } +void ChromeOsCdmFactory::OnVerificationMojoConnectionError() { + DVLOG(1) << __func__; + platform_verification_.reset(); +} + } // namespace chromeos
diff --git a/chromeos/components/cdm_factory_daemon/chromeos_cdm_factory.h b/chromeos/components/cdm_factory_daemon/chromeos_cdm_factory.h index c5a4925..ce41d36 100644 --- a/chromeos/components/cdm_factory_daemon/chromeos_cdm_factory.h +++ b/chromeos/components/cdm_factory_daemon/chromeos_cdm_factory.h
@@ -73,7 +73,8 @@ const media::SessionKeysChangeCB& session_keys_change_cb, const media::SessionExpirationUpdateCB& session_expiration_update_cb, media::CdmCreatedCB cdm_created_cb); - void OnMojoConnectionError(); + void OnFactoryMojoConnectionError(); + void OnVerificationMojoConnectionError(); media::mojom::FrameInterfaceFactory* frame_interfaces_; mojo::Remote<cdm::mojom::CdmFactory> remote_factory_;
diff --git a/chromeos/components/diagnostics_ui/diagnostics_ui.cc b/chromeos/components/diagnostics_ui/diagnostics_ui.cc index f8a4c9d..6226236 100644 --- a/chromeos/components/diagnostics_ui/diagnostics_ui.cc +++ b/chromeos/components/diagnostics_ui/diagnostics_ui.cc
@@ -36,6 +36,8 @@ {"cpuTemp", IDS_DIAGNOSTICS_CPU_TEMPERATURE_LABEL}, {"cpuTitle", IDS_DIAGNOSTICS_CPU_TITLE}, {"cpuUsage", IDS_DIAGNOSTICS_CPU_USAGE_LABEL}, + {"cpuUsageSystem", IDS_DIAGNOSTICS_CPU_USAGE_SYSTEM_LABEL}, + {"cpuUsageUser", IDS_DIAGNOSTICS_CPU_USAGE_USER_LABEL}, {"currentNow", IDS_DIAGNOSTICS_CURRENT_NOW_LABEL}, {"cycleCount", IDS_DIAGNOSTICS_CYCLE_COUNT_LABEL}, {"diagnosticsTitle", IDS_DIAGNOSTICS_TITLE},
diff --git a/chromeos/components/diagnostics_ui/resources/battery_status_card.js b/chromeos/components/diagnostics_ui/resources/battery_status_card.js index a0adeb6f..7f73f4ca 100644 --- a/chromeos/components/diagnostics_ui/resources/battery_status_card.js +++ b/chromeos/components/diagnostics_ui/resources/battery_status_card.js
@@ -6,12 +6,13 @@ import './diagnostics_card.js'; import './diagnostics_shared_css.js'; import './percent_bar_chart.js'; +import './strings.m.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 {BatteryChargeStatus, BatteryHealth, BatteryInfo, SystemDataProviderInterface} from './diagnostics_types.js' import {getSystemDataProvider} from './mojo_interface_provider.js'; -import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; -import './strings.js'; /** * @fileoverview
diff --git a/chromeos/components/diagnostics_ui/resources/cpu_card.js b/chromeos/components/diagnostics_ui/resources/cpu_card.js index aec8b026..5b1ffe6 100644 --- a/chromeos/components/diagnostics_ui/resources/cpu_card.js +++ b/chromeos/components/diagnostics_ui/resources/cpu_card.js
@@ -6,13 +6,14 @@ import './diagnostics_card.js'; import './diagnostics_shared_css.js'; import './realtime_cpu_chart.js'; +import './strings.m.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 {CpuUsage, SystemDataProviderInterface} from './diagnostics_types.js' import {getSystemDataProvider} from './mojo_interface_provider.js'; -import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; -import './strings.js'; + /** * @fileoverview
diff --git a/chromeos/components/diagnostics_ui/resources/diagnostics_app.js b/chromeos/components/diagnostics_ui/resources/diagnostics_app.js index 56b7825..156ad46 100644 --- a/chromeos/components/diagnostics_ui/resources/diagnostics_app.js +++ b/chromeos/components/diagnostics_ui/resources/diagnostics_app.js
@@ -9,10 +9,10 @@ import './diagnostics_shared_css.js'; import './memory_card.js'; import './overview_card.js'; +import './strings.m.js'; -import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; -import './strings.js'; +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {SystemDataProviderInterface, SystemInfo} from './diagnostics_types.js' import {getSystemDataProvider} from './mojo_interface_provider.js';
diff --git a/chromeos/components/diagnostics_ui/resources/fake_data.js b/chromeos/components/diagnostics_ui/resources/fake_data.js index 90c0e8c..2f14de9b 100644 --- a/chromeos/components/diagnostics_ui/resources/fake_data.js +++ b/chromeos/components/diagnostics_ui/resources/fake_data.js
@@ -78,7 +78,27 @@ cpu_temp_degrees_celcius: 109, percent_usage_system: 55, percent_usage_user: 24, - } + }, + { + cpu_temp_degrees_celcius: 109, + percent_usage_system: 49, + percent_usage_user: 10, + }, + { + cpu_temp_degrees_celcius: 161, + percent_usage_system: 1, + percent_usage_user: 99, + }, + { + cpu_temp_degrees_celcius: 118, + percent_usage_system: 35, + percent_usage_user: 37, + }, + { + cpu_temp_degrees_celcius: 110, + percent_usage_system: 26, + percent_usage_user: 30, + }, ]; /* @type {!Array<!MemoryUsage>} */
diff --git a/chromeos/components/diagnostics_ui/resources/memory_card.js b/chromeos/components/diagnostics_ui/resources/memory_card.js index 65fc777..bb0d1ac 100644 --- a/chromeos/components/diagnostics_ui/resources/memory_card.js +++ b/chromeos/components/diagnostics_ui/resources/memory_card.js
@@ -6,12 +6,13 @@ import './diagnostics_card.js'; import './diagnostics_shared_css.js'; import './percent_bar_chart.js'; +import './strings.m.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 {MemoryUsage, SystemDataProviderInterface} from './diagnostics_types.js' import {getSystemDataProvider} from './mojo_interface_provider.js'; -import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; -import './strings.js'; /** * @fileoverview
diff --git a/chromeos/components/diagnostics_ui/resources/realtime_cpu_chart.html b/chromeos/components/diagnostics_ui/resources/realtime_cpu_chart.html index 485651d..efc43bb 100644 --- a/chromeos/components/diagnostics_ui/resources/realtime_cpu_chart.html +++ b/chromeos/components/diagnostics_ui/resources/realtime_cpu_chart.html
@@ -50,13 +50,13 @@ </g> </svg> <div id="chart-legend"> - <!-- TODO(joonbug): Localize strings, including the % --> + <!-- TODO(joonbug): Add i18n string for percent number format --> <div id="legend-user"> - <label>User</label> + <label>[[i18n('cpuUsageUser')]]</label> <span>[[user]]</span> </div> <div id="legend-system"> - <label>System</label> + <label>[[i18n('cpuUsageSystem')]]</label> <span>[[system]]</span> </div> </div>
diff --git a/chromeos/components/diagnostics_ui/resources/realtime_cpu_chart.js b/chromeos/components/diagnostics_ui/resources/realtime_cpu_chart.js index fa749c9d..5a069c0 100644 --- a/chromeos/components/diagnostics_ui/resources/realtime_cpu_chart.js +++ b/chromeos/components/diagnostics_ui/resources/realtime_cpu_chart.js
@@ -2,12 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import './d3.min.js'; import './diagnostics_fonts_css.js'; import './diagnostics_shared_css.js'; - -import './d3.min.js'; +import './strings.m.js'; import {assert} from 'chrome://resources/js/assert.m.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'; /** @@ -20,6 +21,8 @@ _template: html`{__html_template__}`, + behaviors: [I18nBehavior], + /** * Helper function to map range of x coordinates to graph width. * @private {?d3.LinearScale}
diff --git a/chromeos/components/diagnostics_ui/resources/routine_result_entry.html b/chromeos/components/diagnostics_ui/resources/routine_result_entry.html index cb332227..567fcfab 100644 --- a/chromeos/components/diagnostics_ui/resources/routine_result_entry.html +++ b/chromeos/components/diagnostics_ui/resources/routine_result_entry.html
@@ -1,5 +1,13 @@ <style include="diagnostics-shared"> + .entryRow { + display: flex; + flex-direction: row; + justify-content: space-between; + } </style> <div class="entryRow"> + <!-- TODO(zentaro): Create mapping to localized strings. --> + <div id="routine">[[routineName_]]</div> + <div id="status">[[status_]]</div> </div>
diff --git a/chromeos/components/diagnostics_ui/resources/routine_result_entry.js b/chromeos/components/diagnostics_ui/resources/routine_result_entry.js index 2ea61864..659f8aa 100644 --- a/chromeos/components/diagnostics_ui/resources/routine_result_entry.js +++ b/chromeos/components/diagnostics_ui/resources/routine_result_entry.js
@@ -5,7 +5,31 @@ import './diagnostics_card.js'; import './diagnostics_shared_css.js'; +import {assert} from 'chrome://resources/js/assert.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {RoutineName, RoutineResult, StandardRoutineResult} from './diagnostics_types.js'; +import {ExecutionProgress, ResultStatusItem} from './routine_list_executor.js'; + +/** + * Resolves an enum value to the string name. This is used temporarily to + * provide a human readable string until the final mapping of enum values to + * localized strings is finalized. + * TODO(zentaro): Remove this function when strings are finalized. + * @param {!Object} enumType + * @param {number} enumValue + * @return {string} + */ +function lookupEnumValueName(enumType, enumValue) { + for (const [key, value] of Object.entries(enumType)) { + if (value === enumValue) { + return key; + } + } + + // Values should always be found in the enum. + assert(false); + return ''; +} /** * @fileoverview @@ -16,7 +40,56 @@ _template: html`{__html_template__}`, - properties: {}, + properties: { + /** @type {!ResultStatusItem} */ + item: { + type: Object, + }, + + /** @private */ + routineName_: { + type: String, + computed: 'getRoutineName_(item.routine)', + }, + + /** @private */ + status_: { + type: String, + computed: 'getRoutineStatus_(item.progress, item.result)', + }, + }, + + /** + * Get the string name for the routine. + * TODO(zentaro): Replace with a mapping to localized string when they are + * finalized. + * @param {!RoutineName} routine + * @return {string} + */ + getRoutineName_(routine) { + return lookupEnumValueName(RoutineName, routine); + }, + + /** + * Get the status for the routine. This is a combination of progress and + * result. + * TODO(zentaro): Replace with a mapping to localized string when they are + * finalized. + * @param {!ExecutionProgress} progress + * @param {!RoutineResult} result + * @return {string} + */ + getRoutineStatus_(progress, result) { + if (progress === ExecutionProgress.kNotStarted) { + return ''; + } + + if (progress === ExecutionProgress.kRunning) { + return lookupEnumValueName(ExecutionProgress, ExecutionProgress.kRunning); + } + + return lookupEnumValueName(StandardRoutineResult, result.simple_result); + }, /** @override */ created() {},
diff --git a/chromeos/profiles/orderfile.newest.txt b/chromeos/profiles/orderfile.newest.txt index 9069250c..c7a1d6ef1 100644 --- a/chromeos/profiles/orderfile.newest.txt +++ b/chromeos/profiles/orderfile.newest.txt
@@ -1 +1 @@ -chromeos-chrome-orderfile-field-87-4277.0-1602498224-benchmark-87.0.4280.20-r1.orderfile.xz +chromeos-chrome-orderfile-field-88-4277.0-1602497703-benchmark-88.0.4288.0-r1.orderfile.xz
diff --git a/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom b/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom index 2b0e51a..310188119 100644 --- a/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom +++ b/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom
@@ -304,6 +304,12 @@ uint32 scaling_max_frequency_khz; // Current frequency the CPU is running at. uint32 scaling_current_frequency_khz; + // Time spent in user mode since last boot. USER_HZ can be converted to + // seconds with the conversion factor given by sysconf(_SC_CLK_TCK). + uint64 user_time_user_hz; + // Time spent in system mode since last boot. USER_HZ can be converted to + // seconds with the conversion factor given by sysconf(_SC_CLK_TCK). + uint64 system_time_user_hz; // Idle time since last boot. USER_HZ can be converted to seconds with the // conversion factor given by sysconf(_SC_CLK_TCK). uint32 idle_time_user_hz;
diff --git a/chromeos/services/multidevice_setup/wifi_sync_feature_manager_impl.cc b/chromeos/services/multidevice_setup/wifi_sync_feature_manager_impl.cc index 2702b81..b7126f74 100644 --- a/chromeos/services/multidevice_setup/wifi_sync_feature_manager_impl.cc +++ b/chromeos/services/multidevice_setup/wifi_sync_feature_manager_impl.cc
@@ -15,6 +15,7 @@ #include "chromeos/constants/chromeos_features.h" #include "chromeos/services/device_sync/feature_status_change.h" #include "chromeos/services/multidevice_setup/host_status_provider.h" +#include "chromeos/services/multidevice_setup/public/cpp/prefs.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" @@ -96,11 +97,8 @@ !ShouldEnableOnVerify()) { ResetPendingWifiSyncHostNetworkRequest(); } - // kHostSetLocallyButWaitingForBackendConfirmation is only possible if the - // setup flow has been completed on the local device. - if (host_status_with_device.host_status() == - mojom::HostStatus::kHostSetLocallyButWaitingForBackendConfirmation && - features::IsWifiSyncAndroidEnabled()) { + + if (ShouldAttemptToEnableAfterHostVerified()) { SetPendingWifiSyncHostNetworkRequest( PendingState::kSetPendingEnableOnVerify); return; @@ -317,6 +315,33 @@ SetIsWifiSyncEnabled(true); } +bool WifiSyncFeatureManagerImpl::ShouldAttemptToEnableAfterHostVerified() { + HostStatusProvider::HostStatusWithDevice host_status_with_device = + host_status_provider_->GetHostWithStatus(); + + // kHostSetLocallyButWaitingForBackendConfirmation is only possible if the + // setup flow has been completed on the local device. + if (host_status_with_device.host_status() != + mojom::HostStatus::kHostSetLocallyButWaitingForBackendConfirmation) { + return false; + } + + // Check if enterprise policy prohibits Wifi Sync or if feature flag is + // disabled. + if (!IsFeatureAllowed(mojom::Feature::kWifiSync, pref_service_)) { + return false; + } + + // Check if wifi sync is supported by host device. + if (host_status_with_device.host_device()->GetSoftwareFeatureState( + multidevice::SoftwareFeature::kWifiSyncHost) == + multidevice::SoftwareFeatureState::kNotSupported) { + return false; + } + + return true; +} + } // namespace multidevice_setup } // namespace chromeos
diff --git a/chromeos/services/multidevice_setup/wifi_sync_feature_manager_impl.h b/chromeos/services/multidevice_setup/wifi_sync_feature_manager_impl.h index 7acfaa5..d5c747b 100644 --- a/chromeos/services/multidevice_setup/wifi_sync_feature_manager_impl.h +++ b/chromeos/services/multidevice_setup/wifi_sync_feature_manager_impl.h
@@ -123,6 +123,7 @@ device_sync::mojom::NetworkRequestResult result_code); bool ShouldEnableOnVerify(); void ProcessEnableOnVerifyAttempt(); + bool ShouldAttemptToEnableAfterHostVerified(); HostStatusProvider* host_status_provider_; PrefService* pref_service_;
diff --git a/chromeos/services/multidevice_setup/wifi_sync_feature_manager_impl_unittest.cc b/chromeos/services/multidevice_setup/wifi_sync_feature_manager_impl_unittest.cc index 5d5378e..95a20d1b 100644 --- a/chromeos/services/multidevice_setup/wifi_sync_feature_manager_impl_unittest.cc +++ b/chromeos/services/multidevice_setup/wifi_sync_feature_manager_impl_unittest.cc
@@ -18,6 +18,7 @@ #include "chromeos/constants/chromeos_features.h" #include "chromeos/services/device_sync/public/cpp/fake_device_sync_client.h" #include "chromeos/services/multidevice_setup/fake_host_status_provider.h" +#include "chromeos/services/multidevice_setup/public/cpp/prefs.h" #include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "testing/gtest/include/gtest/gtest.h" @@ -70,7 +71,9 @@ test_pref_service_ = std::make_unique<sync_preferences::TestingPrefServiceSyncable>(); WifiSyncFeatureManagerImpl::RegisterPrefs(test_pref_service_->registry()); - + // Allow Wifi Sync by policy + test_pref_service_->registry()->RegisterBooleanPref( + kWifiSyncAllowedPrefName, true); fake_device_sync_client_ = std::make_unique<device_sync::FakeDeviceSyncClient>(); fake_device_sync_client_->set_synced_devices(test_devices_); @@ -794,6 +797,47 @@ } TEST_P(MultiDeviceSetupWifiSyncFeatureManagerImplTest, + SetPendingEnableOnVerify_WifiSyncNotAllowedByPolicy) { + SetFeatureFlags(GetParam() /* use_v1_devicesync */, + true /* enable_wifi_sync */); + // Disable by policy + test_pref_service()->SetBoolean(kWifiSyncAllowedPrefName, false); + CreateDelegate(base::nullopt /* initial_host */); + + // kHostSetLocallyButWaitingForBackendConfirmation is only possible if the + // setup flow has been completed on the local device. + SetHostInDeviceSyncClient(test_devices()[0]); + fake_host_status_provider()->SetHostWithStatus( + mojom::HostStatus::kHostSetLocallyButWaitingForBackendConfirmation, + test_devices()[0]); + EXPECT_EQ( + test_pref_service()->GetInteger(kPendingWifiSyncRequestEnabledPrefName), + kPendingNone); + EXPECT_FALSE(delegate()->IsWifiSyncEnabled()); +} + +TEST_P(MultiDeviceSetupWifiSyncFeatureManagerImplTest, + SetPendingEnableOnVerify_WifiSyncNotSupportedOnHostDevice) { + SetFeatureFlags(GetParam() /* use_v1_devicesync */, + true /* enable_wifi_sync */); + CreateDelegate(base::nullopt /* initial_host */); + GetMutableRemoteDevice(test_devices()[0]) + ->software_features[multidevice::SoftwareFeature::kWifiSyncHost] = + multidevice::SoftwareFeatureState::kNotSupported; + + // kHostSetLocallyButWaitingForBackendConfirmation is only possible if the + // setup flow has been completed on the local device. + SetHostInDeviceSyncClient(test_devices()[0]); + fake_host_status_provider()->SetHostWithStatus( + mojom::HostStatus::kHostSetLocallyButWaitingForBackendConfirmation, + test_devices()[0]); + EXPECT_EQ( + test_pref_service()->GetInteger(kPendingWifiSyncRequestEnabledPrefName), + kPendingNone); + EXPECT_FALSE(delegate()->IsWifiSyncEnabled()); +} + +TEST_P(MultiDeviceSetupWifiSyncFeatureManagerImplTest, SetPendingEnableOnVerify_HostRemoved) { SetFeatureFlags(GetParam() /* use_v1_devicesync */, true /* enable_wifi_sync */);
diff --git a/chromeos/ui/base/window_properties.cc b/chromeos/ui/base/window_properties.cc index 57b76565..3e74f3c 100644 --- a/chromeos/ui/base/window_properties.cc +++ b/chromeos/ui/base/window_properties.cc
@@ -5,13 +5,27 @@ #include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/base/window_state_type.h" +// TODO(crbug.com/1138662): Remove this include and the associated property +// and histogram entry. +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" // nogncheck #include "ui/aura/window.h" namespace chromeos { +DEFINE_UI_CLASS_PROPERTY_KEY(bool, kImmersiveImpliedByFullscreen, true) +DEFINE_UI_CLASS_PROPERTY_KEY(bool, kImmersiveIsActive, false) +DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(gfx::Rect, + kImmersiveTopContainerBoundsInScreen, + nullptr) +DEFINE_UI_CLASS_PROPERTY_KEY( + int, + kImmersiveWindowType, + ImmersiveFullscreenController::WindowType::WINDOW_TYPE_OTHER) + DEFINE_UI_CLASS_PROPERTY_KEY(bool, kIsShowingInOverviewKey, false) DEFINE_UI_CLASS_PROPERTY_KEY(WindowStateType, kWindowStateTypeKey, WindowStateType::kDefault) + } // namespace chromeos
diff --git a/chromeos/ui/base/window_properties.h b/chromeos/ui/base/window_properties.h index aab2a63..d39a78c 100644 --- a/chromeos/ui/base/window_properties.h +++ b/chromeos/ui/base/window_properties.h
@@ -13,6 +13,10 @@ using WindowProperty = ui::ClassProperty<T>; } // namespace aura +namespace gfx { +class Rect; +} + namespace chromeos { enum class WindowStateType; @@ -21,6 +25,26 @@ // Alphabetical sort. +// Whether entering fullscreen means that a window should automatically enter +// immersive mode. This is false for some client windows, such as Chrome Apps. +COMPONENT_EXPORT(CHROMEOS_UI_BASE) +extern const aura::WindowProperty<bool>* const kImmersiveImpliedByFullscreen; + +// Whether immersive is currently active (in ImmersiveFullscreenController +// parlance, "enabled"). +COMPONENT_EXPORT(CHROMEOS_UI_BASE) +extern const aura::WindowProperty<bool>* const kImmersiveIsActive; + +// The bounds of the top container in screen coordinates. +COMPONENT_EXPORT(CHROMEOS_UI_BASE) +extern const aura::WindowProperty<gfx::Rect*>* const + kImmersiveTopContainerBoundsInScreen; + +// The type of window for logging immersive metrics. Type: +// ImmersiveFullscreenController::WindowType. +COMPONENT_EXPORT(CHROMEOS_UI_BASE) +extern const aura::WindowProperty<int>* const kImmersiveWindowType; + // If true, the window is currently showing in overview mode. COMPONENT_EXPORT(CHROMEOS_UI_BASE) extern const aura::WindowProperty<bool>* const kIsShowingInOverviewKey;
diff --git a/chromeos/ui/frame/BUILD.gn b/chromeos/ui/frame/BUILD.gn index 88a9f08..fcb0c91 100644 --- a/chromeos/ui/frame/BUILD.gn +++ b/chromeos/ui/frame/BUILD.gn
@@ -20,6 +20,15 @@ "caption_buttons/frame_size_button_delegate.h", "caption_buttons/snap_controller.cc", "caption_buttons/snap_controller.h", + "immersive/immersive_context.cc", + "immersive/immersive_context.h", + "immersive/immersive_focus_watcher.cc", + "immersive/immersive_focus_watcher.h", + "immersive/immersive_fullscreen_controller.cc", + "immersive/immersive_fullscreen_controller.h", + "immersive/immersive_fullscreen_controller_delegate.h", + "immersive/immersive_revealed_lock.cc", + "immersive/immersive_revealed_lock.h", ] deps = [ @@ -31,5 +40,26 @@ "//ui/base", "//ui/strings:ui_strings_grit", "//ui/views", + "//ui/wm/public", + ] +} + +source_set("test_support") { + testonly = true + sources = [ + "immersive/immersive_fullscreen_controller_test_api.cc", + "immersive/immersive_fullscreen_controller_test_api.h", + ] + + deps = [ + ":frame", + "//base", + "//services/device/public/cpp:test_support", + "//services/network/public/cpp:cpp", + "//ui/aura", + "//ui/aura:test_support", + "//ui/gfx", + "//ui/gfx:test_support", + "//ui/views", ] }
diff --git a/chromeos/ui/frame/DEPS b/chromeos/ui/frame/DEPS index b2b9550..cb567ae 100644 --- a/chromeos/ui/frame/DEPS +++ b/chromeos/ui/frame/DEPS
@@ -2,9 +2,11 @@ "+ui/aura", "+ui/base", "+ui/compositor/scoped_animation_duration_scale_mode.h", - "+ui/events/event_sink.h", + "+ui/display", + "+ui/events", "+ui/gfx", "+ui/strings/grit/ui_strings.h", "+ui/views", + "+ui/wm/public", "+third_party/skia", ]
diff --git a/ash/public/cpp/immersive/immersive_context.cc b/chromeos/ui/frame/immersive/immersive_context.cc similarity index 83% rename from ash/public/cpp/immersive/immersive_context.cc rename to chromeos/ui/frame/immersive/immersive_context.cc index 7ab1e54..b914243 100644 --- a/ash/public/cpp/immersive/immersive_context.cc +++ b/chromeos/ui/frame/immersive/immersive_context.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/public/cpp/immersive/immersive_context.h" +#include "chromeos/ui/frame/immersive/immersive_context.h" #include "base/check_op.h" -namespace ash { +namespace chromeos { namespace { @@ -29,4 +29,4 @@ g_instance = this; } -} // namespace ash +} // namespace chromeos
diff --git a/ash/public/cpp/immersive/immersive_context.h b/chromeos/ui/frame/immersive/immersive_context.h similarity index 77% rename from ash/public/cpp/immersive/immersive_context.h rename to chromeos/ui/frame/immersive/immersive_context.h index 1240bd7..47aa7f8 100644 --- a/ash/public/cpp/immersive/immersive_context.h +++ b/chromeos/ui/frame/immersive/immersive_context.h
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ASH_PUBLIC_CPP_IMMERSIVE_IMMERSIVE_CONTEXT_H_ -#define ASH_PUBLIC_CPP_IMMERSIVE_IMMERSIVE_CONTEXT_H_ +#ifndef CHROMEOS_UI_FRAME_IMMERSIVE_IMMERSIVE_CONTEXT_H_ +#define CHROMEOS_UI_FRAME_IMMERSIVE_IMMERSIVE_CONTEXT_H_ -#include "ash/public/cpp/ash_public_export.h" +#include "base/component_export.h" namespace gfx { class Rect; @@ -15,13 +15,13 @@ class Widget; } -namespace ash { +namespace chromeos { class ImmersiveFullscreenController; // ImmersiveContext abstracts away all the windowing related calls so that // ImmersiveFullscreenController does not depend upon aura or ash. -class ASH_PUBLIC_EXPORT ImmersiveContext { +class COMPONENT_EXPORT(CHROMEOS_UI_FRAME) ImmersiveContext { public: virtual ~ImmersiveContext(); @@ -45,6 +45,6 @@ ImmersiveContext(); }; -} // namespace ash +} // namespace chromeos -#endif // ASH_PUBLIC_CPP_IMMERSIVE_IMMERSIVE_CONTEXT_H_ +#endif // CHROMEOS_UI_FRAME_IMMERSIVE_IMMERSIVE_CONTEXT_H_
diff --git a/ash/public/cpp/immersive/immersive_focus_watcher.cc b/chromeos/ui/frame/immersive/immersive_focus_watcher.cc similarity index 97% rename from ash/public/cpp/immersive/immersive_focus_watcher.cc rename to chromeos/ui/frame/immersive/immersive_focus_watcher.cc index 3817d3f0..400518b 100644 --- a/ash/public/cpp/immersive/immersive_focus_watcher.cc +++ b/chromeos/ui/frame/immersive/immersive_focus_watcher.cc
@@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/public/cpp/immersive/immersive_focus_watcher.h" +#include "chromeos/ui/frame/immersive/immersive_focus_watcher.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" #include "ui/aura/client/transient_window_client.h" #include "ui/aura/window.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" @@ -12,7 +12,7 @@ #include "ui/views/widget/widget.h" #include "ui/wm/public/activation_client.h" -namespace ash { +namespace chromeos { namespace { @@ -276,7 +276,7 @@ immersive_fullscreen_controller_->top_container()->Contains(anchor)) { // Observe the aura::Window because the BubbleDelegateView may not be // parented to the widget's root view yet so |bubble_delegate->GetWidget()| - // may still return NULL. + // may still return null. bubble_observer_->StartObserving(transient); } } @@ -287,4 +287,4 @@ bubble_observer_->StopObserving(transient); } -} // namespace ash +} // namespace chromeos
diff --git a/ash/public/cpp/immersive/immersive_focus_watcher.h b/chromeos/ui/frame/immersive/immersive_focus_watcher.h similarity index 92% rename from ash/public/cpp/immersive/immersive_focus_watcher.h rename to chromeos/ui/frame/immersive/immersive_focus_watcher.h index 7799b06f..c4b0f11 100644 --- a/ash/public/cpp/immersive/immersive_focus_watcher.h +++ b/chromeos/ui/frame/immersive/immersive_focus_watcher.h
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ASH_PUBLIC_CPP_IMMERSIVE_IMMERSIVE_FOCUS_WATCHER_H_ -#define ASH_PUBLIC_CPP_IMMERSIVE_IMMERSIVE_FOCUS_WATCHER_H_ +#ifndef CHROMEOS_UI_FRAME_IMMERSIVE_IMMERSIVE_FOCUS_WATCHER_H_ +#define CHROMEOS_UI_FRAME_IMMERSIVE_IMMERSIVE_FOCUS_WATCHER_H_ #include "ui/aura/client/focus_change_observer.h" #include "ui/aura/client/transient_window_client_observer.h" #include "ui/views/focus/focus_manager.h" #include "ui/wm/public/activation_change_observer.h" -namespace ash { +namespace chromeos { class ImmersiveFullscreenController; class ImmersiveRevealedLock; @@ -76,6 +76,6 @@ DISALLOW_COPY_AND_ASSIGN(ImmersiveFocusWatcher); }; -} // namespace ash +} // namespace chromeos -#endif // ASH_PUBLIC_CPP_IMMERSIVE_IMMERSIVE_FOCUS_WATCHER_H_ +#endif // CHROMEOS_UI_FRAME_IMMERSIVE_IMMERSIVE_FOCUS_WATCHER_H_
diff --git a/ash/public/cpp/immersive/immersive_fullscreen_controller.cc b/chromeos/ui/frame/immersive/immersive_fullscreen_controller.cc similarity index 97% rename from ash/public/cpp/immersive/immersive_fullscreen_controller.cc rename to chromeos/ui/frame/immersive/immersive_fullscreen_controller.cc index c9cf255..f28077b9 100644 --- a/ash/public/cpp/immersive/immersive_fullscreen_controller.cc +++ b/chromeos/ui/frame/immersive/immersive_fullscreen_controller.cc
@@ -2,16 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" #include <set> -#include "ash/public/cpp/immersive/immersive_context.h" -#include "ash/public/cpp/immersive/immersive_focus_watcher.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller_delegate.h" -#include "ash/public/cpp/window_properties.h" #include "base/bind.h" #include "base/metrics/histogram_macros.h" +#include "chromeos/ui/base/window_properties.h" +#include "chromeos/ui/frame/immersive/immersive_context.h" +#include "chromeos/ui/frame/immersive/immersive_focus_watcher.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_delegate.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/client/cursor_client.h" #include "ui/aura/env.h" @@ -28,9 +28,9 @@ #include "ui/views/view.h" #include "ui/views/widget/widget.h" -DEFINE_UI_CLASS_PROPERTY_TYPE(ash::ImmersiveFullscreenController*) +DEFINE_UI_CLASS_PROPERTY_TYPE(chromeos::ImmersiveFullscreenController*) -namespace ash { +namespace chromeos { DEFINE_UI_CLASS_PROPERTY_KEY(ImmersiveFullscreenController*, kImmersiveFullscreenControllerKey, @@ -463,8 +463,8 @@ for (size_t i = 0; i < hit_bounds_in_screen.size(); ++i) { // Allow the cursor to move slightly off the top-of-window views before // sliding closed. In the case of ImmersiveModeControllerAsh, this helps - // when the user is attempting to click on the bookmark bar and overshoots - // slightly. + // when the user is attempting to click on the bookmark bar and + // overshoots slightly. if (event && event->type() == ui::ET_MOUSE_MOVED) { const int kBoundsOffsetY = 8; hit_bounds_in_screen[i].Inset(0, 0, 0, -kBoundsOffsetY); @@ -768,6 +768,7 @@ } if (enabled_) { + // TODO(https://crbug.com/1138662): Remove this expired histogram entry. UMA_HISTOGRAM_ENUMERATION( "Ash.ImmersiveFullscreen.WindowType", static_cast<WindowType>( @@ -784,4 +785,4 @@ {}, gfx::Insets(enable ? kImmersiveFullscreenTopEdgeInset : 0, 0, 0, 0)); } -} // namespace ash +} // namespace chromeos
diff --git a/ash/public/cpp/immersive/immersive_fullscreen_controller.h b/chromeos/ui/frame/immersive/immersive_fullscreen_controller.h similarity index 93% rename from ash/public/cpp/immersive/immersive_fullscreen_controller.h rename to chromeos/ui/frame/immersive/immersive_fullscreen_controller.h index 9bf77ea..ba83ea8 100644 --- a/ash/public/cpp/immersive/immersive_fullscreen_controller.h +++ b/chromeos/ui/frame/immersive/immersive_fullscreen_controller.h
@@ -2,16 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ASH_PUBLIC_CPP_IMMERSIVE_IMMERSIVE_FULLSCREEN_CONTROLLER_H_ -#define ASH_PUBLIC_CPP_IMMERSIVE_IMMERSIVE_FULLSCREEN_CONTROLLER_H_ +#ifndef CHROMEOS_UI_FRAME_IMMERSIVE_IMMERSIVE_FULLSCREEN_CONTROLLER_H_ +#define CHROMEOS_UI_FRAME_IMMERSIVE_IMMERSIVE_FULLSCREEN_CONTROLLER_H_ #include <memory> #include <vector> -#include "ash/public/cpp/ash_public_export.h" -#include "ash/public/cpp/immersive/immersive_revealed_lock.h" +#include "base/component_export.h" #include "base/macros.h" #include "base/timer/timer.h" +#include "chromeos/ui/frame/immersive/immersive_revealed_lock.h" #include "ui/aura/window_observer.h" #include "ui/events/event_handler.h" #include "ui/events/event_observer.h" @@ -22,7 +22,11 @@ namespace aura { class WindowTargeter; -} +} // namespace aura + +namespace ash { +class ImmersiveFullscreenControllerTest; +} // namespace ash namespace gfx { class Point; @@ -40,13 +44,15 @@ class Widget; } // namespace views -namespace ash { +namespace chromeos { class ImmersiveFocusWatcher; class ImmersiveFullscreenControllerDelegate; class ImmersiveFullscreenControllerTestApi; -class ASH_PUBLIC_EXPORT ImmersiveFullscreenController +// This class is tested as part of //ash, eg ImmersiveFullscreenControllerTest, +// which inherits from AshTestBase. +class COMPONENT_EXPORT(CHROMEOS_UI_FRAME) ImmersiveFullscreenController : public aura::WindowObserver, public gfx::AnimationDelegate, public ui::EventObserver, @@ -130,7 +136,7 @@ void AnimationEnded(const gfx::Animation* animation) override; void AnimationProgressed(const gfx::Animation* animation) override; - // ash::ImmersiveRevealedLock::Delegate overrides: + // chromeos::ImmersiveRevealedLock::Delegate overrides: void LockRevealedState(AnimateReveal animate_reveal) override; void UnlockRevealedState() override; @@ -139,7 +145,7 @@ static ImmersiveFullscreenController* Get(views::Widget* widget); private: - friend class ImmersiveFullscreenControllerTest; + friend class ash::ImmersiveFullscreenControllerTest; friend class ImmersiveFullscreenControllerTestApi; enum Animate { @@ -179,7 +185,7 @@ // Updates |located_event_revealed_lock_| based on the current mouse state and // the current touch state. - // |event| is NULL if the source event is not known. + // |event| is null if the source event is not known. void UpdateLocatedEventRevealedLock(const ui::LocatedEvent* event, const gfx::Point& location_in_screen); @@ -309,6 +315,6 @@ DISALLOW_COPY_AND_ASSIGN(ImmersiveFullscreenController); }; -} // namespace ash +} // namespace chromeos -#endif // ASH_PUBLIC_CPP_IMMERSIVE_IMMERSIVE_FULLSCREEN_CONTROLLER_H_ +#endif // CHROMEOS_UI_FRAME_IMMERSIVE_IMMERSIVE_FULLSCREEN_CONTROLLER_H_
diff --git a/ash/public/cpp/immersive/immersive_fullscreen_controller_delegate.h b/chromeos/ui/frame/immersive/immersive_fullscreen_controller_delegate.h similarity index 79% rename from ash/public/cpp/immersive/immersive_fullscreen_controller_delegate.h rename to chromeos/ui/frame/immersive/immersive_fullscreen_controller_delegate.h index f2e5b7a..2a2b2de 100644 --- a/ash/public/cpp/immersive/immersive_fullscreen_controller_delegate.h +++ b/chromeos/ui/frame/immersive/immersive_fullscreen_controller_delegate.h
@@ -2,20 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ASH_PUBLIC_CPP_IMMERSIVE_IMMERSIVE_FULLSCREEN_CONTROLLER_DELEGATE_H_ -#define ASH_PUBLIC_CPP_IMMERSIVE_IMMERSIVE_FULLSCREEN_CONTROLLER_DELEGATE_H_ +#ifndef CHROMEOS_UI_FRAME_IMMERSIVE_IMMERSIVE_FULLSCREEN_CONTROLLER_DELEGATE_H_ +#define CHROMEOS_UI_FRAME_IMMERSIVE_IMMERSIVE_FULLSCREEN_CONTROLLER_DELEGATE_H_ #include <vector> -#include "ash/public/cpp/ash_public_export.h" +#include "base/component_export.h" namespace gfx { class Rect; } -namespace ash { +namespace chromeos { -class ASH_PUBLIC_EXPORT ImmersiveFullscreenControllerDelegate { +class COMPONENT_EXPORT(CHROMEOS_UI_FRAME) + ImmersiveFullscreenControllerDelegate { public: // Called when a reveal of the top-of-window views starts. virtual void OnImmersiveRevealStarted() = 0; @@ -49,6 +50,6 @@ virtual ~ImmersiveFullscreenControllerDelegate() {} }; -} // namespace ash +} // namespace chromeos -#endif // ASH_PUBLIC_CPP_IMMERSIVE_IMMERSIVE_FULLSCREEN_CONTROLLER_DELEGATE_H_ +#endif // CHROMEOS_UI_FRAME_IMMERSIVE_IMMERSIVE_FULLSCREEN_CONTROLLER_DELEGATE_H_
diff --git a/ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.cc b/chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.cc similarity index 87% rename from ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.cc rename to chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.cc index 9f1d2081a..c52d866 100644 --- a/ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.cc +++ b/chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.cc
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller_delegate.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_delegate.h" #include "ui/aura/env.h" #include "ui/gfx/geometry/rect.h" -namespace ash { +namespace chromeos { ImmersiveFullscreenControllerTestApi::ImmersiveFullscreenControllerTestApi( ImmersiveFullscreenController* controller) @@ -54,4 +54,4 @@ false; } -} // namespace ash +} // namespace chromeos
diff --git a/ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h b/chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h similarity index 69% rename from ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h rename to chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h index d8fb97e..18fa4ba 100644 --- a/ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h +++ b/chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h
@@ -2,17 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ASH_PUBLIC_CPP_IMMERSIVE_IMMERSIVE_FULLSCREEN_CONTROLLER_TEST_API_H_ -#define ASH_PUBLIC_CPP_IMMERSIVE_IMMERSIVE_FULLSCREEN_CONTROLLER_TEST_API_H_ +#ifndef CHROMEOS_UI_FRAME_IMMERSIVE_IMMERSIVE_FULLSCREEN_CONTROLLER_TEST_API_H_ +#define CHROMEOS_UI_FRAME_IMMERSIVE_IMMERSIVE_FULLSCREEN_CONTROLLER_TEST_API_H_ +#include "base/component_export.h" #include "base/macros.h" -namespace ash { +namespace chromeos { class ImmersiveFullscreenController; // Use by tests to access private state of ImmersiveFullscreenController. -class ImmersiveFullscreenControllerTestApi { +class COMPONENT_EXPORT(CHROMEOS_UI_FRAME) ImmersiveFullscreenControllerTestApi { public: explicit ImmersiveFullscreenControllerTestApi( ImmersiveFullscreenController* controller); @@ -20,7 +21,7 @@ // Disables animations for any ImmersiveFullscreenControllers created while // GlobalAnimationDisabler exists. - class GlobalAnimationDisabler { + class COMPONENT_EXPORT(CHROMEOS_UI_FRAME) GlobalAnimationDisabler { public: GlobalAnimationDisabler(); ~GlobalAnimationDisabler(); @@ -41,6 +42,6 @@ DISALLOW_COPY_AND_ASSIGN(ImmersiveFullscreenControllerTestApi); }; -} // namespace ash +} // namespace chromeos -#endif // ASH_PUBLIC_CPP_IMMERSIVE_IMMERSIVE_FULLSCREEN_CONTROLLER_TEST_API_H_ +#endif // CHROMEOS_UI_FRAME_IMMERSIVE_IMMERSIVE_FULLSCREEN_CONTROLLER_TEST_API_H_
diff --git a/ash/public/cpp/immersive/immersive_revealed_lock.cc b/chromeos/ui/frame/immersive/immersive_revealed_lock.cc similarity index 81% rename from ash/public/cpp/immersive/immersive_revealed_lock.cc rename to chromeos/ui/frame/immersive/immersive_revealed_lock.cc index 25e7aaa..057af36a 100644 --- a/ash/public/cpp/immersive/immersive_revealed_lock.cc +++ b/chromeos/ui/frame/immersive/immersive_revealed_lock.cc
@@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/public/cpp/immersive/immersive_revealed_lock.h" +#include "chromeos/ui/frame/immersive/immersive_revealed_lock.h" -namespace ash { +namespace chromeos { ImmersiveRevealedLock::ImmersiveRevealedLock( const base::WeakPtr<Delegate>& delegate, @@ -18,4 +18,4 @@ delegate_->UnlockRevealedState(); } -} // namespace ash +} // namespace chromeos
diff --git a/ash/public/cpp/immersive/immersive_revealed_lock.h b/chromeos/ui/frame/immersive/immersive_revealed_lock.h similarity index 72% rename from ash/public/cpp/immersive/immersive_revealed_lock.h rename to chromeos/ui/frame/immersive/immersive_revealed_lock.h index 1a5622d..9c008731a 100644 --- a/ash/public/cpp/immersive/immersive_revealed_lock.h +++ b/chromeos/ui/frame/immersive/immersive_revealed_lock.h
@@ -2,23 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ASH_PUBLIC_CPP_IMMERSIVE_IMMERSIVE_REVEALED_LOCK_H_ -#define ASH_PUBLIC_CPP_IMMERSIVE_IMMERSIVE_REVEALED_LOCK_H_ +#ifndef CHROMEOS_UI_FRAME_IMMERSIVE_IMMERSIVE_REVEALED_LOCK_H_ +#define CHROMEOS_UI_FRAME_IMMERSIVE_IMMERSIVE_REVEALED_LOCK_H_ -#include "ash/public/cpp/ash_public_export.h" +#include "base/component_export.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -namespace ash { +namespace chromeos { // Class which keeps the top-of-window views revealed for the duration of its // lifetime. If acquiring the lock causes a reveal, the top-of-window views // will animate according to the |animate_reveal| parameter passed in the // constructor. See ImmersiveFullscreenController::GetRevealedLock() for more // details. -class ASH_PUBLIC_EXPORT ImmersiveRevealedLock { +class COMPONENT_EXPORT(CHROMEOS_UI_FRAME) ImmersiveRevealedLock { public: - class ASH_PUBLIC_EXPORT Delegate { + class COMPONENT_EXPORT(CHROMEOS_UI_FRAME) Delegate { public: enum AnimateReveal { ANIMATE_REVEAL_YES, ANIMATE_REVEAL_NO }; @@ -39,6 +39,6 @@ DISALLOW_COPY_AND_ASSIGN(ImmersiveRevealedLock); }; -} // namespace ash +} // namespace chromeos -#endif // ASH_PUBLIC_CPP_IMMERSIVE_IMMERSIVE_REVEALED_LOCK_H_ +#endif // CHROMEOS_UI_FRAME_IMMERSIVE_IMMERSIVE_REVEALED_LOCK_H_
diff --git a/components/autofill/core/browser/payments/autofill_wallet_model_type_controller.cc b/components/autofill/core/browser/payments/autofill_wallet_model_type_controller.cc index 11885fc..b330910 100644 --- a/components/autofill/core/browser/payments/autofill_wallet_model_type_controller.cc +++ b/components/autofill/core/browser/payments/autofill_wallet_model_type_controller.cc
@@ -14,14 +14,11 @@ #include "components/autofill/core/common/autofill_prefs.h" #include "components/prefs/pref_service.h" #include "components/sync/driver/sync_auth_util.h" +#include "components/sync/driver/sync_driver_switches.h" #include "components/sync/driver/sync_service.h" #include "components/sync/driver/sync_user_settings.h" #include "google_apis/gaia/google_service_auth_error.h" -namespace { - -} // namespace - namespace browser_sync { AutofillWalletModelTypeController::AutofillWalletModelTypeController( @@ -111,6 +108,22 @@ : PreconditionState::kMustStopAndClearData; } +bool AutofillWalletModelTypeController::ShouldRunInTransportOnlyMode() const { + if (type() != syncer::AUTOFILL_WALLET_DATA) { + return false; + } + if (!base::FeatureList::IsEnabled( + autofill::features::kAutofillEnableAccountWalletStorage)) { + return false; + } + if (sync_service_->GetUserSettings()->IsUsingSecondaryPassphrase() && + !base::FeatureList::IsEnabled( + switches::kSyncAllowWalletDataInTransportModeWithCustomPassphrase)) { + return false; + } + return true; +} + void AutofillWalletModelTypeController::OnUserPrefChanged() { DCHECK(CalledOnValidThread()); sync_service_->DataTypePreconditionChanged(type());
diff --git a/components/autofill/core/browser/payments/autofill_wallet_model_type_controller.h b/components/autofill/core/browser/payments/autofill_wallet_model_type_controller.h index 03d0312c..8a016e0 100644 --- a/components/autofill/core/browser/payments/autofill_wallet_model_type_controller.h +++ b/components/autofill/core/browser/payments/autofill_wallet_model_type_controller.h
@@ -47,6 +47,7 @@ void Stop(syncer::ShutdownReason shutdown_reason, StopCallback callback) override; PreconditionState GetPreconditionState() const override; + bool ShouldRunInTransportOnlyMode() const override; // syncer::SyncServiceObserver implementation. void OnStateChanged(syncer::SyncService* sync) override;
diff --git a/components/autofill_assistant/browser/BUILD.gn b/components/autofill_assistant/browser/BUILD.gn index cf7a038c..76d0ea5 100644 --- a/components/autofill_assistant/browser/BUILD.gn +++ b/components/autofill_assistant/browser/BUILD.gn
@@ -166,6 +166,10 @@ "service/service.h", "service/service_impl.cc", "service/service_impl.h", + "service/service_request_sender.cc", + "service/service_request_sender.h", + "service/simple_url_loader_factory.cc", + "service/simple_url_loader_factory.h", "state.h", "string_conversions_util.cc", "string_conversions_util.h", @@ -302,6 +306,8 @@ "event_handler_unittest.cc", "field_formatter_unittest.cc", "generic_ui_replace_placeholders_unittest.cc", + "mock_client_context.cc", + "mock_client_context.h", "protocol_utils_unittest.cc", "radio_button_controller_unittest.cc", "retry_timer_unittest.cc", @@ -312,7 +318,17 @@ "service/api_key_fetcher_unittest.cc", "service/lite_service_unittest.cc", "service/lite_service_util_unittest.cc", + "service/mock_access_token_fetcher.cc", + "service/mock_access_token_fetcher.h", + "service/mock_service_request_sender.cc", + "service/mock_service_request_sender.h", + "service/mock_simple_url_loader_factory.cc", + "service/mock_simple_url_loader_factory.h", + "service/mock_url_loader.cc", + "service/mock_url_loader.h", "service/server_url_fetcher_unittest.cc", + "service/service_impl_unittest.cc", + "service/service_request_sender_unittest.cc", "string_conversions_util_unittest.cc", "test_util.cc", "test_util.h", @@ -388,6 +404,7 @@ ":proto", "//base", "//chrome/android/features/autofill_assistant:test_support_jni_headers", + "//net", "//url:url", ] }
diff --git a/components/autofill_assistant/browser/DEPS b/components/autofill_assistant/browser/DEPS index ff90e40..856d035 100644 --- a/components/autofill_assistant/browser/DEPS +++ b/components/autofill_assistant/browser/DEPS
@@ -15,6 +15,7 @@ "+google_apis", "+net", "+services/network/public/cpp", + "+services/network/public/mojom", "+third_party/blink/public/mojom/payments/payment_request.mojom.h", "+third_party/icu/source/common/unicode", "+third_party/libaddressinput/chromium/addressinput_util.h",
diff --git a/components/autofill_assistant/browser/controller.cc b/components/autofill_assistant/browser/controller.cc index 3a19d11e..b6c41de 100644 --- a/components/autofill_assistant/browser/controller.cc +++ b/components/autofill_assistant/browser/controller.cc
@@ -31,6 +31,7 @@ #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" +#include "net/http/http_status_code.h" #include "ui/base/l10n/l10n_util.h" #include "url/gurl.h" @@ -885,7 +886,7 @@ } void Controller::OnGetScripts(const GURL& url, - bool result, + int http_status, const std::string& response) { if (state_ == AutofillAssistantState::STOPPED) return; @@ -895,11 +896,13 @@ if (!HasSameDomainAs(script_url_, url)) return; - if (!result) { + if (http_status != net::HTTP_OK) { #ifdef NDEBUG - VLOG(1) << "Failed to get assistant scripts for <redacted>"; + VLOG(1) << "Failed to get assistant scripts for <redacted>, http-status=" + << http_status; #else - VLOG(1) << "Failed to get assistant scripts for " << script_url_.host(); + VLOG(1) << "Failed to get assistant scripts for " << script_url_.host() + << ", http-status=" << http_status; #endif OnFatalError(l10n_util::GetStringUTF8(IDS_AUTOFILL_ASSISTANT_DEFAULT_ERROR), Metrics::DropOutReason::GET_SCRIPTS_FAILED);
diff --git a/components/autofill_assistant/browser/controller.h b/components/autofill_assistant/browser/controller.h index 066e0d2..b755b62 100644 --- a/components/autofill_assistant/browser/controller.h +++ b/components/autofill_assistant/browser/controller.h
@@ -268,7 +268,9 @@ // once right now and schedule regular checks. Otherwise, do nothing. void GetOrCheckScripts(); - void OnGetScripts(const GURL& url, bool result, const std::string& response); + void OnGetScripts(const GURL& url, + int http_status, + const std::string& response); // Execute |script_path| and, if execution succeeds, enter |end_state| and // call |on_success|.
diff --git a/components/autofill_assistant/browser/controller_unittest.cc b/components/autofill_assistant/browser/controller_unittest.cc index 8b8faeb..8f9a485 100644 --- a/components/autofill_assistant/browser/controller_unittest.cc +++ b/components/autofill_assistant/browser/controller_unittest.cc
@@ -31,6 +31,7 @@ #include "content/public/test/test_browser_context.h" #include "content/public/test/test_renderer_host.h" #include "content/public/test/web_contents_tester.h" +#include "net/http/http_status_code.h" #include "testing/gmock/include/gmock/gmock.h" #include "ui/base/l10n/l10n_util.h" @@ -118,14 +119,14 @@ // Fetching scripts succeeds for all URLs, but return nothing. ON_CALL(*mock_service_, OnGetScriptsForUrl(_, _, _)) - .WillByDefault(RunOnceCallback<2>(true, "")); + .WillByDefault(RunOnceCallback<2>(net::HTTP_OK, "")); // Scripts run, but have no actions. ON_CALL(*mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillByDefault(RunOnceCallback<5>(true, "")); + .WillByDefault(RunOnceCallback<5>(net::HTTP_OK, "")); ON_CALL(*mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillByDefault(RunOnceCallback<5>(true, "")); + .WillByDefault(RunOnceCallback<5>(net::HTTP_OK, "")); ON_CALL(*mock_service_, IsLiteService).WillByDefault(Return(false)); @@ -163,7 +164,7 @@ std::string scripts_str; scripts.SerializeToString(&scripts_str); EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(_, _, _)) - .WillOnce(RunOnceCallback<2>(true, scripts_str)); + .WillOnce(RunOnceCallback<2>(net::HTTP_OK, scripts_str)); } void SetupActionsForScript(const std::string& path, @@ -171,7 +172,7 @@ std::string actions_response_str; actions_response.SerializeToString(&actions_response_str); EXPECT_CALL(*mock_service_, OnGetActions(StrEq(path), _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, actions_response_str)); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, actions_response_str)); } void Start() { Start("http://initialurl.com"); } @@ -209,7 +210,7 @@ response.SerializeToString(&response_str); EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(_, _, _)) - .WillOnce(RunOnceCallback<2>(true, response_str)); + .WillOnce(RunOnceCallback<2>(net::HTTP_OK, response_str)); } // Sets up all calls to the service for scripts to return |response|. @@ -218,7 +219,7 @@ response.SerializeToString(&response_str); EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(_, _, _)) - .WillRepeatedly(RunOnceCallback<2>(true, response_str)); + .WillRepeatedly(RunOnceCallback<2>(net::HTTP_OK, response_str)); } UserData* GetUserData() { return controller_->user_data_.get(); } @@ -325,7 +326,7 @@ // Choose script2 and run it successfully. EXPECT_CALL(*mock_service_, OnGetActions(StrEq("script2"), _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, "")); EXPECT_TRUE(controller_->PerformUserAction(1)); // Offering the remaining choice: script1 as script2 can only run once. @@ -548,7 +549,7 @@ std::string actions_response_str; actions_response.SerializeToString(&actions_response_str); EXPECT_CALL(*mock_service_, OnGetActions(StrEq("stop"), _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, actions_response_str)); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, actions_response_str)); Start(); ASSERT_THAT(controller_->GetUserActions(), SizeIs(1)); @@ -568,7 +569,7 @@ std::string actions_response_str; actions_response.SerializeToString(&actions_response_str); EXPECT_CALL(*mock_service_, OnGetActions(StrEq("stop"), _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, actions_response_str)); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, actions_response_str)); Start(); ASSERT_THAT(controller_->GetUserActions(), SizeIs(1)); @@ -588,10 +589,10 @@ EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(Eq(GURL("http://a.example.com/path1")), _, _)) - .WillOnce(RunOnceCallback<2>(true, scripts_str)); + .WillOnce(RunOnceCallback<2>(net::HTTP_OK, scripts_str)); EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(Eq(GURL("http://b.example.com/path1")), _, _)) - .WillOnce(RunOnceCallback<2>(true, scripts_str)); + .WillOnce(RunOnceCallback<2>(net::HTTP_OK, scripts_str)); Start("http://a.example.com/path1"); SimulateNavigateToUrl(GURL("http://a.example.com/path2")); @@ -608,7 +609,7 @@ SetNextScriptResponse(script_response); EXPECT_CALL(*mock_service_, OnGetActions(StrEq("autostart"), _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, "")); EXPECT_CALL(mock_client_, AttachUI()); Start("http://a.example.com/path"); @@ -651,7 +652,7 @@ TEST_F(ControllerTest, InitialUrlLoads) { GURL initialUrl("http://a.example.com/path"); EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(Eq(initialUrl), _, _)) - .WillOnce(RunOnceCallback<2>(true, "")); + .WillOnce(RunOnceCallback<2>(net::HTTP_OK, "")); controller_->Start(initialUrl, TriggerContext::CreateEmpty()); } @@ -904,7 +905,7 @@ on_timeout_error.SerializeToString(&on_timeout_error_str); EXPECT_CALL(*mock_service_, OnGetActions(StrEq("on_timeout_error"), _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, on_timeout_error_str)); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, on_timeout_error_str)); Start("http://a.example.com/path"); for (int i = 0; i < 30; i++) { @@ -936,7 +937,7 @@ on_timeout_error.SerializeToString(&on_timeout_error_str); EXPECT_CALL(*mock_service_, OnGetActions(StrEq("on_timeout_error"), _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, on_timeout_error_str)); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, on_timeout_error_str)); Start("http://a.example.com/path"); @@ -1100,7 +1101,7 @@ std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(*mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); Start("http://a.example.com/path"); EXPECT_THAT(controller_->GetUserActions(), SizeIs(1)); @@ -1133,7 +1134,7 @@ std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(*mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); Start("http://a.example.com/path"); EXPECT_THAT(controller_->GetUserActions(), SizeIs(1)); @@ -1179,11 +1180,11 @@ script_response.SerializeToString(&response_str); EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(GURL("http://example.com/"), _, _)) - .WillOnce(RunOnceCallback<2>(true, response_str)); + .WillOnce(RunOnceCallback<2>(net::HTTP_OK, response_str)); EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(GURL("http://b.example.com/"), _, _)) - .WillOnce(RunOnceCallback<2>(true, "")); + .WillOnce(RunOnceCallback<2>(net::HTTP_OK, "")); // Start tracking at example.com, with one script matching SetLastCommittedUrl(GURL("http://example.com/")); @@ -1287,7 +1288,7 @@ // Running the script fails, due to a backend issue. The error message should // be shown. EXPECT_CALL(*mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(false, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_UNAUTHORIZED, "")); // Start tracking at example.com, with one script matching SetLastCommittedUrl(GURL("http://example.com/")); @@ -1317,7 +1318,7 @@ script_response.SerializeToString(&response_str); EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(GURL("http://example.com/"), _, _)) - .WillOnce(RunOnceCallback<2>(true, response_str)); + .WillOnce(RunOnceCallback<2>(net::HTTP_OK, response_str)); // Start tracking at example.com, with one script matching SetLastCommittedUrl(GURL("http://example.com/")); @@ -1327,7 +1328,7 @@ ASSERT_THAT(controller_->GetUserActions(), SizeIs(1)); EXPECT_CALL(*mock_service_, OnGetActions(StrEq("runnable"), _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(false, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_UNAUTHORIZED, "")); // When the script fails, the controller transitions to STOPPED state, then // right away back to TRACKING state. @@ -1373,7 +1374,7 @@ AddRunnableScript(&script_response, "runnable"); std::string response_str; script_response.SerializeToString(&response_str); - std::move(get_scripts_callback).Run(true, response_str); + std::move(get_scripts_callback).Run(net::HTTP_OK, response_str); EXPECT_TRUE(first_check_done); EXPECT_TRUE(controller_->HasRunFirstCheck()); @@ -1451,7 +1452,7 @@ EXPECT_THAT(controller_->GetUserActions(), SizeIs(1)); EXPECT_CALL(*mock_service_, OnGetActions(StrEq("autostart"), _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, "")); ActionsResponseProto runnable_script; runnable_script.add_actions()->mutable_tell()->set_message("runnable"); @@ -1491,7 +1492,7 @@ script_response.SerializeToString(&response_str); EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(GURL("http://example.com/"), _, _)) - .WillOnce(RunOnceCallback<2>(true, response_str)); + .WillOnce(RunOnceCallback<2>(net::HTTP_OK, response_str)); EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(GURL("http://b.example.com/"), _, _)) .Times(0); @@ -1536,7 +1537,7 @@ script_response.SerializeToString(&response_str); EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(GURL("http://a.example.com/"), _, _)) - .WillOnce(RunOnceCallback<2>(true, response_str)); + .WillOnce(RunOnceCallback<2>(net::HTTP_OK, response_str)); Start("http://a.example.com/"); EXPECT_EQ(AutofillAssistantState::BROWSE, controller_->GetState()); @@ -1579,7 +1580,7 @@ script_response.SerializeToString(&response_str); EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(GURL("http://a.example.com/"), _, _)) - .WillOnce(RunOnceCallback<2>(true, response_str)); + .WillOnce(RunOnceCallback<2>(net::HTTP_OK, response_str)); Start("http://a.example.com/"); EXPECT_EQ(AutofillAssistantState::BROWSE, controller_->GetState()); @@ -1614,7 +1615,7 @@ script_response.SerializeToString(&response_str); EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(GURL("http://example.com/"), _, _)) - .WillOnce(RunOnceCallback<2>(true, response_str)); + .WillOnce(RunOnceCallback<2>(net::HTTP_OK, response_str)); Start("http://example.com/"); EXPECT_EQ(AutofillAssistantState::PROMPT, controller_->GetState()); @@ -1934,7 +1935,7 @@ script_response.SerializeToString(&response_str); EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(GURL("http://a.example.com/"), _, _)) - .WillOnce(RunOnceCallback<2>(true, response_str)); + .WillOnce(RunOnceCallback<2>(net::HTTP_OK, response_str)); Start("http://a.example.com/"); EXPECT_EQ(AutofillAssistantState::BROWSE, controller_->GetState()); @@ -2624,7 +2625,7 @@ TEST_F(ControllerTest, StartPasswordChangeFlow) { GURL initialUrl("http://example.com/password"); EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(Eq(initialUrl), _, _)) - .WillOnce(RunOnceCallback<2>(true, "")); + .WillOnce(RunOnceCallback<2>(net::HTTP_OK, "")); std::map<std::string, std::string> parameters; std::string username = "test_username"; parameters["PASSWORD_CHANGE_USERNAME"] = username; @@ -2658,7 +2659,7 @@ std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(*mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); Start("http://a.example.com/path");
diff --git a/components/autofill_assistant/browser/mock_client_context.cc b/components/autofill_assistant/browser/mock_client_context.cc new file mode 100644 index 0000000..1c989ab0 --- /dev/null +++ b/components/autofill_assistant/browser/mock_client_context.cc
@@ -0,0 +1,12 @@ +// 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/autofill_assistant/browser/mock_client_context.h" + +namespace autofill_assistant { + +MockClientContext::MockClientContext() = default; +MockClientContext::~MockClientContext() = default; + +} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/mock_client_context.h b/components/autofill_assistant/browser/mock_client_context.h new file mode 100644 index 0000000..cc9a593c --- /dev/null +++ b/components/autofill_assistant/browser/mock_client_context.h
@@ -0,0 +1,27 @@ +// 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_AUTOFILL_ASSISTANT_BROWSER_MOCK_CLIENT_CONTEXT_H_ +#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_MOCK_CLIENT_CONTEXT_H_ + +#include "components/autofill_assistant/browser/client_context.h" + +#include "components/autofill_assistant/browser/service.pb.h" +#include "components/autofill_assistant/browser/trigger_context.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace autofill_assistant { + +class MockClientContext : public ClientContext { + public: + MockClientContext(); + ~MockClientContext() override; + + MOCK_METHOD1(Update, void(const TriggerContext& trigger_context)); + MOCK_CONST_METHOD0(AsProto, ClientContextProto()); +}; + +} // namespace autofill_assistant + +#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_MOCK_CLIENT_CONTEXT_H_
diff --git a/components/autofill_assistant/browser/script_executor.cc b/components/autofill_assistant/browser/script_executor.cc index de7f320..628bc78ae 100644 --- a/components/autofill_assistant/browser/script_executor.cc +++ b/components/autofill_assistant/browser/script_executor.cc
@@ -27,6 +27,7 @@ #include "components/autofill_assistant/browser/web/element_finder.h" #include "components/autofill_assistant/browser/web/web_controller.h" #include "components/strings/grit/components_strings.h" +#include "net/http/http_status_code.h" #include "ui/base/l10n/l10n_util.h" namespace autofill_assistant { @@ -809,13 +810,14 @@ } void ScriptExecutor::OnGetActions(base::TimeTicks start_time, - bool result, + int http_status, const std::string& response) { + VLOG(2) << __func__ << " http-status=" << http_status; batch_start_time_ = base::TimeTicks::Now(); roundtrip_timing_stats_.set_roundtrip_time_ms( (batch_start_time_ - start_time).InMilliseconds()); - bool success = result && ProcessNextActionResponse(response); - VLOG(2) << __func__ << " result=" << result; + bool success = + http_status == net::HTTP_OK && ProcessNextActionResponse(response); if (should_stop_script_) { // The last action forced the script to stop. Sending the result of the // action is considered best effort in this situation. Report a successful
diff --git a/components/autofill_assistant/browser/script_executor.h b/components/autofill_assistant/browser/script_executor.h index 5ea7b55..54d1d91 100644 --- a/components/autofill_assistant/browser/script_executor.h +++ b/components/autofill_assistant/browser/script_executor.h
@@ -380,7 +380,7 @@ }; void OnGetActions(base::TimeTicks start_time, - bool result, + int http_status, const std::string& response); bool ProcessNextActionResponse(const std::string& response); void ReportPayloadsToListener();
diff --git a/components/autofill_assistant/browser/script_executor_unittest.cc b/components/autofill_assistant/browser/script_executor_unittest.cc index aa45c404..306a74d 100644 --- a/components/autofill_assistant/browser/script_executor_unittest.cc +++ b/components/autofill_assistant/browser/script_executor_unittest.cc
@@ -15,6 +15,7 @@ #include "components/autofill_assistant/browser/service/mock_service.h" #include "components/autofill_assistant/browser/service/service.h" #include "components/autofill_assistant/browser/web/mock_web_controller.h" +#include "net/http/http_status_code.h" #include "testing/gmock/include/gmock/gmock.h" namespace autofill_assistant { @@ -110,7 +111,8 @@ wait_action->set_allow_interrupt(true); interruptible.add_actions()->mutable_tell()->set_message(path); EXPECT_CALL(mock_service_, OnGetActions(StrEq(path), _, _, _, _, _)) - .WillRepeatedly(RunOnceCallback<5>(true, Serialize(interruptible))); + .WillRepeatedly( + RunOnceCallback<5>(net::HTTP_OK, Serialize(interruptible))); } // Creates an interrupt that contains a tell. It will always succeed. @@ -120,7 +122,8 @@ ActionsResponseProto interrupt_actions; InitInterruptActions(&interrupt_actions, path); EXPECT_CALL(mock_service_, OnGetActions(StrEq(path), _, _, _, _, _)) - .WillRepeatedly(RunOnceCallback<5>(true, Serialize(interrupt_actions))); + .WillRepeatedly( + RunOnceCallback<5>(net::HTTP_OK, Serialize(interrupt_actions))); } void InitInterruptActions(ActionsResponseProto* interrupt_actions, @@ -168,7 +171,7 @@ TEST_F(ScriptExecutorTest, GetActionsFails) { EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(false, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_UNAUTHORIZED, "")); EXPECT_CALL(executor_callback_, Run(AllOf(Field(&ScriptExecutor::Result::success, false), Field(&ScriptExecutor::Result::at_end, @@ -196,7 +199,7 @@ EXPECT_THAT("value", trigger_context.GetParameter("param").value_or("")); - std::move(callback).Run(true, ""); + std::move(callback).Run(net::HTTP_OK, ""); })); EXPECT_CALL(executor_callback_, @@ -210,12 +213,12 @@ ToSelectorProto("will fail"); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); EXPECT_CALL(executor_callback_, Run(AllOf(Field(&ScriptExecutor::Result::success, true), Field(&ScriptExecutor::Result::at_end, @@ -233,18 +236,19 @@ initial_actions_response.add_actions()->mutable_tell()->set_message("1"); initial_actions_response.add_actions()->mutable_tell()->set_message("2"); EXPECT_CALL(mock_service_, OnGetActions(StrEq(kScriptPath), _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(initial_actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, + Serialize(initial_actions_response))); ActionsResponseProto next_actions_response; next_actions_response.add_actions()->mutable_tell()->set_message("3"); std::vector<ProcessedActionProto> processed_actions1_capture; std::vector<ProcessedActionProto> processed_actions2_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillOnce( - DoAll(SaveArg<3>(&processed_actions1_capture), - RunOnceCallback<5>(true, Serialize(next_actions_response)))) + .WillOnce(DoAll( + SaveArg<3>(&processed_actions1_capture), + RunOnceCallback<5>(net::HTTP_OK, Serialize(next_actions_response)))) .WillOnce(DoAll(SaveArg<3>(&processed_actions2_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, true))); executor_->Run(&user_data_, executor_callback_.Get()); @@ -258,12 +262,12 @@ actions_response.add_actions(); // action definition missing EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, true))); executor_->Run(&user_data_, executor_callback_.Get()); @@ -277,10 +281,10 @@ actions_response.add_actions()->mutable_stop(); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, "")); EXPECT_CALL(executor_callback_, Run(AllOf(Field(&ScriptExecutor::Result::success, true), Field(&ScriptExecutor::Result::at_end, @@ -299,7 +303,8 @@ "never run"); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(initial_actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, + Serialize(initial_actions_response))); ActionsResponseProto next_actions_response; next_actions_response.add_actions()->mutable_tell()->set_message( @@ -307,11 +312,11 @@ std::vector<ProcessedActionProto> processed_actions1_capture; std::vector<ProcessedActionProto> processed_actions2_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillOnce( - DoAll(SaveArg<3>(&processed_actions1_capture), - RunOnceCallback<5>(true, Serialize(next_actions_response)))) + .WillOnce(DoAll( + SaveArg<3>(&processed_actions1_capture), + RunOnceCallback<5>(net::HTTP_OK, Serialize(next_actions_response)))) .WillOnce(DoAll(SaveArg<3>(&processed_actions2_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, true))); executor_->Run(&user_data_, executor_callback_.Get()); @@ -334,12 +339,12 @@ action->set_action_delay_ms(1000); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); // executor_callback_.Run() not expected to be run just yet, as the action is // delayed. @@ -362,9 +367,9 @@ *actions_response.add_actions() = click_with_clean_contextual_ui; EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, "")); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, true))); @@ -382,9 +387,9 @@ actions_response.add_actions()->mutable_tell()->set_message("Wait no!"); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, "")); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, true))); @@ -397,9 +402,9 @@ ActionsResponseProto actions_response; actions_response.add_actions()->mutable_tell()->set_message("Hello"); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(false, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_UNAUTHORIZED, "")); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, false))); delegate_.SetDetails(std::make_unique<Details>()); // empty, but not null @@ -420,7 +425,7 @@ TEST_F(ScriptExecutorTest, UpdateScriptStateOnError) { EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(false, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_UNAUTHORIZED, "")); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, false))); executor_->Run(&user_data_, executor_callback_.Get()); @@ -433,9 +438,10 @@ ActionsResponseProto initial_actions_response; initial_actions_response.add_actions()->mutable_tell()->set_message("ok"); EXPECT_CALL(mock_service_, OnGetActions(StrEq(kScriptPath), _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(initial_actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, + Serialize(initial_actions_response))); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, "")); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, true))); executor_->Run(&user_data_, executor_callback_.Get()); @@ -452,14 +458,15 @@ EXPECT_CALL(mock_service_, OnGetActions(_, _, _, "initial global payload", "initial payload", _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); ActionsResponseProto next_actions_response; next_actions_response.set_global_payload("last global payload"); next_actions_response.set_script_payload("last payload"); EXPECT_CALL(mock_service_, OnGetNextActions(_, "actions global payload", "actions payload", _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(next_actions_response))); + .WillOnce( + RunOnceCallback<5>(net::HTTP_OK, Serialize(next_actions_response))); EXPECT_CALL(executor_callback_, Run(_)); executor_->Run(&user_data_, executor_callback_.Get()); @@ -476,11 +483,11 @@ EXPECT_CALL(mock_service_, OnGetActions(_, _, _, "initial global payload", "initial payload", _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); EXPECT_CALL(mock_service_, OnGetNextActions(_, "actions global payload", "actions payload", _, _, _)) - .WillOnce(RunOnceCallback<5>(false, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_UNAUTHORIZED, "")); EXPECT_CALL(executor_callback_, Run(_)); executor_->Run(&user_data_, executor_callback_.Get()); @@ -496,11 +503,11 @@ ToSelectorProto("element"); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); // First check does not find the element, wait for dom waits 1s, then the // element is found, and the action succeeds. @@ -530,9 +537,9 @@ std::vector<ProcessedActionProto> processed_actions2_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions1_capture), - RunOnceCallback<5>(true, ""))) + RunOnceCallback<5>(net::HTTP_OK, ""))) .WillOnce(DoAll(SaveArg<3>(&processed_actions2_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, true))); @@ -569,13 +576,13 @@ testing::InSequence seq; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, "payload for interrupt1", _, _, _)) - .WillOnce(RunOnceCallback<5>(true, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, "")); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, "payload for interrupt2", _, _, _)) - .WillOnce(RunOnceCallback<5>(true, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, "")); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, "main script payload", _, _, _)) - .WillOnce(RunOnceCallback<5>(true, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, "")); } EXPECT_CALL(executor_callback_, @@ -600,7 +607,8 @@ wait_action->set_allow_interrupt(true); } EXPECT_CALL(mock_service_, OnGetActions(StrEq("script_path"), _, _, _, _, _)) - .WillRepeatedly(RunOnceCallback<5>(true, Serialize(interruptible))); + .WillRepeatedly( + RunOnceCallback<5>(net::HTTP_OK, Serialize(interruptible))); // 'interrupt' with matching preconditions runs exactly three times. RegisterInterrupt("interrupt", "interrupt_trigger"); @@ -608,11 +616,12 @@ InitInterruptActions(&interrupt_actions, "interrupt"); EXPECT_CALL(mock_service_, OnGetActions(StrEq("interrupt"), _, _, _, _, _)) .Times(3) - .WillRepeatedly(RunOnceCallback<5>(true, Serialize(interrupt_actions))); + .WillRepeatedly( + RunOnceCallback<5>(net::HTTP_OK, Serialize(interrupt_actions))); // All scripts succeed with no more actions. EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillRepeatedly(RunOnceCallback<5>(true, "")); + .WillRepeatedly(RunOnceCallback<5>(net::HTTP_OK, "")); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, true))); @@ -630,8 +639,8 @@ "last payload from interrupt"); EXPECT_CALL(mock_service_, OnGetNextActions(_, "global payload for interrupt", "payload for interrupt", _, _, _)) - .WillOnce( - RunOnceCallback<5>(true, Serialize(next_interrupt_actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, + Serialize(next_interrupt_actions_response))); ActionsResponseProto next_main_actions_response; next_main_actions_response.set_global_payload( @@ -640,8 +649,8 @@ EXPECT_CALL(mock_service_, OnGetNextActions(_, "last global payload from interrupt", "main script payload", _, _, _)) - .WillOnce( - RunOnceCallback<5>(true, Serialize(next_main_actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, + Serialize(next_main_actions_response))); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, true))); @@ -657,11 +666,11 @@ EXPECT_CALL(mock_service_, OnGetNextActions(_, "global payload for interrupt", "payload for interrupt", _, _, _)) - .WillOnce(RunOnceCallback<5>(false, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_UNAUTHORIZED, "")); EXPECT_CALL(mock_service_, OnGetNextActions(_, "global payload for interrupt", "main script payload", _, _, _)) - .WillOnce(RunOnceCallback<5>(false, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_UNAUTHORIZED, "")); EXPECT_CALL(executor_callback_, Run(_)); executor_->Run(&user_data_, executor_callback_.Get()); @@ -684,7 +693,7 @@ .WillRepeatedly(RunOnceCallback<1>(ClientStatus())); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillRepeatedly(RunOnceCallback<5>(true, "")); + .WillRepeatedly(RunOnceCallback<5>(net::HTTP_OK, "")); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, true))); @@ -703,14 +712,14 @@ ToSelectorProto("element"); // allow_interrupt is not set EXPECT_CALL(mock_service_, OnGetActions(StrEq(kScriptPath), _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(interruptible))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(interruptible))); // The interrupt would trigger, since interrupt_trigger exits, but it's not // given an opportunity to. SetupInterrupt("interrupt", "interrupt_trigger"); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillRepeatedly(RunOnceCallback<5>(true, "")); + .WillRepeatedly(RunOnceCallback<5>(net::HTTP_OK, "")); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, true))); @@ -729,7 +738,7 @@ // The interrupt fails. EXPECT_CALL(mock_service_, OnGetNextActions(_, _, "payload for interrupt", _, _, _)) - .WillOnce(RunOnceCallback<5>(false, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_UNAUTHORIZED, "")); // The main script gets a report of the failure from the interrupt, and fails // in turn. @@ -740,7 +749,7 @@ ElementsAre(Property(&ProcessedActionProto::status, ProcessedActionStatusProto::INTERRUPT_FAILED)), _, _)) - .WillOnce(RunOnceCallback<5>(false, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_UNAUTHORIZED, "")); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, false))); @@ -763,13 +772,14 @@ // Get interrupt actions EXPECT_CALL(mock_service_, OnGetActions(StrEq("interrupt"), _, _, _, _, _)) - .WillRepeatedly(RunOnceCallback<5>(true, Serialize(interrupt_actions))); + .WillRepeatedly( + RunOnceCallback<5>(net::HTTP_OK, Serialize(interrupt_actions))); // We expect to get result of interrupt action, then result of the main script // action. EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) .Times(2) - .WillRepeatedly(RunOnceCallback<5>(true, "")); + .WillRepeatedly(RunOnceCallback<5>(net::HTTP_OK, "")); EXPECT_CALL(executor_callback_, Run(AllOf(Field(&ScriptExecutor::Result::success, true), @@ -796,7 +806,8 @@ ToSelectorProto("end_prompt"); interruptible.add_actions()->mutable_tell()->set_message("done"); EXPECT_CALL(mock_service_, OnGetActions(kScriptPath, _, _, _, _, _)) - .WillRepeatedly(RunOnceCallback<5>(true, Serialize(interruptible))); + .WillRepeatedly( + RunOnceCallback<5>(net::HTTP_OK, Serialize(interruptible))); EXPECT_CALL(mock_web_controller_, OnElementCheck(Eq(Selector({"interrupt_trigger"})), _)) @@ -809,7 +820,7 @@ .WillRepeatedly(RunOnceCallback<1>(OkClientStatus())); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillRepeatedly(RunOnceCallback<5>(true, "")); + .WillRepeatedly(RunOnceCallback<5>(net::HTTP_OK, "")); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, true))); @@ -843,7 +854,7 @@ prompt->set_browse_mode(true); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); executor_->Run(&user_data_, executor_callback_.Get()); EXPECT_EQ(AutofillAssistantState::BROWSE, delegate_.GetState()); @@ -855,7 +866,7 @@ prompt->add_choices()->mutable_chip()->set_text("done"); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); executor_->Run(&user_data_, executor_callback_.Get()); EXPECT_EQ(AutofillAssistantState::PROMPT, delegate_.GetState()); @@ -873,7 +884,8 @@ *prompt_action->add_choices()->mutable_auto_select_when()->mutable_match() = ToSelectorProto("end_prompt"); EXPECT_CALL(mock_service_, OnGetActions(kScriptPath, _, _, _, _, _)) - .WillRepeatedly(RunOnceCallback<5>(true, Serialize(interruptible))); + .WillRepeatedly( + RunOnceCallback<5>(net::HTTP_OK, Serialize(interruptible))); // interrupt_trigger goes away and come back, which means that the interrupt // will be run twice. @@ -896,7 +908,7 @@ .WillRepeatedly(RunOnceCallback<1>(OkClientStatus())); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillRepeatedly(RunOnceCallback<5>(true, "")); + .WillRepeatedly(RunOnceCallback<5>(net::HTTP_OK, "")); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, true))); @@ -927,7 +939,8 @@ ActionsResponseProto initial_actions_response; initial_actions_response.add_actions()->mutable_tell()->set_message("1"); EXPECT_CALL(mock_service_, OnGetActions(StrEq(kScriptPath), _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(initial_actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, + Serialize(initial_actions_response))); ActionsResponseProto next_actions_response; next_actions_response.add_actions()->mutable_tell()->set_message("2"); @@ -939,8 +952,9 @@ presentation->mutable_precondition(); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(next_actions_response))) - .WillOnce(RunOnceCallback<5>(true, "")); + .WillOnce( + RunOnceCallback<5>(net::HTTP_OK, Serialize(next_actions_response))) + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, "")); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, true))); @@ -967,12 +981,12 @@ presentation->mutable_precondition(); EXPECT_CALL(mock_service_, OnGetActions(StrEq(kScriptPath), _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); script->set_path("path2"); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))) - .WillOnce(RunOnceCallback<5>(true, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))) + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, "")); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, true))); @@ -996,7 +1010,7 @@ interrupt_actions.add_actions()->mutable_tell()->set_message("abc"); EXPECT_CALL(mock_service_, OnGetActions(StrEq("interrupt"), _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(interrupt_actions))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(interrupt_actions))); auto* script = interrupt_actions.mutable_update_script_list()->add_scripts(); script->set_path("path"); @@ -1009,8 +1023,8 @@ // script which will finish without running any actions. EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) .Times(3) - .WillOnce(RunOnceCallback<5>(true, Serialize(interrupt_actions))) - .WillRepeatedly(RunOnceCallback<5>(true, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(interrupt_actions))) + .WillRepeatedly(RunOnceCallback<5>(net::HTTP_OK, "")); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, true))); @@ -1037,17 +1051,19 @@ ToSelectorProto("element"); wait_action->set_allow_interrupt(true); EXPECT_CALL(mock_service_, OnGetActions(kScriptPath, _, _, _, _, _)) - .WillRepeatedly(RunOnceCallback<5>(true, Serialize(interruptible))); + .WillRepeatedly( + RunOnceCallback<5>(net::HTTP_OK, Serialize(interruptible))); RegisterInterrupt("interrupt", "interrupt_trigger"); ActionsResponseProto interrupt_actions; interrupt_actions.add_actions()->mutable_tell()->set_message( "interrupt status"); EXPECT_CALL(mock_service_, OnGetActions(StrEq("interrupt"), _, _, _, _, _)) - .WillRepeatedly(RunOnceCallback<5>(true, Serialize(interrupt_actions))); + .WillRepeatedly( + RunOnceCallback<5>(net::HTTP_OK, Serialize(interrupt_actions))); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillRepeatedly(RunOnceCallback<5>(true, "")); + .WillRepeatedly(RunOnceCallback<5>(net::HTTP_OK, "")); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, true))); @@ -1066,10 +1082,11 @@ ToSelectorProto("element"); wait_action->set_allow_interrupt(true); EXPECT_CALL(mock_service_, OnGetActions(kScriptPath, _, _, _, _, _)) - .WillRepeatedly(RunOnceCallback<5>(true, Serialize(interruptible))); + .WillRepeatedly( + RunOnceCallback<5>(net::HTTP_OK, Serialize(interruptible))); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillRepeatedly(RunOnceCallback<5>(true, "")); + .WillRepeatedly(RunOnceCallback<5>(net::HTTP_OK, "")); EXPECT_CALL(executor_callback_, Run(Field(&ScriptExecutor::Result::success, true))); @@ -1087,11 +1104,11 @@ ToSelectorProto("element"); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); // First check does not find the element, wait for dom waits 1s. EXPECT_CALL(mock_web_controller_, @@ -1126,11 +1143,11 @@ ToSelectorProto("element"); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); // Navigation starts before WaitForDom starts. WaitForDom does not wait and // completes successfully. @@ -1153,11 +1170,11 @@ ToSelectorProto("will fail"); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); delegate_.UpdateNavigationState(/* navigating= */ false, /* error= */ true); EXPECT_CALL(executor_callback_, Run(_)); @@ -1185,7 +1202,7 @@ .WillRepeatedly( DoAll(InvokeWithoutArgs( [this]() { delegate_.UpdateNavigationState(true, false); }), - RunOnceCallback<5>(true, Serialize(interrupt_actions)), + RunOnceCallback<5>(net::HTTP_OK, Serialize(interrupt_actions)), InvokeWithoutArgs([this]() { delegate_.UpdateNavigationState(false, false); }))); @@ -1194,9 +1211,9 @@ std::vector<ProcessedActionProto> processed_actions2_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions1_capture), - RunOnceCallback<5>(true, ""))) + RunOnceCallback<5>(net::HTTP_OK, ""))) .WillOnce(DoAll(SaveArg<3>(&processed_actions2_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); EXPECT_CALL(executor_callback_, Run(_)); executor_->Run(&user_data_, executor_callback_.Get()); @@ -1211,11 +1228,11 @@ actions_response.add_actions()->mutable_tell()->set_message("b"); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); delegate_.UpdateNavigationState(/* navigating= */ false, /* error= */ true); EXPECT_CALL(executor_callback_, Run(_)); @@ -1235,11 +1252,11 @@ ToSelectorProto("element"); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); // WaitForDom does NOT wait for navigation to end, it immediately checks for // the element, which fails. @@ -1272,11 +1289,11 @@ ToSelectorProto("element"); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); // As the element doesn't exist, WaitForDom returns and waits for 1s. EXPECT_CALL(mock_web_controller_, @@ -1307,11 +1324,11 @@ ToSelectorProto("element"); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); // As the element doesn't exist, WaitForDom returns and waits for 1s. EXPECT_CALL(mock_web_controller_, @@ -1340,11 +1357,11 @@ actions_response.add_actions()->mutable_wait_for_navigation(); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); // WaitForNavigation returns immediately EXPECT_CALL(executor_callback_, Run(_)); @@ -1360,11 +1377,11 @@ actions_response.add_actions()->mutable_wait_for_navigation(); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); // WaitForNavigation waits for navigation to start after expect_navigation EXPECT_CALL(executor_callback_, Run(_)); @@ -1385,11 +1402,11 @@ actions_response.add_actions()->mutable_wait_for_navigation(); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); // The first wait_for_navigation waits for the navigation to happen. After // that, the other wait_for_navigation return immediately. @@ -1411,11 +1428,11 @@ actions_response.add_actions()->mutable_wait_for_navigation(); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); delegate_.UpdateNavigationState(/* navigating= */ true, /* error= */ false); @@ -1445,11 +1462,11 @@ actions_response.add_actions()->mutable_wait_for_navigation(); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), - RunOnceCallback<5>(true, ""))); + RunOnceCallback<5>(net::HTTP_OK, ""))); // WaitForNavigation waits for navigation to start after expect_navigation EXPECT_CALL(executor_callback_, Run(_)); @@ -1471,7 +1488,7 @@ ->set_text("done"); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); executor_->Run(&user_data_, executor_callback_.Get()); EXPECT_EQ(AutofillAssistantState::PROMPT, delegate_.GetState()); @@ -1495,7 +1512,7 @@ ->add_names("done"); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); std::vector<ProcessedActionProto> processed_actions_capture; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) @@ -1523,7 +1540,7 @@ ->set_text("Chip"); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); executor_->Run(&user_data_, executor_callback_.Get()); EXPECT_EQ("Tell", delegate_.GetStatusMessage()); @@ -1561,7 +1578,7 @@ actions_response.add_actions()->mutable_tell()->set_message("Finished"); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); // At first we don't find the element, to keep the |WaitForDomAction| running. EXPECT_CALL(mock_web_controller_, @@ -1609,14 +1626,16 @@ action->mutable_tell()->set_message("1"); action->set_action_delay_ms(1000); EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillOnce(DoAll(Delay(&task_environment_, 200), - RunOnceCallback<5>(true, Serialize(actions_response)))); + .WillOnce( + DoAll(Delay(&task_environment_, 200), + RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response)))); ActionsResponseProto next_actions_response; next_actions_response.add_actions()->mutable_tell()->set_message("3"); RoundtripTimingStats timing_stats; EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillOnce(DoAll(SaveArg<4>(&timing_stats), RunOnceCallback<5>(true, ""))); + .WillOnce(DoAll(SaveArg<4>(&timing_stats), + RunOnceCallback<5>(net::HTTP_OK, ""))); executor_->Run(&user_data_, executor_callback_.Get()); EXPECT_TRUE(task_environment_.NextTaskIsDelayed());
diff --git a/components/autofill_assistant/browser/script_tracker_unittest.cc b/components/autofill_assistant/browser/script_tracker_unittest.cc index 7122534..a2e22a4 100644 --- a/components/autofill_assistant/browser/script_tracker_unittest.cc +++ b/components/autofill_assistant/browser/script_tracker_unittest.cc
@@ -14,6 +14,7 @@ #include "components/autofill_assistant/browser/service/mock_service.h" #include "components/autofill_assistant/browser/service/service.h" #include "components/autofill_assistant/browser/web/mock_web_controller.h" +#include "net/http/http_status_code.h" #include "testing/gmock/include/gmock/gmock.h" namespace autofill_assistant { @@ -43,7 +44,7 @@ // Scripts run, but have no actions. ON_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) - .WillByDefault(RunOnceCallback<5>(true, "")); + .WillByDefault(RunOnceCallback<5>(net::HTTP_OK, "")); } protected: @@ -303,9 +304,9 @@ EXPECT_CALL(mock_service_, OnGetActions(StrEq("runnable name"), _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, "")); base::MockCallback<ScriptExecutor::RunScriptCallback> execute_callback; EXPECT_CALL(execute_callback, @@ -345,9 +346,9 @@ EXPECT_CALL(mock_service_, OnGetActions(StrEq("runnable name"), _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, "")); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, "")); base::MockCallback<ScriptExecutor::RunScriptCallback> execute_callback; EXPECT_CALL(execute_callback, @@ -384,16 +385,16 @@ interrupt_proto->mutable_presentation()->set_interrupt(true); EXPECT_CALL(mock_service_, OnGetActions("main", _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_response))); EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _, _)) - .WillRepeatedly(RunOnceCallback<5>(true, "")); + .WillRepeatedly(RunOnceCallback<5>(net::HTTP_OK, "")); ActionsResponseProto actions_interrupt; actions_response.set_script_payload("from interrupt"); actions_response.add_actions()->mutable_tell()->set_message("interrupt"); EXPECT_CALL(mock_service_, OnGetActions("interrupt", _, _, _, _, _)) - .WillOnce(RunOnceCallback<5>(true, Serialize(actions_interrupt))); + .WillOnce(RunOnceCallback<5>(net::HTTP_OK, Serialize(actions_interrupt))); base::MockCallback<ScriptExecutor::RunScriptCallback> execute_callback; EXPECT_CALL(execute_callback,
diff --git a/components/autofill_assistant/browser/service/java_service.cc b/components/autofill_assistant/browser/service/java_service.cc index 71735e89..63c54611 100644 --- a/components/autofill_assistant/browser/service/java_service.cc +++ b/components/autofill_assistant/browser/service/java_service.cc
@@ -12,6 +12,7 @@ #include "base/android/jni_android.h" #include "base/android/jni_array.h" #include "base/android/jni_string.h" +#include "net/http/http_status_code.h" namespace autofill_assistant { @@ -41,7 +42,7 @@ base::android::ConvertUTF8ToJavaString(env, url.spec())); std::string response; base::android::JavaByteArrayToString(env, jresponse, &response); - std::move(callback).Run(true, response); + std::move(callback).Run(net::HTTP_OK, response); } void JavaService::GetActions(const std::string& script_path, @@ -59,7 +60,7 @@ base::android::ToJavaByteArray(env, script_payload)); std::string response; base::android::JavaByteArrayToString(env, jresponse, &response); - std::move(callback).Run(true, response); + std::move(callback).Run(net::HTTP_OK, response); } void JavaService::GetNextActions( @@ -87,7 +88,7 @@ jprocessed_actions); std::string response; base::android::JavaByteArrayToString(env, jresponse, &response); - std::move(callback).Run(true, response); + std::move(callback).Run(net::HTTP_OK, response); } } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/lite_service.cc b/components/autofill_assistant/browser/service/lite_service.cc index 0cb277f2..097a17f69 100644 --- a/components/autofill_assistant/browser/service/lite_service.cc +++ b/components/autofill_assistant/browser/service/lite_service.cc
@@ -12,6 +12,7 @@ #include "base/bind.h" #include "base/logging.h" #include "base/strings/string_number_conversions.h" +#include "net/http/http_status_code.h" namespace autofill_assistant { @@ -50,7 +51,7 @@ std::string serialized_response; response.SerializeToString(&serialized_response); - std::move(callback).Run(true, serialized_response); + std::move(callback).Run(net::HTTP_OK, serialized_response); } void LiteService::GetActions(const std::string& script_path, @@ -78,9 +79,9 @@ } void LiteService::OnGetActions(ResponseCallback callback, - bool result, + int http_status, const std::string& response) { - if (!result) { + if (http_status != net::HTTP_OK) { StopWithoutErrorMessage( std::move(callback), Metrics::LiteScriptFinishedState::LITE_SCRIPT_GET_ACTIONS_FAILED); @@ -131,7 +132,7 @@ std::string serialized_first_part; split_actions->first.SerializeToString(&serialized_first_part); - std::move(callback).Run(result, serialized_first_part); + std::move(callback).Run(http_status, serialized_first_part); notify_script_running_callback_.Run(/*ui_shown = */ false); } @@ -146,7 +147,7 @@ // The lite script has already terminated. We need to run |callback| with // |success|=true and an empty response to ensure a graceful stop of the // script (i.e., without error message). - std::move(callback).Run(true, std::string()); + std::move(callback).Run(net::HTTP_OK, std::string()); return; } @@ -179,7 +180,7 @@ std::string serialized_second_part; trigger_script_second_part_->SerializeToString(&serialized_second_part); trigger_script_second_part_.reset(); - std::move(callback).Run(true, serialized_second_part); + std::move(callback).Run(net::HTTP_OK, serialized_second_part); notify_script_running_callback_.Run(/*ui_shown = */ true); return; } @@ -234,7 +235,7 @@ response.add_actions()->mutable_stop(); std::string serialized_response; response.SerializeToString(&serialized_response); - std::move(callback).Run(true, serialized_response); + std::move(callback).Run(net::HTTP_OK, serialized_response); } } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/lite_service.h b/components/autofill_assistant/browser/service/lite_service.h index 721c52d..dd846e1 100644 --- a/components/autofill_assistant/browser/service/lite_service.h +++ b/components/autofill_assistant/browser/service/lite_service.h
@@ -69,7 +69,7 @@ friend class LiteServiceTest; void OnGetActions(ResponseCallback callback, - bool result, + int http_status, const std::string& response); // Stops the script and closes autofill assistant without showing an error
diff --git a/components/autofill_assistant/browser/service/lite_service_unittest.cc b/components/autofill_assistant/browser/service/lite_service_unittest.cc index 632aadc6..5e2bfb2 100644 --- a/components/autofill_assistant/browser/service/lite_service_unittest.cc +++ b/components/autofill_assistant/browser/service/lite_service_unittest.cc
@@ -20,6 +20,7 @@ #include "base/test/gmock_callback_support.h" #include "base/test/gtest_util.h" #include "base/test/mock_callback.h" +#include "net/http/http_status_code.h" #include "testing/gmock/include/gmock/gmock.h" namespace autofill_assistant { @@ -54,7 +55,7 @@ Service::ResponseCallback& callback) { std::string serialized_response; get_actions_response_.SerializeToString(&serialized_response); - std::move(callback).Run(true, serialized_response); + std::move(callback).Run(net::HTTP_OK, serialized_response); }); } ~LiteServiceTest() override {} @@ -72,7 +73,8 @@ stop.add_actions()->mutable_stop(); std::string serialized_stop; stop.SerializeToString(&serialized_stop); - EXPECT_CALL(mock_response_callback_, Run(true, serialized_stop)).Times(1); + EXPECT_CALL(mock_response_callback_, Run(net::HTTP_OK, serialized_stop)) + .Times(1); EXPECT_CALL(mock_finished_callback_, Run(state)); } @@ -80,7 +82,7 @@ mock_finished_callback_; base::MockCallback<base::RepeatingCallback<void(bool)>> mock_script_running_callback_; - base::MockCallback<base::OnceCallback<void(bool, const std::string&)>> + base::MockCallback<base::OnceCallback<void(int, const std::string&)>> mock_response_callback_; MockService* mock_native_service_ = nullptr; std::unique_ptr<LiteService> lite_service_; @@ -103,9 +105,9 @@ } TEST_F(LiteServiceTest, GetScriptsForUrl) { - EXPECT_CALL(mock_response_callback_, Run(true, _)) + EXPECT_CALL(mock_response_callback_, Run(net::HTTP_OK, _)) .Times(1) - .WillOnce([](bool success, const std::string& response) { + .WillOnce([](int http_status, const std::string& response) { SupportsScriptResponseProto proto; ASSERT_TRUE(proto.ParseFromString(response)); @@ -163,7 +165,7 @@ const std::string& global_payload, const std::string& script_payload, Service::ResponseCallback& callback) { - std::move(callback).Run(false, std::string()); + std::move(callback).Run(net::HTTP_UNAUTHORIZED, std::string()); }); EXPECT_CALL(mock_script_running_callback_, Run).Times(0); @@ -183,7 +185,7 @@ const std::string& global_payload, const std::string& script_payload, Service::ResponseCallback& callback) { - std::move(callback).Run(true, std::string("invalid proto")); + std::move(callback).Run(net::HTTP_OK, std::string("invalid proto")); }); EXPECT_CALL(mock_script_running_callback_, Run).Times(0); lite_service_->GetActions(kFakeScriptPath, GURL(kFakeUrl), @@ -206,7 +208,7 @@ TEST_F(LiteServiceTest, GetActionsSucceedsForMinimalViableScript) { get_actions_response_.add_actions()->mutable_prompt()->set_browse_mode(true); get_actions_response_.add_actions()->mutable_prompt(); - EXPECT_CALL(mock_response_callback_, Run(true, _)); + EXPECT_CALL(mock_response_callback_, Run(net::HTTP_OK, _)); EXPECT_CALL(mock_script_running_callback_, Run(/*ui_shown =*/false)).Times(1); lite_service_->GetActions(kFakeScriptPath, GURL(kFakeUrl), TriggerContextImpl(), "", "", @@ -233,9 +235,9 @@ } std::vector<ProcessedActionProto> processed_actions; - EXPECT_CALL(mock_response_callback_, Run(true, _)) + EXPECT_CALL(mock_response_callback_, Run(net::HTTP_OK, _)) .Times(1) - .WillOnce([&](bool result, const std::string& response) { + .WillOnce([&](int http_status, const std::string& response) { // Can't directly compare the protos here, because the lite service // will have automatically assigned unique payloads to prompts. ActionsResponseProto proto; @@ -269,9 +271,9 @@ TriggerContextImpl(), "", "", mock_response_callback_.Get()); - EXPECT_CALL(mock_response_callback_, Run(true, _)) + EXPECT_CALL(mock_response_callback_, Run(net::HTTP_OK, _)) .Times(1) - .WillOnce([&](bool result, const std::string& response) { + .WillOnce([&](int http_result, const std::string& response) { ActionsResponseProto proto; ASSERT_TRUE(proto.ParseFromString(response)); ASSERT_TRUE(proto.actions().size() == 1); @@ -314,7 +316,7 @@ processed_actions.back().mutable_prompt_choice()->set_server_payload( "payload"); - EXPECT_CALL(mock_response_callback_, Run(true, "")); + EXPECT_CALL(mock_response_callback_, Run(net::HTTP_OK, "")); EXPECT_CALL(mock_script_running_callback_, Run(/*ui_shown =*/true)).Times(1); lite_service_->GetNextActions(TriggerContextImpl(), "", "", processed_actions, RoundtripTimingStats(), @@ -334,7 +336,7 @@ processed_actions.back().mutable_prompt_choice()->set_server_payload( "payload"); - EXPECT_CALL(mock_response_callback_, Run(true, "")).Times(1); + EXPECT_CALL(mock_response_callback_, Run(net::HTTP_OK, "")).Times(1); lite_service_->GetNextActions(TriggerContextImpl(), "", "", processed_actions, RoundtripTimingStats(), mock_response_callback_.Get());
diff --git a/components/autofill_assistant/browser/service/mock_access_token_fetcher.cc b/components/autofill_assistant/browser/service/mock_access_token_fetcher.cc new file mode 100644 index 0000000..a724f6b56 --- /dev/null +++ b/components/autofill_assistant/browser/service/mock_access_token_fetcher.cc
@@ -0,0 +1,12 @@ +// 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/autofill_assistant/browser/service/mock_access_token_fetcher.h" + +namespace autofill_assistant { + +MockAccessTokenFetcher::MockAccessTokenFetcher() = default; +MockAccessTokenFetcher::~MockAccessTokenFetcher() = default; + +} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/mock_access_token_fetcher.h b/components/autofill_assistant/browser/service/mock_access_token_fetcher.h new file mode 100644 index 0000000..7f3b640c --- /dev/null +++ b/components/autofill_assistant/browser/service/mock_access_token_fetcher.h
@@ -0,0 +1,35 @@ +// 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_AUTOFILL_ASSISTANT_BROWSER_SERVICE_MOCK_ACCESS_TOKEN_FETCHER_H_ +#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SERVICE_MOCK_ACCESS_TOKEN_FETCHER_H_ + +#include <string> + +#include "base/callback.h" +#include "components/autofill_assistant/browser/service/access_token_fetcher.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace autofill_assistant { + +class MockAccessTokenFetcher : public AccessTokenFetcher { + public: + MockAccessTokenFetcher(); + ~MockAccessTokenFetcher() override; + + void FetchAccessToken( + base::OnceCallback<void(bool, const std::string&)> callback) override { + OnFetchAccessToken(callback); + } + + MOCK_METHOD1( + OnFetchAccessToken, + void(base::OnceCallback<void(bool, const std::string&)>& callback)); + + MOCK_METHOD1(InvalidateAccessToken, void(const std::string& access_token)); +}; + +} // namespace autofill_assistant + +#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SERVICE_MOCK_ACCESS_TOKEN_FETCHER_H_
diff --git a/components/autofill_assistant/browser/service/mock_service.cc b/components/autofill_assistant/browser/service/mock_service.cc index d9dbd56e..0b6ce7b 100644 --- a/components/autofill_assistant/browser/service/mock_service.cc +++ b/components/autofill_assistant/browser/service/mock_service.cc
@@ -11,13 +11,10 @@ namespace autofill_assistant { MockService::MockService() - : ServiceImpl(std::string("api_key"), - GURL("http://fake"), - GURL("http://fake"), - nullptr, - nullptr, - nullptr, - true) {} + : ServiceImpl(/* request_sender = */ nullptr, + /* script_server_url = */ GURL("http://fake"), + /* action_server_url = */ GURL("http://fake"), + /* client_context = */ nullptr) {} MockService::~MockService() {} } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/mock_service_request_sender.cc b/components/autofill_assistant/browser/service/mock_service_request_sender.cc new file mode 100644 index 0000000..3c29d38c --- /dev/null +++ b/components/autofill_assistant/browser/service/mock_service_request_sender.cc
@@ -0,0 +1,18 @@ +// 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/autofill_assistant/browser/service/mock_service_request_sender.h" + +namespace autofill_assistant { + +MockServiceRequestSender::MockServiceRequestSender() + : ServiceRequestSender(/* context = */ nullptr, + /* access_token_fetcher = */ nullptr, + /* loader_factory = */ nullptr, + /* api_key = */ std::string("fake_api_key"), + /* auth_enabled = */ false, + /* disable_auth_if_no_access_token = */ true) {} +MockServiceRequestSender::~MockServiceRequestSender() = default; + +} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/mock_service_request_sender.h b/components/autofill_assistant/browser/service/mock_service_request_sender.h new file mode 100644 index 0000000..2911f6f9 --- /dev/null +++ b/components/autofill_assistant/browser/service/mock_service_request_sender.h
@@ -0,0 +1,35 @@ +// 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_AUTOFILL_ASSISTANT_BROWSER_SERVICE_MOCK_SERVICE_REQUEST_SENDER_H_ +#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SERVICE_MOCK_SERVICE_REQUEST_SENDER_H_ + +#include <string> + +#include "components/autofill_assistant/browser/service/service_request_sender.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "url/gurl.h" + +namespace autofill_assistant { + +class MockServiceRequestSender : public ServiceRequestSender { + public: + MockServiceRequestSender(); + ~MockServiceRequestSender() override; + + void SendRequest(const GURL& url, + const std::string& request_body, + ResponseCallback callback) override { + OnSendRequest(url, request_body, callback); + } + + MOCK_METHOD3(OnSendRequest, + void(const GURL& url, + const std::string& request_body, + ResponseCallback& callback)); +}; + +} // namespace autofill_assistant + +#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SERVICE_MOCK_SERVICE_REQUEST_SENDER_H_
diff --git a/components/autofill_assistant/browser/service/mock_simple_url_loader_factory.cc b/components/autofill_assistant/browser/service/mock_simple_url_loader_factory.cc new file mode 100644 index 0000000..10fd7fb8 --- /dev/null +++ b/components/autofill_assistant/browser/service/mock_simple_url_loader_factory.cc
@@ -0,0 +1,12 @@ +// 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/autofill_assistant/browser/service/mock_simple_url_loader_factory.h" + +namespace autofill_assistant { + +MockSimpleURLLoaderFactory::MockSimpleURLLoaderFactory() = default; +MockSimpleURLLoaderFactory::~MockSimpleURLLoaderFactory() = default; + +} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/mock_simple_url_loader_factory.h b/components/autofill_assistant/browser/service/mock_simple_url_loader_factory.h new file mode 100644 index 0000000..9890af3 --- /dev/null +++ b/components/autofill_assistant/browser/service/mock_simple_url_loader_factory.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_AUTOFILL_ASSISTANT_BROWSER_SERVICE_MOCK_SIMPLE_URL_LOADER_FACTORY_H_ +#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SERVICE_MOCK_SIMPLE_URL_LOADER_FACTORY_H_ + +#include <memory> + +#include "components/autofill_assistant/browser/service/simple_url_loader_factory.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "services/network/public/cpp/resource_request.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace autofill_assistant { + +class MockSimpleURLLoaderFactory : public SimpleURLLoaderFactory { + public: + MockSimpleURLLoaderFactory(); + ~MockSimpleURLLoaderFactory() override; + + std::unique_ptr<::network::SimpleURLLoader> CreateLoader( + std::unique_ptr<::network::ResourceRequest> resource_request, + const ::net::NetworkTrafficAnnotationTag& annotation_tag) const override { + return OnCreateLoader(resource_request.get(), annotation_tag); + } + + MOCK_CONST_METHOD2( + OnCreateLoader, + std::unique_ptr<::network::SimpleURLLoader>( + ::network::ResourceRequest* resource_request, + const ::net::NetworkTrafficAnnotationTag& annotation_tag)); +}; + +} // namespace autofill_assistant + +#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SERVICE_MOCK_SIMPLE_URL_LOADER_FACTORY_H_
diff --git a/components/autofill_assistant/browser/service/mock_url_loader.cc b/components/autofill_assistant/browser/service/mock_url_loader.cc new file mode 100644 index 0000000..5d5bd0f --- /dev/null +++ b/components/autofill_assistant/browser/service/mock_url_loader.cc
@@ -0,0 +1,12 @@ +// 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/autofill_assistant/browser/service/mock_url_loader.h" + +namespace autofill_assistant { + +MockURLLoader::MockURLLoader() = default; +MockURLLoader::~MockURLLoader() = default; + +} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/mock_url_loader.h b/components/autofill_assistant/browser/service/mock_url_loader.h new file mode 100644 index 0000000..7dd7fea0 --- /dev/null +++ b/components/autofill_assistant/browser/service/mock_url_loader.h
@@ -0,0 +1,84 @@ +// 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_AUTOFILL_ASSISTANT_BROWSER_SERVICE_MOCK_URL_LOADER_H_ +#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SERVICE_MOCK_URL_LOADER_H_ + +#include "components/autofill_assistant/browser/service/service_request_sender.h" +#include "services/network/public/cpp/simple_url_loader.h" + +#include "testing/gmock/include/gmock/gmock.h" + +namespace network { +namespace mojom { +class URLLoaderFactory; +} // namespace mojom +} // namespace network + +namespace autofill_assistant { + +// TODO(arbesser): Remove this once we pass in the mojom interface to our +// service, instead of the SimpleURLLoader. +class MockURLLoader : public ::network::SimpleURLLoader { + public: + MockURLLoader(); + ~MockURLLoader() override; + MOCK_METHOD3(DownloadToString, + void(::network::mojom::URLLoaderFactory* url_loader_factory, + BodyAsStringCallback body_as_string_callback, + size_t max_body_size)); + MOCK_METHOD2(DownloadToStringOfUnboundedSizeUntilCrashAndDie, + void(::network::mojom::URLLoaderFactory* url_loader_factory, + BodyAsStringCallback body_as_string_callback)); + MOCK_METHOD2(DownloadHeadersOnly, + void(::network::mojom::URLLoaderFactory* url_loader_factory, + HeadersOnlyCallback headers_only_callback)); + MOCK_METHOD4( + DownloadToFile, + void(::network::mojom::URLLoaderFactory* url_loader_factory, + DownloadToFileCompleteCallback download_to_file_complete_callback, + const base::FilePath& file_path, + int64_t max_body_size)); + MOCK_METHOD3( + DownloadToTempFile, + void(::network::mojom::URLLoaderFactory* url_loader_factory, + DownloadToFileCompleteCallback download_to_file_complete_callback, + int64_t max_body_size)); + MOCK_METHOD2(DownloadAsStream, + void(::network::mojom::URLLoaderFactory* url_loader_factory, + ::network::SimpleURLLoaderStreamConsumer* stream_consumer)); + MOCK_METHOD1(SetOnRedirectCallback, + void(const OnRedirectCallback& on_redirect_callback)); + MOCK_METHOD1(SetOnResponseStartedCallback, + void(OnResponseStartedCallback on_response_started_callback)); + MOCK_METHOD1(SetOnUploadProgressCallback, + void(UploadProgressCallback on_upload_progress_callback)); + MOCK_METHOD1(SetOnDownloadProgressCallback, + void(DownloadProgressCallback on_download_progress_callback)); + MOCK_METHOD1(SetAllowPartialResults, void(bool allow_partial_results)); + MOCK_METHOD1(SetAllowHttpErrorResults, void(bool allow_http_error_results)); + MOCK_METHOD2(AttachStringForUpload, + void(const std::string& upload_data, + const std::string& upload_content_type)); + MOCK_METHOD4(AttachFileForUpload, + void(const base::FilePath& upload_file_path, + const std::string& upload_content_type, + uint64_t offset, + uint64_t length)); + MOCK_METHOD2(SetRetryOptions, void(int max_retries, int retry_mode)); + MOCK_METHOD1(SetURLLoaderFactoryOptions, void(uint32_t options)); + MOCK_METHOD1(SetRequestID, void(int32_t request_id)); + MOCK_METHOD1(SetTimeoutDuration, void(base::TimeDelta timeout_duration)); + MOCK_CONST_METHOD0(NetError, int()); + MOCK_CONST_METHOD0(ResponseInfo, const ::network::mojom::URLResponseHead*()); + MOCK_CONST_METHOD0(CompletionStatus, + base::Optional<::network::URLLoaderCompletionStatus>&()); + MOCK_CONST_METHOD0(GetFinalURL, const GURL&()); + MOCK_CONST_METHOD0(LoadedFromCache, bool()); + MOCK_CONST_METHOD0(GetContentSize, int64_t()); +}; + +} // namespace autofill_assistant + +#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SERVICE_MOCK_URL_LOADER_H_
diff --git a/components/autofill_assistant/browser/service/service.h b/components/autofill_assistant/browser/service/service.h index 611aae16..ca413cf 100644 --- a/components/autofill_assistant/browser/service/service.h +++ b/components/autofill_assistant/browser/service/service.h
@@ -27,7 +27,7 @@ virtual bool IsLiteService() const = 0; using ResponseCallback = - base::OnceCallback<void(bool result, const std::string&)>; + base::OnceCallback<void(int http_status, const std::string&)>; // Get scripts for a given |url|, which should be a valid URL. virtual void GetScriptsForUrl(const GURL& url, const TriggerContext& trigger_context,
diff --git a/components/autofill_assistant/browser/service/service_impl.cc b/components/autofill_assistant/browser/service/service_impl.cc index 1542d159..8302dee 100644 --- a/components/autofill_assistant/browser/service/service_impl.cc +++ b/components/autofill_assistant/browser/service/service_impl.cc
@@ -25,59 +25,35 @@ #include "net/traffic_annotation/network_traffic_annotation.h" namespace autofill_assistant { -namespace { - -net::NetworkTrafficAnnotationTag traffic_annotation = - net::DefineNetworkTrafficAnnotation("autofill_service", R"( - semantics { - sender: "Autofill Assistant" - description: - "Chromium posts requests to autofill assistant server to get - scripts for a URL." - trigger: - "Matching URL." - data: "None." - destination: GOOGLE_OWNED_SERVICE - } - policy { - cookies_allowed: NO - setting: - "This feature can be disabled in settings." - policy_exception_justification: "Not implemented." - })"); - -} // namespace // static std::unique_ptr<ServiceImpl> ServiceImpl::Create( content::BrowserContext* context, Client* client) { ServerUrlFetcher url_fetcher{ServerUrlFetcher::GetDefaultServerUrl()}; - return std::make_unique<ServiceImpl>( + auto request_sender = std::make_unique<ServiceRequestSender>( + context, client->GetAccessTokenFetcher(), + std::make_unique<NativeURLLoaderFactory>(), ApiKeyFetcher().GetAPIKey(client->GetChannel()), - url_fetcher.GetSupportsScriptEndpoint(), - url_fetcher.GetNextActionsEndpoint(), context, - std::make_unique<ClientContextImpl>(client), - client->GetAccessTokenFetcher(), /* auth_enabled = */ "false" != base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - switches::kAutofillAssistantAuth)); + switches::kAutofillAssistantAuth), + /* disable_auth_if_no_access_token = */ true); + + return std::make_unique<ServiceImpl>( + std::move(request_sender), url_fetcher.GetSupportsScriptEndpoint(), + url_fetcher.GetNextActionsEndpoint(), + std::make_unique<ClientContextImpl>(client)); } -ServiceImpl::ServiceImpl(const std::string& api_key, +ServiceImpl::ServiceImpl(std::unique_ptr<ServiceRequestSender> request_sender, const GURL& script_server_url, const GURL& action_server_url, - content::BrowserContext* context, - std::unique_ptr<ClientContext> client_context, - AccessTokenFetcher* access_token_fetcher, - bool auth_enabled) - : context_(context), + std::unique_ptr<ClientContext> client_context) + : request_sender_(std::move(request_sender)), script_server_url_(script_server_url), script_action_server_url_(action_server_url), - api_key_(api_key), - client_context_(std::move(client_context)), - access_token_fetcher_(access_token_fetcher), - auth_enabled_(auth_enabled) { + client_context_(std::move(client_context)) { DCHECK(script_server_url.is_valid()); DCHECK(action_server_url.is_valid()); } @@ -88,13 +64,12 @@ const TriggerContext& trigger_context, ResponseCallback callback) { DCHECK(url.is_valid()); - client_context_->Update(trigger_context); - SendRequest(AddLoader( + request_sender_->SendRequest( script_server_url_, ProtocolUtils::CreateGetScriptsRequest(url, client_context_->AsProto(), trigger_context.GetParameters()), - std::move(callback))); + std::move(callback)); } bool ServiceImpl::IsLiteService() const { @@ -108,14 +83,13 @@ const std::string& script_payload, ResponseCallback callback) { DCHECK(!script_path.empty()); - client_context_->Update(trigger_context); - SendRequest(AddLoader( + request_sender_->SendRequest( script_action_server_url_, ProtocolUtils::CreateInitialScriptActionsRequest( script_path, url, global_payload, script_payload, client_context_->AsProto(), trigger_context.GetParameters()), - std::move(callback))); + std::move(callback)); } void ServiceImpl::GetNextActions( @@ -126,147 +100,12 @@ const RoundtripTimingStats& timing_stats, ResponseCallback callback) { client_context_->Update(trigger_context); - SendRequest(AddLoader( + request_sender_->SendRequest( script_action_server_url_, ProtocolUtils::CreateNextScriptActionsRequest( previous_global_payload, previous_script_payload, processed_actions, timing_stats, client_context_->AsProto()), - std::move(callback))); -} - -void ServiceImpl::SendRequest(Loader* loader) { - if (access_token_.empty() && auth_enabled_) { - // Trigger a fetch of the access token. All loaders in loaders_ will be - // started later on, the access token is available. - FetchAccessToken(); - return; - } - - StartLoader(loader); -} - -ServiceImpl::Loader::Loader() : retried_with_fresh_access_token(false) {} -ServiceImpl::Loader::~Loader() {} - -ServiceImpl::Loader* ServiceImpl::AddLoader(const GURL& url, - const std::string& request_body, - ResponseCallback callback) { - std::unique_ptr<Loader> loader = std::make_unique<Loader>(); - loader->url = url; - loader->request_body = request_body; - loader->callback = std::move(callback); - Loader* loader_ptr = loader.get(); - loaders_[loader_ptr] = std::move(loader); - return loader_ptr; -} - -void ServiceImpl::StartLoader(Loader* loader) { - if (loader->loader) - return; - - auto resource_request = std::make_unique<::network::ResourceRequest>(); - resource_request->method = "POST"; - resource_request->redirect_mode = ::network::mojom::RedirectMode::kError; - resource_request->credentials_mode = ::network::mojom::CredentialsMode::kOmit; - if (access_token_.empty()) { - std::string query_str = base::StrCat({"key=", api_key_}); - // query_str must remain valid until ReplaceComponents() has returned. - url::StringPieceReplacements<std::string> add_key; - add_key.SetQueryStr(query_str); - resource_request->url = loader->url.ReplaceComponents(add_key); - } else { - resource_request->url = loader->url; - resource_request->headers.SetHeader( - "Authorization", base::StrCat({"Bearer ", access_token_})); - } - - loader->loader = ::network::SimpleURLLoader::Create( - std::move(resource_request), traffic_annotation); - loader->loader->AttachStringForUpload(loader->request_body, - "application/x-protobuffer"); -#ifdef DEBUG - loader->loader->SetAllowHttpErrorResults(true); -#endif - loader->loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( - content::BrowserContext::GetDefaultStoragePartition(context_) - ->GetURLLoaderFactoryForBrowserProcess() - .get(), - base::BindOnce(&ServiceImpl::OnURLLoaderComplete, base::Unretained(this), - loader)); -} - -void ServiceImpl::OnURLLoaderComplete( - Loader* loader, - std::unique_ptr<std::string> response_body) { - auto loader_it = loaders_.find(loader); - DCHECK(loader_it != loaders_.end()); - - int response_code = 0; - if (loader->loader->ResponseInfo() && - loader->loader->ResponseInfo()->headers) { - response_code = loader->loader->ResponseInfo()->headers->response_code(); - } - - // When getting a 401, refresh the auth token - but only try this once. - if (response_code == 401 && auth_enabled_ && !access_token_.empty() && - !loader->retried_with_fresh_access_token) { - loader->retried_with_fresh_access_token = true; - loader->loader.reset(); - // Invalidate access token and load a new one. - access_token_fetcher_->InvalidateAccessToken(access_token_); - access_token_.clear(); - SendRequest(loader); - return; - } - - // Take ownership of loader. - std::unique_ptr<Loader> loader_instance = std::move(loader_it->second); - loaders_.erase(loader_it); - DCHECK(loader_instance); - - std::string response_body_str; - if (loader_instance->loader->NetError() != net::OK || response_code != 200) { - LOG(ERROR) << "Communicating with autofill assistant server error NetError=" - << loader_instance->loader->NetError() - << " response_code=" << response_code << " message=" - << (response_body == nullptr ? "" : *response_body); - // TODO(crbug.com/806868): Pass an enum to be able to distinguish errors - // downstream. Also introduce a metric for this. - std::move(loader_instance->callback).Run(false, response_body_str); - return; - } - - if (response_body) - response_body_str = std::move(*response_body); - std::move(loader_instance->callback).Run(true, response_body_str); -} - -void ServiceImpl::FetchAccessToken() { - if (fetching_token_) - return; - - fetching_token_ = true; - access_token_fetcher_->FetchAccessToken(base::BindOnce( - &ServiceImpl::OnFetchAccessToken, weak_ptr_factory_.GetWeakPtr())); -} - -void ServiceImpl::OnFetchAccessToken(bool success, - const std::string& access_token) { - fetching_token_ = false; - - if (!success) { - auth_enabled_ = false; - // Give up on authentication for this run. Let the pending requests through, - // which might be rejected, depending on the server configuration. - return; - } - - access_token_ = access_token; - - // Start any pending requests with the access token. - for (const auto& entry : loaders_) { - StartLoader(entry.first); - } + std::move(callback)); } } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/service_impl.h b/components/autofill_assistant/browser/service/service_impl.h index ff8a208..64b53f2 100644 --- a/components/autofill_assistant/browser/service/service_impl.h +++ b/components/autofill_assistant/browser/service/service_impl.h
@@ -17,6 +17,7 @@ #include "components/autofill_assistant/browser/service.pb.h" #include "components/autofill_assistant/browser/service/access_token_fetcher.h" #include "components/autofill_assistant/browser/service/service.h" +#include "components/autofill_assistant/browser/service/service_request_sender.h" #include "components/signin/public/identity_manager/access_token_fetcher.h" #include "google_apis/gaia/google_service_auth_error.h" #include "services/network/public/cpp/simple_url_loader.h" @@ -43,15 +44,12 @@ bool IsLiteService() const override; - // |context| and |access_token_fetcher| must remain valid for the lifetime of - // the service instance. - ServiceImpl(const std::string& api_key, + ServiceImpl(std::unique_ptr<ServiceRequestSender> request_sender, const GURL& script_server_url, const GURL& action_server_url, - content::BrowserContext* context, - std::unique_ptr<ClientContext> client_context, - AccessTokenFetcher* access_token_fetcher, - bool auth_enabled); + std::unique_ptr<ClientContext> client_context); + ServiceImpl(const ServiceImpl&) = delete; + ServiceImpl& operator=(const ServiceImpl&) = delete; ~ServiceImpl() override; // Get scripts for a given |url|, which should be a valid URL. @@ -78,69 +76,17 @@ ResponseCallback callback) override; private: - friend class ServiceImplTest; + // The request sender responsible for communicating with a remote endpoint. + std::unique_ptr<ServiceRequestSender> request_sender_; - // Struct to store scripts and actions request. - struct Loader { - Loader(); - ~Loader(); - - GURL url; - std::string request_body; - ResponseCallback callback; - std::unique_ptr<::network::SimpleURLLoader> loader; - bool retried_with_fresh_access_token; - }; - - void SendRequest(Loader* loader); - - // Creates a loader and adds it to |loaders_|. - Loader* AddLoader(const GURL& url, - const std::string& request_body, - ResponseCallback callback); - - // Sends a request with the given loader, using the current auth token, if one - // is available. - void StartLoader(Loader* loader); - void OnURLLoaderComplete(Loader* loader, - std::unique_ptr<std::string> response_body); - - // Fetches the access token and, once this is done, starts all pending loaders - // in |loaders_|. - void FetchAccessToken(); - void OnFetchAccessToken(bool success, const std::string& access_token); - - content::BrowserContext* context_; + // The RPC endpoints to send requests to. GURL script_server_url_; GURL script_action_server_url_; - // Destroying this object will cancel ongoing requests. - std::map<Loader*, std::unique_ptr<Loader>> loaders_; - - // API key to add to the URL of unauthenticated requests. - std::string api_key_; - // The client context to send to the backend. std::unique_ptr<ClientContext> client_context_; - // Pointer must remain valid for the lifetime of the Service instance. - AccessTokenFetcher* access_token_fetcher_; - - // True while waiting for a response from AccessTokenFetcher. - bool fetching_token_ = false; - - // Whether requests should be authenticated. - bool auth_enabled_ = true; - - // An OAuth 2 token. Empty if not fetched yet or if the token has been - // invalidated. - std::string access_token_; - base::WeakPtrFactory<ServiceImpl> weak_ptr_factory_{this}; - - FRIEND_TEST_ALL_PREFIXES(ServiceImplTestSignedInStatus, SetsSignedInStatus); - - DISALLOW_COPY_AND_ASSIGN(ServiceImpl); }; } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/service_impl_unittest.cc b/components/autofill_assistant/browser/service/service_impl_unittest.cc new file mode 100644 index 0000000..c95f4637 --- /dev/null +++ b/components/autofill_assistant/browser/service/service_impl_unittest.cc
@@ -0,0 +1,101 @@ +// 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/autofill_assistant/browser/service/service_impl.h" + +#include "components/autofill_assistant/browser/mock_client_context.h" +#include "components/autofill_assistant/browser/service/mock_service_request_sender.h" +#include "components/autofill_assistant/browser/service/service.h" + +#include "base/test/gmock_callback_support.h" +#include "base/test/mock_callback.h" +#include "net/http/http_status_code.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace autofill_assistant { + +using ::base::test::RunOnceCallback; +using ::testing::_; +using ::testing::NiceMock; +using ::testing::Return; + +namespace { + +const char kScriptServerUrl[] = "https://www.fake.backend.com/script_server"; +const char kActionServerUrl[] = "https://www.fake.backend.com/action_server"; + +class ServiceImplTest : public testing::Test { + public: + ServiceImplTest() { + auto mock_client_context = std::make_unique<NiceMock<MockClientContext>>(); + mock_client_context_ = mock_client_context.get(); + + auto mock_request_sender = + std::make_unique<NiceMock<MockServiceRequestSender>>(); + mock_request_sender_ = mock_request_sender.get(); + + service_ = std::make_unique<ServiceImpl>( + std::move(mock_request_sender), GURL(kScriptServerUrl), + GURL(kActionServerUrl), std::move(mock_client_context)); + } + ~ServiceImplTest() override = default; + + protected: + base::MockCallback<Service::ResponseCallback> mock_response_callback_; + NiceMock<MockClientContext>* mock_client_context_; + NiceMock<MockServiceRequestSender>* mock_request_sender_; + std::unique_ptr<ServiceImpl> service_; +}; + +TEST_F(ServiceImplTest, GetScriptsForUrl) { + EXPECT_CALL(*mock_client_context_, Update).Times(1); + // TODO(b/158998456), here and in other tests of service_impl: check that + // protocol utils is called with the correct parameters. + EXPECT_CALL(*mock_request_sender_, + OnSendRequest(GURL(kScriptServerUrl), _, _)) + .WillOnce(RunOnceCallback<2>(net::HTTP_OK, std::string("response"))); + EXPECT_CALL(mock_response_callback_, + Run(net::HTTP_OK, std::string("response"))) + .Times(1); + + TriggerContextImpl trigger_context; + service_->GetScriptsForUrl(GURL("https://www.example.com"), trigger_context, + mock_response_callback_.Get()); +} + +TEST_F(ServiceImplTest, GetActions) { + EXPECT_CALL(*mock_client_context_, Update).Times(1); + EXPECT_CALL(*mock_request_sender_, + OnSendRequest(GURL(kActionServerUrl), _, _)) + .WillOnce(RunOnceCallback<2>(net::HTTP_OK, std::string("response"))); + EXPECT_CALL(mock_response_callback_, + Run(net::HTTP_OK, std::string("response"))) + .Times(1); + + TriggerContextImpl trigger_context; + service_->GetActions( + std::string("fake_script_path"), GURL("https://www.example.com"), + trigger_context, std::string("fake_global_payload"), + std::string("fake_script_payload"), mock_response_callback_.Get()); +} + +TEST_F(ServiceImplTest, GetNextActions) { + EXPECT_CALL(*mock_client_context_, Update).Times(1); + EXPECT_CALL(*mock_request_sender_, + OnSendRequest(GURL(kActionServerUrl), _, _)) + .WillOnce(RunOnceCallback<2>(net::HTTP_OK, std::string("response"))); + EXPECT_CALL(mock_response_callback_, + Run(net::HTTP_OK, std::string("response"))) + .Times(1); + + TriggerContextImpl trigger_context; + service_->GetNextActions( + trigger_context, std::string("fake_previous_global_payload"), + std::string("fake_previous_script_payload"), /* processed_actions = */ {}, + /* timing_stats = */ RoundtripTimingStats(), + mock_response_callback_.Get()); +} + +} // namespace +} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/service_request_sender.cc b/components/autofill_assistant/browser/service/service_request_sender.cc new file mode 100644 index 0000000..4009e7ef --- /dev/null +++ b/components/autofill_assistant/browser/service/service_request_sender.cc
@@ -0,0 +1,211 @@ +// 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/autofill_assistant/browser/service/service_request_sender.h" + +#include "base/strings/strcat.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/storage_partition.h" +#include "net/base/load_flags.h" +#include "net/http/http_request_headers.h" +#include "net/http/http_status_code.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/simple_url_loader.h" + +namespace { + +constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation = + net::DefineNetworkTrafficAnnotation("autofill_service", R"( + semantics { + sender: "Autofill Assistant" + description: + "Chromium posts requests to autofill assistant server to get + scripts for a URL." + trigger: + "Matching URL." + data: "None." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: NO + setting: + "This feature can be disabled in settings." + policy_exception_justification: "Not implemented." + })"); + +void OnURLLoaderComplete( + autofill_assistant::ServiceRequestSender::ResponseCallback callback, + std::unique_ptr<::network::SimpleURLLoader> loader, + std::unique_ptr<std::string> response_body) { + std::string response_str; + if (response_body != nullptr) { + response_str = std::move(*response_body); + } + + int response_code = 0; + if (loader->ResponseInfo() && loader->ResponseInfo()->headers) { + response_code = loader->ResponseInfo()->headers->response_code(); + } + std::move(callback).Run(response_code, response_str); +} + +std::unique_ptr<::network::ResourceRequest> CreateResourceRequest(GURL url) { + auto resource_request = std::make_unique<::network::ResourceRequest>(); + resource_request->url = url; + resource_request->method = "POST"; + resource_request->redirect_mode = ::network::mojom::RedirectMode::kError; + resource_request->credentials_mode = ::network::mojom::CredentialsMode::kOmit; + return resource_request; +} + +void SendRequestImpl( + std::unique_ptr<::network::ResourceRequest> request, + const std::string& request_body, + content::BrowserContext* context, + autofill_assistant::SimpleURLLoaderFactory* loader_factory, + autofill_assistant::ServiceRequestSender::ResponseCallback callback) { + auto loader = + loader_factory->CreateLoader(std::move(request), kTrafficAnnotation); + loader->AttachStringForUpload(request_body, "application/x-protobuffer"); +#ifdef DEBUG + loader->SetAllowHttpErrorResults(true); +#endif + loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + content::BrowserContext::GetDefaultStoragePartition(context) + ->GetURLLoaderFactoryForBrowserProcess() + .get(), + base::BindOnce(&OnURLLoaderComplete, std::move(callback), + std::move(loader))); +} + +void SendRequestNoAuth( + const GURL& url, + const std::string& request_body, + content::BrowserContext* context, + autofill_assistant::SimpleURLLoaderFactory* loader_factory, + const std::string& api_key, + autofill_assistant::ServiceRequestSender::ResponseCallback callback) { + if (callback.IsCancelled()) { + return; + } + if (api_key.empty()) { + LOG(ERROR) << "no api key provided"; + std::move(callback).Run(net::HTTP_UNAUTHORIZED, std::string()); + return; + } + + std::string query_str = base::StrCat({"key=", api_key}); + // query_str must remain valid until ReplaceComponents() has returned. + url::StringPieceReplacements<std::string> add_key; + add_key.SetQueryStr(query_str); + GURL modified_url = url.ReplaceComponents(add_key); + + SendRequestImpl(CreateResourceRequest(modified_url), request_body, context, + loader_factory, std::move(callback)); +} + +} // namespace + +namespace autofill_assistant { + +ServiceRequestSender::ServiceRequestSender( + content::BrowserContext* context, + AccessTokenFetcher* access_token_fetcher, + std::unique_ptr<SimpleURLLoaderFactory> loader_factory, + const std::string& api_key, + bool auth_enabled, + bool disable_auth_if_no_access_token) + : context_(context), + access_token_fetcher_(access_token_fetcher), + loader_factory_(std::move(loader_factory)), + api_key_(api_key), + auth_enabled_(auth_enabled), + disable_auth_if_no_access_token_(disable_auth_if_no_access_token) { + DCHECK(!auth_enabled || access_token_fetcher != nullptr); + DCHECK(auth_enabled || !api_key.empty()); +} +ServiceRequestSender::~ServiceRequestSender() = default; + +void ServiceRequestSender::SendRequest(const GURL& url, + const std::string& request_body, + ResponseCallback callback) { + if (auth_enabled_ && access_token_fetcher_ == nullptr) { + LOG(ERROR) << "auth requested, but no access token fetcher provided"; + std::move(callback).Run(net::HTTP_UNAUTHORIZED, std::string()); + return; + } + if (auth_enabled_) { + access_token_fetcher_->FetchAccessToken( + base::BindOnce(&ServiceRequestSender::OnFetchAccessToken, + weak_ptr_factory_.GetWeakPtr(), url, request_body, + std::move(callback))); + return; + } + + SendRequestNoAuth(url, request_body, context_, loader_factory_.get(), + api_key_, std::move(callback)); +} + +void ServiceRequestSender::OnFetchAccessToken(GURL url, + std::string request_body, + ResponseCallback callback, + bool access_token_fetched, + const std::string& access_token) { + if (!access_token_fetched) { + if (disable_auth_if_no_access_token_) { + // Give up on authentication for this run. Without access token, requests + // might be successful or rejected, depending on the server configuration. + auth_enabled_ = false; + SendRequestNoAuth(url, request_body, context_, loader_factory_.get(), + api_key_, std::move(callback)); + return; + } + VLOG(1) << "Failed to fetch access token, but " + "disable_auth_if_no_access_token not set"; + std::move(callback).Run(net::HTTP_UNAUTHORIZED, std::string()); + return; + } + + SendRequestAuth(url, request_body, access_token, std::move(callback)); +} + +void ServiceRequestSender::SendRequestAuth(const GURL& url, + const std::string& request_body, + const std::string& access_token, + ResponseCallback callback) { + if (callback.IsCancelled()) { + return; + } + auto resource_request = CreateResourceRequest(url); + resource_request->headers.SetHeader("Authorization", + base::StrCat({"Bearer ", access_token})); + + if (!retried_with_fresh_access_token_) { + callback = base::BindOnce(&ServiceRequestSender::RetryIfUnauthorized, + weak_ptr_factory_.GetWeakPtr(), url, access_token, + request_body, std::move(callback)); + } + SendRequestImpl(std::move(resource_request), request_body, context_, + loader_factory_.get(), std::move(callback)); +} + +void ServiceRequestSender::RetryIfUnauthorized(const GURL& url, + const std::string& access_token, + const std::string& request_body, + ResponseCallback callback, + int http_status, + const std::string& response) { + // On first UNAUTHORIZED error, invalidate access token and try again. + if (auth_enabled_ && http_status == net::HTTP_UNAUTHORIZED) { + DCHECK(!retried_with_fresh_access_token_); + retried_with_fresh_access_token_ = true; + access_token_fetcher_->InvalidateAccessToken(access_token); + SendRequest(url, request_body, std::move(callback)); + return; + } + std::move(callback).Run(http_status, response); +} + +} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/service_request_sender.h b/components/autofill_assistant/browser/service/service_request_sender.h new file mode 100644 index 0000000..7754e666 --- /dev/null +++ b/components/autofill_assistant/browser/service/service_request_sender.h
@@ -0,0 +1,93 @@ +// 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_AUTOFILL_ASSISTANT_BROWSER_SERVICE_SERVICE_REQUEST_SENDER_H_ +#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SERVICE_SERVICE_REQUEST_SENDER_H_ + +#include <memory> +#include <string> + +#include "base/callback.h" +#include "base/memory/weak_ptr.h" +#include "components/autofill_assistant/browser/service/access_token_fetcher.h" +#include "components/autofill_assistant/browser/service/simple_url_loader_factory.h" +#include "content/public/browser/browser_context.h" +#include "url/gurl.h" + +namespace content { +class BrowserContext; +} // namespace content + +namespace autofill_assistant { + +class ServiceRequestSender { + public: + using ResponseCallback = + base::OnceCallback<void(int http_status, const std::string& response)>; + + // Constructor. |access_token_fetcher| is optional if |auth_enabled| is false. + // Pointers to |context| and, if provided, |access_token_fetcher| must remain + // valid during the lifetime of this instance. + + // If |disable_auth_if_no_access_token| is true, authentication will + // automatically be disabled in case fetching the access token fails. + ServiceRequestSender(content::BrowserContext* context, + AccessTokenFetcher* access_token_fetcher, + std::unique_ptr<SimpleURLLoaderFactory> loader_factory, + const std::string& api_key, + bool auth_enabled, + bool disable_auth_if_no_access_token); + virtual ~ServiceRequestSender(); + ServiceRequestSender(const ServiceRequestSender&) = delete; + ServiceRequestSender& operator=(const ServiceRequestSender&) = delete; + + // Sends |request_body| to |url|. Depending on configuration, the request + // will be authenticated either with an Oauth access token or the api key. + // Returns the http status code and the response itself. If the returned http + // headers could not be parsed, the http code will be 0. + // + // When an auth-request first fails with a 401, the access token is + // invalidated and fetched again. If the request fails again, the request + // is considered failed and the callback is invoked. + virtual void SendRequest(const GURL& url, + const std::string& request_body, + ResponseCallback callback); + + private: + void SendRequestAuth(const GURL& url, + const std::string& request_body, + const std::string& access_token, + ResponseCallback callback); + + void RetryIfUnauthorized(const GURL& url, + const std::string& access_token, + const std::string& request_body, + ResponseCallback callback, + int http_status, + const std::string& response); + + void OnFetchAccessToken(GURL url, + std::string request_body, + ResponseCallback callback, + bool access_token_fetched, + const std::string& access_token); + + content::BrowserContext* context_ = nullptr; + AccessTokenFetcher* access_token_fetcher_ = nullptr; + std::unique_ptr<SimpleURLLoaderFactory> loader_factory_; + + // API key to add to the URL of unauthenticated requests. + std::string api_key_; + + // Whether requests should be authenticated. + bool auth_enabled_ = true; + + bool disable_auth_if_no_access_token_ = true; + bool retried_with_fresh_access_token_ = false; + base::WeakPtrFactory<ServiceRequestSender> weak_ptr_factory_{this}; +}; + +} // namespace autofill_assistant + +#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SERVICE_SERVICE_REQUEST_SENDER_H_
diff --git a/components/autofill_assistant/browser/service/service_request_sender_unittest.cc b/components/autofill_assistant/browser/service/service_request_sender_unittest.cc new file mode 100644 index 0000000..d6990e0 --- /dev/null +++ b/components/autofill_assistant/browser/service/service_request_sender_unittest.cc
@@ -0,0 +1,148 @@ +// 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/autofill_assistant/browser/service/service_request_sender.h" + +#include <memory> +#include <vector> + +#include "base/memory/scoped_refptr.h" +#include "base/strings/strcat.h" +#include "base/strings/string_number_conversions.h" +#include "base/test/gmock_callback_support.h" +#include "base/test/mock_callback.h" +#include "components/autofill_assistant/browser/service/access_token_fetcher.h" +#include "components/autofill_assistant/browser/service/mock_access_token_fetcher.h" +#include "components/autofill_assistant/browser/service/mock_simple_url_loader_factory.h" +#include "components/autofill_assistant/browser/service/mock_url_loader.h" +#include "content/public/test/browser_task_environment.h" +#include "content/public/test/test_browser_context.h" +#include "net/http/http_response_headers.h" +#include "net/http/http_status_code.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/simple_url_loader.h" +#include "services/network/public/mojom/url_response_head.mojom.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace autofill_assistant { + +using ::base::test::RunOnceCallback; +using ::testing::_; +using ::testing::NiceMock; +using ::testing::Return; +using ::testing::WithArgs; + +namespace { + +std::unique_ptr<::network::mojom::URLResponseHead> CreateResponseInfo( + int status_code, + const std::string& status) { + auto response = std::make_unique<::network::mojom::URLResponseHead>(); + response->headers = + base::MakeRefCounted<::net::HttpResponseHeaders>(base::StrCat( + {"HTTP/1.1 ", base::NumberToString(status_code), " ", status})); + return response; +} + +class ServiceRequestSenderTest : public testing::Test { + public: + ServiceRequestSenderTest() = default; + ~ServiceRequestSenderTest() override = default; + + protected: + base::MockCallback<base::OnceCallback<void(int, const std::string&)>> + mock_response_callback_; + // Note: |task_environment_| must be created before |context_|, else creation + // of |context_| will fail (see content/public/test/test_browser_context.cc). + content::BrowserTaskEnvironment task_environment_; + content::TestBrowserContext context_; + NiceMock<MockAccessTokenFetcher> mock_access_token_fetcher_; +}; + +TEST_F(ServiceRequestSenderTest, SendUnauthenticatedRequest) { + auto loader_factory = + std::make_unique<NiceMock<MockSimpleURLLoaderFactory>>(); + auto loader = std::make_unique<NiceMock<MockURLLoader>>(); + auto response_info = CreateResponseInfo(net::HTTP_OK, "OK"); + EXPECT_CALL(*loader_factory, OnCreateLoader(_, _)) + .WillOnce([&](::network::ResourceRequest* resource_request, + const ::net::NetworkTrafficAnnotationTag& annotation_tag) { + EXPECT_FALSE(resource_request->headers.HasHeader("Authorization")); + EXPECT_EQ(resource_request->url, + GURL("https://www.example.com/?key=fake_api_key")); + return std::move(loader); + }); + EXPECT_CALL(*loader, + AttachStringForUpload(std::string("request"), + std::string("application/x-protobuffer"))) + .Times(1); + EXPECT_CALL(*loader, DownloadToStringOfUnboundedSizeUntilCrashAndDie(_, _)) + .WillOnce(WithArgs<1>([&](auto&& callback) { + std::move(callback).Run(std::make_unique<std::string>("response")); + })); + EXPECT_CALL(*loader, ResponseInfo) + .WillRepeatedly(Return(response_info.get())); + + EXPECT_CALL(mock_response_callback_, Run(net::HTTP_OK, "response")); + ServiceRequestSender request_sender{ + &context_, + /* access_token_fetcher = */ nullptr, + std::move(loader_factory), + std::string("fake_api_key"), + /* auth_enabled = */ false, + /* disable_auth_if_no_access_token = */ true}; + request_sender.SendRequest(GURL("https://www.example.com"), + std::string("request"), + mock_response_callback_.Get()); +} + +TEST_F(ServiceRequestSenderTest, SendAuthenticatedRequest) { + auto loader_factory = + std::make_unique<NiceMock<MockSimpleURLLoaderFactory>>(); + auto loader = std::make_unique<NiceMock<MockURLLoader>>(); + auto response_info = CreateResponseInfo(net::HTTP_OK, "OK"); + EXPECT_CALL(*loader_factory, OnCreateLoader(_, _)) + .WillOnce([&](::network::ResourceRequest* resource_request, + const ::net::NetworkTrafficAnnotationTag& annotation_tag) { + std::string authorization; + EXPECT_TRUE(resource_request->headers.GetHeader("Authorization", + &authorization)); + EXPECT_EQ(authorization, "Bearer access_token"); + EXPECT_EQ(resource_request->url, GURL("https://www.example.com")); + return std::move(loader); + }); + EXPECT_CALL(*loader, + AttachStringForUpload(std::string("request"), + std::string("application/x-protobuffer"))) + .Times(1); + EXPECT_CALL(*loader, DownloadToStringOfUnboundedSizeUntilCrashAndDie(_, _)) + .WillOnce(WithArgs<1>([&](auto&& callback) { + std::move(callback).Run(std::make_unique<std::string>("response")); + })); + EXPECT_CALL(*loader, ResponseInfo) + .WillRepeatedly(Return(response_info.get())); + EXPECT_CALL(mock_access_token_fetcher_, OnFetchAccessToken) + .Times(1) + .WillOnce(RunOnceCallback<0>(true, "access_token")); + EXPECT_CALL(mock_access_token_fetcher_, InvalidateAccessToken).Times(0); + + EXPECT_CALL(mock_response_callback_, Run(net::HTTP_OK, "response")); + ServiceRequestSender request_sender{ + &context_, + /* access_token_fetcher = */ &mock_access_token_fetcher_, + std::move(loader_factory), + /* api_key = */ std::string(""), + /* auth_enabled = */ true, + /* disable_auth_if_no_access_token = */ true}; + request_sender.SendRequest(GURL("https://www.example.com"), + std::string("request"), + mock_response_callback_.Get()); +} + +// TODO(b/170934170): Add tests for full unit test coverage of +// service_request_sender. + +} // namespace +} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/simple_url_loader_factory.cc b/components/autofill_assistant/browser/service/simple_url_loader_factory.cc new file mode 100644 index 0000000..00a4c05 --- /dev/null +++ b/components/autofill_assistant/browser/service/simple_url_loader_factory.cc
@@ -0,0 +1,17 @@ +// 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/autofill_assistant/browser/service/simple_url_loader_factory.h" + +namespace autofill_assistant { + +std::unique_ptr<::network::SimpleURLLoader> +NativeURLLoaderFactory::CreateLoader( + std::unique_ptr<::network::ResourceRequest> resource_request, + const ::net::NetworkTrafficAnnotationTag& annotation_tag) const { + return ::network::SimpleURLLoader::Create(std::move(resource_request), + annotation_tag); +} + +} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service/simple_url_loader_factory.h b/components/autofill_assistant/browser/service/simple_url_loader_factory.h new file mode 100644 index 0000000..b23ce8b --- /dev/null +++ b/components/autofill_assistant/browser/service/simple_url_loader_factory.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 COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SERVICE_SIMPLE_URL_LOADER_FACTORY_H_ +#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SERVICE_SIMPLE_URL_LOADER_FACTORY_H_ + +#include <memory> + +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/simple_url_loader.h" + +namespace autofill_assistant { + +// Base interface for creators of URL loaders. +class SimpleURLLoaderFactory { + public: + virtual ~SimpleURLLoaderFactory() = default; + + virtual std::unique_ptr<::network::SimpleURLLoader> CreateLoader( + std::unique_ptr<::network::ResourceRequest> resource_request, + const ::net::NetworkTrafficAnnotationTag& annotation_tag) const = 0; +}; + +// The native implementation of |SimpleURLLoaderFactory|. +class NativeURLLoaderFactory : public SimpleURLLoaderFactory { + public: + NativeURLLoaderFactory() = default; + ~NativeURLLoaderFactory() override = default; + NativeURLLoaderFactory(const NativeURLLoaderFactory&) = delete; + NativeURLLoaderFactory& operator=(const NativeURLLoaderFactory&) = delete; + + std::unique_ptr<::network::SimpleURLLoader> CreateLoader( + std::unique_ptr<::network::ResourceRequest> resource_request, + const ::net::NetworkTrafficAnnotationTag& annotation_tag) const override; +}; + +} // namespace autofill_assistant + +#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SERVICE_SIMPLE_URL_LOADER_FACTORY_H_
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RadioButtonWithDescription.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RadioButtonWithDescription.java index 530862c..143a520 100644 --- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RadioButtonWithDescription.java +++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RadioButtonWithDescription.java
@@ -57,7 +57,7 @@ /** * Interface to listen to radio button changes. */ - interface ButtonCheckedStateChangedListener { + public interface ButtonCheckedStateChangedListener { /** * Invoked when a {@link RadioButtonWithDescription} is selected. * @param checkedRadioButton The radio button that was selected.
diff --git a/components/component_updater/component_updater_service.h b/components/component_updater/component_updater_service.h index f926034a2..a9f9307 100644 --- a/components/component_updater/component_updater_service.h +++ b/components/component_updater/component_updater_service.h
@@ -27,7 +27,7 @@ } namespace settings { -class AccessibilityMainHandler; +class CaptionsHandler; } namespace update_client { @@ -147,7 +147,7 @@ virtual bool GetComponentDetails(const std::string& id, CrxUpdateItem* item) const = 0; - friend class settings::AccessibilityMainHandler; + friend class settings::CaptionsHandler; friend class ::ComponentsHandler; FRIEND_TEST_ALL_PREFIXES(ComponentInstallerTest, RegisterComponent); };
diff --git a/components/embedder_support/android/metrics/android_metrics_service_client.cc b/components/embedder_support/android/metrics/android_metrics_service_client.cc index c4508da..b59d1ce 100644 --- a/components/embedder_support/android/metrics/android_metrics_service_client.cc +++ b/components/embedder_support/android/metrics/android_metrics_service_client.cc
@@ -190,6 +190,20 @@ return file_metrics_provider; } +base::OnceClosure CreateChainedClosure(base::OnceClosure cb1, + base::OnceClosure cb2) { + return base::BindOnce( + [](base::OnceClosure cb1, base::OnceClosure cb2) { + if (cb1) { + std::move(cb1).Run(); + } + if (cb2) { + std::move(cb2).Run(); + } + }, + std::move(cb1), std::move(cb2)); +} + } // namespace // Needs to be kept in sync with the writer in @@ -442,8 +456,11 @@ // Set up the callback task to call after we receive histograms from all // child processes. |timeout| specifies how long to wait before absolutely // calling us back on the task. - content::FetchHistogramsAsynchronously(base::ThreadTaskRunnerHandle::Get(), - std::move(done_callback), timeout); + content::FetchHistogramsAsynchronously( + base::ThreadTaskRunnerHandle::Get(), + CreateChainedClosure(std::move(done_callback), + on_final_metrics_collected_listener_), + timeout); if (collect_final_metrics_for_log_closure_) std::move(collect_final_metrics_for_log_closure_).Run(); @@ -519,6 +536,11 @@ collect_final_metrics_for_log_closure_ = std::move(closure); } +void AndroidMetricsServiceClient::SetOnFinalMetricsCollectedListenerForTesting( + base::RepeatingClosure listener) { + on_final_metrics_collected_listener_ = std::move(listener); +} + int AndroidMetricsServiceClient::GetSampleBucketValue() { return UintToPerMille(base::PersistentHash(metrics_service_->GetClientId())); }
diff --git a/components/embedder_support/android/metrics/android_metrics_service_client.h b/components/embedder_support/android/metrics/android_metrics_service_client.h index d0edeeae..7d6a9f6f 100644 --- a/components/embedder_support/android/metrics/android_metrics_service_client.h +++ b/components/embedder_support/android/metrics/android_metrics_service_client.h
@@ -154,9 +154,14 @@ const content::NotificationSource& source, const content::NotificationDetails& details) override; - // Runs |closure| when CollectFinalMetricsForLog() is called. + // Runs |closure| when CollectFinalMetricsForLog() is called, when we begin + // collecting final metrics. void SetCollectFinalMetricsForLogClosureForTesting(base::OnceClosure closure); + // Runs |listener| after all final metrics have been collected. + void SetOnFinalMetricsCollectedListenerForTesting( + base::RepeatingClosure listener); + metrics::MetricsStateManager* metrics_state_manager() const { return metrics_state_manager_.get(); } @@ -256,6 +261,7 @@ base::TimeDelta overridden_upload_interval_; base::OnceClosure collect_final_metrics_for_log_closure_; + base::RepeatingClosure on_final_metrics_collected_listener_; // MetricsServiceClient may be created before the UI thread is promoted to // BrowserThread::UI. Use |sequence_checker_| to enforce that the
diff --git a/components/exo/DEPS b/components/exo/DEPS index 9b0c1e4..948a6a70 100644 --- a/components/exo/DEPS +++ b/components/exo/DEPS
@@ -4,8 +4,9 @@ "+chromeos/audio/chromeos_sounds.h", "+chromeos/constants/chromeos_features.h", "+chromeos/crosapi/cpp/crosapi_constants.h", - "+chromeos/ui/base/window_state_type.h", + "+chromeos/ui/base", "+chromeos/ui/frame/caption_buttons", + "+chromeos/ui/frame/immersive", "+components/viz/common", "+components/viz/host", "+device/gamepad",
diff --git a/components/exo/client_controlled_shell_surface.cc b/components/exo/client_controlled_shell_surface.cc index 5bbc164..99bbca0 100644 --- a/components/exo/client_controlled_shell_surface.cc +++ b/components/exo/client_controlled_shell_surface.cc
@@ -12,7 +12,6 @@ #include "ash/frame/wide_frame_view.h" #include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/default_frame_header.h" -#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h" #include "ash/public/cpp/rounded_corner_decorator.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/window_backdrop.h" @@ -39,6 +38,7 @@ #include "base/trace_event/traced_value.h" #include "chromeos/ui/base/window_state_type.h" #include "chromeos/ui/frame/caption_buttons/caption_button_model.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" #include "components/exo/shell_surface_util.h" #include "components/exo/surface.h" #include "components/exo/wm_helper.h" @@ -567,7 +567,7 @@ bool enabled = (frame_type_ == SurfaceFrameType::AUTOHIDE && (GetWindowState()->IsMaximizedOrFullscreenOrPinned() || GetWindowState()->IsSnapped())); - ash::ImmersiveFullscreenController::EnableForWidget(widget_, enabled); + chromeos::ImmersiveFullscreenController::EnableForWidget(widget_, enabled); } } @@ -798,7 +798,7 @@ auto frame_view = CreateNonClientFrameViewInternal(widget, /*client_controlled=*/true); immersive_fullscreen_controller_ = - std::make_unique<ash::ImmersiveFullscreenController>(); + std::make_unique<chromeos::ImmersiveFullscreenController>(); static_cast<ash::NonClientFrameViewAsh*>(frame_view.get()) ->InitImmersiveFullscreenControllerForView( immersive_fullscreen_controller_.get()); @@ -1259,7 +1259,7 @@ if (!wide_frame_) { update_frame = true; wide_frame_ = std::make_unique<ash::WideFrameView>(widget_); - ash::ImmersiveFullscreenController::EnableForWidget(widget_, false); + chromeos::ImmersiveFullscreenController::EnableForWidget(widget_, false); wide_frame_->Init(immersive_fullscreen_controller_.get()); wide_frame_->header_view()->GetFrameHeader()->SetFrameTextOverride( GetFrameView() @@ -1278,7 +1278,7 @@ } else { if (wide_frame_) { update_frame = true; - ash::ImmersiveFullscreenController::EnableForWidget(widget_, false); + chromeos::ImmersiveFullscreenController::EnableForWidget(widget_, false); wide_frame_.reset(); GetFrameView()->InitImmersiveFullscreenControllerForView( immersive_fullscreen_controller_.get());
diff --git a/components/exo/client_controlled_shell_surface.h b/components/exo/client_controlled_shell_surface.h index c321ec7..3dcb07e 100644 --- a/components/exo/client_controlled_shell_surface.h +++ b/components/exo/client_controlled_shell_surface.h
@@ -19,7 +19,6 @@ namespace ash { class NonClientFrameViewAsh; -class ImmersiveFullscreenController; class RoundedCornerDecorator; class WideFrameView; @@ -28,6 +27,10 @@ } } // namespace ash +namespace chromeos { +class ImmersiveFullscreenController; +} // namespace chromeos + namespace exo { class Surface; class ClientControlledAcceleratorTarget; @@ -351,7 +354,7 @@ bool can_maximize_ = true; - std::unique_ptr<ash::ImmersiveFullscreenController> + std::unique_ptr<chromeos::ImmersiveFullscreenController> immersive_fullscreen_controller_; std::unique_ptr<ash::WideFrameView> wide_frame_;
diff --git a/components/exo/shell_surface_base.cc b/components/exo/shell_surface_base.cc index 4367cbcd..40b08f2 100644 --- a/components/exo/shell_surface_base.cc +++ b/components/exo/shell_surface_base.cc
@@ -26,6 +26,7 @@ #include "base/trace_event/traced_value.h" #include "cc/trees/layer_tree_frame_sink.h" #include "chromeos/crosapi/cpp/crosapi_constants.h" +#include "chromeos/ui/base//window_properties.h" #include "chromeos/ui/base/window_state_type.h" #include "components/exo/shell_surface_util.h" #include "components/exo/surface.h" @@ -1084,7 +1085,7 @@ bool client_controlled) { aura::Window* window = widget_->GetNativeWindow(); // ShellSurfaces always use immersive mode. - window->SetProperty(ash::kImmersiveIsActive, true); + window->SetProperty(chromeos::kImmersiveIsActive, true); ash::WindowState* window_state = ash::WindowState::Get(window); if (!frame_enabled() && !window_state->HasDelegate()) { window_state->SetDelegate(std::make_unique<CustomWindowStateDelegate>());
diff --git a/components/exo/shell_surface_util.cc b/components/exo/shell_surface_util.cc index 960f92e..271c9e0 100644 --- a/components/exo/shell_surface_util.cc +++ b/components/exo/shell_surface_util.cc
@@ -24,6 +24,7 @@ #if defined(OS_CHROMEOS) #include "ash/public/cpp/window_properties.h" +#include "chromeos/ui/base/window_properties.h" #endif // defined(OS_CHROMEOS) DEFINE_UI_CLASS_PROPERTY_TYPE(exo::Permission*) @@ -118,7 +119,7 @@ void SetShellUseImmersiveForFullscreen(aura::Window* window, bool value) { #if defined(OS_CHROMEOS) - window->SetProperty(ash::kImmersiveImpliedByFullscreen, value); + window->SetProperty(chromeos::kImmersiveImpliedByFullscreen, value); // Ensure the shelf is fully hidden in plain fullscreen, but shown // (auto-hides based on mouse movement) when in immersive fullscreen.
diff --git a/components/exo/surface.cc b/components/exo/surface.cc index fb9675ed..53b0425 100644 --- a/components/exo/surface.cc +++ b/components/exo/surface.cc
@@ -1108,7 +1108,7 @@ quad_state->SetAll( quad_to_target_transform, quad_rect /*quad_layer_rect=*/, quad_rect /*visible_quad_layer_rect=*/, - gfx::RRectF() /*rounded_corner_bounds=*/, gfx::Rect() /*clip_rect=*/, + gfx::MaskFilterInfo() /*mask_filter_info=*/, gfx::Rect() /*clip_rect=*/, false /*is_clipped=*/, are_contents_opaque, state_.alpha /*opacity=*/, SkBlendMode::kSrcOver /*blend_mode=*/, 0 /*sorting_context_id=*/); quad_state->no_damage = damage_rect.IsEmpty();
diff --git a/components/exo/surface_tree_host.cc b/components/exo/surface_tree_host.cc index ceb5e06a..d125275 100644 --- a/components/exo/surface_tree_host.cc +++ b/components/exo/surface_tree_host.cc
@@ -300,7 +300,7 @@ quad_state->SetAll( gfx::Transform(), /*quad_layer_rect=*/quad_rect, /*visible_quad_layer_rect=*/quad_rect, - /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/gfx::Rect(), + /*mask_filter_info=*/gfx::MaskFilterInfo(), /*clip_rect=*/gfx::Rect(), /*is_clipped=*/false, /*are_contents_opaque=*/true, /*opacity=*/1.f, /*blend_mode=*/SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
diff --git a/components/exo/ui_lock_controller.cc b/components/exo/ui_lock_controller.cc index ef4a1605..cb417e0 100644 --- a/components/exo/ui_lock_controller.cc +++ b/components/exo/ui_lock_controller.cc
@@ -5,10 +5,10 @@ #include "components/exo/ui_lock_controller.h" #include "ash/public/cpp/app_types.h" -#include "ash/public/cpp/window_properties.h" #include "ash/wm/window_state.h" #include "base/time/time.h" #include "base/timer/timer.h" +#include "chromeos/ui/base/window_properties.h" #include "components/exo/seat.h" #include "components/exo/shell_surface_util.h" #include "components/exo/surface.h" @@ -67,7 +67,7 @@ return false; aura::Window* window = widget->GetNativeWindow(); - if (!window || window->GetProperty(ash::kImmersiveImpliedByFullscreen)) + if (!window || window->GetProperty(chromeos::kImmersiveImpliedByFullscreen)) return false; // TODO(b/165865831): Add the Borealis AppType if/when we add one.
diff --git a/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/RemotingMediaSource.java b/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/RemotingMediaSource.java index 01208e2..91984bae 100644 --- a/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/RemotingMediaSource.java +++ b/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/RemotingMediaSource.java
@@ -1,6 +1,7 @@ // Copyright 2017 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.media_router.caf.remoting; import android.content.Context; @@ -26,9 +27,13 @@ public class RemotingMediaSource implements MediaSource { private static final String TAG = "MediaRemoting"; - // Need to be in sync with third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp. + // Needs to be in sync with + // third_party/blink/renderer/modules/remoteplayback/remote_playback.cc. // TODO(avayvod): Find a way to share the constants somehow. private static final String SOURCE_PREFIX = "remote-playback://"; + + // Needs to be in sync with AndroidManifest meta-data key (used both by Clank and WebLayer + // clients). private static final String REMOTE_PLAYBACK_APP_ID_KEY = "org.chromium.content.browser.REMOTE_PLAYBACK_APP_ID";
diff --git a/components/password_manager/core/browser/sync/password_model_type_controller.cc b/components/password_manager/core/browser/sync/password_model_type_controller.cc index 425ad22..a8e00c03 100644 --- a/components/password_manager/core/browser/sync/password_model_type_controller.cc +++ b/components/password_manager/core/browser/sync/password_model_type_controller.cc
@@ -14,8 +14,8 @@ #include "components/prefs/pref_service.h" #include "components/signin/public/identity_manager/accounts_in_cookie_jar_info.h" #include "components/sync/base/model_type.h" -#include "components/sync/driver/sync_client.h" #include "components/sync/driver/sync_service.h" +#include "components/sync/driver/sync_user_settings.h" #include "components/sync/model/model_type_controller_delegate.h" namespace password_manager { @@ -140,6 +140,16 @@ : PreconditionState::kMustStopAndClearData; } +bool PasswordModelTypeController::ShouldRunInTransportOnlyMode() const { + if (!base::FeatureList::IsEnabled(features::kEnablePasswordsAccountStorage)) { + return false; + } + if (sync_service_->GetUserSettings()->IsUsingSecondaryPassphrase()) { + return false; + } + return true; +} + void PasswordModelTypeController::OnStateChanged(syncer::SyncService* sync) { DCHECK(CalledOnValidThread()); sync_service_->DataTypePreconditionChanged(syncer::PASSWORDS);
diff --git a/components/password_manager/core/browser/sync/password_model_type_controller.h b/components/password_manager/core/browser/sync/password_model_type_controller.h index f535438..bc5362b 100644 --- a/components/password_manager/core/browser/sync/password_model_type_controller.h +++ b/components/password_manager/core/browser/sync/password_model_type_controller.h
@@ -49,6 +49,7 @@ void Stop(syncer::ShutdownReason shutdown_reason, StopCallback callback) override; PreconditionState GetPreconditionState() const override; + bool ShouldRunInTransportOnlyMode() const override; // SyncServiceObserver overrides. void OnStateChanged(syncer::SyncService* sync) override;
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index c5724f3..7358f07 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -16215,6 +16215,29 @@ Leaving the policy unset means that by default, the feature isn't allowed for managed users but is allowed for other users.''', }, { + 'name': 'WifiSyncAndroidAllowed', + 'owners': ['jonmann@chromium.org', 'cvandermerwe@google.com'], + 'type': 'main', + 'schema': { 'type': 'boolean' }, + 'future_on': ['chrome_os'], + 'features': { + 'dynamic_refresh': True, + 'per_profile': True, + }, + 'example_value': True, + 'default_for_enterprise_users': False, + 'id': 798, + 'caption': '''Allow Wi-Fi network configurations to be synced across <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> devices and a connected Android phone.''', + 'tags': ['local-data-access', 'google-sharing'], + 'desc': '''If this setting is enabled, users will be allowed to sync Wi-Fi network configurations between their <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> device(s) and a connected Android phone. Before Wi-Fi network configurations can sync, users must explicitly opt in to this feature by completing a setup flow. + + If this setting is disabled, users will not be allowed to sync Wi-Fi network configurations. + + This feature depends on the <ph name="WIFI_CONFIGURATIONS_DATATYPE_NAME">wifiConfigurations</ph> datatype in Chrome Sync being enabled. If <ph name="WIFI_CONFIGURATIONS_DATATYPE_NAME">wifiConfigurations</ph> is disabled in the <ph name="SYNC_TYPES_LIST_DISABLED_POLICY_NAME">SyncTypesListDisabled</ph> policy, or Chrome Sync is disabled in the <ph name="SYNC_DISABLED_POLICY_NAME">SyncDisabled</ph> policy this feature will not be enabled. + + If this policy is left not set, the default is not allowed for managed users.''', + }, + { 'name': 'SmartLockSigninAllowed', 'owners': ['hansberry@chromium.org', 'jhawkins@chromium.org'], 'type': 'main', @@ -21484,6 +21507,7 @@ 'features': { 'dynamic_refresh': True, 'per_profile': False, + 'cloud_only': True, }, 'id': 697, 'supported_on': ['chrome.*:84-', 'chrome_os:84-'], @@ -21521,6 +21545,7 @@ 'features': { 'dynamic_refresh': True, 'per_profile': False, + 'cloud_only': True, }, 'id': 699, 'supported_on': ['chrome.*:84-', 'chrome_os:84-'], @@ -21559,7 +21584,8 @@ ], 'features': { 'dynamic_refresh': True, - 'per_profile': True, + 'per_profile': False, + 'cloud_only': True, }, 'example_value': 1, 'id': 728, @@ -24527,6 +24553,6 @@ 'placeholders': [], 'deleted_policy_ids': [114, 115, 412, 476, 544, 546, 562, 569, 578, 583, 589], 'deleted_atomic_policy_group_ids': [], - 'highest_id_currently_used': 797, + 'highest_id_currently_used': 798, 'highest_atomic_group_id_currently_used': 40 }
diff --git a/components/safe_browsing/core/features.cc b/components/safe_browsing/core/features.cc index 4b565625..7461d97 100644 --- a/components/safe_browsing/core/features.cc +++ b/components/safe_browsing/core/features.cc
@@ -104,7 +104,7 @@ const base::Feature kRealTimeUrlLookupEnabledForEnterprise{ "SafeBrowsingRealTimeUrlLookupEnabledForEnterprise", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kRealTimeUrlLookupEnabledForEP{ "SafeBrowsingRealTimeUrlLookupEnabledForEP",
diff --git a/components/shared_highlighting/core/common/shared_highlighting_metrics.cc b/components/shared_highlighting/core/common/shared_highlighting_metrics.cc index 653cc9e..30f4136d 100644 --- a/components/shared_highlighting/core/common/shared_highlighting_metrics.cc +++ b/components/shared_highlighting/core/common/shared_highlighting_metrics.cc
@@ -13,7 +13,8 @@ namespace { TextFragmentLinkOpenSource GetLinkSource(const GURL& referrer) { - bool from_search_engine = SearchEngineUtils::GetEngineType(referrer) > 0; + bool from_search_engine = + referrer.is_valid() && SearchEngineUtils::GetEngineType(referrer) > 0; return from_search_engine ? TextFragmentLinkOpenSource::kSearchEngine : TextFragmentLinkOpenSource::kUnknown; }
diff --git a/components/shared_highlighting/core/common/shared_highlighting_metrics.h b/components/shared_highlighting/core/common/shared_highlighting_metrics.h index cb1e9826..a9c1190 100644 --- a/components/shared_highlighting/core/common/shared_highlighting_metrics.h +++ b/components/shared_highlighting/core/common/shared_highlighting_metrics.h
@@ -9,26 +9,31 @@ namespace shared_highlighting { -// Update corresponding |LinkGenerationError| in enums.xml. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +// The type of errors that can happen during link generation. enum class LinkGenerationError { - kIncorrectSelector, - kNoRange, - kNoContext, - kContextExhausted, - kContextLimitReached, - kEmptySelection, + kIncorrectSelector = 0, + kNoRange = 1, + kNoContext = 2, + kContextExhausted = 3, + kContextLimitReached = 4, + kEmptySelection = 5, - kTabHidden, - kOmniboxNavigation, - kTabCrash, + // Android specific. + kTabHidden = 5, + kOmniboxNavigation = 6, + kTabCrash = 7, kMaxValue = kTabCrash }; -// Update corresponding |TextFragmentLinkOpenSource| in enums.xml. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +// The different sources from which a text fragment URL can come from. enum class TextFragmentLinkOpenSource { - kUnknown, - kSearchEngine, + kUnknown = 0, + kSearchEngine = 1, kMaxValue = kSearchEngine, };
diff --git a/components/shared_highlighting/core/common/shared_highlighting_metrics_unittest.cc b/components/shared_highlighting/core/common/shared_highlighting_metrics_unittest.cc index 136d8ab..1185c36 100644 --- a/components/shared_highlighting/core/common/shared_highlighting_metrics_unittest.cc +++ b/components/shared_highlighting/core/common/shared_highlighting_metrics_unittest.cc
@@ -26,15 +26,23 @@ TEST(SharedHighlightingMetricsTest, LogTextFragmentLinkOpenSource) { base::HistogramTester histogram_tester; - GURL search_engine_url = GURL("https://google.com"); - GURL non_search_engine_url = GURL("https://example.com"); - + GURL search_engine_url("https://google.com"); LogTextFragmentLinkOpenSource(search_engine_url); - histogram_tester.ExpectBucketCount("TextFragmentAnchor.LinkOpenSource", 1, 1); + histogram_tester.ExpectBucketCount("TextFragmentAnchor.LinkOpenSource", + TextFragmentLinkOpenSource::kSearchEngine, + 1); + GURL non_search_engine_url("https://example.com"); LogTextFragmentLinkOpenSource(non_search_engine_url); - histogram_tester.ExpectBucketCount("TextFragmentAnchor.LinkOpenSource", 0, 1); + histogram_tester.ExpectBucketCount("TextFragmentAnchor.LinkOpenSource", + TextFragmentLinkOpenSource::kUnknown, 1); histogram_tester.ExpectTotalCount("TextFragmentAnchor.LinkOpenSource", 2); + + GURL empty_gurl(""); + LogTextFragmentLinkOpenSource(empty_gurl); + histogram_tester.ExpectBucketCount("TextFragmentAnchor.LinkOpenSource", + TextFragmentLinkOpenSource::kUnknown, 2); + histogram_tester.ExpectTotalCount("TextFragmentAnchor.LinkOpenSource", 3); } TEST(SharedHighlightingMetricsTest, LogTextFragmentMatchRate) {
diff --git a/components/sync/driver/data_type_controller.h b/components/sync/driver/data_type_controller.h index 8688e515f..579ec2d 100644 --- a/components/sync/driver/data_type_controller.h +++ b/components/sync/driver/data_type_controller.h
@@ -115,6 +115,10 @@ }; virtual PreconditionState GetPreconditionState() const; + // Returns whether the datatype knows how to, and wants to, run in + // transport-only mode (see syncer::SyncMode enum). + virtual bool ShouldRunInTransportOnlyMode() const = 0; + // Returns a ListValue representing all nodes for this data type through // |callback| on this thread. Can only be called if state() != NOT_RUNNING. // Used for populating nodes in Sync Node Browser of chrome://sync-internals.
diff --git a/components/sync/driver/model_type_controller.cc b/components/sync/driver/model_type_controller.cc index 1d3ec57..c417309f 100644 --- a/components/sync/driver/model_type_controller.cc +++ b/components/sync/driver/model_type_controller.cc
@@ -208,6 +208,14 @@ return state_; } +bool ModelTypeController::ShouldRunInTransportOnlyMode() const { + // By default, running in transport-only mode is enabled if the corresponding + // delegate exists, i.e. the controller is aware of transport-only mode and + // supports it in principle. Subclass can still override this with more + // specific logic. + return delegate_map_.count(SyncMode::kTransportOnly) != 0; +} + void ModelTypeController::GetAllNodes(AllNodesCallback callback) { DCHECK(delegate_); delegate_->GetAllNodesForDebugging(std::move(callback));
diff --git a/components/sync/driver/model_type_controller.h b/components/sync/driver/model_type_controller.h index 5fb62c3..dadf2c2 100644 --- a/components/sync/driver/model_type_controller.h +++ b/components/sync/driver/model_type_controller.h
@@ -53,6 +53,7 @@ void DeactivateDataType(ModelTypeConfigurer* configurer) override; void Stop(ShutdownReason shutdown_reason, StopCallback callback) override; State state() const override; + bool ShouldRunInTransportOnlyMode() const override; void GetAllNodes(AllNodesCallback callback) override; void RecordMemoryUsageAndCountsHistograms() override;
diff --git a/components/sync/driver/profile_sync_service.cc b/components/sync/driver/profile_sync_service.cc index 202986d..3f6007e7 100644 --- a/components/sync/driver/profile_sync_service.cc +++ b/components/sync/driver/profile_sync_service.cc
@@ -217,10 +217,6 @@ base::Unretained(this)))), channel_(init_params.channel), debug_identifier_(init_params.debug_identifier), - autofill_enable_account_wallet_storage_( - init_params.autofill_enable_account_wallet_storage), - enable_passwords_account_storage_( - init_params.enable_passwords_account_storage), sync_service_url_( GetSyncServiceURL(*base::CommandLine::ForCurrentProcess(), channel_)), crypto_( @@ -1359,42 +1355,15 @@ } ModelTypeSet ProfileSyncService::GetModelTypesForTransportOnlyMode() const { - ModelTypeSet allowed_types = { - DEVICE_INFO, - SECURITY_EVENTS, - SHARING_MESSAGE, - SUPERVISED_USER_SETTINGS, - SUPERVISED_USER_ALLOWLISTS, - USER_CONSENTS, - }; - - if (autofill_enable_account_wallet_storage_) { - if (!GetUserSettings()->IsUsingSecondaryPassphrase() || - base::FeatureList::IsEnabled( - switches:: - kSyncAllowWalletDataInTransportModeWithCustomPassphrase)) { - allowed_types.Put(AUTOFILL_WALLET_DATA); + // Collect the types from all controllers that support transport-only mode. + ModelTypeSet allowed_types; + for (const auto& type_and_controller : data_type_controllers_) { + ModelType type = type_and_controller.first; + const DataTypeController* controller = type_and_controller.second.get(); + if (controller->ShouldRunInTransportOnlyMode()) { + allowed_types.Put(type); } } - - if (enable_passwords_account_storage_ && - !GetUserSettings()->IsUsingSecondaryPassphrase()) { - allowed_types.Put(PASSWORDS); - } - - // Outside the #if so non-Chrome OS developers will hit it before uploading. - static_assert(41 == ModelType::NUM_ENTRIES, - "If a new ModelType is Chrome OS-only and uses OS sync " - "consent, add it below."); -#if defined(OS_CHROMEOS) - // Chrome OS system types are not tied to browser sync-the-feature. - if (chromeos::features::IsSplitSettingsSyncEnabled()) { - allowed_types.PutAll({APP_LIST, APP_SETTINGS, APPS, ARC_PACKAGE, - OS_PREFERENCES, OS_PRIORITY_PREFERENCES, PRINTERS, - WEB_APPS, WIFI_CONFIGURATIONS}); - } -#endif // defined(OS_CHROMEOS) - return allowed_types; }
diff --git a/components/sync/driver/profile_sync_service.h b/components/sync/driver/profile_sync_service.h index 03ead02..bd17fe7c 100644 --- a/components/sync/driver/profile_sync_service.h +++ b/components/sync/driver/profile_sync_service.h
@@ -92,8 +92,6 @@ network::NetworkConnectionTracker* network_connection_tracker = nullptr; version_info::Channel channel = version_info::Channel::UNKNOWN; std::string debug_identifier; - bool autofill_enable_account_wallet_storage = false; - bool enable_passwords_account_storage = false; private: DISALLOW_COPY_AND_ASSIGN(InitParams); @@ -393,9 +391,6 @@ // An identifier representing this instance for debugging purposes. const std::string debug_identifier_; - const bool autofill_enable_account_wallet_storage_; - const bool enable_passwords_account_storage_; - // This specifies where to find the sync server. const GURL sync_service_url_;
diff --git a/components/sync/driver/profile_sync_service_unittest.cc b/components/sync/driver/profile_sync_service_unittest.cc index bbb281b..560aff4 100644 --- a/components/sync/driver/profile_sync_service_unittest.cc +++ b/components/sync/driver/profile_sync_service_unittest.cc
@@ -179,14 +179,20 @@ void SignIn() { identity_test_env()->MakePrimaryAccountAvailable(kTestUser); } void CreateService(ProfileSyncService::StartBehavior behavior, - ModelTypeSet registered_types = - ModelTypeSet(BOOKMARKS, SUPERVISED_USER_SETTINGS)) { + std::vector<std::pair<ModelType, bool>> + registered_types_and_transport_mode_support = { + {BOOKMARKS, false}, + {DEVICE_INFO, true}}) { DCHECK(!service_); // Default includes a regular controller and a transport-mode controller. DataTypeController::TypeVector controllers; - for (const ModelType type : registered_types) { - controllers.push_back(std::make_unique<FakeDataTypeController>(type)); + for (const auto& type_and_transport_mode_support : + registered_types_and_transport_mode_support) { + ModelType type = type_and_transport_mode_support.first; + bool transport_mode_support = type_and_transport_mode_support.second; + controllers.push_back(std::make_unique<FakeDataTypeController>( + type, transport_mode_support)); } std::unique_ptr<SyncClientMock> sync_client = @@ -211,8 +217,8 @@ // Include a regular controller and a transport-mode controller. DataTypeController::TypeVector controllers; controllers.push_back(std::make_unique<FakeDataTypeController>(BOOKMARKS)); - controllers.push_back( - std::make_unique<FakeDataTypeController>(SUPERVISED_USER_SETTINGS)); + controllers.push_back(std::make_unique<FakeDataTypeController>( + DEVICE_INFO, /*enable_transport_only_modle=*/true)); std::unique_ptr<SyncClientMock> sync_client = profile_sync_service_bundle_.CreateSyncClientMock(); @@ -468,7 +474,7 @@ EXPECT_FALSE(service()->GetActiveDataTypes().Has(BOOKMARKS)); // ModelTypes for sync-the-transport are configured. - EXPECT_TRUE(service()->GetActiveDataTypes().Has(SUPERVISED_USER_SETTINGS)); + EXPECT_TRUE(service()->GetActiveDataTypes().Has(DEVICE_INFO)); } // Verify that the SetSetupInProgress function call updates state @@ -1634,7 +1640,7 @@ TEST_F(ProfileSyncServiceTestWithSyncInvalidationsServiceCreated, ShouldEnableAndDisableInvalidationsForSessions) { CreateService(ProfileSyncService::AUTO_START, - ModelTypeSet(SESSIONS, TYPED_URLS)); + {{SESSIONS, false}, {TYPED_URLS, false}}); SignIn(); InitializeForNthSync();
diff --git a/components/sync/driver/sync_service_crypto.cc b/components/sync/driver/sync_service_crypto.cc index fa658927e..f597cb8 100644 --- a/components/sync/driver/sync_service_crypto.cc +++ b/components/sync/driver/sync_service_crypto.cc
@@ -279,16 +279,6 @@ RequiredUserAction::kTrustedVaultRecoverabilityDegraded; } -void SyncServiceCrypto::EnableEncryptEverything() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(state_.engine); - - // TODO(atwilson): Persist the encryption_pending flag to address the various - // problems around cancelling encryption in the background (crbug.com/119649). - if (!state_.encrypt_everything) - state_.encryption_pending = true; -} - bool SyncServiceCrypto::IsEncryptEverythingEnabled() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(state_.engine);
diff --git a/components/sync/driver/sync_service_crypto.h b/components/sync/driver/sync_service_crypto.h index 5cfde56..1f60911 100644 --- a/components/sync/driver/sync_service_crypto.h +++ b/components/sync/driver/sync_service_crypto.h
@@ -50,7 +50,6 @@ bool IsUsingSecondaryPassphrase() const; bool IsTrustedVaultKeyRequired() const; bool IsTrustedVaultRecoverabilityDegraded() const; - void EnableEncryptEverything(); bool IsEncryptEverythingEnabled() const; void SetEncryptionPassphrase(const std::string& passphrase); bool SetDecryptionPassphrase(const std::string& passphrase);
diff --git a/components/sync/driver/sync_user_settings.h b/components/sync/driver/sync_user_settings.h index 765d422..c360552 100644 --- a/components/sync/driver/sync_user_settings.h +++ b/components/sync/driver/sync_user_settings.h
@@ -91,12 +91,6 @@ virtual bool IsEncryptEverythingAllowed() const = 0; // Whether we are currently set to encrypt all the Sync data. virtual bool IsEncryptEverythingEnabled() const = 0; - // Turns on encryption for all data. Callers must call SetChosenDataTypes() - // after calling this to force the encryption to occur. - // TODO(crbug.com/1033040): This was only relevant for the Directory - // implementation of Nigori, and should be cleaned up. The same goes for - // related code in PeopleHandler and possibly its Javascript counterpart. - virtual void EnableEncryptEverything() = 0; // The current set of encrypted data types. virtual ModelTypeSet GetEncryptedDataTypes() const = 0;
diff --git a/components/sync/driver/sync_user_settings_impl.cc b/components/sync/driver/sync_user_settings_impl.cc index b37454b..ba8b9e4 100644 --- a/components/sync/driver/sync_user_settings_impl.cc +++ b/components/sync/driver/sync_user_settings_impl.cc
@@ -173,11 +173,6 @@ return crypto_->IsEncryptEverythingEnabled(); } -void SyncUserSettingsImpl::EnableEncryptEverything() { - DCHECK(IsEncryptEverythingAllowed()); - crypto_->EnableEncryptEverything(); -} - bool SyncUserSettingsImpl::IsPassphraseRequired() const { return crypto_->IsPassphraseRequired(); }
diff --git a/components/sync/driver/sync_user_settings_impl.h b/components/sync/driver/sync_user_settings_impl.h index 4a6ed38..8e7889c 100644 --- a/components/sync/driver/sync_user_settings_impl.h +++ b/components/sync/driver/sync_user_settings_impl.h
@@ -59,7 +59,6 @@ bool IsEncryptEverythingAllowed() const override; bool IsEncryptEverythingEnabled() const override; - void EnableEncryptEverything() override; ModelTypeSet GetEncryptedDataTypes() const override; bool IsPassphraseRequired() const override;
diff --git a/components/sync/driver/sync_user_settings_mock.h b/components/sync/driver/sync_user_settings_mock.h index c412959..f51b26b 100644 --- a/components/sync/driver/sync_user_settings_mock.h +++ b/components/sync/driver/sync_user_settings_mock.h
@@ -44,7 +44,6 @@ MOCK_CONST_METHOD0(IsEncryptEverythingAllowed, bool()); MOCK_CONST_METHOD0(IsEncryptEverythingEnabled, bool()); - MOCK_METHOD0(EnableEncryptEverything, void()); MOCK_CONST_METHOD0(GetEncryptedDataTypes, ModelTypeSet()); MOCK_CONST_METHOD0(IsPassphraseRequired, bool());
diff --git a/components/sync/driver/test_sync_user_settings.cc b/components/sync/driver/test_sync_user_settings.cc index 5031631..dc207fd 100644 --- a/components/sync/driver/test_sync_user_settings.cc +++ b/components/sync/driver/test_sync_user_settings.cc
@@ -149,8 +149,6 @@ return false; } -void TestSyncUserSettings::EnableEncryptEverything() {} - ModelTypeSet TestSyncUserSettings::GetEncryptedDataTypes() const { if (!IsUsingSecondaryPassphrase()) { // PASSWORDS and WIFI_CONFIGURATIONS are always encrypted.
diff --git a/components/sync/driver/test_sync_user_settings.h b/components/sync/driver/test_sync_user_settings.h index b46f829c..a72ba9e 100644 --- a/components/sync/driver/test_sync_user_settings.h +++ b/components/sync/driver/test_sync_user_settings.h
@@ -48,7 +48,6 @@ bool IsEncryptEverythingAllowed() const override; bool IsEncryptEverythingEnabled() const override; - void EnableEncryptEverything() override; syncer::ModelTypeSet GetEncryptedDataTypes() const override; bool IsPassphraseRequired() const override;
diff --git a/components/sync_sessions/proxy_tabs_data_type_controller.cc b/components/sync_sessions/proxy_tabs_data_type_controller.cc index 19dc01f1..3f868e0 100644 --- a/components/sync_sessions/proxy_tabs_data_type_controller.cc +++ b/components/sync_sessions/proxy_tabs_data_type_controller.cc
@@ -61,6 +61,10 @@ return state_; } +bool ProxyTabsDataTypeController::ShouldRunInTransportOnlyMode() const { + return false; +} + void ProxyTabsDataTypeController::DeactivateDataType( syncer::ModelTypeConfigurer* configurer) { if (state_ == RUNNING) {
diff --git a/components/sync_sessions/proxy_tabs_data_type_controller.h b/components/sync_sessions/proxy_tabs_data_type_controller.h index 1df714f5..62a1d8f 100644 --- a/components/sync_sessions/proxy_tabs_data_type_controller.h +++ b/components/sync_sessions/proxy_tabs_data_type_controller.h
@@ -31,6 +31,7 @@ void Stop(syncer::ShutdownReason shutdown_reason, StopCallback callback) override; State state() const override; + bool ShouldRunInTransportOnlyMode() const override; void DeactivateDataType(syncer::ModelTypeConfigurer* configurer) override; void GetAllNodes(AllNodesCallback callback) override; void RecordMemoryUsageAndCountsHistograms() override;
diff --git a/components/viz/common/quads/compositor_render_pass_unittest.cc b/components/viz/common/quads/compositor_render_pass_unittest.cc index cda0bebd..e6010a50 100644 --- a/components/viz/common/quads/compositor_render_pass_unittest.cc +++ b/components/viz/common/quads/compositor_render_pass_unittest.cc
@@ -85,7 +85,7 @@ // Stick a quad in the pass, this should not get copied. SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(gfx::Transform(), gfx::Rect(), gfx::Rect(), - gfx::RRectF(), gfx::Rect(), false, false, 1, + gfx::MaskFilterInfo(), gfx::Rect(), false, false, 1, SkBlendMode::kSrcOver, 0); auto* color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); @@ -144,7 +144,7 @@ // Two quads using one shared state. SharedQuadState* shared_state1 = pass->CreateAndAppendSharedQuadState(); shared_state1->SetAll(gfx::Transform(), gfx::Rect(0, 0, 1, 1), gfx::Rect(), - gfx::RRectF(), gfx::Rect(), false, false, 1, + gfx::MaskFilterInfo(), gfx::Rect(), false, false, 1, SkBlendMode::kSrcOver, 0); auto* color_quad1 = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); @@ -160,7 +160,7 @@ // And two quads using another shared state. SharedQuadState* shared_state2 = pass->CreateAndAppendSharedQuadState(); shared_state2->SetAll(gfx::Transform(), gfx::Rect(0, 0, 2, 2), gfx::Rect(), - gfx::RRectF(), gfx::Rect(), false, false, 1, + gfx::MaskFilterInfo(), gfx::Rect(), false, false, 1, SkBlendMode::kSrcOver, 0); auto* color_quad3 = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); @@ -201,8 +201,8 @@ SharedQuadState* contrib_shared_state = contrib->CreateAndAppendSharedQuadState(); contrib_shared_state->SetAll(gfx::Transform(), gfx::Rect(0, 0, 2, 2), - gfx::Rect(), gfx::RRectF(), gfx::Rect(), false, - false, 1, SkBlendMode::kSrcOver, 0); + gfx::Rect(), gfx::MaskFilterInfo(), gfx::Rect(), + false, false, 1, SkBlendMode::kSrcOver, 0); auto* contrib_quad = contrib->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); contrib_quad->SetNew(contrib->shared_quad_state_list.back(), @@ -254,7 +254,7 @@ // A shared state with a quad. SharedQuadState* shared_state1 = pass->CreateAndAppendSharedQuadState(); shared_state1->SetAll(gfx::Transform(), gfx::Rect(0, 0, 1, 1), gfx::Rect(), - gfx::RRectF(), gfx::Rect(), false, false, 1, + gfx::MaskFilterInfo(), gfx::Rect(), false, false, 1, SkBlendMode::kSrcOver, 0); auto* color_quad1 = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); @@ -265,19 +265,19 @@ // A shared state with no quads, they were culled. SharedQuadState* shared_state2 = pass->CreateAndAppendSharedQuadState(); shared_state2->SetAll(gfx::Transform(), gfx::Rect(0, 0, 2, 2), gfx::Rect(), - gfx::RRectF(), gfx::Rect(), false, false, 1, + gfx::MaskFilterInfo(), gfx::Rect(), false, false, 1, SkBlendMode::kSrcOver, 0); // A second shared state with no quads. SharedQuadState* shared_state3 = pass->CreateAndAppendSharedQuadState(); shared_state3->SetAll(gfx::Transform(), gfx::Rect(0, 0, 2, 2), gfx::Rect(), - gfx::RRectF(), gfx::Rect(), false, false, 1, + gfx::MaskFilterInfo(), gfx::Rect(), false, false, 1, SkBlendMode::kSrcOver, 0); // A last shared state with a quad again. SharedQuadState* shared_state4 = pass->CreateAndAppendSharedQuadState(); shared_state4->SetAll(gfx::Transform(), gfx::Rect(0, 0, 2, 2), gfx::Rect(), - gfx::RRectF(), gfx::Rect(), false, false, 1, + gfx::MaskFilterInfo(), gfx::Rect(), false, false, 1, SkBlendMode::kSrcOver, 0); auto* color_quad2 = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
diff --git a/components/viz/common/quads/draw_quad.h b/components/viz/common/quads/draw_quad.h index 313e208f..4900fb6 100644 --- a/components/viz/common/quads/draw_quad.h +++ b/components/viz/common/quads/draw_quad.h
@@ -79,7 +79,7 @@ bool ShouldDrawWithBlending() const { return needs_blending || shared_quad_state->opacity < 1.0f || shared_quad_state->blend_mode != SkBlendMode::kSrcOver || - !shared_quad_state->rounded_corner_bounds.IsEmpty(); + !shared_quad_state->mask_filter_info.IsEmpty(); } // Is the left edge of this tile aligned with the originating layer's
diff --git a/components/viz/common/quads/draw_quad_perftest.cc b/components/viz/common/quads/draw_quad_perftest.cc index 00f0de929..3c0d2e63 100644 --- a/components/viz/common/quads/draw_quad_perftest.cc +++ b/components/viz/common/quads/draw_quad_perftest.cc
@@ -42,9 +42,9 @@ SkBlendMode blend_mode = SkBlendMode::kSrcOver; SharedQuadState* state = render_pass->CreateAndAppendSharedQuadState(); - state->SetAll(quad_transform, content_rect, visible_layer_rect, gfx::RRectF(), - clip_rect, is_clipped, are_contents_opaque, opacity, blend_mode, - sorting_context_id); + state->SetAll(quad_transform, content_rect, visible_layer_rect, + gfx::MaskFilterInfo(), clip_rect, is_clipped, + are_contents_opaque, opacity, blend_mode, sorting_context_id); return state; }
diff --git a/components/viz/common/quads/draw_quad_unittest.cc b/components/viz/common/quads/draw_quad_unittest.cc index c4097751..3cb4975 100644 --- a/components/viz/common/quads/draw_quad_unittest.cc +++ b/components/viz/common/quads/draw_quad_unittest.cc
@@ -53,9 +53,9 @@ int sorting_context_id = 65536; auto state = std::make_unique<SharedQuadState>(); - state->SetAll(quad_transform, layer_rect, visible_layer_rect, gfx::RRectF(), - clip_rect, is_clipped, are_contents_opaque, opacity, blend_mode, - sorting_context_id); + state->SetAll(quad_transform, layer_rect, visible_layer_rect, + gfx::MaskFilterInfo(), clip_rect, is_clipped, + are_contents_opaque, opacity, blend_mode, sorting_context_id); auto copy = std::make_unique<SharedQuadState>(*state); EXPECT_EQ(quad_transform, copy->quad_to_target_transform); @@ -79,9 +79,9 @@ SkBlendMode blend_mode = SkBlendMode::kSrcOver; SharedQuadState* state = render_pass->CreateAndAppendSharedQuadState(); - state->SetAll(quad_transform, layer_rect, visible_layer_rect, gfx::RRectF(), - clip_rect, is_clipped, are_contents_opaque, opacity, blend_mode, - sorting_context_id); + state->SetAll(quad_transform, layer_rect, visible_layer_rect, + gfx::MaskFilterInfo(), clip_rect, is_clipped, + are_contents_opaque, opacity, blend_mode, sorting_context_id); return state; }
diff --git a/components/viz/common/quads/render_pass_io.cc b/components/viz/common/quads/render_pass_io.cc index 8bd58e1..e988c2c 100644 --- a/components/viz/common/quads/render_pass_io.cc +++ b/components/viz/common/quads/render_pass_io.cc
@@ -1602,14 +1602,16 @@ dict.SetKey("quad_layer_rect", RectToDict(sqs.quad_layer_rect)); dict.SetKey("visible_quad_layer_rect", RectToDict(sqs.visible_quad_layer_rect)); - dict.SetKey("rounded_corner_bounds", RRectFToDict(sqs.rounded_corner_bounds)); + dict.SetKey("rounded_corner_bounds", + RRectFToDict(sqs.mask_filter_info.rounded_corner_bounds())); dict.SetKey("clip_rect", RectToDict(sqs.clip_rect)); dict.SetBoolKey("is_clipped", sqs.is_clipped); dict.SetBoolKey("are_contents_opaque", sqs.are_contents_opaque); dict.SetDoubleKey("opacity", sqs.opacity); dict.SetStringKey("blend_mode", BlendModeToString(sqs.blend_mode)); dict.SetIntKey("sorting_context_id", sqs.sorting_context_id); - dict.SetBoolKey("is_fast_rounded_corner", sqs.is_fast_rounded_corner); + dict.SetBoolKey("is_fast_rounded_corner", + sqs.mask_filter_info.is_fast_rounded_corner()); dict.SetDoubleKey("de_jelly_delta_y", sqs.de_jelly_delta_y); return dict; } @@ -1697,13 +1699,13 @@ if (blend_mode_index < 0) return false; SkBlendMode t_blend_mode = static_cast<SkBlendMode>(blend_mode_index); - + gfx::MaskFilterInfo mask_filter_info(t_rounded_corner_bounds, + is_fast_rounded_corner.value()); sqs->SetAll(t_quad_to_target_transform, t_quad_layer_rect, - t_visible_quad_layer_rect, t_rounded_corner_bounds, t_clip_rect, + t_visible_quad_layer_rect, mask_filter_info, t_clip_rect, is_clipped.value(), are_contents_opaque.value(), static_cast<float>(opacity.value()), t_blend_mode, sorting_context_id.value()); - sqs->is_fast_rounded_corner = is_fast_rounded_corner.value(); sqs->de_jelly_delta_y = static_cast<float>(de_jelly_delta_y.value()); return true; }
diff --git a/components/viz/common/quads/render_pass_io_unittest.cc b/components/viz/common/quads/render_pass_io_unittest.cc index e9f8144..6644bc5e 100644 --- a/components/viz/common/quads/render_pass_io_unittest.cc +++ b/components/viz/common/quads/render_pass_io_unittest.cc
@@ -123,10 +123,10 @@ transform.MakeIdentity(); sqs1->SetAll(transform, gfx::Rect(0, 0, 640, 480), gfx::Rect(10, 10, 600, 400), - gfx::RRectF(gfx::RectF(2.f, 3.f, 4.f, 5.f), 1.5f), + gfx::MaskFilterInfo( + gfx::RRectF(gfx::RectF(2.f, 3.f, 4.f, 5.f), 1.5f), true), gfx::Rect(5, 20, 1000, 200), true, false, 0.5f, SkBlendMode::kDstOver, 101); - sqs1->is_fast_rounded_corner = true; sqs1->de_jelly_delta_y = 0.7f; } base::Value dict0 = CompositorRenderPassToDict(*render_pass0); @@ -141,14 +141,14 @@ EXPECT_TRUE(sqs0->quad_to_target_transform.IsIdentity()); EXPECT_EQ(gfx::Rect(), sqs0->quad_layer_rect); EXPECT_EQ(gfx::Rect(), sqs0->visible_quad_layer_rect); - EXPECT_TRUE(sqs0->rounded_corner_bounds.IsEmpty()); + EXPECT_FALSE(sqs0->mask_filter_info.HasRoundedCorners()); + EXPECT_FALSE(sqs0->mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(gfx::Rect(), sqs0->clip_rect); EXPECT_FALSE(sqs0->is_clipped); EXPECT_TRUE(sqs0->are_contents_opaque); EXPECT_EQ(1.0f, sqs0->opacity); EXPECT_EQ(SkBlendMode::kSrcOver, sqs0->blend_mode); EXPECT_EQ(0, sqs0->sorting_context_id); - EXPECT_FALSE(sqs0->is_fast_rounded_corner); EXPECT_EQ(0.0f, sqs0->de_jelly_delta_y); const SharedQuadState* sqs1 = @@ -158,17 +158,17 @@ EXPECT_EQ(gfx::Rect(0, 0, 640, 480), sqs1->quad_layer_rect); EXPECT_EQ(gfx::Rect(10, 10, 600, 400), sqs1->visible_quad_layer_rect); EXPECT_EQ(gfx::RRectF::Type::kSingle, - sqs1->rounded_corner_bounds.GetType()); - EXPECT_EQ(1.5f, sqs1->rounded_corner_bounds.GetSimpleRadius()); - EXPECT_EQ(gfx::RectF(2.f, 3.f, 4.f, 5.f), - sqs1->rounded_corner_bounds.rect()); + sqs1->mask_filter_info.rounded_corner_bounds().GetType()); + EXPECT_EQ(1.5f, + sqs1->mask_filter_info.rounded_corner_bounds().GetSimpleRadius()); + EXPECT_EQ(gfx::RectF(2.f, 3.f, 4.f, 5.f), sqs1->mask_filter_info.bounds()); + EXPECT_TRUE(sqs1->mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(gfx::Rect(5, 20, 1000, 200), sqs1->clip_rect); EXPECT_TRUE(sqs1->is_clipped); EXPECT_FALSE(sqs1->are_contents_opaque); EXPECT_EQ(0.5f, sqs1->opacity); EXPECT_EQ(SkBlendMode::kDstOver, sqs1->blend_mode); EXPECT_EQ(101, sqs1->sorting_context_id); - EXPECT_TRUE(sqs1->is_fast_rounded_corner); EXPECT_EQ(0.7f, sqs1->de_jelly_delta_y); } base::Value dict1 = CompositorRenderPassToDict(*render_pass1);
diff --git a/components/viz/common/quads/shared_quad_state.cc b/components/viz/common/quads/shared_quad_state.cc index 42cab6b..5d7d3b3 100644 --- a/components/viz/common/quads/shared_quad_state.cc +++ b/components/viz/common/quads/shared_quad_state.cc
@@ -23,7 +23,7 @@ void SharedQuadState::SetAll(const gfx::Transform& quad_to_target_transform, const gfx::Rect& quad_layer_rect, const gfx::Rect& visible_quad_layer_rect, - const gfx::RRectF& rounded_corner_bounds, + const gfx::MaskFilterInfo& mask_filter_info, const gfx::Rect& clip_rect, bool is_clipped, bool are_contents_opaque, @@ -33,7 +33,7 @@ this->quad_to_target_transform = quad_to_target_transform; this->quad_layer_rect = quad_layer_rect; this->visible_quad_layer_rect = visible_quad_layer_rect; - this->rounded_corner_bounds = rounded_corner_bounds; + this->mask_filter_info = mask_filter_info; this->clip_rect = clip_rect; this->is_clipped = is_clipped; this->are_contents_opaque = are_contents_opaque; @@ -47,8 +47,11 @@ cc::MathUtil::AddToTracedValue("layer_content_rect", quad_layer_rect, value); cc::MathUtil::AddToTracedValue("layer_visible_content_rect", visible_quad_layer_rect, value); - cc::MathUtil::AddToTracedValue("rounded_corner_bounds", rounded_corner_bounds, - value); + cc::MathUtil::AddToTracedValue("mask_filter_bounds", + mask_filter_info.bounds(), value); + cc::MathUtil::AddCornerRadiiToTracedValue( + "mask_filter_rounded_corners_radii", + mask_filter_info.rounded_corner_bounds(), value); value->SetBoolean("is_clipped", is_clipped); cc::MathUtil::AddToTracedValue("clip_rect", clip_rect, value);
diff --git a/components/viz/common/quads/shared_quad_state.h b/components/viz/common/quads/shared_quad_state.h index 97681e500..ba4650b3 100644 --- a/components/viz/common/quads/shared_quad_state.h +++ b/components/viz/common/quads/shared_quad_state.h
@@ -11,6 +11,7 @@ #include "components/viz/common/viz_common_export.h" #include "third_party/skia/include/core/SkBlendMode.h" #include "ui/gfx/geometry/rect.h" +#include "ui/gfx/mask_filter_info.h" #include "ui/gfx/rrect_f.h" #include "ui/gfx/transform.h" @@ -36,7 +37,7 @@ void SetAll(const gfx::Transform& quad_to_target_transform, const gfx::Rect& quad_layer_rect, const gfx::Rect& visible_layer_rect, - const gfx::RRectF& rounded_corner_bounds, + const gfx::MaskFilterInfo& mask_filter_info, const gfx::Rect& clip_rect, bool is_clipped, bool are_contents_opaque, @@ -55,9 +56,11 @@ // The size of the visible area in the quads' originating layer, in the space // of the quad rects. gfx::Rect visible_quad_layer_rect; - // This rect lives in the target content space. It defines the corner radius - // to clip the quads with. - gfx::RRectF rounded_corner_bounds; + // This mask filter's coordinates is in the target content space. It defines + // the corner radius to clip the quads with, and the |is_fast_rounded_corner| + // used by SurfaceAggregator to decide whether to merge quads for a surface + // into their target render pass for performance optimization. + gfx::MaskFilterInfo mask_filter_info; // This rect lives in the target content space. gfx::Rect clip_rect; bool is_clipped = false; @@ -66,10 +69,6 @@ float opacity = 1.f; SkBlendMode blend_mode = SkBlendMode::kSrcOver; int sorting_context_id = 0; - // Used by SurfaceAggregator to decide whether to merge quads for a surface - // into their target render pass. It is a performance optimization by avoiding - // render passes as much as possible. - bool is_fast_rounded_corner = false; // This is for underlay optimization and used only in the SurfaceAggregator // and the OverlayProcessor. Do not set the value in CompositorRenderPass. // This index points to the damage rect in the surface damage rect list where
diff --git a/components/viz/demo/client/demo_client.cc b/components/viz/demo/client/demo_client.cc index 75e6f81..6f255f94 100644 --- a/components/viz/demo/client/demo_client.cc +++ b/components/viz/demo/client/demo_client.cc
@@ -102,7 +102,7 @@ transform, /*quad_layer_rect=*/child_bounds, /*visible_quad_layer_rect=*/child_bounds, - /*rounded_corner_bounds=*/gfx::RRectF(), + /*mask_filter_info=*/gfx::MaskFilterInfo(), /*clip_rect=*/gfx::Rect(), /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/1.f, /*blend_mode=*/SkBlendMode::kSrcOver, /*sorting_context_id=*/0); @@ -127,7 +127,7 @@ gfx::Transform(), /*quad_layer_rect=*/output_rect, /*visible_quad_layer_rect=*/output_rect, - /*rounded_corner_bounds=*/gfx::RRectF(), + /*mask_filter_info=*/gfx::MaskFilterInfo(), /*clip_rect=*/gfx::Rect(), /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/1.f, /*blend_mode=*/SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
diff --git a/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc b/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc index 6a316432..226e84a89 100644 --- a/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc +++ b/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc
@@ -15,6 +15,7 @@ #include "components/viz/common/resources/bitmap_allocation.h" #include "components/viz/common/resources/resource_sizes.h" #include "third_party/skia/include/core/SkBitmap.h" +#include "ui/gfx/mask_filter_info.h" namespace viz { namespace { @@ -343,8 +344,8 @@ shared_quad_state->SetAll( GetTransformFromProtobuf(quad_spec.sqs().transform()), GetRectFromProtobuf(quad_spec.sqs().layer_rect()), - GetRectFromProtobuf(quad_spec.sqs().visible_rect()), gfx::RRectF(), - GetRectFromProtobuf(quad_spec.sqs().clip_rect()), + GetRectFromProtobuf(quad_spec.sqs().visible_rect()), + gfx::MaskFilterInfo(), GetRectFromProtobuf(quad_spec.sqs().clip_rect()), quad_spec.sqs().is_clipped(), quad_spec.sqs().are_contents_opaque(), Normalize(quad_spec.sqs().opacity()), SkBlendMode::kSrcOver, quad_spec.sqs().sorting_context_id()); @@ -360,12 +361,12 @@ .transform_to_root_target()); } - shared_quad_state->SetAll(transform, GetRectFromProtobuf(quad_spec.rect()), - GetRectFromProtobuf(quad_spec.visible_rect()), - gfx::RRectF(), gfx::Rect(), /*is_clipped=*/false, - /*are_contents_opaque=*/true, /*opacity=*/1.0, - SkBlendMode::kSrcOver, - /*sorting_context_id=*/0); + shared_quad_state->SetAll( + transform, GetRectFromProtobuf(quad_spec.rect()), + GetRectFromProtobuf(quad_spec.visible_rect()), gfx::MaskFilterInfo(), + gfx::Rect(), /*is_clipped=*/false, + /*are_contents_opaque=*/true, /*opacity=*/1.0, SkBlendMode::kSrcOver, + /*sorting_context_id=*/0); } }
diff --git a/components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.cc b/components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.cc index 628c046..8820b5c3 100644 --- a/components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.cc +++ b/components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.cc
@@ -130,7 +130,7 @@ renderer_sqs->SetAll(gfx::Transform(1.0, 0.0, 0.0, 1.0, 0, 80), gfx::Rect(kRendererFrameSize), gfx::Rect(kRendererFrameSize), - /*rounded_corner_bounds=*/gfx::RRectF(), + /*mask_filter_info=*/gfx::MaskFilterInfo(), gfx::Rect(kRendererFrameSize), /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/1, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); @@ -144,7 +144,7 @@ auto* toolbar_sqs = pass->CreateAndAppendSharedQuadState(); toolbar_sqs->SetAll( gfx::Transform(), gfx::Rect(kTopBarSize), gfx::Rect(kTopBarSize), - /*rounded_corner_bounds=*/gfx::RRectF(), gfx::Rect(kTopBarSize), + /*mask_filter_info=*/gfx::MaskFilterInfo(), gfx::Rect(kTopBarSize), /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/1, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
diff --git a/components/viz/service/display/ca_layer_overlay.cc b/components/viz/service/display/ca_layer_overlay.cc index cf09d0d..72426617 100644 --- a/components/viz/service/display/ca_layer_overlay.cc +++ b/components/viz/service/display/ca_layer_overlay.cc
@@ -208,10 +208,10 @@ // possible to make rounded corner rects independent of clip rect (by adding // another CALayer to the tree). Handling non-single border radii is also, // but requires APIs not supported on all macOS versions. - if (!quad->shared_quad_state->rounded_corner_bounds.IsEmpty()) { + if (quad->shared_quad_state->mask_filter_info.HasRoundedCorners()) { DCHECK(quad->shared_quad_state->is_clipped); - if (quad->shared_quad_state->rounded_corner_bounds.GetType() > - gfx::RRectF::Type::kSingle) { + if (quad->shared_quad_state->mask_filter_info.rounded_corner_bounds() + .GetType() > gfx::RRectF::Type::kSingle) { return CA_LAYER_FAILED_QUAD_ROUNDED_CORNER_NOT_UNIFORM; } } @@ -238,7 +238,7 @@ most_recent_overlay_shared_state_->clip_rect = gfx::RectF(quad->shared_quad_state->clip_rect); most_recent_overlay_shared_state_->rounded_corner_bounds = - quad->shared_quad_state->rounded_corner_bounds; + quad->shared_quad_state->mask_filter_info.rounded_corner_bounds(); most_recent_overlay_shared_state_->opacity = quad->shared_quad_state->opacity;
diff --git a/components/viz/service/display/damage_frame_annotator.cc b/components/viz/service/display/damage_frame_annotator.cc index a65710d..38d85d4e 100644 --- a/components/viz/service/display/damage_frame_annotator.cc +++ b/components/viz/service/display/damage_frame_annotator.cc
@@ -53,7 +53,7 @@ SharedQuadState* new_sqs = render_pass->shared_quad_state_list .AllocateAndConstruct<SharedQuadState>(); new_sqs->SetAll(annotation.transform, output_rect, output_rect, - gfx::RRectF(), output_rect, true, false, 1.f, + gfx::MaskFilterInfo(), output_rect, true, false, 1.f, SkBlendMode::kSrcOver, 0); DebugBorderDrawQuad* new_quad =
diff --git a/components/viz/service/display/dc_layer_overlay.cc b/components/viz/service/display/dc_layer_overlay.cc index 680d771f..52cbb6ea 100644 --- a/components/viz/service/display/dc_layer_overlay.cc +++ b/components/viz/service/display/dc_layer_overlay.cc
@@ -104,7 +104,7 @@ return DC_LAYER_FAILED_TOO_MANY_OVERLAYS; // Rounded corner on overlays are not supported. - if (!quad->shared_quad_state->rounded_corner_bounds.IsEmpty()) + if (quad->shared_quad_state->mask_filter_info.HasRoundedCorners()) return DC_LAYER_FAILED_ROUNDED_CORNERS; auto quad_target_rect = gfx::ToEnclosingRect(ClippedQuadRectangle(quad)); @@ -172,7 +172,7 @@ } // Rounded corner on overlays are not supported. - if (!quad->shared_quad_state->rounded_corner_bounds.IsEmpty()) + if (quad->shared_quad_state->mask_filter_info.HasRoundedCorners()) return DC_LAYER_FAILED_ROUNDED_CORNERS; auto quad_target_rect = gfx::ToEnclosingRect(ClippedQuadRectangle(quad));
diff --git a/components/viz/service/display/direct_renderer.cc b/components/viz/service/display/direct_renderer.cc index 3b9c1195..5b094621 100644 --- a/components/viz/service/display/direct_renderer.cc +++ b/components/viz/service/display/direct_renderer.cc
@@ -919,12 +919,15 @@ bool DirectRenderer::ShouldApplyRoundedCorner(const DrawQuad* quad) const { const SharedQuadState* sqs = quad->shared_quad_state; - const gfx::RRectF& rounded_corner_bounds = sqs->rounded_corner_bounds; + const gfx::MaskFilterInfo& mask_filter_info = sqs->mask_filter_info; // There is no rounded corner set. - if (rounded_corner_bounds.IsEmpty()) + if (!mask_filter_info.HasRoundedCorners()) return false; + const gfx::RRectF& rounded_corner_bounds = + mask_filter_info.rounded_corner_bounds(); + const gfx::RectF target_quad = cc::MathUtil::MapClippedRect( sqs->quad_to_target_transform, gfx::RectF(quad->visible_rect));
diff --git a/components/viz/service/display/display.cc b/components/viz/service/display/display.cc index 6df3fba..249aa00 100644 --- a/components/viz/service/display/display.cc +++ b/components/viz/service/display/display.cc
@@ -1107,9 +1107,10 @@ // If a rounded corner is being applied then the visible rect for the // sqs is actually even smaller. Reduce the rect size to get a // rounded corner adjusted occluding region. - if (!last_sqs->rounded_corner_bounds.IsEmpty()) { - sqs_rect_in_target.Intersect(gfx::ToEnclosedRect( - GetOccludingRectForRRectF(last_sqs->rounded_corner_bounds))); + if (last_sqs->mask_filter_info.HasRoundedCorners()) { + sqs_rect_in_target.Intersect( + gfx::ToEnclosedRect(GetOccludingRectForRRectF( + last_sqs->mask_filter_info.rounded_corner_bounds()))); } if (last_sqs->is_clipped)
diff --git a/components/viz/service/display/display_perftest.cc b/components/viz/service/display/display_perftest.cc index 37faed27..59e18d36 100644 --- a/components/viz/service/display/display_perftest.cc +++ b/components/viz/service/display/display_perftest.cc
@@ -98,7 +98,7 @@ SharedQuadState* state = render_pass->CreateAndAppendSharedQuadState(); state->SetAll(quad_transform, rect, rect, - /*rounded_corner_bounds=*/gfx::RRectF(), rect, is_clipped, + /*mask_filter_info=*/gfx::MaskFilterInfo(), rect, is_clipped, are_contents_opaque, opacity, blend_mode, sorting_context_id); return state; }
diff --git a/components/viz/service/display/display_unittest.cc b/components/viz/service/display/display_unittest.cc index 6213ce7..7ffe50e 100644 --- a/components/viz/service/display/display_unittest.cc +++ b/components/viz/service/display/display_unittest.cc
@@ -771,7 +771,7 @@ shared_quad_state1->SetAll( gfx::Transform(), /*quad_layer_rect=*/sub_surface_rect, /*visible_quad_layer_rect=*/sub_surface_rect, - /*rounded_corner_bounds=*/gfx::RRectF(), + /*mask_filter_info=*/gfx::MaskFilterInfo(), /*clip_rect=*/sub_surface_rect, /*is_clipped=*/false, /*are_contents_opaque=*/true, /*opacity=*/1.0f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); @@ -787,7 +787,7 @@ gfx::Rect rect1(display_size); shared_quad_state2->SetAll(gfx::Transform(), /*quad_layer_rect=*/rect1, /*visible_quad_layer_rect=*/rect1, - /*rounded_corner_bounds=*/gfx::RRectF(), + /*mask_filter_info=*/gfx::MaskFilterInfo(), /*clip_rect=*/rect1, /*is_clipped=*/false, /*are_contents_opaque=*/true, /*opacity=*/1.0f, SkBlendMode::kSrcOver, @@ -927,13 +927,13 @@ auto* src_sqs = render_pass->CreateAndAppendSharedQuadState(); src_sqs->SetAll( - gfx::Transform(), src_rect, src_rect, gfx::RRectF(), src_rect, + gfx::Transform(), src_rect, src_rect, gfx::MaskFilterInfo(), src_rect, is_clipped, are_contents_opaque, opacity, is_root_render_pass ? SkBlendMode::kSrcOver : SkBlendMode::kSrcIn, 0); auto* dest_sqs = render_pass->CreateAndAppendSharedQuadState(); dest_sqs->SetAll( - gfx::Transform(), dest_rect, dest_rect, gfx::RRectF(), dest_rect, - is_clipped, are_contents_opaque, opacity, + gfx::Transform(), dest_rect, dest_rect, gfx::MaskFilterInfo(), + dest_rect, is_clipped, are_contents_opaque, opacity, is_root_render_pass ? SkBlendMode::kSrcOver : SkBlendMode::kDstIn, 0); auto* src_quad = render_pass->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); @@ -993,7 +993,7 @@ for (int i = 0; i < 3; i++) { shared_quad_states[i] = root_render_pass->CreateAndAppendSharedQuadState(); shared_quad_states[i]->SetAll( - gfx::Transform(), rects[i], rects[i], gfx::RRectF(), rects[i], + gfx::Transform(), rects[i], rects[i], gfx::MaskFilterInfo(), rects[i], is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); if (i == 0) { // Backdrop filter quad @@ -1058,9 +1058,9 @@ // | | // +----+ { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); EXPECT_EQ(1u, NumVisibleRects(frame.render_pass_list.front()->quad_list)); @@ -1083,13 +1083,13 @@ // +----+ | // +----+ { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), - rect2, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect2, rect2, gfx::MaskFilterInfo(), rect2, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); @@ -1118,13 +1118,13 @@ // | | | | // +--+ +--+ { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), - rect3, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect3, rect3, gfx::MaskFilterInfo(), rect3, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect3, rect3, SK_ColorBLACK, false); @@ -1152,13 +1152,13 @@ // +----+ +----+ // +--+ +--+ { - shared_quad_state->SetAll(gfx::Transform(), rect7, rect7, gfx::RRectF(), - rect7, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect7, rect7, gfx::MaskFilterInfo(), rect7, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect6, rect6, gfx::RRectF(), - rect6, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect6, rect6, gfx::MaskFilterInfo(), rect6, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect7, rect7, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect6, rect6, SK_ColorBLACK, false); @@ -1185,13 +1185,13 @@ // | | +--+ // +----+ { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect4, rect4, gfx::RRectF(), - rect4, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect4, rect4, gfx::MaskFilterInfo(), rect4, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect4, rect4, SK_ColorBLACK, false); @@ -1217,13 +1217,13 @@ // +-----+| // +------+ { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect5, rect5, gfx::RRectF(), - rect5, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect5, rect5, gfx::MaskFilterInfo(), rect5, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect5, rect5, SK_ColorBLACK, false); @@ -1275,9 +1275,9 @@ frame.render_pass_list.front()->CreateAndAppendSharedQuadState(); auto* quad = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, - is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect, rect, gfx::MaskFilterInfo(), rect, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect, rect, SK_ColorBLACK, false); } @@ -1331,9 +1331,9 @@ frame.render_pass_list.front()->CreateAndAppendSharedQuadState(); auto* quad = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, - is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect, rect, gfx::MaskFilterInfo(), rect, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect, rect, SK_ColorBLACK, false); } @@ -1390,12 +1390,12 @@ // | | // +-----+ { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect1, rect1, SK_ColorBLACK, false); @@ -1415,12 +1415,12 @@ { quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), - rect2, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect2, rect2, gfx::MaskFilterInfo(), rect2, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); @@ -1441,12 +1441,12 @@ { quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), - rect3, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect3, rect3, gfx::MaskFilterInfo(), rect3, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect3, rect3, SK_ColorBLACK, false); @@ -1467,13 +1467,13 @@ { quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect4, rect4, gfx::RRectF(), - rect4, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect4, rect4, gfx::MaskFilterInfo(), rect4, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect4, rect4, SK_ColorBLACK, false); @@ -1532,11 +1532,11 @@ ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(half_scale, rect2, rect2, gfx::RRectF(), rect2, - is_clipped, are_contents_opaque, opacity, + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll(half_scale, rect2, rect2, gfx::MaskFilterInfo(), + rect2, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -1555,11 +1555,11 @@ { quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(half_scale, rect3, rect3, gfx::RRectF(), rect3, - is_clipped, are_contents_opaque, opacity, + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll(half_scale, rect3, rect3, gfx::MaskFilterInfo(), + rect3, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -1578,12 +1578,12 @@ { quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(half_scale, rect4, rect4, gfx::RRectF(), rect4, - is_clipped, are_contents_opaque, opacity, + shared_quad_state2->SetAll(half_scale, rect4, rect4, gfx::MaskFilterInfo(), + rect4, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -1601,8 +1601,8 @@ } { - shared_quad_state->SetAll(double_scale, rect1, rect1, gfx::RRectF(), rect1, - is_clipped, are_contents_opaque, opacity, + shared_quad_state->SetAll(double_scale, rect1, rect1, gfx::MaskFilterInfo(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -1619,13 +1619,13 @@ { quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(double_scale, rect5, rect5, gfx::RRectF(), rect5, - is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + double_scale, rect5, rect5, gfx::MaskFilterInfo(), rect5, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect5, rect5, SK_ColorBLACK, false); @@ -1647,13 +1647,13 @@ } { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(double_scale, rect6, rect6, gfx::RRectF(), rect6, - is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + double_scale, rect6, rect6, gfx::MaskFilterInfo(), rect6, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect6, rect6, SK_ColorBLACK, false); @@ -1676,13 +1676,13 @@ } { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(double_scale, rect7, rect7, gfx::RRectF(), rect7, - is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + double_scale, rect7, rect7, gfx::MaskFilterInfo(), rect7, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect7, rect7, SK_ColorBLACK, false); @@ -1704,13 +1704,13 @@ } { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(double_scale, rect8, rect8, gfx::RRectF(), rect8, - is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + double_scale, rect8, rect8, gfx::MaskFilterInfo(), rect8, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect8, rect8, SK_ColorBLACK, false); @@ -1732,13 +1732,13 @@ } { - shared_quad_state->SetAll(double_scale, rect10, rect10, gfx::RRectF(), - rect10, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + double_scale, rect10, rect10, gfx::MaskFilterInfo(), rect10, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(double_scale, rect9, rect9, gfx::RRectF(), rect9, - is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + double_scale, rect9, rect9, gfx::MaskFilterInfo(), rect9, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect10, rect10, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect9, rect9, SK_ColorBLACK, false); @@ -1792,11 +1792,11 @@ gfx::Transform inverted; { - shared_quad_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, - is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(zero_scale, rect, rect, gfx::RRectF(), rect, - is_clipped, are_contents_opaque, opacity, + shared_quad_state->SetAll( + gfx::Transform(), rect, rect, gfx::MaskFilterInfo(), rect, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll(zero_scale, rect, rect, gfx::MaskFilterInfo(), + rect, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect, rect, SK_ColorBLACK, false); @@ -1816,11 +1816,11 @@ } { - shared_quad_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, - is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(epsilon_scale, rect, rect, gfx::RRectF(), rect, - is_clipped, are_contents_opaque, opacity, + shared_quad_state->SetAll( + gfx::Transform(), rect, rect, gfx::MaskFilterInfo(), rect, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll(epsilon_scale, rect, rect, gfx::MaskFilterInfo(), + rect, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 1); quad->SetNew(shared_quad_state, rect, rect, SK_ColorBLACK, false); @@ -1846,12 +1846,12 @@ } { - shared_quad_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, - is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(larger_epsilon_scale, rect, rect, gfx::RRectF(), - rect, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect, rect, gfx::MaskFilterInfo(), rect, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + larger_epsilon_scale, rect, rect, gfx::MaskFilterInfo(), rect, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect, rect, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect, rect, SK_ColorBLACK, false); @@ -1895,12 +1895,12 @@ { negative_scale.Scale3d(-1, 1, 1); - shared_quad_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, - is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(negative_scale, rect, rect, gfx::RRectF(), rect, - is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect, rect, gfx::MaskFilterInfo(), rect, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + negative_scale, rect, rect, gfx::MaskFilterInfo(), rect, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect, rect, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect, rect, SK_ColorBLACK, false); @@ -1927,12 +1927,12 @@ { negative_scale.MakeIdentity(); negative_scale.Scale3d(1, -1, 1); - shared_quad_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, - is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(negative_scale, rect, rect, gfx::RRectF(), rect, - is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect, rect, gfx::MaskFilterInfo(), rect, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + negative_scale, rect, rect, gfx::MaskFilterInfo(), rect, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect, rect, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect, rect, SK_ColorBLACK, false); @@ -1959,12 +1959,12 @@ { negative_scale.MakeIdentity(); negative_scale.Scale3d(1, 1, -1); - shared_quad_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, - is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(negative_scale, rect, rect, gfx::RRectF(), rect, - is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect, rect, gfx::MaskFilterInfo(), rect, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + negative_scale, rect, rect, gfx::MaskFilterInfo(), rect, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect, rect, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect, rect, SK_ColorBLACK, false); @@ -2021,12 +2021,12 @@ ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); { // Apply rotation transform on |rect1| only. - shared_quad_state->SetAll(rotate, rect1, rect1, gfx::RRectF(), rect1, - is_clipped, are_contents_opaque, opacity, + shared_quad_state->SetAll(rotate, rect1, rect1, gfx::MaskFilterInfo(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), - rect2, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect2, rect2, gfx::MaskFilterInfo(), rect2, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); EXPECT_EQ(2u, NumVisibleRects(frame.render_pass_list.front()->quad_list)); @@ -2045,11 +2045,11 @@ { // Apply rotation transform on |rect1| and |rect2|. - shared_quad_state->SetAll(rotate, rect1, rect1, gfx::RRectF(), rect1, - is_clipped, are_contents_opaque, opacity, + shared_quad_state->SetAll(rotate, rect1, rect1, gfx::MaskFilterInfo(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(rotate, rect2, rect2, gfx::RRectF(), rect2, - is_clipped, are_contents_opaque, opacity, + shared_quad_state2->SetAll(rotate, rect2, rect2, gfx::MaskFilterInfo(), + rect2, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); @@ -2067,12 +2067,12 @@ { quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(rotate, rect1, rect1, gfx::RRectF(), rect1, - is_clipped, are_contents_opaque, opacity, + shared_quad_state->SetAll(rotate, rect1, rect1, gfx::MaskFilterInfo(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), - rect3, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect3, rect3, gfx::MaskFilterInfo(), rect3, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect3, rect3, SK_ColorBLACK, false); EXPECT_EQ(2u, NumVisibleRects(frame.render_pass_list.front()->quad_list)); @@ -2093,11 +2093,11 @@ // Since we only support updating |visible_rect| of DrawQuad with scale // or translation transform and rotation transform applies to quads, // |visible_rect| of |quad2| should not be changed. - shared_quad_state->SetAll(rotate, rect1, rect1, gfx::RRectF(), rect1, - is_clipped, are_contents_opaque, opacity, + shared_quad_state->SetAll(rotate, rect1, rect1, gfx::MaskFilterInfo(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(rotate, rect3, rect3, gfx::RRectF(), rect3, - is_clipped, are_contents_opaque, opacity, + shared_quad_state2->SetAll(rotate, rect3, rect3, gfx::MaskFilterInfo(), + rect3, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect3, rect3, SK_ColorBLACK, false); @@ -2146,12 +2146,12 @@ auto* quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); { - shared_quad_state->SetAll(perspective, rect1, rect1, gfx::RRectF(), rect1, - is_clipped, are_contents_opaque, opacity, + shared_quad_state->SetAll(perspective, rect1, rect1, gfx::MaskFilterInfo(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect1, rect1, SK_ColorBLACK, false); EXPECT_EQ(2u, NumVisibleRects(frame.render_pass_list.front()->quad_list)); @@ -2170,11 +2170,11 @@ } { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(perspective, rect2, rect2, gfx::RRectF(), rect2, - is_clipped, are_contents_opaque, opacity, + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll(perspective, rect2, rect2, gfx::MaskFilterInfo(), + rect2, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); @@ -2216,12 +2216,13 @@ auto* quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, - opacityLess1, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), - rect2, is_clipped, are_contents_opaque, opacity1, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, + gfx::MaskFilterInfo(), rect1, is_clipped, + are_contents_opaque, opacityLess1, + SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect2, rect2, gfx::MaskFilterInfo(), rect2, + is_clipped, are_contents_opaque, opacity1, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); EXPECT_EQ(2u, NumVisibleRects(frame.render_pass_list.front()->quad_list)); @@ -2238,12 +2239,12 @@ } { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity1, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), - rect2, is_clipped, are_contents_opaque, opacity1, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity1, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect2, rect2, gfx::MaskFilterInfo(), rect2, + is_clipped, are_contents_opaque, opacity1, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); EXPECT_EQ(2u, NumVisibleRects(frame.render_pass_list.front()->quad_list)); @@ -2280,12 +2281,12 @@ auto* quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, transparent_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), - rect2, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, transparent_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect2, rect2, gfx::MaskFilterInfo(), rect2, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); EXPECT_EQ(2u, NumVisibleRects(frame.render_pass_list.front()->quad_list)); @@ -2302,12 +2303,12 @@ } { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), - rect2, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect2, rect2, gfx::MaskFilterInfo(), rect2, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); EXPECT_EQ(2u, NumVisibleRects(frame.render_pass_list.front()->quad_list)); @@ -2351,12 +2352,12 @@ // | | // +-----+ { - shared_quad_state->SetAll(translate_back, rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 1); - shared_quad_state2->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 1); + shared_quad_state->SetAll( + translate_back, rect1, rect1, gfx::MaskFilterInfo(), rect1, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 1); + shared_quad_state2->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 1); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect1, SK_ColorBLACK, false); @@ -2409,12 +2410,12 @@ // +----+ // +-+ // +-+ - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, transparent_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), - rect2, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, transparent_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect2, rect2, gfx::MaskFilterInfo(), rect2, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); EXPECT_EQ(2u, NumVisibleRects(frame.render_pass_list.front()->quad_list)); @@ -2438,12 +2439,12 @@ // +----+ => | +-+ | // +-+ | +-+ | // +-+ +-----+ - shared_quad_state->SetAll(translate_up, rect1, rect1, gfx::RRectF(), rect1, - is_clipped, opaque_content, opacity, + shared_quad_state->SetAll(translate_up, rect1, rect1, gfx::MaskFilterInfo(), + rect1, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), - rect2, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect2, rect2, gfx::MaskFilterInfo(), rect2, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); EXPECT_EQ(2u, NumVisibleRects(frame.render_pass_list.front()->quad_list)); @@ -2468,12 +2469,12 @@ // +---+ +----+ quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(translate_up, rect1, rect1, gfx::RRectF(), rect1, - is_clipped, opaque_content, opacity, + shared_quad_state->SetAll(translate_up, rect1, rect1, gfx::MaskFilterInfo(), + rect1, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), - rect3, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect3, rect3, gfx::MaskFilterInfo(), rect3, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect3, rect3, SK_ColorBLACK, false); EXPECT_EQ(2u, NumVisibleRects(frame.render_pass_list.front()->quad_list)); @@ -2532,15 +2533,15 @@ // | |----+ => | |----+ // +----+ +----+ // - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), - rect2, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state3->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), - rect3, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect2, rect2, gfx::MaskFilterInfo(), rect2, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state3->SetAll( + gfx::Transform(), rect3, rect3, gfx::MaskFilterInfo(), rect3, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); quad3->SetNew(shared_quad_state3, rect3, rect3, SK_ColorBLACK, false); @@ -2567,9 +2568,9 @@ // quad3 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state3->SetAll(gfx::Transform(), rect4, rect4, gfx::RRectF(), - rect4, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state3->SetAll( + gfx::Transform(), rect4, rect4, gfx::MaskFilterInfo(), rect4, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad3->SetNew(shared_quad_state3, rect4, rect4, SK_ColorBLACK, false); EXPECT_EQ(3u, NumVisibleRects(frame.render_pass_list.front()->quad_list)); display_->RemoveOverdrawQuads(&frame); @@ -2596,9 +2597,9 @@ // | |----+ => | | |--|-+ // +----+ +-|--+ | // +-----+ - shared_quad_state3->SetAll(gfx::Transform(), rect5, rect5, gfx::RRectF(), - rect5, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state3->SetAll( + gfx::Transform(), rect5, rect5, gfx::MaskFilterInfo(), rect5, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad3->SetNew(shared_quad_state3, rect5, rect5, SK_ColorBLACK, false); EXPECT_EQ(3u, NumVisibleRects(frame.render_pass_list.front()->quad_list)); display_->RemoveOverdrawQuads(&frame); @@ -2646,7 +2647,7 @@ quads[i] = render_pass->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); shared_quad_states[i]->SetAll( - gfx::Transform(), rects[i], rects[i], gfx::RRectF(), rects[i], + gfx::Transform(), rects[i], rects[i], gfx::MaskFilterInfo(), rects[i], false /*is_clipped*/, true /*are_contents_opaque*/, 1.f /*opacity*/, SkBlendMode::kSrcOver, 0 /*sorting_context_id*/); quads[i]->SetNew(shared_quad_states[i], rects[i], rects[i], SK_ColorBLACK, @@ -2709,15 +2710,15 @@ // | |----+ => | |----+ // +----+ +----+ // - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), - rect2, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state3->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), - rect3, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect2, rect2, gfx::MaskFilterInfo(), rect2, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state3->SetAll( + gfx::Transform(), rect3, rect3, gfx::MaskFilterInfo(), rect3, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); quad3->SetNew(shared_quad_state3, rect3, rect3, SK_ColorBLACK, false); @@ -2782,12 +2783,12 @@ // +----+ // - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad1->SetNew(shared_quad_state2, rect1, rect1, render_pass_id, mask_resource_id, gfx::RectF(), gfx::Size(), @@ -2843,12 +2844,12 @@ // | | || // +------+ // - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, non_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), - rect2, non_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + non_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect2, rect2, gfx::MaskFilterInfo(), rect2, + non_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); EXPECT_EQ(2u, NumVisibleRects(frame.render_pass_list.front()->quad_list)); @@ -2870,12 +2871,12 @@ // quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - clip_rect, clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), - rect2, non_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), clip_rect, + clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect2, rect2, gfx::MaskFilterInfo(), rect2, + non_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); EXPECT_EQ(2u, NumVisibleRects(frame.render_pass_list.front()->quad_list)); @@ -2899,12 +2900,12 @@ // | +-+| => +--+++ // +------+ // - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - clip_rect, clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), - rect3, non_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), clip_rect, + clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect3, rect3, gfx::MaskFilterInfo(), rect3, + non_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect3, rect3, SK_ColorBLACK, false); EXPECT_EQ(2u, NumVisibleRects(frame.render_pass_list.front()->quad_list)); @@ -2948,12 +2949,12 @@ auto* quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), - rect2, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect2, rect2, gfx::MaskFilterInfo(), rect2, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); frame.render_pass_list.front()->copy_requests.push_back( @@ -3018,18 +3019,18 @@ // | | | | // | R1 | | R2 | // +-------+---+--------+ - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), - rect2, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state3->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), - rect3, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state4->SetAll(gfx::Transform(), rect4, rect4, gfx::RRectF(), - rect4, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect2, rect2, gfx::MaskFilterInfo(), rect2, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state3->SetAll( + gfx::Transform(), rect3, rect3, gfx::MaskFilterInfo(), rect3, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state4->SetAll( + gfx::Transform(), rect4, rect4, gfx::MaskFilterInfo(), rect4, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); R1->SetNew(shared_quad_state, rect1, rect1, render_pass_id, mask_resource_id, gfx::RectF(), gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); @@ -3066,18 +3067,18 @@ // | | | // | R2 | R1 | // +-------+-----------+ - shared_quad_state->SetAll(gfx::Transform(), rect5, rect5, gfx::RRectF(), - rect5, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state3->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), - rect3, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state4->SetAll(gfx::Transform(), rect6, rect6, gfx::RRectF(), - rect6, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect5, rect5, gfx::MaskFilterInfo(), rect5, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state3->SetAll( + gfx::Transform(), rect3, rect3, gfx::MaskFilterInfo(), rect3, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state4->SetAll( + gfx::Transform(), rect6, rect6, gfx::MaskFilterInfo(), rect6, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); R1->SetNew(shared_quad_state, rect5, rect5, render_pass_id, mask_resource_id, gfx::RectF(), gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); @@ -3113,18 +3114,18 @@ // |-----+ | | // | R2 | R1 | // +-----------+-------+ - shared_quad_state->SetAll(gfx::Transform(), rect5, rect5, gfx::RRectF(), - rect5, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state3->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), - rect3, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state4->SetAll(gfx::Transform(), rect7, rect7, gfx::RRectF(), - rect7, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect5, rect5, gfx::MaskFilterInfo(), rect5, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state3->SetAll( + gfx::Transform(), rect3, rect3, gfx::MaskFilterInfo(), rect3, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state4->SetAll( + gfx::Transform(), rect7, rect7, gfx::MaskFilterInfo(), rect7, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); R1->SetNew(shared_quad_state, rect5, rect5, render_pass_id, mask_resource_id, gfx::RectF(), gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, 1.0f); @@ -3202,11 +3203,11 @@ // +--+--+ // | | | // +--+--+ - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); shared_quad_state2->SetAll(gfx::Transform(), rect_in_rect1, rect_in_rect1, - gfx::RRectF(), rect_in_rect1, is_clipped, + gfx::MaskFilterInfo(), rect_in_rect1, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad1->SetNew(shared_quad_state, rect1_1, rect1_1, SK_ColorBLACK, false); @@ -3246,8 +3247,8 @@ ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); shared_quad_state2->SetAll( gfx::Transform(), rect_intersects_rect1, rect_intersects_rect1, - gfx::RRectF(), rect_intersects_rect1, is_clipped, opaque_content, - opacity, SkBlendMode::kSrcOver, 0); + gfx::MaskFilterInfo(), rect_intersects_rect1, is_clipped, + opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad5->SetNew(shared_quad_state2, rect_intersects_rect1, rect_intersects_rect1, SK_ColorBLACK, false); EXPECT_EQ(5u, NumVisibleRects(frame.render_pass_list.front()->quad_list)); @@ -3285,12 +3286,12 @@ auto* quad6 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), - rect2, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), - rect3, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect2, rect2, gfx::MaskFilterInfo(), rect2, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect3, rect3, gfx::MaskFilterInfo(), rect3, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad1->SetNew(shared_quad_state, rect2_1, rect2_1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state, rect2_2, rect2_2, SK_ColorBLACK, false); quad3->SetNew(shared_quad_state, rect2_3, rect2_3, SK_ColorBLACK, false); @@ -3375,15 +3376,15 @@ // |quad1| forms an occlusion rect; |quad2| follows a invertible transform // and is hiding behind quad1; |quad3| follows a non-invertible transform // and it is not covered by the occlusion rect. - shared_quad_state1->SetAll(invertible, rect1, rect1, gfx::RRectF(), rect1, - is_clipped, opaque_content, opacity, + shared_quad_state1->SetAll(invertible, rect1, rect1, gfx::MaskFilterInfo(), + rect1, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(invertible, rect2, rect2, gfx::RRectF(), rect2, - is_clipped, opaque_content, opacity, + shared_quad_state2->SetAll(invertible, rect2, rect2, gfx::MaskFilterInfo(), + rect2, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state3->SetAll(non_invertible, rect3, rect3, gfx::RRectF(), - rect3, is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state3->SetAll( + non_invertible, rect3, rect3, gfx::MaskFilterInfo(), rect3, is_clipped, + opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad1->SetNew(shared_quad_state1, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); quad3->SetNew(shared_quad_state3, rect3, rect3, SK_ColorBLACK, false); @@ -3408,13 +3409,13 @@ // | | | | // +--------+ +--------+ // Verify if draw occlusion can occlude quad with non-invertible - // transfrom. - shared_quad_state1->SetAll(invertible, rect1, rect1, gfx::RRectF(), rect1, - is_clipped, opaque_content, opacity, + // transform. + shared_quad_state1->SetAll(invertible, rect1, rect1, gfx::MaskFilterInfo(), + rect1, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state3->SetAll(non_invertible_miss_z, rect3, rect3, - gfx::RRectF(), rect3, is_clipped, opaque_content, - opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state3->SetAll( + non_invertible_miss_z, rect3, rect3, gfx::MaskFilterInfo(), rect3, + is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad1->SetNew(shared_quad_state1, rect1, rect1, SK_ColorBLACK, false); quad3->SetNew(shared_quad_state3, rect3, rect3, SK_ColorBLACK, false); @@ -3453,9 +3454,9 @@ // | | // +----+ { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), - rect1, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), rect1, rect1, gfx::MaskFilterInfo(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); EXPECT_EQ(1u, NumVisibleRects(frame.render_pass_list.front()->quad_list)); @@ -3520,7 +3521,7 @@ shared_quad_state1->SetAll( gfx::Transform(), rect1 /* quad_layer_rect */, rect1 /* visible_quad_layer_rect */, - gfx::RRectF() /* rounded_corner_bounds*/, rect1 /*clip_rect */, + gfx::MaskFilterInfo() /* mask_filter_info */, rect1 /*clip_rect */, false /* is_clipped */, false /* are_contents_opaque */, 0.5f /* opacity */, SkBlendMode::kSrcOver, 0 /* sorting_context_id */); auto* quad1 = pass->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); @@ -3533,7 +3534,7 @@ shared_quad_state2->SetAll( gfx::Transform(), rect2 /* quad_layer_rect */, rect2 /* visible_quad_layer_rect */, - gfx::RRectF() /* rounded_corner_bounds */, rect2 /*clip_rect */, + gfx::MaskFilterInfo() /* mask_filter_info */, rect2 /*clip_rect */, false /* is_clipped */, true /* are_contents_opaque */, 1.0f /* opacity */, SkBlendMode::kSrcOver, 0 /* sorting_context_id */); auto* quad2 = pass->quad_list.AllocateAndConstruct<SurfaceDrawQuad>(); @@ -3938,7 +3939,8 @@ // The quad with rounded corner does not completely cover the quad below it. // The corners of the below quad are visiblg through the clipped corners. gfx::Rect quad_rect(10, 10, 100, 100); - gfx::RRectF rounded_corner_bounds(gfx::RectF(quad_rect), 10.f); + gfx::MaskFilterInfo mask_filter_info(gfx::RRectF(gfx::RectF(quad_rect), 10.f), + false); bool is_clipped = false; bool are_contents_opaque = true; @@ -3956,16 +3958,16 @@ ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); { - shared_quad_state_occluded->SetAll( - gfx::Transform(), quad_rect, quad_rect, gfx::RRectF(), quad_rect, - is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state_occluded->SetAll(gfx::Transform(), quad_rect, quad_rect, + gfx::MaskFilterInfo(), quad_rect, + is_clipped, are_contents_opaque, opacity, + SkBlendMode::kSrcOver, 0); occluded_quad->SetNew(shared_quad_state_occluded, quad_rect, quad_rect, SK_ColorRED, false); - shared_quad_state_with_rrect->SetAll(gfx::Transform(), quad_rect, quad_rect, - rounded_corner_bounds, quad_rect, - is_clipped, are_contents_opaque, - opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state_with_rrect->SetAll( + gfx::Transform(), quad_rect, quad_rect, mask_filter_info, quad_rect, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); rounded_corner_quad->SetNew(shared_quad_state_with_rrect, quad_rect, quad_rect, SK_ColorBLUE, false); @@ -3992,8 +3994,9 @@ // The quad with rounded corner completely covers the quad below it. AggregatedFrame frame = MakeDefaultAggregatedFrame(); gfx::Rect quad_rect(10, 10, 1000, 1000); - gfx::RRectF rounded_corner_bounds(gfx::RectF(quad_rect), 10.f); gfx::Rect occluded_quad_rect(13, 13, 994, 994); + gfx::MaskFilterInfo mask_filter_info(gfx::RRectF(gfx::RectF(quad_rect), 10.f), + false); bool is_clipped = false; bool are_contents_opaque = true; @@ -4012,16 +4015,15 @@ { shared_quad_state_occluded->SetAll( - gfx::Transform(), occluded_quad_rect, occluded_quad_rect, gfx::RRectF(), - occluded_quad_rect, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + gfx::Transform(), occluded_quad_rect, occluded_quad_rect, + gfx::MaskFilterInfo(), occluded_quad_rect, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); occluded_quad->SetNew(shared_quad_state_occluded, occluded_quad_rect, occluded_quad_rect, SK_ColorRED, false); - shared_quad_state_with_rrect->SetAll(gfx::Transform(), quad_rect, quad_rect, - rounded_corner_bounds, quad_rect, - is_clipped, are_contents_opaque, - opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state_with_rrect->SetAll( + gfx::Transform(), quad_rect, quad_rect, mask_filter_info, quad_rect, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); rounded_corner_quad->SetNew(shared_quad_state_with_rrect, quad_rect, quad_rect, SK_ColorBLUE, false); @@ -4081,16 +4083,16 @@ { shared_quad_state_occluder->SetAll( - gfx::Transform(), occluding_rect, occluding_rect, gfx::RRectF(), + gfx::Transform(), occluding_rect, occluding_rect, gfx::MaskFilterInfo(), occluding_rect, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quads[0]->SetNew(shared_quad_state_occluder, occluding_rect, occluding_rect, SK_ColorRED, false); shared_quad_state_occluded->SetAll( - gfx::Transform(), occluded_sqs_rect, occluded_sqs_rect, gfx::RRectF(), - occluded_sqs_rect, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + gfx::Transform(), occluded_sqs_rect, occluded_sqs_rect, + gfx::MaskFilterInfo(), occluded_sqs_rect, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); for (int i = 1; i < 4; i++) { quads[i]->SetNew(shared_quad_state_occluded, quad_rects[i - 1], quad_rects[i - 1], SK_ColorRED, false); @@ -4184,9 +4186,9 @@ for (const auto& r : occluding_rects) { SharedQuadState* shared_quad_state_occluder = frame.render_pass_list.front()->CreateAndAppendSharedQuadState(); - shared_quad_state_occluder->SetAll(gfx::Transform(), r, r, gfx::RRectF(), r, - is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state_occluder->SetAll( + gfx::Transform(), r, r, gfx::MaskFilterInfo(), r, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); SolidColorDrawQuad* quad = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); @@ -4198,7 +4200,7 @@ SharedQuadState* shared_quad_state_occluded = frame.render_pass_list.front()->CreateAndAppendSharedQuadState(); shared_quad_state_occluded->SetAll( - gfx::Transform(), occluded_rect, occluded_rect, gfx::RRectF(), + gfx::Transform(), occluded_rect, occluded_rect, gfx::MaskFilterInfo(), occluded_rect, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); SolidColorDrawQuad* occluded_quad = @@ -4266,7 +4268,7 @@ frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); shared_quad_state_occluding->SetAll( - gfx::Transform(), occluding_rect, occluding_rect, gfx::RRectF(), + gfx::Transform(), occluding_rect, occluding_rect, gfx::MaskFilterInfo(), occluding_rect, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); occluding_quad->SetNew(shared_quad_state_occluding, occluding_rect, @@ -4279,7 +4281,7 @@ frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); shared_quad_state_occluded->SetAll( - gfx::Transform(), occluded_rect, occluded_rect, gfx::RRectF(), + gfx::Transform(), occluded_rect, occluded_rect, gfx::MaskFilterInfo(), occluded_rect, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); occluded_quad->SetNew(shared_quad_state_occluded, occluded_rect, @@ -4315,7 +4317,8 @@ // // * -> Visible rect for the quads. gfx::Rect quad_rect(10, 10, 1000, 1000); - gfx::RRectF rounded_corner_bounds(gfx::RectF(quad_rect), 10.f); + gfx::MaskFilterInfo mask_filter_info(gfx::RRectF(gfx::RectF(quad_rect), 10.f), + false); gfx::Rect occluded_quad_rect_1(0, 20, 600, 490); gfx::Rect occluded_quad_rect_2(600, 20, 600, 490); gfx::Rect occluded_quad_rect_3(0, 510, 600, 490); @@ -4352,9 +4355,9 @@ { shared_quad_state_occluded->SetAll( - gfx::Transform(), occluded_sqs_rect, occluded_sqs_rect, gfx::RRectF(), - occluded_sqs_rect, is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + gfx::Transform(), occluded_sqs_rect, occluded_sqs_rect, + gfx::MaskFilterInfo(), occluded_sqs_rect, is_clipped, + are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); occluded_quad_1->SetNew(shared_quad_state_occluded, occluded_quad_rect_1, occluded_quad_rect_1, SK_ColorRED, false); occluded_quad_2->SetNew(shared_quad_state_occluded, occluded_quad_rect_2, @@ -4364,10 +4367,9 @@ occluded_quad_4->SetNew(shared_quad_state_occluded, occluded_quad_rect_4, occluded_quad_rect_4, SK_ColorRED, false); - shared_quad_state_with_rrect->SetAll(gfx::Transform(), quad_rect, quad_rect, - rounded_corner_bounds, quad_rect, - is_clipped, are_contents_opaque, - opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state_with_rrect->SetAll( + gfx::Transform(), quad_rect, quad_rect, mask_filter_info, quad_rect, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); rounded_corner_quad->SetNew(shared_quad_state_with_rrect, quad_rect, quad_rect, SK_ColorBLUE, false);
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc index 31fa3d2..83af241 100644 --- a/components/viz/service/display/gl_renderer.cc +++ b/components/viz/service/display/gl_renderer.cc
@@ -1798,9 +1798,9 @@ SetShaderOpacity(params->quad->shared_quad_state->opacity); if (current_program_->rounded_corner_rect_location() != -1) { - SetShaderRoundedCorner( - params->quad->shared_quad_state->rounded_corner_bounds, - params->window_matrix * params->projection_matrix); + SetShaderRoundedCorner(params->quad->shared_quad_state->mask_filter_info + .rounded_corner_bounds(), + params->window_matrix * params->projection_matrix); } SetShaderQuadF(params->surface_quad); } @@ -2201,7 +2201,7 @@ SetShaderColor(color, opacity); if (current_program_->rounded_corner_rect_location() != -1) { SetShaderRoundedCorner( - quad->shared_quad_state->rounded_corner_bounds, + quad->shared_quad_state->mask_filter_info.rounded_corner_bounds(), current_frame()->window_matrix * current_frame()->projection_matrix); } @@ -2388,7 +2388,7 @@ SetShaderOpacity(quad->shared_quad_state->opacity); if (current_program_->rounded_corner_rect_location() != -1) { SetShaderRoundedCorner( - quad->shared_quad_state->rounded_corner_bounds, + quad->shared_quad_state->mask_filter_info.rounded_corner_bounds(), current_frame()->window_matrix * current_frame()->projection_matrix); } DCHECK(CanApplyBlendModeUsingBlendFunc(quad->shared_quad_state->blend_mode)); @@ -2488,7 +2488,7 @@ SetShaderOpacity(quad->shared_quad_state->opacity); if (current_program_->rounded_corner_rect_location() != -1) { SetShaderRoundedCorner( - quad->shared_quad_state->rounded_corner_bounds, + quad->shared_quad_state->mask_filter_info.rounded_corner_bounds(), current_frame()->window_matrix * current_frame()->projection_matrix); } @@ -2628,7 +2628,7 @@ if (current_program_->rounded_corner_rect_location() != -1) { SetShaderRoundedCorner( - quad->shared_quad_state->rounded_corner_bounds, + quad->shared_quad_state->mask_filter_info.rounded_corner_bounds(), current_frame()->window_matrix * current_frame()->projection_matrix); } @@ -2772,7 +2772,7 @@ SetShaderOpacity(quad->shared_quad_state->opacity); if (current_program_->rounded_corner_rect_location() != -1) { SetShaderRoundedCorner( - quad->shared_quad_state->rounded_corner_bounds, + quad->shared_quad_state->mask_filter_info.rounded_corner_bounds(), current_frame()->window_matrix * current_frame()->projection_matrix); } gfx::Size texture_size = lock.size(); @@ -2832,7 +2832,7 @@ if (current_program_->rounded_corner_rect_location() != -1) { SetShaderRoundedCorner( - draw_cache_.rounded_corner_bounds, + draw_cache_.mask_filter_info.rounded_corner_bounds(), current_frame()->window_matrix * current_frame()->projection_matrix); } @@ -2945,8 +2945,8 @@ draw_cache_.needs_blending != quad->ShouldDrawWithBlending() || draw_cache_.nearest_neighbor != quad->nearest_neighbor || draw_cache_.background_color != quad->background_color || - draw_cache_.rounded_corner_bounds != - quad->shared_quad_state->rounded_corner_bounds || + draw_cache_.mask_filter_info != + quad->shared_quad_state->mask_filter_info || draw_cache_.matrix_data.size() >= max_quads || draw_cache_.is_video_frame != quad->is_video_frame) { FlushTextureQuadCache(SHARED_BINDING); @@ -2956,8 +2956,7 @@ draw_cache_.needs_blending = quad->ShouldDrawWithBlending(); draw_cache_.nearest_neighbor = quad->nearest_neighbor; draw_cache_.background_color = quad->background_color; - draw_cache_.rounded_corner_bounds = - quad->shared_quad_state->rounded_corner_bounds; + draw_cache_.mask_filter_info = quad->shared_quad_state->mask_filter_info; draw_cache_.is_video_frame = quad->is_video_frame; } @@ -4207,7 +4206,6 @@ ca_layer_overlay->shared_state->clip_rect.y(), ca_layer_overlay->shared_state->clip_rect.width(), ca_layer_overlay->shared_state->clip_rect.height()}; - const gfx::RectF& rect = ca_layer_overlay->shared_state->rounded_corner_bounds.rect(); GLfloat rounded_corner_rect[5] = { @@ -4354,9 +4352,9 @@ if (!use_fast_path_solid_color_quad_) return false; - // Rounded corners require blending with the background, which is not possible + // Mask filters require blending with the background, which is not possible // with the glClear draw method. - if (!sqs->rounded_corner_bounds.IsEmpty()) + if (!sqs->mask_filter_info.IsEmpty()) return false; // 3D transforms need vertex computation in 3D and cannot be handled using
diff --git a/components/viz/service/display/gl_renderer_draw_cache.h b/components/viz/service/display/gl_renderer_draw_cache.h index a637154e..6abe06cc 100644 --- a/components/viz/service/display/gl_renderer_draw_cache.h +++ b/components/viz/service/display/gl_renderer_draw_cache.h
@@ -10,7 +10,7 @@ #include "base/macros.h" #include "components/viz/service/display/program_binding.h" #include "third_party/skia/include/core/SkColor.h" -#include "ui/gfx/rrect_f.h" +#include "ui/gfx/mask_filter_info.h" namespace viz { @@ -39,7 +39,7 @@ bool needs_blending = false; bool nearest_neighbor = false; SkColor background_color = 0; - gfx::RRectF rounded_corner_bounds; + gfx::MaskFilterInfo mask_filter_info; // A cache for the coalesced quad data. std::vector<Float4> uv_xform_data;
diff --git a/components/viz/service/display/gl_renderer_unittest.cc b/components/viz/service/display/gl_renderer_unittest.cc index 6be5c8f..cb48150 100644 --- a/components/viz/service/display/gl_renderer_unittest.cc +++ b/components/viz/service/display/gl_renderer_unittest.cc
@@ -792,7 +792,7 @@ root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(gfx::Transform(), gfx::Rect(viewport_size), - gfx::Rect(1023, 1023), gfx::RRectF(), + gfx::Rect(1023, 1023), gfx::MaskFilterInfo(), gfx::Rect(1023, 1023), false, false, 1, SkBlendMode::kSrcOver, 0); overlay_quad->SetNew(shared_state, gfx::Rect(1023, 1023), @@ -855,7 +855,7 @@ root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(gfx::Transform(), gfx::Rect(viewport_size), - gfx::Rect(1025, 1025), gfx::RRectF(), + gfx::Rect(1025, 1025), gfx::MaskFilterInfo(), gfx::Rect(1025, 1025), false, false, 1, SkBlendMode::kSrcOver, 0); overlay_quad->SetNew(shared_state, gfx::Rect(1025, 1025), @@ -913,7 +913,7 @@ root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(gfx::Transform(), gfx::Rect(viewport_size), - gfx::Rect(kTextureSize), gfx::RRectF(), + gfx::Rect(kTextureSize), gfx::MaskFilterInfo(), gfx::Rect(kTextureSize), false, false, 1, SkBlendMode::kSrcOver, 0); overlay_quad->SetNew(shared_state, gfx::Rect(kTextureSize), @@ -1450,8 +1450,9 @@ visible_rect.Inset(10, 20, 30, 40); SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(gfx::Transform(), gfx::Rect(), rect, gfx::RRectF(), rect, - false, false, 1, SkBlendMode::kSrcOver, 0); + shared_state->SetAll(gfx::Transform(), gfx::Rect(), rect, + gfx::MaskFilterInfo(), rect, false, false, 1, + SkBlendMode::kSrcOver, 0); YUVVideoDrawQuad* quad = root_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>(); @@ -2003,8 +2004,8 @@ // Add rounded corners to the solid color draw quad so that the fast path // of drawing using glClear is not used. - root_pass->shared_quad_state_list.front()->rounded_corner_bounds = - gfx::RRectF(gfx::RectF(quad_rect), 2.f); + root_pass->shared_quad_state_list.front()->mask_filter_info = + gfx::MaskFilterInfo(gfx::RRectF(gfx::RectF(quad_rect), 2.f), false); renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); DrawFrame(renderer_.get(), viewport_size); @@ -2031,8 +2032,8 @@ // Add rounded corners to the solid color draw quad so that the fast path // of drawing using glClear is not used. - root_pass->shared_quad_state_list.front()->rounded_corner_bounds = - gfx::RRectF(gfx::RectF(quad_rect), 1.f); + root_pass->shared_quad_state_list.front()->mask_filter_info = + gfx::MaskFilterInfo(gfx::RRectF(gfx::RectF(quad_rect), 1.f), false); renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); DrawFrame(renderer_.get(), viewport_size); @@ -2910,7 +2911,7 @@ root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(gfx::Transform(), gfx::Rect(viewport_size), - gfx::Rect(viewport_size), gfx::RRectF(), + gfx::Rect(viewport_size), gfx::MaskFilterInfo(), gfx::Rect(viewport_size), false, false, 1, SkBlendMode::kSrcOver, 0); overlay_quad->SetNew(shared_state, gfx::Rect(viewport_size), @@ -3222,8 +3223,8 @@ root_pass->damage_rect = root_pass_damage_rect; cc::AddQuad(root_pass, quad_rect, SK_ColorRED); - root_pass->shared_quad_state_list.front()->rounded_corner_bounds = - gfx::RRectF(gfx::RectF(quad_rect), 5.f); + root_pass->shared_quad_state_list.front()->mask_filter_info = + gfx::MaskFilterInfo(gfx::RRectF(gfx::RectF(quad_rect), 5.f), false); // Fast Solid color draw quads should not be executed. AddExpectations(false /*use_fast_path*/, gfx::Rect()); @@ -3695,8 +3696,8 @@ gfx::RectF tex_coord_rect(0, 0, 1, 1); SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, - false, false, 1, SkBlendMode::kSrcOver, 0); + shared_state->SetAll(gfx::Transform(), rect, rect, gfx::MaskFilterInfo(), + rect, false, false, 1, SkBlendMode::kSrcOver, 0); YUVVideoDrawQuad* quad = root_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>(); quad->SetNew(shared_state, rect, rect, needs_blending, tex_coord_rect, @@ -4110,8 +4111,8 @@ sqs->is_clipped = true; sqs->clip_rect = gfx::Rect(2, 2, 6, 6); const float radius = 2; - sqs->rounded_corner_bounds = - gfx::RRectF(gfx::RectF(sqs->clip_rect), radius); + sqs->mask_filter_info = gfx::MaskFilterInfo( + gfx::RRectF(gfx::RectF(sqs->clip_rect), radius), false); switch (subtest) { case 0: @@ -4131,8 +4132,12 @@ break; case 2: // Subtest 2 has a non-simple rounded rect. - sqs->rounded_corner_bounds.SetCornerRadii( - gfx::RRectF::Corner::kUpperLeft, 1, 1); + gfx::RRectF rounded_corner_bounds = + sqs->mask_filter_info.rounded_corner_bounds(); + rounded_corner_bounds.SetCornerRadii(gfx::RRectF::Corner::kUpperLeft, 1, + 1); + sqs->mask_filter_info = + gfx::MaskFilterInfo(rounded_corner_bounds, false); // Called 2 extra times in order to set up the rounded corner // parameters in the shader, because the CALayer is not handling // the rounded corners. @@ -5094,7 +5099,7 @@ root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(gfx::Transform(), gfx::Rect(viewport_size), - gfx::Rect(50, 50), gfx::RRectF(), + gfx::Rect(50, 50), gfx::MaskFilterInfo(), gfx::Rect(viewport_size), false, false, 1, SkBlendMode::kSrcOver, 0); overlay_quad->SetNew(
diff --git a/components/viz/service/display/overlay_candidate.cc b/components/viz/service/display/overlay_candidate.cc index d320f89..2ef62f7 100644 --- a/components/viz/service/display/overlay_candidate.cc +++ b/components/viz/service/display/overlay_candidate.cc
@@ -142,8 +142,8 @@ // We don't support an opacity value different than one for an overlay plane. if (quad->shared_quad_state->opacity != 1.f) return false; - // We can't support overlays with rounded corner clipping. - if (!quad->shared_quad_state->rounded_corner_bounds.IsEmpty()) + // We can't support overlays with mask filter. + if (!quad->shared_quad_state->mask_filter_info.IsEmpty()) return false; // We support only kSrc (no blending) and kSrcOver (blending with premul). if (!(quad->shared_quad_state->blend_mode == SkBlendMode::kSrc ||
diff --git a/components/viz/service/display/overlay_processor_using_strategy.cc b/components/viz/service/display/overlay_processor_using_strategy.cc index f8645cf..beddfaf3 100644 --- a/components/viz/service/display/overlay_processor_using_strategy.cc +++ b/components/viz/service/display/overlay_processor_using_strategy.cc
@@ -159,6 +159,15 @@ bool always_unoccluded = overlay.is_unoccluded && previous_frame_underlay_was_unoccluded; + // We need to make sure that when we change the overlay we damage the + // region where the underlay will be positioned. This is because a + // black transparent hole is made for the underlay to show through + // but its possible that the damage for this quad is less than the + // complete size of the underlay. https://crbug.com/1130733 + if (!same_underlay_rect) { + damage_rect->Union(this_frame_underlay_rect); + } + if (same_underlay_rect && !transition_from_occluded_to_unoccluded && (always_unoccluded || overlay.no_occluding_damage)) { damage_rect->Subtract(this_frame_underlay_rect);
diff --git a/components/viz/service/display/overlay_unittest.cc b/components/viz/service/display/overlay_unittest.cc index dbd4763..02838d8d 100644 --- a/components/viz/service/display/overlay_unittest.cc +++ b/components/viz/service/display/overlay_unittest.cc
@@ -2043,18 +2043,22 @@ } TEST_F(UnderlayTest, UpdateDamageRectWhenNoPromotion) { - // In the first pass there is an overlay promotion and the expected damage - // size should be unchanged. - // In the second pass there is no overlay promotion, but the damage should be - // the union of the damage_rect with CreateRenderPass's output_rect which is - // {0, 0, 256, 256}. - bool has_fullscreen_candidate[] = {true, false}; - gfx::Rect damages[] = {gfx::Rect(0, 0, 32, 32), gfx::Rect(0, 0, 312, 16)}; - gfx::Rect expected_damages[] = {gfx::Rect(0, 0, 32, 32), + // In the first pass there is an overlay promotion and the expected damage is + // a union of the hole made for the underlay and the incoming damage. In the + // second pass there is no occluding damage so the incoming damage is + // attributed to the overlay candidate and the final output damage is zero. In + // the third pass there is no overlay promotion, but the damage should be the + // union of the damage_rect with CreateRenderPass's output_rect which is {0, + // 0, 256, 256}. This is due to the demotion of the current overlay. + bool has_fullscreen_candidate[] = {true, true, false}; + gfx::Rect damages[] = {gfx::Rect(0, 0, 32, 32), gfx::Rect(0, 0, 32, 32), + gfx::Rect(0, 0, 312, 16)}; + gfx::Rect expected_damages[] = {gfx::Rect(0, 0, 256, 256), + gfx::Rect(0, 0, 0, 0), gfx::Rect(0, 0, 312, 256)}; - size_t expected_candidate_size[] = {1, 0}; + size_t expected_candidate_size[] = {1, 1, 0}; - for (int i = 0; i < 2; ++i) { + for (size_t i = 0; i < base::size(expected_damages); ++i) { auto pass = CreateRenderPass(); if (has_fullscreen_candidate[i]) { @@ -3191,7 +3195,7 @@ quad_state->SetAll( /*quad_layer_rect=*/quad_to_target_transform, quad_rect, /*visible_quad_layer_rect=*/quad_rect, - /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/gfx::Rect(), + /*mask_filter_info=*/gfx::MaskFilterInfo(), /*clip_rect=*/gfx::Rect(), /*is_clipped=*/false, /*are contents opaque=*/true, /*opacity=*/1.f,
diff --git a/components/viz/service/display/renderer_perftest.cc b/components/viz/service/display/renderer_perftest.cc index 6589178..83154b0 100644 --- a/components/viz/service/display/renderer_perftest.cc +++ b/components/viz/service/display/renderer_perftest.cc
@@ -143,19 +143,18 @@ gfx::Transform quad_to_target_transform, const gfx::Rect& rect, CompositorRenderPass* render_pass, - const gfx::RRectF& rrect) { + const gfx::MaskFilterInfo& mask_filter_info) { const gfx::Rect layer_rect = rect; const gfx::Rect visible_layer_rect = rect; const gfx::Rect clip_rect = rect; const bool is_clipped = false; const bool are_contents_opaque = false; const float opacity = 1.0f; - const gfx::RRectF rounded_corner_bounds = rrect; const SkBlendMode blend_mode = SkBlendMode::kSrcOver; const int sorting_context_id = 0; SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(quad_to_target_transform, layer_rect, visible_layer_rect, - rounded_corner_bounds, clip_rect, is_clipped, + mask_filter_info, clip_rect, is_clipped, are_contents_opaque, opacity, blend_mode, sorting_context_id); return shared_state; @@ -499,7 +498,7 @@ std::unique_ptr<CompositorRenderPass> pass = CreateTestRootRenderPass(); SharedQuadState* shared_state = CreateTestSharedQuadState( - gfx::Transform(), kSurfaceRect, pass.get(), gfx::RRectF()); + gfx::Transform(), kSurfaceRect, pass.get(), gfx::MaskFilterInfo()); CreateTestTextureDrawQuad(resource_list_.back().id, kSurfaceRect, /*background_color=*/SK_ColorTRANSPARENT, @@ -534,7 +533,7 @@ do { std::unique_ptr<CompositorRenderPass> pass = CreateTestRootRenderPass(); SharedQuadState* shared_state = CreateTestSharedQuadState( - gfx::Transform(), kSurfaceRect, pass.get(), gfx::RRectF()); + gfx::Transform(), kSurfaceRect, pass.get(), gfx::MaskFilterInfo()); for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { @@ -571,7 +570,7 @@ do { std::unique_ptr<CompositorRenderPass> pass = CreateTestRootRenderPass(); SharedQuadState* shared_state = CreateTestSharedQuadState( - gfx::Transform(), kSurfaceRect, pass.get(), gfx::RRectF()); + gfx::Transform(), kSurfaceRect, pass.get(), gfx::MaskFilterInfo()); for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { @@ -630,7 +629,7 @@ // SharedQuadState SharedQuadState* shared_state = CreateTestSharedQuadState( current_transform, gfx::Rect(kSurfaceSize), pass.get(), - gfx::RRectF()); + gfx::MaskFilterInfo()); ResourceId resource_id = share_resources ? resource_list_[0].id : resource_list_[i].id; CreateTestTileDrawQuad(resource_id, gfx::Rect(kTileSize), kTextureSize,
diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc index 744d39f..aac9365 100644 --- a/components/viz/service/display/renderer_pixeltest.cc +++ b/components/viz/service/display/renderer_pixeltest.cc
@@ -151,12 +151,12 @@ const bool is_clipped = false; const bool are_contents_opaque = false; const float opacity = 1.0f; - const gfx::RRectF rounded_corner_bounds = rrect; + const gfx::MaskFilterInfo mask_filter_info(rrect, false); const SkBlendMode blend_mode = SkBlendMode::kSrcOver; int sorting_context_id = 0; SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(quad_to_target_transform, layer_rect, visible_layer_rect, - rounded_corner_bounds, clip_rect, is_clipped, + mask_filter_info, clip_rect, is_clipped, are_contents_opaque, opacity, blend_mode, sorting_context_id); return shared_state; @@ -176,7 +176,7 @@ int sorting_context_id = 0; SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(quad_to_target_transform, layer_rect, visible_layer_rect, - /*rounded_corner_bounds=*/gfx::RRectF(), clip_rect, + /*mask_filter_info=*/gfx::MaskFilterInfo(), clip_rect, is_clipped, are_contents_opaque, opacity, blend_mode, sorting_context_id); return shared_state; @@ -5279,6 +5279,10 @@ // Confirm that the trail can't be drawn beyond the presentation area. TEST_P(DelegatedInkTest, TrailExtendsBeyondPresentationArea) { + // TODO(crbug.com/1021566): Enable this test for SkiaRenderer Dawn. + if (renderer_type() == RendererType::kSkiaDawn) + return; + const gfx::RectF kPresentationArea(30, 30, 100, 100); CreateAndSendMetadata(gfx::PointF(50.2f, 89.999f), 15.22f, SK_ColorCYAN, kPresentationArea); @@ -5334,7 +5338,7 @@ &pass_list, base::FilePath( FILE_PATH_LITERAL("delegated_ink_trail_on_batched_quads.png")), - cc::ExactPixelComparator(true))); + cc::FuzzyPixelOffByOneComparator(true))); } #endif // !defined(OS_ANDROID)
diff --git a/components/viz/service/display/skia_readback_pixeltest.cc b/components/viz/service/display/skia_readback_pixeltest.cc index 509179b4..64d15de 100644 --- a/components/viz/service/display/skia_readback_pixeltest.cc +++ b/components/viz/service/display/skia_readback_pixeltest.cc
@@ -49,7 +49,7 @@ const gfx::Rect clip_rect = rect; SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(gfx::Transform(), layer_rect, visible_layer_rect, - gfx::RRectF(), clip_rect, /*is_clipped=*/false, + gfx::MaskFilterInfo(), clip_rect, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/1.0f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index af54c9f..7e5fb225 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc
@@ -1237,8 +1237,8 @@ if (ShouldApplyRoundedCorner(quad)) { // Transform by the window and projection matrix to go from target to // device space, which should always be a scale+translate. - SkRRect corner_bounds = - SkRRect(quad->shared_quad_state->rounded_corner_bounds); + SkRRect corner_bounds = SkRRect( + quad->shared_quad_state->mask_filter_info.rounded_corner_bounds()); SkMatrix to_device; gfx::TransformToFlattenedSkMatrix(target_to_device, &to_device); @@ -2591,13 +2591,10 @@ overlay->rpdq = nullptr; gfx::Transform target_to_device = current_frame()->window_matrix * current_frame()->projection_matrix; - // Use nullptr scissor, so we can always render the whole render pass in an - // overlay backing. - // TODO(penghuang): reusing overlay backing from previous frame to avoid - // reproducing the overlay backing if the render pass content quad properties - // and content are not changed. + const gfx::Rect* scissor = is_scissor_enabled_ ? &scissor_rect_ : nullptr; + DrawQuadParams params = CalculateDrawQuadParams( - target_to_device, /*scissor=*/nullptr, quad, /*draw_region=*/nullptr); + target_to_device, scissor, quad, /*draw_region=*/nullptr); DrawRPDQParams rpdq_params = CalculateRPDQParams(quad, ¶ms); // |filter_bounds| is the content space bounds that includes any filtered
diff --git a/components/viz/service/display/software_renderer.cc b/components/viz/service/display/software_renderer.cc index 3aafdbd..a7db4ee 100644 --- a/components/viz/service/display/software_renderer.cc +++ b/components/viz/service/display/software_renderer.cc
@@ -257,7 +257,8 @@ } if (should_apply_rounded_corner) - SetClipRRect(quad->shared_quad_state->rounded_corner_bounds); + SetClipRRect( + quad->shared_quad_state->mask_filter_info.rounded_corner_bounds()); gfx::Transform quad_rect_matrix; QuadRectTransform(&quad_rect_matrix,
diff --git a/components/viz/service/display/software_renderer_unittest.cc b/components/viz/service/display/software_renderer_unittest.cc index 83b8301f..eaeb103c 100644 --- a/components/viz/service/display/software_renderer_unittest.cc +++ b/components/viz/service/display/software_renderer_unittest.cc
@@ -153,7 +153,7 @@ SharedQuadState* shared_quad_state = root_render_pass->CreateAndAppendSharedQuadState(); shared_quad_state->SetAll(gfx::Transform(), outer_rect, outer_rect, - gfx::RRectF(), outer_rect, false, true, 1.0, + gfx::MaskFilterInfo(), outer_rect, false, true, 1.0, SkBlendMode::kSrcOver, 0); auto* inner_quad = root_render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); @@ -221,7 +221,7 @@ SharedQuadState* shared_quad_state = root_render_pass->CreateAndAppendSharedQuadState(); shared_quad_state->SetAll(gfx::Transform(), outer_rect, outer_rect, - gfx::RRectF(), outer_rect, false, true, 1.0, + gfx::MaskFilterInfo(), outer_rect, false, true, 1.0, SkBlendMode::kSrcOver, 0); auto* inner_quad = root_render_pass->CreateAndAppendDrawQuad<TileDrawQuad>(); inner_quad->SetNew(shared_quad_state, inner_rect, inner_rect, needs_blending, @@ -283,7 +283,7 @@ SharedQuadState* shared_quad_state = root_render_pass->CreateAndAppendSharedQuadState(); shared_quad_state->SetAll(gfx::Transform(), tile_rect, tile_rect, - gfx::RRectF(), tile_rect, false, true, 1.0, + gfx::MaskFilterInfo(), tile_rect, false, true, 1.0, SkBlendMode::kSrcOver, 0); auto* quad = root_render_pass->CreateAndAppendDrawQuad<TileDrawQuad>(); quad->SetNew(shared_quad_state, tile_rect, tile_rect, needs_blending, @@ -444,8 +444,8 @@ SharedQuadState* shared_quad_state = root_pass->CreateAndAppendSharedQuadState(); shared_quad_state->SetAll(gfx::Transform(), outer_rect, outer_rect, - gfx::RRectF(), gfx::Rect(1, 1, 30, 30), true, - true, 1.0, SkBlendMode::kSrcOver, 0); + gfx::MaskFilterInfo(), gfx::Rect(1, 1, 30, 30), + true, true, 1.0, SkBlendMode::kSrcOver, 0); auto* outer_quad = root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); outer_quad->SetNew(shared_quad_state, outer_rect, outer_rect, SK_ColorGREEN, false); @@ -458,10 +458,10 @@ SharedQuadState* shared_quad_state = root_pass->CreateAndAppendSharedQuadState(); - shared_quad_state->SetAll(gfx::Transform(), inner_rect, inner_rect, - gfx::RRectF(gfx::RectF(5, 5, 10, 10), 2), - inner_rect, false, true, 1.0, - SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll( + gfx::Transform(), inner_rect, inner_rect, + gfx::MaskFilterInfo(gfx::RRectF(gfx::RectF(5, 5, 10, 10), 2), false), + inner_rect, false, true, 1.0, SkBlendMode::kSrcOver, 0); auto* inner_quad = root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); inner_quad->SetNew(shared_quad_state, inner_rect, inner_rect, SK_ColorRED, false);
diff --git a/components/viz/service/display/surface_aggregator.cc b/components/viz/service/display/surface_aggregator.cc index fb1fd60..c4dbdd5 100644 --- a/components/viz/service/display/surface_aggregator.cc +++ b/components/viz/service/display/surface_aggregator.cc
@@ -100,25 +100,6 @@ gfx::ContentColorUsage content_color_usage = gfx::ContentColorUsage::kSRGB; }; -struct SurfaceAggregator::RoundedCornerInfo { - RoundedCornerInfo() = default; - - // |target_transform| is the transform that maps |bounds_arg| from its current - // space into the desired target space. It must be an axis aligned transform. - RoundedCornerInfo(const gfx::RRectF& bounds_arg, - bool is_fast_rounded_corner, - const gfx::Transform target_transform) - : bounds(bounds_arg), is_fast_rounded_corner(is_fast_rounded_corner) { - if (bounds.IsEmpty()) - return; - bool success = target_transform.TransformRRectF(&bounds); - DCHECK(success); - } - - gfx::RRectF bounds; - bool is_fast_rounded_corner; -}; - struct SurfaceAggregator::RenderPassMapEntry { explicit RenderPassMapEntry(CompositorRenderPass* render_pass) : render_pass(render_pass) {} @@ -388,7 +369,7 @@ bool ignore_undamaged, gfx::Rect* damage_rect_in_quad_space, bool* damage_rect_in_quad_space_valid, - const RoundedCornerInfo& rounded_corner_info) { + const gfx::MaskFilterInfo& mask_filter_info) { SurfaceId primary_surface_id = surface_quad->surface_range.end(); Surface* latest_surface = manager_->GetLatestInFlightSurface(surface_quad->surface_range); @@ -412,7 +393,7 @@ // can happen after a Viz process crash. if (!latest_surface || !latest_surface->HasActiveFrame()) { EmitDefaultBackgroundColorQuad(surface_quad, target_transform, clip_rect, - dest_pass, rounded_corner_info); + dest_pass, mask_filter_info); return; } @@ -432,13 +413,13 @@ surface_quad->shared_quad_state, target_transform, clip_rect, fallback_frame.metadata.root_background_color, - dest_pass, rounded_corner_info); + dest_pass, mask_filter_info); } EmitSurfaceContent(latest_surface, parent_device_scale_factor, surface_quad, target_transform, clip_rect, dest_pass, ignore_undamaged, damage_rect_in_quad_space, damage_rect_in_quad_space_valid, - rounded_corner_info); + mask_filter_info); } void SurfaceAggregator::EmitSurfaceContent( @@ -451,7 +432,7 @@ bool ignore_undamaged, gfx::Rect* damage_rect_in_quad_space, bool* damage_rect_in_quad_space_valid, - const RoundedCornerInfo& rounded_corner_info) { + const gfx::MaskFilterInfo& mask_filter_info) { // If this surface's id is already in our referenced set then it creates // a cycle in the graph and should be dropped. SurfaceId surface_id = surface->surface_id(); @@ -540,7 +521,7 @@ bool merge_pass = CanPotentiallyMergePass(*surface_quad) && !reflected_and_scaled && copy_requests.empty() && combined_transform.Preserves2dAxisAlignment() && - CanMergeRoundedCorner(rounded_corner_info, *render_pass_list.back()); + CanMergeMaskFilterInfo(mask_filter_info, *render_pass_list.back()); if (frame.metadata.delegated_ink_metadata) { // The metadata must be taken off of the surface, rather than a copy being @@ -594,7 +575,7 @@ CopyQuadsToPass(source, copy_pass.get(), frame.device_scale_factor(), child_to_parent_map, gfx::Transform(), {}, surface_id, - RoundedCornerInfo()); + gfx::MaskFilterInfo()); // If the render pass has copy requests, or should be cached, or has // moving-pixel filters, or in a moving-pixel surface, we should damage the @@ -640,7 +621,7 @@ CopyQuadsToPass(last_pass, dest_pass, frame.device_scale_factor(), child_to_parent_map, combined_transform, quads_clip, - surface_id, rounded_corner_info); + surface_id, mask_filter_info); } else { auto* shared_quad_state = CopyAndScaleSharedQuadState( source_sqs, scaled_quad_to_target_transform, target_transform, @@ -650,7 +631,7 @@ gfx::ScaleToEnclosingRect(source_sqs->visible_quad_layer_rect, inverse_extra_content_scale_x, inverse_extra_content_scale_y), - clip_rect, dest_pass, rounded_corner_info); + clip_rect, dest_pass, mask_filter_info); // At this point, we need to calculate three values in order to construct // the CompositorRenderPassDrawQuad: @@ -710,14 +691,14 @@ const gfx::Transform& target_transform, const ClipData& clip_rect, AggregatedRenderPass* dest_pass, - const RoundedCornerInfo& rounded_corner_info) { + const gfx::MaskFilterInfo& mask_filter_info) { // The primary surface is unavailable and there is no fallback // surface specified so create a SolidColorDrawQuad with the default // background color. SkColor background_color = surface_quad->default_background_color; auto* shared_quad_state = CopySharedQuadState(surface_quad->shared_quad_state, target_transform, - clip_rect, dest_pass, rounded_corner_info); + clip_rect, dest_pass, mask_filter_info); auto* solid_color_quad = dest_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); @@ -733,7 +714,7 @@ const ClipData& clip_rect, SkColor background_color, AggregatedRenderPass* dest_pass, - const RoundedCornerInfo& rounded_corner_info) { + const gfx::MaskFilterInfo& mask_filter_info) { bool has_transparent_background = background_color == SK_ColorTRANSPARENT; // If the fallback Surface's active CompositorFrame has a non-transparent @@ -751,7 +732,7 @@ primary_shared_quad_state, primary_shared_quad_state->quad_to_target_transform, target_transform, right_gutter_rect, right_gutter_rect, clip_rect, dest_pass, - rounded_corner_info); + mask_filter_info); auto* right_gutter = dest_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); @@ -768,7 +749,7 @@ primary_shared_quad_state, primary_shared_quad_state->quad_to_target_transform, target_transform, bottom_gutter_rect, bottom_gutter_rect, clip_rect, dest_pass, - rounded_corner_info); + mask_filter_info); auto* bottom_gutter = dest_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); @@ -820,7 +801,7 @@ /*quad_to_target_transform=*/gfx::Transform(), /*quad_layer_rect=*/output_rect, /*visible_quad_layer_rect=*/output_rect, - /*rounded_corner_bounds=*/gfx::RRectF(), + /*mask_filter_info=*/gfx::MaskFilterInfo(), /*clip_rect=*/gfx::Rect(), /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/1.f, /*blend_mode=*/SkBlendMode::kSrc, /*sorting_context_id=*/0); @@ -877,7 +858,7 @@ /*quad_to_target_transform=*/root_surface_transform_, /*quad_layer_rect=*/output_rect, /*visible_quad_layer_rect=*/output_rect, - /*rounded_corner_bounds=*/gfx::RRectF(), + /*mask_filter_info=*/gfx::MaskFilterInfo(), /*clip_rect=*/gfx::Rect(), /*is_clipped=*/false, are_contents_opaque, /*opacity=*/1.f, /*blend_mode=*/SkBlendMode::kSrcOver, /*sorting_context_id=*/0); @@ -897,11 +878,11 @@ const gfx::Transform& target_transform, const ClipData& clip_rect, AggregatedRenderPass* dest_render_pass, - const RoundedCornerInfo& rounded_corner_info) { + const gfx::MaskFilterInfo& mask_filter_info) { return CopyAndScaleSharedQuadState( source_sqs, source_sqs->quad_to_target_transform, target_transform, source_sqs->quad_layer_rect, source_sqs->visible_quad_layer_rect, - clip_rect, dest_render_pass, rounded_corner_info); + clip_rect, dest_render_pass, mask_filter_info); } SharedQuadState* SurfaceAggregator::CopyAndScaleSharedQuadState( @@ -912,7 +893,7 @@ const gfx::Rect& visible_quad_layer_rect, const ClipData& clip_rect, AggregatedRenderPass* dest_render_pass, - const RoundedCornerInfo& rounded_corner_info) { + const gfx::MaskFilterInfo& mask_filter_info) { auto* shared_quad_state = dest_render_pass->CreateAndAppendSharedQuadState(); ClipData new_clip_rect = CalculateClipRect( clip_rect, {source_sqs->is_clipped, source_sqs->clip_rect}, @@ -928,12 +909,10 @@ new_transform.ConcatTransform(target_transform); shared_quad_state->SetAll( - new_transform, quad_layer_rect, visible_quad_layer_rect, - rounded_corner_info.bounds, new_clip_rect.rect, new_clip_rect.is_clipped, + new_transform, quad_layer_rect, visible_quad_layer_rect, mask_filter_info, + new_clip_rect.rect, new_clip_rect.is_clipped, source_sqs->are_contents_opaque, source_sqs->opacity, source_sqs->blend_mode, source_sqs->sorting_context_id); - shared_quad_state->is_fast_rounded_corner = - rounded_corner_info.is_fast_rounded_corner; shared_quad_state->de_jelly_delta_y = source_sqs->de_jelly_delta_y; @@ -948,7 +927,7 @@ const gfx::Transform& target_transform, const ClipData& clip_rect, const SurfaceId& surface_id, - const RoundedCornerInfo& parent_rounded_corner_info) { + const gfx::MaskFilterInfo& parent_mask_filter_info) { const QuadList& source_quad_list = source_pass.quad_list; const SharedQuadState* last_copied_source_shared_quad_state = nullptr; @@ -988,12 +967,12 @@ ProcessOverlayDamageList(source_pass, dest_pass, target_transform, surface_id, clip_rect, &overlay_damage_index); - RoundedCornerInfo new_rounded_corner_info = parent_rounded_corner_info; + gfx::MaskFilterInfo new_mask_filter_info = parent_mask_filter_info; for (auto* quad : source_quad_list) { // Both cannot be set at once. If this happens then a surface is being // merged when it should not. - DCHECK(quad->shared_quad_state->rounded_corner_bounds.IsEmpty() || - parent_rounded_corner_info.bounds.IsEmpty()); + DCHECK(quad->shared_quad_state->mask_filter_info.IsEmpty() || + parent_mask_filter_info.IsEmpty()); if (quad->material == DrawQuad::Material::kSurfaceContent) { const auto* surface_quad = SurfaceDrawQuad::MaterialCast(quad); @@ -1004,27 +983,24 @@ if (!surface_quad->surface_range.end().is_valid()) continue; - if (parent_rounded_corner_info.bounds.IsEmpty()) { - new_rounded_corner_info = RoundedCornerInfo( - quad->shared_quad_state->rounded_corner_bounds, - quad->shared_quad_state->is_fast_rounded_corner, target_transform); + if (parent_mask_filter_info.IsEmpty()) { + new_mask_filter_info = quad->shared_quad_state->mask_filter_info; + new_mask_filter_info.Transform(target_transform); } - HandleSurfaceQuad( - surface_quad, parent_device_scale_factor, target_transform, clip_rect, - dest_pass, ignore_undamaged, &damage_rect_in_quad_space, - &damage_rect_in_quad_space_valid, new_rounded_corner_info); + HandleSurfaceQuad(surface_quad, parent_device_scale_factor, + target_transform, clip_rect, dest_pass, + ignore_undamaged, &damage_rect_in_quad_space, + &damage_rect_in_quad_space_valid, new_mask_filter_info); } else { if (quad->shared_quad_state != last_copied_source_shared_quad_state) { - if (parent_rounded_corner_info.bounds.IsEmpty()) { - new_rounded_corner_info = - RoundedCornerInfo(quad->shared_quad_state->rounded_corner_bounds, - quad->shared_quad_state->is_fast_rounded_corner, - target_transform); + if (parent_mask_filter_info.IsEmpty()) { + new_mask_filter_info = quad->shared_quad_state->mask_filter_info; + new_mask_filter_info.Transform(target_transform); } SharedQuadState* dest_shared_quad_state = CopySharedQuadState(quad->shared_quad_state, target_transform, - clip_rect, dest_pass, new_rounded_corner_info); + clip_rect, dest_pass, new_mask_filter_info); if (quad == quad_with_overlay_damage_index) dest_shared_quad_state->overlay_damage_index = overlay_damage_index; @@ -1182,7 +1158,7 @@ child_to_parent_map, apply_surface_transform_to_root_pass ? surface_transform : gfx::Transform(), - {}, surface->surface_id(), RoundedCornerInfo()); + {}, surface->surface_id(), gfx::MaskFilterInfo()); // If the render pass has copy requests, or should be cached, or has // moving-pixel filters, or in a moving-pixel surface, we should damage the @@ -1631,23 +1607,24 @@ } } -bool SurfaceAggregator::CanMergeRoundedCorner( - const RoundedCornerInfo& rounded_corner_info, +bool SurfaceAggregator::CanMergeMaskFilterInfo( + const gfx::MaskFilterInfo& mask_filter_info, const CompositorRenderPass& root_render_pass) { - // If the quad has no rounded corner, then we do not have to block merging. - if (rounded_corner_info.bounds.IsEmpty()) + // If the quad has no mask filter, then we do not have to block merging. + if (mask_filter_info.IsEmpty()) return true; // If the quad has rounded corner and it is not a fast rounded corner, we // cannot merge. - if (!rounded_corner_info.is_fast_rounded_corner) + if (mask_filter_info.HasRoundedCorners() && + !mask_filter_info.is_fast_rounded_corner()) return false; - // If any of the quads in the root render pass has a rounded corner of its + // If any of the quads in the root render pass has a mask filter of its // own, then we cannot merge. const SharedQuadStateList& sqs_list = root_render_pass.shared_quad_state_list; for (const auto* sqs : sqs_list) { - if (!sqs->rounded_corner_bounds.IsEmpty()) + if (!sqs->mask_filter_info.IsEmpty()) return false; } return true; @@ -2145,8 +2122,8 @@ auto* new_state = root_pass->CreateAndAppendSharedQuadState(); gfx::Transform transform; new_state->SetAll(transform, render_pass->output_rect, - render_pass->output_rect, gfx::RRectF(), jelly_clip, true, - false, opacity, blend_mode, 0); + render_pass->output_rect, gfx::MaskFilterInfo(), jelly_clip, + true, false, opacity, blend_mode, 0); auto* quad = root_pass->CreateAndAppendDrawQuad<AggregatedRenderPassDrawQuad>(); quad->SetNew(new_state, render_pass->output_rect, render_pass->output_rect,
diff --git a/components/viz/service/display/surface_aggregator.h b/components/viz/service/display/surface_aggregator.h index 7f49924..fa40470a 100644 --- a/components/viz/service/display/surface_aggregator.h +++ b/components/viz/service/display/surface_aggregator.h
@@ -93,7 +93,6 @@ private: struct ClipData; struct PrewalkResult; - struct RoundedCornerInfo; struct ChildSurfaceInfo; struct RenderPassMapEntry; @@ -115,7 +114,7 @@ bool ignore_undamaged, gfx::Rect* damage_rect_in_quad_space, bool* damage_rect_in_quad_space_valid, - const RoundedCornerInfo& rounded_corner_info); + const gfx::MaskFilterInfo& rounded_corner_info); void EmitSurfaceContent(Surface* surface, float parent_device_scale_factor, @@ -126,14 +125,14 @@ bool ignore_undamaged, gfx::Rect* damage_rect_in_quad_space, bool* damage_rect_in_quad_space_valid, - const RoundedCornerInfo& rounded_corner_info); + const gfx::MaskFilterInfo& rounded_corner_info); void EmitDefaultBackgroundColorQuad( const SurfaceDrawQuad* surface_quad, const gfx::Transform& target_transform, const ClipData& clip_rect, AggregatedRenderPass* dest_pass, - const RoundedCornerInfo& rounded_corner_info); + const gfx::MaskFilterInfo& rounded_corner_info); void EmitGutterQuadsIfNecessary( const gfx::Rect& primary_rect, @@ -143,14 +142,14 @@ const ClipData& clip_rect, SkColor background_color, AggregatedRenderPass* dest_pass, - const RoundedCornerInfo& rounded_corner_info); + const gfx::MaskFilterInfo& rounded_corner_info); SharedQuadState* CopySharedQuadState( const SharedQuadState* source_sqs, const gfx::Transform& target_transform, const ClipData& clip_rect, AggregatedRenderPass* dest_render_pass, - const RoundedCornerInfo& rounded_corner_info); + const gfx::MaskFilterInfo& rounded_corner_info); SharedQuadState* CopyAndScaleSharedQuadState( const SharedQuadState* source_sqs, @@ -160,7 +159,7 @@ const gfx::Rect& visible_quad_layer_rect, const ClipData& clip_rect, AggregatedRenderPass* dest_render_pass, - const RoundedCornerInfo& rounded_corner_info); + const gfx::MaskFilterInfo& rounded_corner_info); void CopyQuadsToPass( const CompositorRenderPass& source_pass, @@ -170,7 +169,7 @@ const gfx::Transform& target_transform, const ClipData& clip_rect, const SurfaceId& surface_id, - const RoundedCornerInfo& rounded_corner_info); + const gfx::MaskFilterInfo& rounded_corner_info); // Recursively walks through the render pass and updates the // |can_use_backdrop_filter_cache| flag on all RenderPassDrawQuads(RPDQ). @@ -235,9 +234,9 @@ void PropagateCopyRequestPasses(); // Returns true if the quad list from the render pass provided can be merged - // with its target render pass based on rounded corners. - bool CanMergeRoundedCorner(const RoundedCornerInfo& rounded_corner_info, - const CompositorRenderPass& root_render_pass); + // with its target render pass based on mask filter info. + bool CanMergeMaskFilterInfo(const gfx::MaskFilterInfo& rounded_corner_info, + const CompositorRenderPass& root_render_pass); int ChildIdForSurface(Surface* surface); bool IsSurfaceFrameIndexSameAsPrevious(const Surface* surface) const;
diff --git a/components/viz/service/display/surface_aggregator_pixeltest.cc b/components/viz/service/display/surface_aggregator_pixeltest.cc index e5ff4f3e..96203ed4 100644 --- a/components/viz/service/display/surface_aggregator_pixeltest.cc +++ b/components/viz/service/display/surface_aggregator_pixeltest.cc
@@ -72,7 +72,7 @@ const gfx::Size& size) { const gfx::Rect layer_rect = gfx::Rect(size); const gfx::Rect visible_layer_rect = gfx::Rect(size); - const gfx::RRectF rounded_corner_bounds = gfx::RRectF(); + const gfx::MaskFilterInfo mask_filter_info; const gfx::Rect clip_rect = gfx::Rect(size); bool is_clipped = false; bool are_contents_opaque = false; @@ -80,7 +80,7 @@ const SkBlendMode blend_mode = SkBlendMode::kSrcOver; auto* shared_state = render_pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(transform, layer_rect, visible_layer_rect, - rounded_corner_bounds, clip_rect, is_clipped, + mask_filter_info, clip_rect, is_clipped, are_contents_opaque, opacity, blend_mode, 0); return shared_state; } @@ -381,7 +381,7 @@ root_surface_id, this->GetNextDisplayTime(), gfx::OVERLAY_TRANSFORM_NONE); bool discard_alpha = false; - cc::ExactPixelComparator pixel_comparator(discard_alpha); + cc::FuzzyPixelOffByOneComparator pixel_comparator(discard_alpha); auto* pass_list = &aggregated_frame.render_pass_list; EXPECT_TRUE(this->RunPixelTest( pass_list, base::FilePath(FILE_PATH_LITERAL("delegated_ink_trail.png")),
diff --git a/components/viz/service/display/surface_aggregator_unittest.cc b/components/viz/service/display/surface_aggregator_unittest.cc index dd7a8022..77e457b 100644 --- a/components/viz/service/display/surface_aggregator_unittest.cc +++ b/components/viz/service/display/surface_aggregator_unittest.cc
@@ -183,8 +183,7 @@ float opacity, const gfx::Transform& transform, bool stretch_content_to_fill_bounds, - const gfx::RRectF& rounded_corner_bounds, - bool is_fast_rounded_corner) { + const gfx::MaskFilterInfo& mask_filter_info) { Quad quad; quad.material = DrawQuad::Material::kSurfaceContent; quad.primary_surface_rect = primary_surface_rect; @@ -193,8 +192,7 @@ quad.surface_range = surface_range; quad.default_background_color = default_background_color; quad.stretch_content_to_fill_bounds = stretch_content_to_fill_bounds; - quad.rounded_corner_bounds = rounded_corner_bounds; - quad.is_fast_rounded_corner = is_fast_rounded_corner; + quad.mask_filter_info = mask_filter_info; return quad; } @@ -218,8 +216,7 @@ gfx::Rect primary_surface_rect; float opacity; gfx::Transform to_target_transform; - gfx::RRectF rounded_corner_bounds; - bool is_fast_rounded_corner; + gfx::MaskFilterInfo mask_filter_info; bool allow_merge = true; // Set when material==DrawQuad::Material::kSolidColor. @@ -279,8 +276,7 @@ desc.to_target_transform, desc.surface_range, desc.default_background_color, desc.stretch_content_to_fill_bounds, - desc.rounded_corner_bounds, desc.is_fast_rounded_corner, - desc.allow_merge); + desc.mask_filter_info, desc.allow_merge); break; case DrawQuad::Material::kCompositorRenderPass: AddRenderPassQuad(pass, desc.render_pass_id, desc.transform, @@ -371,8 +367,7 @@ const SurfaceRange& surface_range, SkColor default_background_color, bool stretch_content_to_fill_bounds, - const gfx::RRectF& rounded_corner_bounds, - bool is_fast_rounded_corner, + const gfx::MaskFilterInfo& mask_filter_info, bool allow_merge) { gfx::Transform layer_to_target_transform = transform; gfx::Rect layer_bounds(primary_surface_rect); @@ -384,10 +379,9 @@ auto* shared_quad_state = pass->CreateAndAppendSharedQuadState(); shared_quad_state->SetAll(layer_to_target_transform, layer_bounds, - visible_layer_rect, rounded_corner_bounds, - clip_rect, is_clipped, are_contents_opaque, - opacity, blend_mode, 0); - shared_quad_state->is_fast_rounded_corner = is_fast_rounded_corner; + visible_layer_rect, mask_filter_info, clip_rect, + is_clipped, are_contents_opaque, opacity, + blend_mode, 0); SurfaceDrawQuad* surface_quad = pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); @@ -404,9 +398,9 @@ bool can_use_backdrop_filter_cache) { gfx::Rect output_rect = gfx::Rect(0, 0, 5, 5); auto* shared_state = pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(transform, output_rect, output_rect, gfx::RRectF(), - output_rect, false, false, 1, SkBlendMode::kSrcOver, - 0); + shared_state->SetAll(transform, output_rect, output_rect, + gfx::MaskFilterInfo(), output_rect, false, false, 1, + SkBlendMode::kSrcOver, 0); auto* quad = pass->CreateAndAppendDrawQuad<CompositorRenderPassDrawQuad>(); quad->SetAll( shared_state, output_rect, output_rect, /*needs_blending=*/true, @@ -419,7 +413,7 @@ const gfx::Rect& output_rect) { auto* shared_state = pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(gfx::Transform(), output_rect, output_rect, - gfx::RRectF(), output_rect, false, false, 1, + gfx::MaskFilterInfo(), output_rect, false, false, 1, SkBlendMode::kSrcOver, 0); auto* quad = pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>(); quad->SetNew(shared_state, output_rect, output_rect, false, @@ -553,8 +547,7 @@ for (const SurfaceRange& range : ranges) { quads.push_back(Quad::SurfaceQuad( range, SK_ColorWHITE, gfx::Rect(5, 5), 1.f, gfx::Transform(), - /*stretch_content_to_fill_bounds=*/false, gfx::RRectF(), - /*is_fast_border_radius*/ false)); + /*stretch_content_to_fill_bounds=*/false, gfx::MaskFilterInfo())); } std::vector<Pass> passes = {Pass(quads, SurfaceSize())}; CompositorRenderPassList pass_list; @@ -661,8 +654,7 @@ std::vector<Quad> quads = {Quad::SurfaceQuad( SurfaceRange(base::nullopt, embedded_surface_id), SK_ColorWHITE, gfx::Rect(5, 5), .5f, gfx::Transform(), - /*stretch_content_to_fill_bounds=*/false, gfx::RRectF(), - /*is_fast_border_radius*/ false)}; + /*stretch_content_to_fill_bounds=*/false, gfx::MaskFilterInfo())}; std::vector<Pass> passes = {Pass(quads, SurfaceSize())}; SubmitCompositorFrame(root_sink_.get(), passes, root_local_surface_id_, @@ -684,8 +676,7 @@ std::vector<Quad> quads = {Quad::SurfaceQuad( SurfaceRange(base::nullopt, embedded_surface_id), SK_ColorWHITE, gfx::Rect(5, 5), .9999f, gfx::Transform(), - /*stretch_content_to_fill_bounds=*/false, gfx::RRectF(), - /*is_fast_border_radius*/ false)}; + /*stretch_content_to_fill_bounds=*/false, gfx::MaskFilterInfo())}; std::vector<Pass> passes = {Pass(quads, SurfaceSize())}; SubmitCompositorFrame(root_sink_.get(), passes, root_local_surface_id_, @@ -720,11 +711,10 @@ embedded_local_surface_id, device_scale_factor); gfx::Transform rotate; rotate.Rotate(30); - std::vector<Quad> quads = { - Quad::SurfaceQuad(SurfaceRange(base::nullopt, embedded_surface_id), - SK_ColorWHITE, gfx::Rect(5, 5), 1.f, rotate, - /*stretch_content_to_fill_bounds=*/false, gfx::RRectF(), - /*is_fast_border_radius*/ false)}; + std::vector<Quad> quads = {Quad::SurfaceQuad( + SurfaceRange(base::nullopt, embedded_surface_id), SK_ColorWHITE, + gfx::Rect(5, 5), 1.f, rotate, + /*stretch_content_to_fill_bounds=*/false, gfx::MaskFilterInfo())}; std::vector<Pass> passes = {Pass(quads, SurfaceSize())}; SubmitCompositorFrame(root_sink_.get(), passes, root_local_surface_id_, @@ -2204,14 +2194,14 @@ ->render_pass_id); } -void AddSolidColorQuadWithBlendMode(const gfx::Size& size, - CompositorRenderPass* pass, - const SkBlendMode blend_mode, - const gfx::RRectF& corner_bounds) { +void AddSolidColorQuadWithBlendMode( + const gfx::Size& size, + CompositorRenderPass* pass, + const SkBlendMode blend_mode, + const gfx::MaskFilterInfo& mask_filter_info) { const gfx::Transform layer_to_target_transform; const gfx::Rect layer_rect(size); const gfx::Rect visible_layer_rect(size); - const gfx::RRectF rounded_corner_bounds = corner_bounds; const gfx::Rect clip_rect(size); bool is_clipped = false; @@ -2222,7 +2212,7 @@ bool force_anti_aliasing_off = false; auto* sqs = pass->CreateAndAppendSharedQuadState(); sqs->SetAll(layer_to_target_transform, layer_rect, visible_layer_rect, - rounded_corner_bounds, clip_rect, is_clipped, are_contents_opaque, + mask_filter_info, clip_rect, is_clipped, are_contents_opaque, opacity, blend_mode, 0); auto* color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); @@ -2291,7 +2281,7 @@ grandchild_pass->SetNew(pass_id, output_rect, damage_rect, transform_to_root_target); AddSolidColorQuadWithBlendMode(SurfaceSize(), grandchild_pass.get(), - blend_modes[2], gfx::RRectF()); + blend_modes[2], gfx::MaskFilterInfo()); QueuePassAsFrame(std::move(grandchild_pass), grandchild_local_surface_id, device_scale_factor, grandchild_support.get()); @@ -2305,7 +2295,7 @@ child_one_pass->SetNew(pass_id, output_rect, damage_rect, transform_to_root_target); AddSolidColorQuadWithBlendMode(SurfaceSize(), child_one_pass.get(), - blend_modes[1], gfx::RRectF()); + blend_modes[1], gfx::MaskFilterInfo()); auto* grandchild_surface_quad = child_one_pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); grandchild_surface_quad->SetNew( @@ -2314,7 +2304,7 @@ SurfaceRange(base::nullopt, grandchild_surface_id), SK_ColorWHITE, /*stretch_content_to_fill_bounds=*/false); AddSolidColorQuadWithBlendMode(SurfaceSize(), child_one_pass.get(), - blend_modes[3], gfx::RRectF()); + blend_modes[3], gfx::MaskFilterInfo()); QueuePassAsFrame(std::move(child_one_pass), child_one_local_surface_id, device_scale_factor, child_one_support.get()); @@ -2328,7 +2318,7 @@ child_two_pass->SetNew(pass_id, output_rect, damage_rect, transform_to_root_target); AddSolidColorQuadWithBlendMode(SurfaceSize(), child_two_pass.get(), - blend_modes[5], gfx::RRectF()); + blend_modes[5], gfx::MaskFilterInfo()); QueuePassAsFrame(std::move(child_two_pass), child_two_local_surface_id, device_scale_factor, child_two_support.get()); @@ -2337,7 +2327,7 @@ transform_to_root_target); AddSolidColorQuadWithBlendMode(SurfaceSize(), root_pass.get(), blend_modes[0], - gfx::RRectF()); + gfx::MaskFilterInfo()); auto* child_one_surface_quad = root_pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); child_one_surface_quad->SetNew( @@ -2346,7 +2336,7 @@ SurfaceRange(base::nullopt, child_one_surface_id), SK_ColorWHITE, /*stretch_content_to_fill_bounds=*/false); AddSolidColorQuadWithBlendMode(SurfaceSize(), root_pass.get(), blend_modes[4], - gfx::RRectF()); + gfx::MaskFilterInfo()); auto* child_two_surface_quad = root_pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); child_two_surface_quad->SetNew( @@ -2355,7 +2345,7 @@ SurfaceRange(base::nullopt, child_two_surface_id), SK_ColorWHITE, /*stretch_content_to_fill_bounds=*/false); AddSolidColorQuadWithBlendMode(SurfaceSize(), root_pass.get(), blend_modes[6], - gfx::RRectF()); + gfx::MaskFilterInfo()); QueuePassAsFrame(std::move(root_pass), root_local_surface_id_, device_scale_factor, root_sink_.get()); @@ -2406,8 +2396,10 @@ // quad(d) - rounded corner [2] TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateRoundedCornerBounds) { - const gfx::RRectF kFastRoundedCornerBounds = gfx::RRectF(0, 0, 640, 480, 5); - const gfx::RRectF kRoundedCornerBounds = gfx::RRectF(0, 0, 100, 100, 2); + const gfx::MaskFilterInfo kMaskFilterInfoWithFastRoundedCorners( + gfx::RRectF(0, 0, 640, 480, 5), true); + const gfx::MaskFilterInfo kMaskFilterInfoWithRoundedCorners( + gfx::RRectF(0, 0, 100, 100, 2), false); ParentLocalSurfaceIdAllocator child_root_allocator; ParentLocalSurfaceIdAllocator child_one_allocator; @@ -2439,7 +2431,7 @@ child_three_pass->SetNew(pass_id, output_rect, damage_rect, transform_to_root_target); AddSolidColorQuadWithBlendMode(SurfaceSize(), child_three_pass.get(), - SkBlendMode::kSrcOver, gfx::RRectF()); + SkBlendMode::kSrcOver, gfx::MaskFilterInfo()); QueuePassAsFrame(std::move(child_three_pass), child_three_local_surface_id, device_scale_factor, child_three_support.get()); @@ -2454,7 +2446,7 @@ child_one_pass->SetNew(pass_id, output_rect, damage_rect, transform_to_root_target); AddSolidColorQuadWithBlendMode(SurfaceSize(), child_one_pass.get(), - SkBlendMode::kSrcOver, gfx::RRectF()); + SkBlendMode::kSrcOver, gfx::MaskFilterInfo()); // Add child three surface quad auto* child_three_surface_sqs = @@ -2482,9 +2474,10 @@ child_two_pass->SetNew(pass_id, output_rect, damage_rect, transform_to_root_target); AddSolidColorQuadWithBlendMode(SurfaceSize(), child_two_pass.get(), - SkBlendMode::kSrcOver, gfx::RRectF()); + SkBlendMode::kSrcOver, gfx::MaskFilterInfo()); AddSolidColorQuadWithBlendMode(SurfaceSize(), child_two_pass.get(), - SkBlendMode::kSrcOver, kRoundedCornerBounds); + SkBlendMode::kSrcOver, + kMaskFilterInfoWithRoundedCorners); QueuePassAsFrame(std::move(child_two_pass), child_two_local_surface_id, device_scale_factor, child_two_support.get()); @@ -2523,7 +2516,7 @@ // Add solid color quad AddSolidColorQuadWithBlendMode(SurfaceSize(), child_root_pass.get(), - SkBlendMode::kSrcOver, gfx::RRectF()); + SkBlendMode::kSrcOver, gfx::MaskFilterInfo()); QueuePassAsFrame(std::move(child_root_pass), child_root_local_surface_id, device_scale_factor, child_root_support.get()); @@ -2535,8 +2528,8 @@ auto* child_root_surface_quad = root_pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); child_root_surface_sqs->opacity = 1.f; - child_root_surface_sqs->rounded_corner_bounds = kFastRoundedCornerBounds; - child_root_surface_sqs->is_fast_rounded_corner = true; + child_root_surface_sqs->mask_filter_info = + kMaskFilterInfoWithFastRoundedCorners; child_root_surface_quad->SetNew( child_root_surface_sqs, gfx::Rect(SurfaceSize()), gfx::Rect(SurfaceSize()), @@ -2561,17 +2554,17 @@ const auto& aggregated_quad_list_of_surface = aggregated_pass_list[0]->quad_list; EXPECT_EQ(2u, aggregated_quad_list_of_surface.size()); - EXPECT_EQ(kRoundedCornerBounds, + EXPECT_EQ(kMaskFilterInfoWithRoundedCorners, aggregated_quad_list_of_surface.back() - ->shared_quad_state->rounded_corner_bounds); + ->shared_quad_state->mask_filter_info); // The root render pass will have all the remaining quads with the rounded // corner set on them. const auto& aggregated_quad_list_of_root = aggregated_pass_list[1]->quad_list; EXPECT_EQ(4u, aggregated_quad_list_of_root.size()); for (const auto* q : aggregated_quad_list_of_root) { - EXPECT_EQ(q->shared_quad_state->rounded_corner_bounds, - kFastRoundedCornerBounds); + EXPECT_EQ(q->shared_quad_state->mask_filter_info, + kMaskFilterInfoWithFastRoundedCorners); } } @@ -6760,12 +6753,11 @@ // root surface quads std::vector<Quad> root_surface_quads = { Quad::SolidColorQuad(SK_ColorRED, gfx::Rect(60, 0, 40, 40)), - Quad::SurfaceQuad(SurfaceRange(base::nullopt, child_surface_id), - SK_ColorWHITE, - /*primary_surface_rect*/ gfx::Rect(0, 0, 100, 100), - /*opacity*/ 1.f, video_transform, - /*stretch_content_to_fill_bounds=*/false, gfx::RRectF(), - /*is_fast_border_radius*/ false)}; + Quad::SurfaceQuad( + SurfaceRange(base::nullopt, child_surface_id), SK_ColorWHITE, + /*primary_surface_rect*/ gfx::Rect(0, 0, 100, 100), + /*opacity*/ 1.f, video_transform, + /*stretch_content_to_fill_bounds=*/false, gfx::MaskFilterInfo())}; std::vector<Pass> root_passes = { Pass(root_surface_quads, @@ -6885,8 +6877,7 @@ SurfaceRange(base::nullopt, child_surface_id), SK_ColorWHITE, /*primary_surface_rect*/ gfx::Rect(0, 0, 100, 100), /*opacity*/ 1.f, video_transform, - /*stretch_content_to_fill_bounds=*/false, gfx::RRectF(), - /*is_fast_border_radius*/ false)}; + /*stretch_content_to_fill_bounds=*/false, gfx::MaskFilterInfo())}; std::vector<Pass> root_passes = { Pass(root_surface_quads, @@ -6983,8 +6974,7 @@ SurfaceRange(base::nullopt, child_surface_id), SK_ColorWHITE, /*primary_surface_rect*/ gfx::Rect(0, 0, 100, 100), /*opacity*/ 1.f, video_transform, - /*stretch_content_to_fill_bounds=*/false, gfx::RRectF(), - /*is_fast_border_radius*/ false)}; + /*stretch_content_to_fill_bounds=*/false, gfx::MaskFilterInfo())}; std::vector<Pass> root_passes = { Pass(root_surface_quads, @@ -7308,7 +7298,8 @@ child_frame.render_pass_list[0] ->shared_quad_state_list.front() - ->rounded_corner_bounds = gfx::RRectF(0, 0, 100, 10, 5); + ->mask_filter_info = + gfx::MaskFilterInfo(gfx::RRectF(0, 0, 100, 10, 5), false); child_sink_->SubmitCompositorFrame(child_local_surface_id, std::move(child_frame)); @@ -7337,8 +7328,9 @@ auto* aggregated_first_pass_sqs = aggregated_frame.render_pass_list[0]->shared_quad_state_list.front(); - EXPECT_EQ(gfx::RRectF(0, 7, 100, 10, 5), - aggregated_first_pass_sqs->rounded_corner_bounds); + EXPECT_EQ( + gfx::RRectF(0, 7, 100, 10, 5), + aggregated_first_pass_sqs->mask_filter_info.rounded_corner_bounds()); } // Tests that the rounded corner bounds of a surface quad that gets transformed @@ -7380,11 +7372,11 @@ child_local_surface_id); { // Set an opacity in order to prevent merging into the root render pass. - std::vector<Quad> child_quads = { - Quad::SurfaceQuad(SurfaceRange(base::nullopt, grandchild_surface_id), - SK_ColorWHITE, gfx::Rect(5, 5), 0.5f, - gfx::Transform(), false, gfx::RRectF(0, 0, 96, 10, 5), - /*is_fast_border_radius*/ false)}; + std::vector<Quad> child_quads = {Quad::SurfaceQuad( + SurfaceRange(base::nullopt, grandchild_surface_id), SK_ColorWHITE, + gfx::Rect(5, 5), 0.5f, gfx::Transform(), false, + gfx::MaskFilterInfo(gfx::RRectF(0, 0, 96, 10, 5), + /*is_fast_rounded_corner=*/false))}; std::vector<Pass> child_passes = { Pass(child_quads, CompositorRenderPassId{1}, SurfaceSize())}; @@ -7402,7 +7394,7 @@ surface_transform.Translate(3, 4); std::vector<Quad> secondary_quads = {Quad::SurfaceQuad( SurfaceRange(base::nullopt, child_surface_id), SK_ColorWHITE, - gfx::Rect(5, 5), 1.f, surface_transform, false, gfx::RRectF(), false)}; + gfx::Rect(5, 5), 1.f, surface_transform, false, gfx::MaskFilterInfo())}; std::vector<Pass> root_passes = {Pass(secondary_quads, SurfaceSize())}; @@ -7427,8 +7419,9 @@ // Original rounded rect is (0, 0, 96, 10, 5). This then gets multiplied // by a device scale factor of 2 to (0, 0, 192, 20, 10), then moved // by a (3, 4) translation followed by a (0, 7) translation. - EXPECT_EQ(gfx::RRectF(3, 11, 192, 20, 10), - aggregated_first_pass_sqs->rounded_corner_bounds); + EXPECT_EQ( + gfx::RRectF(3, 11, 192, 20, 10), + aggregated_first_pass_sqs->mask_filter_info.rounded_corner_bounds()); } // This is a variant of RoundedCornerTransformedSurfaceQuad that does not @@ -7467,11 +7460,10 @@ SurfaceId child_surface_id(child_sink_->frame_sink_id(), child_local_surface_id); { - std::vector<Quad> child_quads = { - Quad::SurfaceQuad(SurfaceRange(base::nullopt, grandchild_surface_id), - SK_ColorWHITE, gfx::Rect(5, 5), 1.f, gfx::Transform(), - false, gfx::RRectF(0, 0, 96, 10, 5), - /*is_fast_border_radius*/ false)}; + std::vector<Quad> child_quads = {Quad::SurfaceQuad( + SurfaceRange(base::nullopt, grandchild_surface_id), SK_ColorWHITE, + gfx::Rect(5, 5), 1.f, gfx::Transform(), false, + gfx::MaskFilterInfo(gfx::RRectF(0, 0, 96, 10, 5), false))}; std::vector<Pass> child_passes = { Pass(child_quads, CompositorRenderPassId{1}, SurfaceSize())}; @@ -7489,8 +7481,7 @@ surface_transform.Translate(3, 4); std::vector<Quad> secondary_quads = {Quad::SurfaceQuad( SurfaceRange(base::nullopt, child_surface_id), SK_ColorWHITE, - gfx::Rect(5, 5), 1.f, surface_transform, false, gfx::RRectF(), - /*is_fast_border_radius*/ false)}; + gfx::Rect(5, 5), 1.f, surface_transform, false, gfx::MaskFilterInfo())}; std::vector<Pass> root_passes = {Pass(secondary_quads, SurfaceSize())}; @@ -7515,8 +7506,9 @@ // Original rounded rect is (0, 0, 96, 10, 5). This then gets multiplied // by a device scale factor of 2 to (0, 0, 192, 20, 10), then moved // by a (3, 4) translation followed by a (0, 7) translation. - EXPECT_EQ(gfx::RRectF(3, 11, 192, 20, 10), - aggregated_first_pass_sqs->rounded_corner_bounds); + EXPECT_EQ( + gfx::RRectF(3, 11, 192, 20, 10), + aggregated_first_pass_sqs->mask_filter_info.rounded_corner_bounds()); } TEST_F(SurfaceAggregatorValidSurfaceTest, TransformedRoundedSurfaceQuad) { @@ -7550,11 +7542,11 @@ // Root surface. gfx::Transform surface_transform; surface_transform.Translate(3, 4); - std::vector<Quad> secondary_quads = { - Quad::SurfaceQuad(SurfaceRange(base::nullopt, child_surface_id), - SK_ColorWHITE, gfx::Rect(5, 5), 1.f, surface_transform, - false, gfx::RRectF(0, 0, 96, 10, 5), - /* is_fast_border_radius */ true)}; + std::vector<Quad> secondary_quads = {Quad::SurfaceQuad( + SurfaceRange(base::nullopt, child_surface_id), SK_ColorWHITE, + gfx::Rect(5, 5), 1.f, surface_transform, false, + gfx::MaskFilterInfo(gfx::RRectF(0, 0, 96, 10, 5), + /*is_fast_rounded_corner=*/true))}; std::vector<Pass> root_passes = {Pass(secondary_quads, SurfaceSize())}; @@ -7581,8 +7573,9 @@ // The rounded rect on the surface quad is already in the space of the root // surface, so the (3, 4) translation should not apply to it. - EXPECT_EQ(gfx::RRectF(0, 0, 96, 10, 5), - aggregated_first_pass_sqs->rounded_corner_bounds); + EXPECT_EQ( + gfx::RRectF(0, 0, 96, 10, 5), + aggregated_first_pass_sqs->mask_filter_info.rounded_corner_bounds()); } // Verifies that if a child surface is embedded twice in the root surface,
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc index 2a8379f..73c56d47 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -527,6 +527,7 @@ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // Make sure there is no unsubmitted PaintFrame or PaintRenderPass. DCHECK(!current_paint_); + DCHECK(resource_sync_tokens_.empty()); SkSurfaceCharacterization characterization = CreateSkSurfaceCharacterization( size, BufferFormat(format), mipmap, std::move(color_space), @@ -705,9 +706,6 @@ void SkiaOutputSurfaceImpl::ScheduleOverlays( OverlayList overlays, std::vector<gpu::SyncToken> sync_tokens) { - std::move(resource_sync_tokens_.begin(), resource_sync_tokens_.end(), - std::back_inserter(sync_tokens)); - resource_sync_tokens_.clear(); auto task = base::BindOnce(&SkiaOutputSurfaceImplOnGpu::ScheduleOverlays, base::Unretained(impl_on_gpu_.get()), std::move(overlays),
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 04f3d64..810e77d 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -208,7 +208,6 @@ "//third_party/blink/public:scaled_resources", "//third_party/blink/public/common", "//third_party/blink/public/common:font_enumeration_table_proto", - "//third_party/blink/public/mojom:mojom_broadcastchannel_bindings", "//third_party/blink/public/mojom/dom_storage", "//third_party/blink/public/mojom/frame", "//third_party/blink/public/strings", @@ -261,6 +260,7 @@ "//ipc", "//media/mojo/mojom:remoting", "//third_party/blink/public/mojom:embedded_frame_sink_mojo_bindings", + "//third_party/blink/public/mojom:mojom_broadcastchannel_bindings", "//third_party/leveldatabase", ]
diff --git a/content/browser/accessibility/browser_accessibility_android.cc b/content/browser/accessibility/browser_accessibility_android.cc index 7dc456d..bfe1241f 100644 --- a/content/browser/accessibility/browser_accessibility_android.cc +++ b/content/browser/accessibility/browser_accessibility_android.cc
@@ -549,30 +549,37 @@ } base::string16 BrowserAccessibilityAndroid::GetStateDescription() const { + std::vector<base::string16> state_descs; + // For multiselectable state, generate a state description. We do not set a // state description for pop up/<select> to prevent double utterances. if (IsMultiselectable() && GetRole() != ax::mojom::Role::kPopUpButton) - return GetMultiselectableStateDescription(); - - // For Toggle buttons, we will append "on"/"off" in the state description. - if (GetRole() == ax::mojom::Role::kToggleButton) - return GetToggleButtonStateDescription(); + state_descs.push_back(GetMultiselectableStateDescription()); // For Checkboxes, if we are in a kMixed state, we will communicate - // "partially checked" through the state description. - if (IsCheckable() && !IsReportingCheckable()) - return GetCheckboxStateDescription(); + // "partially checked" through the state description. This is mutually + // exclusive with the on/off of toggle buttons below. + if (IsCheckable() && !IsReportingCheckable()) { + state_descs.push_back(GetCheckboxStateDescription()); + } else if (GetRole() == ax::mojom::Role::kToggleButton) { + // For Toggle buttons, we will append "on"/"off" in the state description. + state_descs.push_back(GetToggleButtonStateDescription()); + } - // For list boxes, use state description to communicate child item count. - if (GetRole() == ax::mojom::Role::kListBox) - return GetListBoxStateDescription(); + // For list boxes, use state description to communicate child item count. We + // will not communicate this in the case that the listbox is also + // multiselectable and has some items selected, since the same info would be + // communicated as "x of y selected". + if (GetRole() == ax::mojom::Role::kListBox && + (!IsMultiselectable() || !GetSelectedItemCount())) + state_descs.push_back(GetListBoxStateDescription()); // For list box items, use state description to communicate index of item. if (GetRole() == ax::mojom::Role::kListBoxOption) - return GetListBoxItemStateDescription(); + state_descs.push_back(GetListBoxItemStateDescription()); - // Otherwise we will not use state description - return base::string16(); + // Concatenate all state descriptions and return. + return base::JoinString(state_descs, base::ASCIIToUTF16(" ")); } base::string16 BrowserAccessibilityAndroid::GetMultiselectableStateDescription() @@ -1315,6 +1322,20 @@ return count; } +int BrowserAccessibilityAndroid::GetSelectedItemCount() const { + // Count the number of selected children. + int selected_count = 0; + for (PlatformChildIterator it = PlatformChildrenBegin(); + it != PlatformChildrenEnd(); ++it) { + BrowserAccessibilityAndroid* child = + static_cast<BrowserAccessibilityAndroid*>(it.get()); + if (child->IsSelected()) + selected_count++; + } + + return selected_count; +} + bool BrowserAccessibilityAndroid::CanScrollForward() const { if (IsSlider()) { // If it's not a native INPUT element, then increment and decrement
diff --git a/content/browser/accessibility/browser_accessibility_android.h b/content/browser/accessibility/browser_accessibility_android.h index e99ea62b..66347b5 100644 --- a/content/browser/accessibility/browser_accessibility_android.h +++ b/content/browser/accessibility/browser_accessibility_android.h
@@ -101,6 +101,7 @@ int GetItemIndex() const; int GetItemCount() const; + int GetSelectedItemCount() const; bool CanScrollForward() const; bool CanScrollBackward() const;
diff --git a/content/browser/appcache/appcache_disk_cache.cc b/content/browser/appcache/appcache_disk_cache.cc index 13f2f352..e5263754 100644 --- a/content/browser/appcache/appcache_disk_cache.cc +++ b/content/browser/appcache/appcache_disk_cache.cc
@@ -382,6 +382,12 @@ return_value = DoomEntry(call.key, copyable_callback); break; } + + // disk_cache::{Create,Open,Doom}Entry() call their callbacks iff they + // return net::ERR_IO_PENDING. In this case, the callback was not called. + // However, the corresponding ServiceWorkerDiskCache wrapper returned + // net::ERR_IO_PENDING as it queued up the pending call. To follow the + // disk_cache API contract, we need to call the callback ourselves here. if (return_value != net::ERR_IO_PENDING) copyable_callback.Run(return_value); }
diff --git a/content/browser/font_unique_name_lookup/font_unique_name_browsertest.cc b/content/browser/font_unique_name_lookup/font_unique_name_browsertest.cc index 358b07a8..b3c6b8c 100644 --- a/content/browser/font_unique_name_lookup/font_unique_name_browsertest.cc +++ b/content/browser/font_unique_name_lookup/font_unique_name_browsertest.cc
@@ -20,18 +20,10 @@ #include "content/browser/renderer_host/dwrite_font_lookup_table_builder_win.h" #endif -#if defined(OS_ANDROID) -#include "base/android/build_info.h" -#include "base/feature_list.h" -#include "components/viz/common/features.h" -#include "gpu/config/gpu_finch_features.h" -#endif - namespace content { namespace { #if defined(OS_ANDROID) -const char* kGoogleSans = "Google Sans"; const char* kExpectedFontFamilyNames[] = {"AndroidClock", "Roboto", "Droid Sans Mono", @@ -72,10 +64,7 @@ "Roboto Condensed", "Roboto Condensed", "Roboto Condensed", - "Roboto", - kGoogleSans, - kGoogleSans, - kGoogleSans}; + "Roboto"}; #elif defined(OS_LINUX) || defined(OS_CHROMEOS) const char* kExpectedFontFamilyNames[] = {"Ahem", "Arimo", @@ -215,22 +204,6 @@ ASSERT_TRUE(first_font_name); ASSERT_TRUE(first_font_name->is_string()); ASSERT_GT(first_font_name->GetString().size(), 0u); -#if defined(OS_ANDROID) - // Skip Android Google Sans test on Pixel devices < Marshmallow SDK level, - // as the firmware font files do not contain this font. - bool at_least_marshmallow = - base::android::BuildInfo::GetInstance()->sdk_int() >= - base::android::SDK_VERSION_MARSHMALLOW; - // https://crbug.com/1129552 work around the SkiaRenderer Vulkan bot not - // having the Google Sans font. - bool on_vulkan_bot = - base::FeatureList::IsEnabled(features::kUseSkiaRenderer) && - base::FeatureList::IsEnabled(features::kVulkan); - if ((!at_least_marshmallow || on_vulkan_bot) && - std::string(kExpectedFontFamilyNames[i]) == std::string(kGoogleSans)) { - continue; - } -#endif ASSERT_EQ(first_font_name->GetString(), kExpectedFontFamilyNames[i]); } }
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc index f9fb1e2..510e880 100644 --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc
@@ -1045,8 +1045,6 @@ DCHECK(browser_initiated_ || common_params_->initiator_origin.has_value()); DCHECK(!IsRendererDebugURL(common_params_->url)); DCHECK(common_params_->method == "POST" || !common_params_->post_data); - DCHECK((IsInMainFrame() && browser_initiated) || - commit_params_->frame_policy.has_value()); TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("navigation", "NavigationRequest", navigation_id_, "navigation_request", @@ -5012,24 +5010,8 @@ DCHECK(!HasCommitted()); DCHECK(!IsErrorPage()); - network::mojom::WebSandboxFlags out; - if (commit_params_->frame_policy) { - // This corresponds to the sandbox policy of the frame embedding the - // document that were active when the navigation started. - out = commit_params_->frame_policy->sandbox_flags; - } else { - // The document doesn't have a sandbox policy. This case should in theory - // contains only the navigations that are: - // - main frame. - // - browser initiated. - // - non-history. - // - non-error. - // - // TODO(arthursonzogni): In practice, a few navigations not complying with - // one of the 4 items above are using this path. They must be identified - // and removed. A set of DCHECK must be added. - out = network::mojom::WebSandboxFlags::kNone; - } + network::mojom::WebSandboxFlags out = + commit_params_->frame_policy.sandbox_flags; // The response can also restrict the policy further. if (response_head_) {
diff --git a/content/browser/renderer_host/navigator.cc b/content/browser/renderer_host/navigator.cc index 36f30f7e..4bac1a60 100644 --- a/content/browser/renderer_host/navigator.cc +++ b/content/browser/renderer_host/navigator.cc
@@ -301,12 +301,6 @@ } } - // For browser initiated navigation and same document navigation, frame policy - // in commit_params is nullopt and should use fallback value instead. - const blink::FramePolicy pending_frame_policy = - navigation_request->commit_params().frame_policy.value_or( - frame_tree_node->pending_frame_policy()); - // DidNavigateFrame() must be called before replicating the new origin and // other properties to proxies. This is because it destroys the subframes of // the frame we're navigating from, which might trigger those subframes to @@ -317,7 +311,7 @@ is_same_document_navigation, navigation_request->coop_status() .require_browsing_instance_swap() /* clear_proxies_on_commit */, - pending_frame_policy); + navigation_request->commit_params().frame_policy); // Save the new page's origin and other properties, and replicate them to // proxies, including the proxy created in DidNavigateFrame() to replace the
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 161a379..700b495 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -720,12 +720,12 @@ const url::Origin& subframe_origin) { // For main frame loads, the frame's feature policy is determined entirely by // response headers, which are provided by the renderer. - if (!parent || !commit_params.frame_policy) + if (!parent) return network::mojom::TrustTokenRedemptionPolicy::kPotentiallyPermit; const blink::FeaturePolicy* parent_policy = parent->feature_policy(); blink::ParsedFeaturePolicy container_policy = - commit_params.frame_policy->container_policy; + commit_params.frame_policy.container_policy; auto subframe_policy = blink::FeaturePolicy::CreateFromParentPolicy( parent_policy, container_policy, subframe_origin);
diff --git a/content/browser/site_instance_impl.h b/content/browser/site_instance_impl.h index 1420d0ba..7f1af8fa 100644 --- a/content/browser/site_instance_impl.h +++ b/content/browser/site_instance_impl.h
@@ -124,7 +124,7 @@ bool is_guest() const { return is_guest_; } - // Returns false if the site_url() is empty. + // Returns true if the site_url() is empty. bool is_empty() const { return site_url().possibly_invalid_spec().empty(); } SiteInfo& operator=(const SiteInfo& rhs);
diff --git a/content/common/navigation_params.mojom b/content/common/navigation_params.mojom index fb5b7a8..3f115208 100644 --- a/content/common/navigation_params.mojom +++ b/content/common/navigation_params.mojom
@@ -436,24 +436,25 @@ // Documents that will emit UKM events need valid ids. int64 document_ukm_source_id; - // A snapshot value of frame policy(both sandbox flags and container policy) + // A snapshot value of frame policy (both sandbox flags and container policy) // of the frame that is being navigated. The snapshot value is captured at the - // start of navigation. - // - The value is set to null for top-level browser-initiated navigation. - // - The value is also set to null when Ctrl-click was used to create a new - // tab and navigate, i.e. the document in new tab will inherit no - // frame_policy. - // - For navigation created from NavigationControllerImpl:: - // CreateNavigationRequestFromEntry which corresponds to history navigation, - // the value is set to current FrameTreeNode::pending_frame_policy in - // frame_tree_node. This behavior is currently undocumented and probably need - // further discussion. Another potential approach is to record frame policy - // value in NavigationEntry and reuse the historical value. + // start of navigation: // - For local frame navigation, the value is set at NavigationRequest:: // CreateRendererInitiated. // - For remote frame navigation, the value is set at // NavigationControllerImpl::CreateNavigationRequestFromLoadParams. - blink.mojom.FramePolicy? frame_policy; + // - For navigation created from + // NavigationControllerImpl::CreateNavigationRequestFromEntry which + // corresponds to history navigation, the value is set to current + // FrameTreeNode::pending_frame_policy in frame_tree_node. This behavior is + // currently undocumented and probably need further discussion. Another + // potential approach is to record frame policy value in NavigationEntry and + // reuse the historical value. + // + // The default FramePolicy is the laxest. It is used for: + // - Top-level browser-initiated navigations. + // - Ctrl+click navigation (opening a link in a new tab). + blink.mojom.FramePolicy frame_policy; // The names of origin trials to be force enabled for this navigation. array<string> force_enabled_origin_trials;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 4eb225a..166d63cf 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1296,7 +1296,6 @@ "//testing/gmock", "//testing/gtest", "//third_party/blink/public:blink", - "//third_party/blink/public/mojom:mojom_broadcastchannel_bindings", "//third_party/blink/public/mojom/frame", "//third_party/leveldatabase", "//third_party/mesa_headers",
diff --git a/content/test/data/accessibility/aria/aria-multiselectable-expected-android.txt b/content/test/data/accessibility/aria/aria-multiselectable-expected-android.txt index 3ea87b03..1873c8c 100644 --- a/content/test/data/accessibility/aria/aria-multiselectable-expected-android.txt +++ b/content/test/data/accessibility/aria/aria-multiselectable-expected-android.txt
@@ -1,5 +1,5 @@ android.webkit.WebView focusable focused scrollable -++android.widget.ListView role_description='list box' clickable collection focusable multiselectable name='My Listbox' state_description='multiselectable, none selected.' item_count=4 row_count=4 +++android.widget.ListView role_description='list box' clickable collection focusable multiselectable name='My Listbox' state_description='multiselectable, none selected. 4 items' item_count=4 row_count=4 ++++android.view.View clickable collection_item focusable name='Example 1' state_description='in list, item 1 of 4' ++++android.view.View clickable collection_item focusable name='Example 2' state_description='in list, item 2 of 4' item_index=1 row_index=1 ++++android.view.View clickable collection_item focusable name='Example 3' state_description='in list, item 3 of 4' item_index=2 row_index=2
diff --git a/content/test/data/accessibility/aria/aria-pressed-expected-android.txt b/content/test/data/accessibility/aria/aria-pressed-expected-android.txt index 87b308d..d878a67 100644 --- a/content/test/data/accessibility/aria/aria-pressed-expected-android.txt +++ b/content/test/data/accessibility/aria/aria-pressed-expected-android.txt
@@ -2,4 +2,4 @@ ++android.widget.Button role_description='button' clickable focusable name='Regular button' ++android.widget.ToggleButton role_description='toggle button' checkable clickable focusable name='Toggle button unpressed' state_description='Off' ++android.widget.ToggleButton role_description='toggle button' checkable checked clickable focusable name='Toggle button pressed' state_description='On' -++android.widget.ToggleButton role_description='toggle button' checkable clickable focusable name='Toggle button mixed' state_description='Off' \ No newline at end of file +++android.widget.ToggleButton role_description='toggle button' checkable clickable focusable name='Toggle button mixed' state_description='Partially Checked' \ No newline at end of file
diff --git a/content/test/data/accessibility/aria/aria-togglebutton-expected-android.txt b/content/test/data/accessibility/aria/aria-togglebutton-expected-android.txt index 5989142..dab075f 100644 --- a/content/test/data/accessibility/aria/aria-togglebutton-expected-android.txt +++ b/content/test/data/accessibility/aria/aria-togglebutton-expected-android.txt
@@ -2,4 +2,4 @@ ++android.widget.Button role_description='button' clickable focusable name='Regular button' ++android.widget.ToggleButton role_description='toggle button' checkable clickable focusable name='Toggle button' state_description='Off' ++android.widget.ToggleButton role_description='toggle button' checkable checked clickable focusable name='Toggle button' state_description='On' -++android.widget.ToggleButton role_description='toggle button' checkable clickable focusable name='Toggle button' state_description='Off' \ No newline at end of file +++android.widget.ToggleButton role_description='toggle button' checkable clickable focusable name='Toggle button' state_description='Partially Checked' \ No newline at end of file
diff --git a/content/test/data/font_src_local_matching.html b/content/test/data/font_src_local_matching.html index ade3d664..b0de52f 100644 --- a/content/test/data/font_src_local_matching.html +++ b/content/test/data/font_src_local_matching.html
@@ -51,9 +51,6 @@ ["RobotoCondensed-Italic", "0"], ["RobotoCondensed-Regular", "0"], ["Roboto-Italic", "0"], - ["Google Sans", "0"], - ["Google Sans Medium", "0"], - ["Google Sans Bold", "0"], ]; } else if (navigator.userAgent.indexOf("Linux") !== -1 || navigator.userAgent.indexOf("CrOS") !== -1) {
diff --git a/content/test/data/sxg/generate-test-certs.sh b/content/test/data/sxg/generate-test-certs.sh index b011697..1570b929 100755 --- a/content/test/data/sxg/generate-test-certs.sh +++ b/content/test/data/sxg/generate-test-certs.sh
@@ -24,6 +24,11 @@ openssl req -new -sha256 -key prime256v1.key -out prime256v1-sha256.csr \ -subj '/CN=test.example.org/O=Test/C=US' +openssl req -new -sha256 -key prime256v1.key -out \ + prime256v1-sha256-google-com.csr \ + -subj '/CN=google-com.example.org/O=Test/C=US' + + # Generate a certificate whose validity period starts at 2019-06-01 and # valid for 90 days. openssl ca -batch \ @@ -34,6 +39,17 @@ -in prime256v1-sha256.csr \ -out prime256v1-sha256.public.pem +# Generate a certificate whose validity period starts at 2019-06-01 and +# valid for 90 days. Same as above, but for google-com.example.org. +openssl ca -batch \ + -config google-com-ca.cnf \ + -extensions sxg_cert \ + -startdate 190601000000Z \ + -enddate 190830000000Z \ + -in prime256v1-sha256-google-com.csr \ + -out prime256v1-sha256-google-com.public.pem + + # Generate a certificate without CanSignHttpExchangesDraft extension. openssl ca -batch \ -config ca.cnf \
diff --git a/content/test/data/sxg/generate-test-sxgs.sh b/content/test/data/sxg/generate-test-sxgs.sh index e7c6e19f..3685b89 100755 --- a/content/test/data/sxg/generate-test-sxgs.sh +++ b/content/test/data/sxg/generate-test-sxgs.sh
@@ -33,6 +33,11 @@ gen-certurl -pem prime256v1-sha256.public.pem \ -ocsp $tmpdir/ocsp -sctDir $sctdir > test.example.org.public.pem.cbor + +# Same as above, but for google-com.example.org. +gen-certurl -pem prime256v1-sha256-google-com.public.pem \ + -ocsp $tmpdir/ocsp -sctDir $sctdir > google-com.example.org.public.pem.cbor + # Generate the certificate chain of "*.example.org", whose validity period is # more than 90 days. gen-certurl -pem prime256v1-sha256-validity-too-long.public.pem \ @@ -72,8 +77,8 @@ -uri https://google-com.example.org/test/ \ -status 200 \ -content test.html \ - -certificate prime256v1-sha256.public.pem \ - -certUrl https://cert.example.org/cert.msg \ + -certificate prime256v1-sha256-google-com.public.pem \ + -certUrl https://google-com.example.org/cert.msg \ -validityUrl https://google-com.example.org/resource.validity.msg \ -privateKey prime256v1.key \ -date $signature_date \
diff --git a/content/test/data/sxg/google-com-ca.cnf b/content/test/data/sxg/google-com-ca.cnf new file mode 100644 index 0000000..1a0f042 --- /dev/null +++ b/content/test/data/sxg/google-com-ca.cnf
@@ -0,0 +1,35 @@ +# This file is same as ca.cnf with the exception of subjectAltName field. +[ca] +default_ca = CA_root +preserve = yes + +[CA_root] +dir = out +new_certs_dir = $dir +database = $dir/index.txt +serial = $dir/serial +certificate = ../../../../net/data/ssl/certificates/root_ca_cert.pem +private_key = ../../../../net/data/ssl/certificates/root_ca_cert.pem +default_md = sha256 +unique_subject = no +policy = policy_anything + +[sxg_cert] +basicConstraints = CA:FALSE +# OID required for sxg since d54c469 +1.3.6.1.4.1.11129.2.1.22 = ASN1:NULL +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer +subjectAltName=DNS:google-com.example.org + +[policy_anything] +# Default signing policy +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = optional +emailAddress = optional
diff --git a/content/test/data/sxg/google-com.example.org.public.pem.cbor b/content/test/data/sxg/google-com.example.org.public.pem.cbor new file mode 100644 index 0000000..a29246a8 --- /dev/null +++ b/content/test/data/sxg/google-com.example.org.public.pem.cbor Binary files differ
diff --git a/content/test/data/sxg/google-com.example.org.public.pem.cbor.mock-http-headers b/content/test/data/sxg/google-com.example.org.public.pem.cbor.mock-http-headers new file mode 100644 index 0000000..ba8c1b7 --- /dev/null +++ b/content/test/data/sxg/google-com.example.org.public.pem.cbor.mock-http-headers
@@ -0,0 +1,2 @@ +HTTP/1.1 200 OK +Content-Type: application/cert-chain+cbor
diff --git a/content/test/data/sxg/google-com.example.org_test.sxg b/content/test/data/sxg/google-com.example.org_test.sxg index 7bf176a3..1a53ee27f 100644 --- a/content/test/data/sxg/google-com.example.org_test.sxg +++ b/content/test/data/sxg/google-com.example.org_test.sxg Binary files differ
diff --git a/content/test/data/sxg/prime256v1-sha256-google-com.csr b/content/test/data/sxg/prime256v1-sha256-google-com.csr new file mode 100644 index 0000000..dbb47f6 --- /dev/null +++ b/content/test/data/sxg/prime256v1-sha256-google-com.csr
@@ -0,0 +1,8 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIH4MIGfAgEAMD0xHzAdBgNVBAMMFmdvb2dsZS1jb20uZXhhbXBsZS5vcmcxDTAL +BgNVBAoMBFRlc3QxCzAJBgNVBAYTAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD +QgAElFfdVfWVnYyDSfXmIkjMokHtKd1SLpMcJiV1gzYsTABuyq5PUhaghqpelLbG +vTBUEYH8BupWh2DdIF01fR3Kw6AAMAoGCCqGSM49BAMCA0gAMEUCIQC4wI2Lo4CN +/8MDiD14faGKqizZZURk1wNln5qQ7ZhLngIgZ3XkkcNcemHTc5srzamFFNKJU2L3 +zpJjorgaC+H3rn8= +-----END CERTIFICATE REQUEST-----
diff --git a/content/test/data/sxg/prime256v1-sha256-google-com.public.pem b/content/test/data/sxg/prime256v1-sha256-google-com.public.pem new file mode 100644 index 0000000..1ba6d8ad --- /dev/null +++ b/content/test/data/sxg/prime256v1-sha256-google-com.public.pem
@@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 2 (0x2) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=California, L=Mountain View, O=Test CA, CN=Test Root CA + Validity + Not Before: Jun 1 00:00:00 2019 GMT + Not After : Aug 30 00:00:00 2019 GMT + Subject: CN=google-com.example.org, O=Test, C=US + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (256 bit) + pub: + 04:94:57:dd:55:f5:95:9d:8c:83:49:f5:e6:22:48: + cc:a2:41:ed:29:dd:52:2e:93:1c:26:25:75:83:36: + 2c:4c:00:6e:ca:ae:4f:52:16:a0:86:aa:5e:94:b6: + c6:bd:30:54:11:81:fc:06:ea:56:87:60:dd:20:5d: + 35:7d:1d:ca:c3 + ASN1 OID: prime256v1 + NIST CURVE: P-256 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + 1.3.6.1.4.1.11129.2.1.22: + .. + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Subject Key Identifier: + CF:65:B9:9B:EE:0E:EC:8E:A6:B9:69:96:82:20:F4:F7:8B:8A:B2:FA + X509v3 Authority Key Identifier: + keyid:9B:26:0B:8A:98:A9:BB:1D:B9:1F:1C:E3:1A:40:33:ED:8E:17:88:AB + + X509v3 Subject Alternative Name: + DNS:google-com.example.org + Signature Algorithm: sha256WithRSAEncryption + ae:16:c3:1d:a9:b1:53:86:22:ee:90:e6:07:e6:03:c1:a1:10: + 79:98:32:d9:61:31:f2:27:5c:6a:a2:80:c6:0b:d1:40:16:06: + 65:5e:b9:72:e1:77:e1:a9:02:bf:b9:18:56:8a:24:0f:b7:84: + 94:d7:53:51:e6:9f:51:fd:7e:fe:d2:64:9e:73:d0:97:2d:2f: + ad:64:41:28:ef:9e:e7:86:ca:18:04:39:7d:7d:b1:9f:3c:20: + f4:44:5b:a0:d4:00:28:bf:8c:c2:50:c9:c8:5e:cf:d5:1c:37: + 98:8e:2e:d8:81:71:43:79:77:60:6b:85:01:34:14:70:73:33: + 1d:df:6e:2e:30:b5:99:ff:0c:ac:82:b5:23:c2:f4:8c:8a:e0: + 53:f2:f4:3f:cb:18:78:3c:b3:f4:f9:41:e3:d4:83:75:24:c8: + b6:16:15:d7:36:d1:06:a3:9a:0b:59:6b:cd:e4:05:8e:25:d8: + 1f:44:bf:30:20:3b:92:dd:66:74:3b:e6:d2:91:0c:5a:81:ac: + d1:9d:3f:9e:fe:cd:31:a0:36:40:58:6f:01:01:f5:9c:f7:ab: + 81:91:3f:d3:f1:3c:29:a3:47:a0:60:71:55:86:8c:15:3e:9e: + 0c:54:45:04:4c:10:33:36:09:c5:88:56:3a:8e:78:3b:dc:5d: + 43:5a:cd:84 +-----BEGIN CERTIFICATE----- +MIIC9jCCAd6gAwIBAgIBAjANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzET +MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G +A1UECgwHVGVzdCBDQTEVMBMGA1UEAwwMVGVzdCBSb290IENBMB4XDTE5MDYwMTAw +MDAwMFoXDTE5MDgzMDAwMDAwMFowPTEfMB0GA1UEAwwWZ29vZ2xlLWNvbS5leGFt +cGxlLm9yZzENMAsGA1UECgwEVGVzdDELMAkGA1UEBhMCVVMwWTATBgcqhkjOPQIB +BggqhkjOPQMBBwNCAASUV91V9ZWdjINJ9eYiSMyiQe0p3VIukxwmJXWDNixMAG7K +rk9SFqCGql6Utsa9MFQRgfwG6laHYN0gXTV9HcrDo4GlMIGiMAkGA1UdEwQCMAAw +EAYKKwYBBAHWeQIBFgQCBQAwCwYDVR0PBAQDAgXgMBMGA1UdJQQMMAoGCCsGAQUF +BwMBMB0GA1UdDgQWBBTPZbmb7g7sjqa5aZaCIPT3i4qy+jAfBgNVHSMEGDAWgBSb +JguKmKm7HbkfHOMaQDPtjheIqzAhBgNVHREEGjAYghZnb29nbGUtY29tLmV4YW1w +bGUub3JnMA0GCSqGSIb3DQEBCwUAA4IBAQCuFsMdqbFThiLukOYH5gPBoRB5mDLZ +YTHyJ1xqooDGC9FAFgZlXrly4XfhqQK/uRhWiiQPt4SU11NR5p9R/X7+0mSec9CX +LS+tZEEo757nhsoYBDl9fbGfPCD0RFug1AAov4zCUMnIXs/VHDeYji7YgXFDeXdg +a4UBNBRwczMd324uMLWZ/wysgrUjwvSMiuBT8vQ/yxh4PLP0+UHj1IN1JMi2FhXX +NtEGo5oLWWvN5AWOJdgfRL8wIDuS3WZ0O+bSkQxagazRnT+e/s0xoDZAWG8BAfWc +96uBkT/T8Twpo0egYHFVhowVPp4MVEUETBAzNgnFiFY6jng73F1DWs2E +-----END CERTIFICATE-----
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 d53ef98..e9f0c46 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
@@ -933,48 +933,6 @@ crbug.com/1126631 [ android android-pixel-2 passthrough ] conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-half_float.html [ RetryOnFailure ] crbug.com/1126631 [ android android-pixel-2 passthrough ] conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html [ RetryOnFailure ] crbug.com/1126631 [ android android-pixel-2 passthrough ] conformance/textures/webgl_canvas/tex-2d-luminance-luminance-unsigned_byte.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance/textures/canvas/tex-2d-alpha-alpha-unsigned_byte.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance/textures/canvas/tex-2d-luminance-luminance-unsigned_byte.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance/textures/canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_byte.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_byte.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-float.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-r16f-red-float.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-r16f-red-half_float.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-r32f-red-float.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-r8-red-unsigned_byte.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-r8ui-red_integer-unsigned_byte.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rg16f-rg-float.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rg16f-rg-half_float.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rg32f-rg-float.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rg8-rg-unsigned_byte.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rgb16f-rgb-float.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rgb16f-rgb-half_float.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rgb32f-rgb-float.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rgb565-rgb-unsigned_byte.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rgb8-rgb-unsigned_byte.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-float.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-half_float.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rgba16f-rgba-float.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rgba16f-rgba-half_float.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rgba32f-rgba-float.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rgba4-rgba-unsigned_byte.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rgba8-rgba-unsigned_byte.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-srgb8-rgb-unsigned_byte.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-pixel-2 no-passthrough ] conformance2/textures/canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html [ RetryOnFailure ] # This test is failing on Android Pixel 2 and 3 (Qualcomm) # Seems to be an OpenGL ES bug.
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 4719e8b..7290ed8f 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
@@ -624,14 +624,6 @@ crbug.com/951628 [ android android-nexus-5x no-passthrough no-swiftshader-gl ] conformance/rendering/blending.html [ Failure ] crbug.com/1083320 [ android android-nexus-5x ] conformance/misc/uninitialized-test.html [ Skip ] crbug.com/1056830 [ android android-nexus-5x ] conformance/extensions/webgl-compressed-texture-astc.html [ Failure ] -crbug.com/1095679 [ android android-nexus-5x no-passthrough ] conformance/textures/canvas/tex-2d-alpha-alpha-unsigned_byte.html [ Skip ] -crbug.com/1095679 [ android android-nexus-5x no-passthrough ] conformance/textures/canvas/tex-2d-luminance-luminance-unsigned_byte.html [ Skip ] -crbug.com/1095679 [ android android-nexus-5x no-passthrough ] conformance/textures/canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ Skip ] -crbug.com/1095679 [ android android-nexus-5x no-passthrough ] conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_byte.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-nexus-5x no-passthrough ] conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html [ Skip ] -crbug.com/1095679 [ android android-nexus-5x no-passthrough ] conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_byte.html [ RetryOnFailure ] -crbug.com/1095679 [ android android-nexus-5x no-passthrough ] conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html [ Skip ] -crbug.com/1095679 [ android android-nexus-5x no-passthrough ] conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ Skip ] crbug.com/1135785 [ android android-nexus-5x no-passthrough ] conformance/textures/misc/texture-video-transparent.html [ RetryOnFailure ] # Timing out on this device for unknown reasons. crbug.com/1099148 [ android android-nexus-5x ] deqp/data/gles2/shaders/swizzles.html [ Skip ]
diff --git a/device/BUILD.gn b/device/BUILD.gn index 747e5b6..2113a942 100644 --- a/device/BUILD.gn +++ b/device/BUILD.gn
@@ -147,6 +147,7 @@ if (!is_android) { sources += [ "fido/attestation_statement_formats_unittest.cc", + "fido/auth_token_requester_unittest.cc", "fido/bio/enrollment_handler_unittest.cc", "fido/ble_adapter_manager_unittest.cc", "fido/cable/fido_ble_connection_unittest.cc",
diff --git a/device/bluetooth/bluetooth_strings.grd b/device/bluetooth/bluetooth_strings.grd index 2827178..ccffde0 100644 --- a/device/bluetooth/bluetooth_strings.grd +++ b/device/bluetooth/bluetooth_strings.grd
@@ -278,6 +278,9 @@ <message name="IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_UNKNOWN" desc="accessibility description for a device type that is not one of the known/supported device types for Chrome OS"> <ph name="DEVICE_NAME">$1<ex>Device XYZ</ex></ph>, Unknown device type </message> + <message name="IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_AND_CONNECTION_STATUS" desc="accessibility description for a Bluetooth connectable device that includes its status. IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_* will be used as an input to DEVICE_NAME_AND_TYPE"> + <ph name="DEVICE_NAME_AND_TYPE">$1<ex>Device XYZ, Audio Device</ex></ph> <ph name="CONNECTION_STATUS">$2<ex>Not connected</ex></ph> + </message> </messages> </release> </grit>
diff --git a/device/bluetooth/bluetooth_strings_grd/IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_AND_CONNECTION_STATUS.png.sha1 b/device/bluetooth/bluetooth_strings_grd/IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_AND_CONNECTION_STATUS.png.sha1 new file mode 100644 index 0000000..3cdee77 --- /dev/null +++ b/device/bluetooth/bluetooth_strings_grd/IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_AND_CONNECTION_STATUS.png.sha1
@@ -0,0 +1 @@ +fb77f1fc922da677235a6cc7dcfcb31c9082897f \ No newline at end of file
diff --git a/device/fido/BUILD.gn b/device/fido/BUILD.gn index 6e58545..5a6df05 100644 --- a/device/fido/BUILD.gn +++ b/device/fido/BUILD.gn
@@ -82,6 +82,8 @@ "attestation_statement.h", "attestation_statement_formats.cc", "attestation_statement_formats.h", + "auth_token_requester.cc", + "auth_token_requester.h", "authenticator_data.cc", "authenticator_data.h", "authenticator_get_assertion_response.cc",
diff --git a/device/fido/auth_token_requester.cc b/device/fido/auth_token_requester.cc new file mode 100644 index 0000000..6dc8b5c --- /dev/null +++ b/device/fido/auth_token_requester.cc
@@ -0,0 +1,326 @@ +// 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 "device/fido/auth_token_requester.h" + +#include <set> +#include <utility> + +#include "base/bind.h" +#include "base/logging.h" +#include "base/stl_util.h" +#include "components/device_event_log/device_event_log.h" +#include "device/fido/authenticator_supported_options.h" +#include "device/fido/fido_authenticator.h" + +namespace device { + +using ClientPinAvailability = + AuthenticatorSupportedOptions::ClientPinAvailability; +using UserVerificationAvailability = + AuthenticatorSupportedOptions::UserVerificationAvailability; +using BioEnrollmentAvailability = + AuthenticatorSupportedOptions::BioEnrollmentAvailability; + +AuthTokenRequester::Delegate::~Delegate() = default; + +AuthTokenRequester::Options::Options() = default; +AuthTokenRequester::Options::Options(Options&&) = default; +AuthTokenRequester::Options& AuthTokenRequester::Options::operator=(Options&&) = + default; +AuthTokenRequester::Options::~Options() = default; + +AuthTokenRequester::AuthTokenRequester(Delegate* delegate, + FidoAuthenticator* authenticator, + Options options) + : delegate_(delegate), + authenticator_(authenticator), + options_(std::move(options)) { + DCHECK(delegate_); + DCHECK(authenticator_); + DCHECK(authenticator_->Options()); + DCHECK(!options_.token_permissions.empty()); + DCHECK(!options_.rp_id || !options_.rp_id->empty()); + // Authenticators with CTAP2.0-style pinToken support only support certain + // default permissions. + DCHECK( + authenticator_->Options()->supports_pin_uv_auth_token || + base::STLSetDifference<std::set<pin::Permissions>>( + options_.token_permissions, + std::set<pin::Permissions>{pin::Permissions::kMakeCredential, + pin::Permissions::kGetAssertion, + pin::Permissions::kBioEnrollment, + pin::Permissions::kCredentialManagement}) + .empty()); +} + +AuthTokenRequester::~AuthTokenRequester() = default; + +void AuthTokenRequester::ObtainPINUVAuthToken() { + if (authenticator_->Options()->supports_pin_uv_auth_token) { + // Only attempt to obtain a token through internal UV if the authenticator + // supports CTAP 2.1 pinUvAuthTokens. If it does not, it could be a 2.0 + // authenticator that supports UV without any sort of token. + const UserVerificationAvailability user_verification_availability = + authenticator_->Options()->user_verification_availability; + switch (user_verification_availability) { + case UserVerificationAvailability::kNotSupported: + case UserVerificationAvailability::kSupportedButNotConfigured: + // Try PIN first. + break; + case UserVerificationAvailability::kSupportedAndConfigured: + ObtainTokenFromInternalUV(); + return; + } + } + + const ClientPinAvailability client_pin_availability = + authenticator_->Options()->client_pin_availability; + switch (client_pin_availability) { + case ClientPinAvailability::kNotSupported: + delegate_->HavePINUVAuthTokenResultForAuthenticator( + authenticator_, Result::kPreTouchUnsatisfiableRequest, base::nullopt); + return; + case ClientPinAvailability::kSupportedAndPinSet: + if (options_.skip_pin_touch) { + ObtainTokenFromPIN(); + return; + } + authenticator_->GetTouch(base::BindOnce( + &AuthTokenRequester::ObtainTokenFromPIN, weak_factory_.GetWeakPtr())); + return; + case ClientPinAvailability::kSupportedButPinNotSet: + if (options_.skip_pin_touch) { + ObtainTokenFromNewPIN(); + return; + } + authenticator_->GetTouch( + base::BindOnce(&AuthTokenRequester::ObtainTokenFromNewPIN, + weak_factory_.GetWeakPtr())); + return; + } +} + +void AuthTokenRequester::ObtainTokenFromInternalUV() { + authenticator_->GetUvRetries(base::BindOnce( + &AuthTokenRequester::OnGetUVRetries, weak_factory_.GetWeakPtr())); +} + +void AuthTokenRequester::OnGetUVRetries( + CtapDeviceResponseCode status, + base::Optional<pin::RetriesResponse> response) { + if (status != CtapDeviceResponseCode::kSuccess) { + delegate_->HavePINUVAuthTokenResultForAuthenticator( + authenticator_, Result::kPreTouchAuthenticatorResponseInvalid, + base::nullopt); + return; + } + + if (response->retries == 0) { + // The authenticator was locked prior to calling + // ObtainTokenFromInternalUV(). Fall back to PIN if able. + if (authenticator_->Options()->client_pin_availability == + ClientPinAvailability::kSupportedAndPinSet) { + delegate_->InternalUVLockedForAuthToken(); + if (options_.skip_pin_touch) { + ObtainTokenFromPIN(); + return; + } + authenticator_->GetTouch(base::BindOnce( + &AuthTokenRequester::ObtainTokenFromPIN, weak_factory_.GetWeakPtr())); + return; + } + authenticator_->GetTouch(base::BindOnce( + &AuthTokenRequester::NotifyAuthenticatorSelectedAndFailWithResult, + weak_factory_.GetWeakPtr(), + Result::kPostTouchAuthenticatorInternalUVLock)); + return; + } + + delegate_->PromptForInternalUVRetry(response->retries); + authenticator_->GetUvToken({std::begin(options_.token_permissions), + std::end(options_.token_permissions)}, + options_.rp_id, + base::BindOnce(&AuthTokenRequester::OnGetUVToken, + weak_factory_.GetWeakPtr())); +} + +void AuthTokenRequester::OnGetUVToken( + CtapDeviceResponseCode status, + base::Optional<pin::TokenResponse> response) { + if (!base::Contains( + std::set<CtapDeviceResponseCode>{ + CtapDeviceResponseCode::kCtap2ErrUvInvalid, + CtapDeviceResponseCode::kCtap2ErrOperationDenied, + CtapDeviceResponseCode::kCtap2ErrUvBlocked, + CtapDeviceResponseCode::kSuccess}, + status)) { + // The request was rejected outright, no touch occurred. + FIDO_LOG(ERROR) << "Ignoring status " << static_cast<int>(status) + << " from " << authenticator_->GetDisplayName(); + delegate_->HavePINUVAuthTokenResultForAuthenticator( + authenticator_, Result::kPreTouchAuthenticatorResponseInvalid, + base::nullopt); + return; + } + + NotifyAuthenticatorSelected(); + + if (status == CtapDeviceResponseCode::kCtap2ErrOperationDenied) { + // The user explicitly denied to the operation on an authenticator with + // a display. + delegate_->HavePINUVAuthTokenResultForAuthenticator( + authenticator_, Result::kPostTouchAuthenticatorOperationDenied, + base::nullopt); + return; + } + + if (status == CtapDeviceResponseCode::kCtap2ErrUvInvalid) { + authenticator_->GetUvRetries(base::BindOnce( + &AuthTokenRequester::OnGetUVRetries, weak_factory_.GetWeakPtr())); + return; + } + + if (status == CtapDeviceResponseCode::kCtap2ErrUvBlocked) { + // Fall back to PIN if able. + if (authenticator_->Options()->client_pin_availability == + ClientPinAvailability::kSupportedAndPinSet) { + delegate_->InternalUVLockedForAuthToken(); + ObtainTokenFromPIN(); + return; + } + // This can be returned pre-touch if the authenticator was already locked at + // the time GetUvToken() was called. However, we checked the number of + // remaining retries just before that to handle that case. + delegate_->HavePINUVAuthTokenResultForAuthenticator( + authenticator_, Result::kPostTouchAuthenticatorInternalUVLock, + base::nullopt); + return; + } + + if (status != CtapDeviceResponseCode::kSuccess) { + NOTREACHED(); + return; + } + + delegate_->HavePINUVAuthTokenResultForAuthenticator( + authenticator_, Result::kSuccess, *response); +} + +void AuthTokenRequester::ObtainTokenFromPIN() { + NotifyAuthenticatorSelected(); + authenticator_->GetPinRetries(base::BindOnce( + &AuthTokenRequester::OnGetPINRetries, weak_factory_.GetWeakPtr())); +} + +void AuthTokenRequester::OnGetPINRetries( + CtapDeviceResponseCode status, + base::Optional<pin::RetriesResponse> response) { + if (status != CtapDeviceResponseCode::kSuccess) { + delegate_->HavePINUVAuthTokenResultForAuthenticator( + authenticator_, Result::kPostTouchAuthenticatorResponseInvalid, + base::nullopt); + return; + } + if (response->retries == 0) { + delegate_->HavePINUVAuthTokenResultForAuthenticator( + authenticator_, Result::kPostTouchAuthenticatorPINHardLock, + base::nullopt); + return; + } + delegate_->CollectExistingPIN( + response->retries, + base::BindOnce(&AuthTokenRequester::HavePIN, weak_factory_.GetWeakPtr())); +} + +void AuthTokenRequester::HavePIN(std::string pin) { + DCHECK(pin::IsValid(pin)); + authenticator_->GetPINToken(std::move(pin), + {std::begin(options_.token_permissions), + std::end(options_.token_permissions)}, + options_.rp_id, + base::BindOnce(&AuthTokenRequester::OnGetPINToken, + weak_factory_.GetWeakPtr())); + return; +} + +void AuthTokenRequester::OnGetPINToken( + CtapDeviceResponseCode status, + base::Optional<pin::TokenResponse> response) { + if (status == CtapDeviceResponseCode::kCtap2ErrPinInvalid) { + ObtainTokenFromPIN(); + return; + } + + if (status != CtapDeviceResponseCode::kSuccess) { + Result ret; + switch (status) { + case CtapDeviceResponseCode::kCtap2ErrPinAuthBlocked: + ret = Result::kPostTouchAuthenticatorPINSoftLock; + break; + case CtapDeviceResponseCode::kCtap2ErrPinBlocked: + ret = Result::kPostTouchAuthenticatorPINHardLock; + break; + default: + ret = Result::kPostTouchAuthenticatorResponseInvalid; + break; + } + delegate_->HavePINUVAuthTokenResultForAuthenticator(authenticator_, ret, + base::nullopt); + return; + } + + delegate_->HavePINUVAuthTokenResultForAuthenticator( + authenticator_, Result::kSuccess, std::move(*response)); +} + +void AuthTokenRequester::ObtainTokenFromNewPIN() { + NotifyAuthenticatorSelected(); + delegate_->CollectNewPIN(base::BindOnce(&AuthTokenRequester::HaveNewPIN, + weak_factory_.GetWeakPtr())); +} + +void AuthTokenRequester::HaveNewPIN(const std::string pin) { + DCHECK(pin::IsValid(pin)); + authenticator_->SetPIN(pin, base::BindOnce(&AuthTokenRequester::OnSetPIN, + weak_factory_.GetWeakPtr(), pin)); + return; +} + +void AuthTokenRequester::OnSetPIN(std::string pin, + CtapDeviceResponseCode status, + base::Optional<pin::EmptyResponse> response) { + if (status != CtapDeviceResponseCode::kSuccess) { + delegate_->HavePINUVAuthTokenResultForAuthenticator( + authenticator_, Result::kPostTouchAuthenticatorResponseInvalid, + base::nullopt); + return; + } + + // Having just set the PIN, we need to immediately turn around and use it to + // get a PIN token. + authenticator_->GetPINToken(std::move(pin), + {std::begin(options_.token_permissions), + std::end(options_.token_permissions)}, + options_.rp_id, + base::BindOnce(&AuthTokenRequester::OnGetPINToken, + weak_factory_.GetWeakPtr())); +} + +void AuthTokenRequester::NotifyAuthenticatorSelected() { + if (authenticator_was_selected_) { + return; + } + authenticator_was_selected_ = true; + delegate_->AuthenticatorSelectedForPINUVAuthToken(authenticator_); +} + +void AuthTokenRequester::NotifyAuthenticatorSelectedAndFailWithResult( + Result result) { + NotifyAuthenticatorSelected(); + delegate_->HavePINUVAuthTokenResultForAuthenticator(authenticator_, result, + base::nullopt); +} + +} // namespace device
diff --git a/device/fido/auth_token_requester.h b/device/fido/auth_token_requester.h new file mode 100644 index 0000000..97ae8ad3 --- /dev/null +++ b/device/fido/auth_token_requester.h
@@ -0,0 +1,173 @@ +// 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 DEVICE_FIDO_AUTH_TOKEN_REQUESTER_H_ +#define DEVICE_FIDO_AUTH_TOKEN_REQUESTER_H_ + +#include <set> +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/component_export.h" +#include "base/memory/weak_ptr.h" +#include "base/optional.h" +#include "device/fido/fido_constants.h" +#include "device/fido/pin.h" + +namespace device { + +class FidoAuthenticator; + +// AuthTokenRequester obtains a pinUvAuthToken from a CTAP2 device. +class COMPONENT_EXPORT(DEVICE_FIDO) AuthTokenRequester { + public: + // Result indicates the outcome of running ObtainPINUVAuthToken(). beginning + // with `kPreTouch` are returned without interaction from the user, which + // generally means the caller ought to silently ignore this device. + enum class Result { + kSuccess, + kPreTouchUnsatisfiableRequest, + kPreTouchAuthenticatorResponseInvalid, + kPostTouchAuthenticatorResponseInvalid, + kPostTouchAuthenticatorOperationDenied, + kPostTouchAuthenticatorPINSoftLock, + kPostTouchAuthenticatorPINHardLock, + kPostTouchAuthenticatorInternalUVLock, + }; + + // Options configures a AuthTokenRequester. + struct COMPONENT_EXPORT(DEVICE_FIDO) Options { + Options(); + Options(Options&&); + Options& operator=(Options&&); + ~Options(); + + // token_permissions are the pinUvAuthToken permissions to request with the + // token. + std::set<pin::Permissions> token_permissions; + + // rp_id is the permissions RP ID for the token to be requested. + base::Optional<std::string> rp_id; + + // skip_pin_touch indicates whether not to request a touch before attempting + // to obtain a token using a PIN. + bool skip_pin_touch = false; + }; + + class COMPONENT_EXPORT(DEVICE_FIDO) Delegate { + public: + // ProvidePINCallback is used to provide the AuthTokenRequester with a PIN + // entered by the user. Callers must use |pin::IsValid()| to validate |pin| + // before invoking this callback. + using ProvidePINCallback = base::OnceCallback<void(std::string pin)>; + + virtual ~Delegate(); + + // AuthenticatorSelectedForPINUVAuthToken is invoked to indicate that the + // user has interacted with this authenticator (i.e. tapped its button). + // The Delegate typically uses this signal to cancel outstanding requests to + // other authenticators. + // + // This method is guaranteed to be called first and at exactly once + // throughout the handler's lifetime, *unless* + // HavePINUVAuthTokenResultForAuthenticator() is invoked first with one of + // the Result codes starting with `kPreTouch`. + virtual void AuthenticatorSelectedForPINUVAuthToken( + FidoAuthenticator* authenticator) = 0; + + // CollectNewPIN is invoked to prompt the user to enter a new PIN for an + // authenticator. + // + // The callee must provide the PIN by invoking |provide_pin_cb|. The + // callback is weakly bound and safe to invoke even after the + // AuthTokenRequester was freed. + virtual void CollectNewPIN(ProvidePINCallback provide_pin_cb) = 0; + + // CollectExistingPIN is invoked to prompt the user to provide the existing + // PIN to an authenticator. |attempts| is the number of remaining attempts + // before the authenticator is locked. + // + // The callee must provide the PIN by invoking |provide_pin_cb|. The + // callback is weakly bound and safe to invoke even after the + // AuthTokenRequester was freed. If CollectExistingPIN() is called again + // after callback invocation, the provided PIN was incorrect. + virtual void CollectExistingPIN(int attempts, + ProvidePINCallback provide_pin_cb) = 0; + + // InternalUVLockedForAuthToken() notifies the delegate that the + // authenticator's internal modality was locked due to too many invalid + // authentication attempts. It is followed by a call to CollectExistingPIN() + // to prompt for a PIN as a fallback authentication mechanism. + virtual void InternalUVLockedForAuthToken() = 0; + + // PromptForInternalUVRetry is invoked to prompt the user to retry internal + // user verification (usually on a fingerprint sensor). |attempts| is the + // number of remaining attempts before the authenticator is locked. This + // method may be then be called again if the user verification attempt fails + // again. + virtual void PromptForInternalUVRetry(int attempts) = 0; + + // HavePINUVAuthTokenResultForAuthenticator notifies the delegate of the + // outcome of ObtainPINUVAuthToken(). |response| is `base::nullopt`, unless + // |result| is |Result::kSuccess|. + virtual void HavePINUVAuthTokenResultForAuthenticator( + FidoAuthenticator* authenticator, + Result result, + base::Optional<pin::TokenResponse> response) = 0; + }; + + // Instantiates a new AuthTokenRequester. |delegate| and |authenticator| must + // outlive this instance. + AuthTokenRequester(Delegate* delegate, + FidoAuthenticator* authenticator, + Options options); + ~AuthTokenRequester(); + AuthTokenRequester(AuthTokenRequester&) = delete; + AuthTokenRequester& operator=(AuthTokenRequester&) = delete; + AuthTokenRequester(AuthTokenRequester&&) = delete; + AuthTokenRequester& operator=(AuthTokenRequester&&) = delete; + + // ObtainPINUVAuthToken attempts to obtain a pinUvAuthToken from the + // authenticator. + void ObtainPINUVAuthToken(); + + FidoAuthenticator* authenticator() { return authenticator_; } + + private: + void ObtainTokenFromInternalUV(); + void OnGetUVRetries(CtapDeviceResponseCode status, + base::Optional<pin::RetriesResponse> response); + void OnGetUVToken(CtapDeviceResponseCode status, + base::Optional<pin::TokenResponse> response); + + void ObtainTokenFromPIN(); + void OnGetPINRetries(CtapDeviceResponseCode status, + base::Optional<pin::RetriesResponse> response); + void HavePIN(std::string pin); + void OnGetPINToken(CtapDeviceResponseCode status, + base::Optional<pin::TokenResponse> response); + + void ObtainTokenFromNewPIN(); + void HaveNewPIN(std::string pin); + void OnSetPIN(std::string pin, + CtapDeviceResponseCode status, + base::Optional<pin::EmptyResponse> response); + + void NotifyAuthenticatorSelected(); + void NotifyAuthenticatorSelectedAndFailWithResult(Result result); + + Delegate* delegate_; + FidoAuthenticator* authenticator_; + + Options options_; + + bool authenticator_was_selected_ = false; + + base::WeakPtrFactory<AuthTokenRequester> weak_factory_{this}; +}; + +} // namespace device + +#endif // DEVICE_FIDO_AUTH_TOKEN_REQUESTER_H_
diff --git a/device/fido/auth_token_requester_unittest.cc b/device/fido/auth_token_requester_unittest.cc new file mode 100644 index 0000000..b38dafef --- /dev/null +++ b/device/fido/auth_token_requester_unittest.cc
@@ -0,0 +1,396 @@ +// 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 "device/fido/auth_token_requester.h" + +#include <string> + +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +#include "base/containers/span.h" +#include "base/logging.h" +#include "base/memory/scoped_refptr.h" +#include "base/optional.h" +#include "base/run_loop.h" +#include "base/test/task_environment.h" +#include "device/fido/fido_constants.h" +#include "device/fido/fido_device_authenticator.h" +#include "device/fido/pin.h" +#include "device/fido/virtual_ctap2_device.h" + +namespace device { +namespace { + +using ::testing::ElementsAreArray; + +using ClientPinAvailability = + device::AuthenticatorSupportedOptions::ClientPinAvailability; +using UserVerificationAvailability = + device::AuthenticatorSupportedOptions::UserVerificationAvailability; + +constexpr char kTestPIN[] = "1234"; + +class TestAuthTokenRequesterDelegate : public AuthTokenRequester::Delegate { + public: + explicit TestAuthTokenRequesterDelegate(std::string pin) + : pin_(std::move(pin)) {} + + void WaitForResult() { wait_for_result_loop_.Run(); } + base::Optional<AuthTokenRequester::Result>& result() { return result_; } + base::Optional<pin::TokenResponse>& response() { return response_; } + bool pin_was_set() { return pin_was_set_; } + bool pin_was_collected() { return pin_was_collected_; } + bool internal_uv_was_prompted() { return internal_uv_was_prompted_; } + bool internal_uv_was_locked() { return internal_uv_was_locked_; } + + private: + // AuthTokenRequester::Delegate: + void AuthenticatorSelectedForPINUVAuthToken( + FidoAuthenticator* authenticator) override {} + void CollectNewPIN(ProvidePINCallback provide_pin_cb) override { + DCHECK(!pin_.empty()); + pin_was_set_ = true; + std::move(provide_pin_cb).Run(pin_); + } + void CollectExistingPIN(int attempts, + ProvidePINCallback provide_pin_cb) override { + DCHECK(!pin_.empty()); + pin_was_collected_ = true; + std::move(provide_pin_cb).Run(pin_); + } + void PromptForInternalUVRetry(int attempts) override { + internal_uv_was_prompted_ = true; + } + void InternalUVLockedForAuthToken() override { + internal_uv_was_locked_ = true; + } + void HavePINUVAuthTokenResultForAuthenticator( + FidoAuthenticator* authenticator, + AuthTokenRequester::Result result, + base::Optional<pin::TokenResponse> response) override { + DCHECK(!result_); + result_ = result; + response_ = std::move(response); + wait_for_result_loop_.Quit(); + } + + std::string pin_; + + base::Optional<AuthTokenRequester::Result> result_; + base::Optional<pin::TokenResponse> response_; + + bool pin_was_collected_ = false; + bool pin_was_set_ = false; + bool internal_uv_was_prompted_ = false; + bool internal_uv_was_locked_ = false; + + base::RunLoop wait_for_result_loop_; +}; + +struct TestCase { + ClientPinAvailability client_pin; + UserVerificationAvailability user_verification; + bool success; +}; + +class AuthTokenRequesterTest : public ::testing::Test { + protected: + void SetUp() override {} + + void RunTestCase(VirtualCtap2Device::Config config, + scoped_refptr<VirtualFidoDevice::State> state, + const TestCase& test_case) { + state_ = state; + + switch (test_case.client_pin) { + case ClientPinAvailability::kNotSupported: + config.pin_support = false; + break; + case ClientPinAvailability::kSupportedButPinNotSet: + config.pin_support = true; + break; + case ClientPinAvailability::kSupportedAndPinSet: + config.pin_support = true; + state_->pin = kTestPIN; + break; + } + switch (test_case.user_verification) { + case UserVerificationAvailability::kNotSupported: + config.internal_uv_support = false; + break; + case UserVerificationAvailability::kSupportedButNotConfigured: + config.internal_uv_support = true; + break; + case UserVerificationAvailability::kSupportedAndConfigured: + config.internal_uv_support = true; + state_->fingerprints_enrolled = true; + break; + } + + auto authenticator = std::make_unique<FidoDeviceAuthenticator>( + std::make_unique<VirtualCtap2Device>(state_, std::move(config))); + + base::RunLoop init_loop; + authenticator->InitializeAuthenticator(init_loop.QuitClosure()); + init_loop.Run(); + + delegate_ = std::make_unique<TestAuthTokenRequesterDelegate>(kTestPIN); + AuthTokenRequester::Options options; + options.token_permissions = {pin::Permissions::kMakeCredential}; + options.rp_id = "foobar.com"; + AuthTokenRequester requester(delegate_.get(), authenticator.get(), + std::move(options)); + requester.ObtainPINUVAuthToken(); + delegate_->WaitForResult(); + } + + base::test::TaskEnvironment task_environment_{ + base::test::TaskEnvironment::TimeSource::MOCK_TIME}; + + scoped_refptr<VirtualFidoDevice::State> state_; + std::unique_ptr<TestAuthTokenRequesterDelegate> delegate_; +}; + +TEST_F(AuthTokenRequesterTest, AuthenticatorWithoutUVTokenSupport) { + constexpr TestCase kTestCases[]{ + { + ClientPinAvailability::kNotSupported, + UserVerificationAvailability::kNotSupported, + false, + }, + { + ClientPinAvailability::kNotSupported, + UserVerificationAvailability::kSupportedButNotConfigured, + false, + }, + { + ClientPinAvailability::kNotSupported, + UserVerificationAvailability::kSupportedAndConfigured, + false, + }, + { + ClientPinAvailability::kSupportedButPinNotSet, + UserVerificationAvailability::kNotSupported, + true, + }, + { + ClientPinAvailability::kSupportedButPinNotSet, + UserVerificationAvailability::kSupportedButNotConfigured, + true, + }, + { + ClientPinAvailability::kSupportedButPinNotSet, + UserVerificationAvailability::kSupportedAndConfigured, + true, + }, + { + ClientPinAvailability::kSupportedAndPinSet, + UserVerificationAvailability::kNotSupported, + true, + }, + { + ClientPinAvailability::kSupportedAndPinSet, + UserVerificationAvailability::kSupportedButNotConfigured, + true, + }, + { + ClientPinAvailability::kSupportedAndPinSet, + UserVerificationAvailability::kSupportedAndConfigured, + true, + }, + }; + + int i = 0; + for (const TestCase& t : kTestCases) { + SCOPED_TRACE(i++); + VirtualCtap2Device::Config config; + config.pin_uv_auth_token_support = false; + RunTestCase(std::move(config), + base::MakeRefCounted<VirtualFidoDevice::State>(), t); + + if (t.success) { + EXPECT_EQ(*delegate_->result(), AuthTokenRequester::Result::kSuccess); + EXPECT_THAT(delegate_->response()->token_for_testing(), + ElementsAreArray(state_->pin_token)); + EXPECT_EQ(delegate_->pin_was_set(), + t.client_pin == ClientPinAvailability::kSupportedButPinNotSet); + EXPECT_EQ(delegate_->pin_was_collected(), + t.client_pin == ClientPinAvailability::kSupportedAndPinSet); + } else { + EXPECT_EQ(*delegate_->result(), + AuthTokenRequester::Result::kPreTouchUnsatisfiableRequest); + EXPECT_FALSE(delegate_->response()); + EXPECT_FALSE(delegate_->pin_was_set()); + EXPECT_FALSE(delegate_->pin_was_collected()); + } + EXPECT_FALSE(delegate_->internal_uv_was_prompted()); + EXPECT_FALSE(delegate_->internal_uv_was_locked()); + } +} + +TEST_F(AuthTokenRequesterTest, AuthenticatorWithUVTokenSupport) { + constexpr TestCase kTestCases[]{ + { + ClientPinAvailability::kNotSupported, + UserVerificationAvailability::kNotSupported, + false, + }, + { + ClientPinAvailability::kNotSupported, + UserVerificationAvailability::kSupportedButNotConfigured, + false, + }, + { + ClientPinAvailability::kNotSupported, + UserVerificationAvailability::kSupportedAndConfigured, + true, + }, + { + ClientPinAvailability::kSupportedButPinNotSet, + UserVerificationAvailability::kNotSupported, + true, + }, + { + ClientPinAvailability::kSupportedButPinNotSet, + UserVerificationAvailability::kSupportedButNotConfigured, + true, + }, + { + ClientPinAvailability::kSupportedButPinNotSet, + UserVerificationAvailability::kSupportedAndConfigured, + true, + }, + { + ClientPinAvailability::kSupportedAndPinSet, + UserVerificationAvailability::kNotSupported, + true, + }, + { + ClientPinAvailability::kSupportedAndPinSet, + UserVerificationAvailability::kSupportedButNotConfigured, + true, + }, + { + ClientPinAvailability::kSupportedAndPinSet, + UserVerificationAvailability::kSupportedAndConfigured, + true, + }, + }; + + int i = 0; + for (const TestCase& t : kTestCases) { + SCOPED_TRACE(i++); + + VirtualCtap2Device::Config config; + config.pin_uv_auth_token_support = true; + config.ctap2_versions = {std::begin(kCtap2Versions2_1), + std::end(kCtap2Versions2_1)}; + RunTestCase(std::move(config), + base::MakeRefCounted<VirtualFidoDevice::State>(), t); + + if (t.success) { + EXPECT_EQ(*delegate_->result(), AuthTokenRequester::Result::kSuccess); + EXPECT_EQ(state_->pin_uv_token_rpid, "foobar.com"); + EXPECT_EQ(state_->pin_uv_token_permissions, + static_cast<uint8_t>(pin::Permissions::kMakeCredential)); + EXPECT_THAT(delegate_->response()->token_for_testing(), + ElementsAreArray(state_->pin_token)); + EXPECT_EQ(delegate_->pin_was_set(), + t.client_pin == ClientPinAvailability::kSupportedButPinNotSet && + t.user_verification != + UserVerificationAvailability::kSupportedAndConfigured); + EXPECT_EQ(delegate_->pin_was_collected(), + t.client_pin == ClientPinAvailability::kSupportedAndPinSet && + t.user_verification != + UserVerificationAvailability::kSupportedAndConfigured); + EXPECT_EQ(delegate_->internal_uv_was_prompted(), + t.user_verification == + UserVerificationAvailability::kSupportedAndConfigured); + EXPECT_FALSE(delegate_->internal_uv_was_locked()); + } else { + EXPECT_EQ(*delegate_->result(), + AuthTokenRequester::Result::kPreTouchUnsatisfiableRequest); + EXPECT_FALSE(delegate_->response()); + EXPECT_FALSE(delegate_->pin_was_set()); + EXPECT_FALSE(delegate_->pin_was_collected()); + EXPECT_FALSE(delegate_->internal_uv_was_prompted()); + EXPECT_FALSE(delegate_->internal_uv_was_locked()); + } + } +} + +TEST_F(AuthTokenRequesterTest, PINSoftLock) { + VirtualCtap2Device::Config config; + config.pin_uv_auth_token_support = true; + config.ctap2_versions = {std::begin(kCtap2Versions2_1), + std::end(kCtap2Versions2_1)}; + auto state = base::MakeRefCounted<VirtualFidoDevice::State>(); + state->soft_locked = true; + + RunTestCase(std::move(config), state, + TestCase{ + ClientPinAvailability::kSupportedAndPinSet, + UserVerificationAvailability::kNotSupported, + false, + }); + + EXPECT_EQ(*delegate_->result(), + AuthTokenRequester::Result::kPostTouchAuthenticatorPINSoftLock); + EXPECT_FALSE(delegate_->response()); + EXPECT_FALSE(delegate_->pin_was_set()); + EXPECT_TRUE(delegate_->pin_was_collected()); + EXPECT_FALSE(delegate_->internal_uv_was_prompted()); + EXPECT_FALSE(delegate_->internal_uv_was_locked()); +} + +TEST_F(AuthTokenRequesterTest, PINHardLock) { + VirtualCtap2Device::Config config; + config.pin_uv_auth_token_support = true; + config.ctap2_versions = {std::begin(kCtap2Versions2_1), + std::end(kCtap2Versions2_1)}; + auto state = base::MakeRefCounted<VirtualFidoDevice::State>(); + state->pin_retries = 0; + + RunTestCase(std::move(config), state, + TestCase{ + ClientPinAvailability::kSupportedAndPinSet, + UserVerificationAvailability::kNotSupported, + false, + }); + + EXPECT_EQ(*delegate_->result(), + AuthTokenRequester::Result::kPostTouchAuthenticatorPINHardLock); + EXPECT_FALSE(delegate_->response()); + EXPECT_FALSE(delegate_->pin_was_set()); + EXPECT_FALSE(delegate_->pin_was_collected()); + EXPECT_FALSE(delegate_->internal_uv_was_prompted()); + EXPECT_FALSE(delegate_->internal_uv_was_locked()); +} + +TEST_F(AuthTokenRequesterTest, UVLockedPINFallback) { + VirtualCtap2Device::Config config; + config.pin_uv_auth_token_support = true; + config.ctap2_versions = {std::begin(kCtap2Versions2_1), + std::end(kCtap2Versions2_1)}; + auto state = base::MakeRefCounted<VirtualFidoDevice::State>(); + state->uv_retries = 0; + + RunTestCase(std::move(config), state, + TestCase{ + ClientPinAvailability::kSupportedAndPinSet, + UserVerificationAvailability::kSupportedAndConfigured, + true, + }); + + EXPECT_EQ(*delegate_->result(), AuthTokenRequester::Result::kSuccess); + EXPECT_TRUE(delegate_->response()); + EXPECT_FALSE(delegate_->pin_was_set()); + EXPECT_TRUE(delegate_->pin_was_collected()); + EXPECT_FALSE(delegate_->internal_uv_was_prompted()); + EXPECT_TRUE(delegate_->internal_uv_was_locked()); +} + +} // namespace +} // namespace device
diff --git a/device/fido/fido_device_authenticator.cc b/device/fido/fido_device_authenticator.cc index 5ea5655..fcf6742 100644 --- a/device/fido/fido_device_authenticator.cc +++ b/device/fido/fido_device_authenticator.cc
@@ -757,9 +757,6 @@ size_t bytes_to_read = max_large_blob_fragment_length(); LargeBlobsRequest request = LargeBlobsRequest::ForRead(bytes_to_read, large_blob_array_reader.size()); - if (pin_uv_auth_token) { - request.SetPinParam(*pin_uv_auth_token); - } RunOperation<LargeBlobsRequest, LargeBlobsResponse>( std::move(request), base::BindOnce(&FidoDeviceAuthenticator::OnReadLargeBlobFragment,
diff --git a/device/fido/large_blob.cc b/device/fido/large_blob.cc index 2b8e7b56..2c5e1b1 100644 --- a/device/fido/large_blob.cc +++ b/device/fido/large_blob.cc
@@ -83,6 +83,7 @@ void LargeBlobsRequest::SetPinParam( const pin::TokenResponse& pin_uv_auth_token) { + DCHECK(set_) << "SetPinParam should only be used for write requests"; std::vector<uint8_t> pin_auth(pin::kPinUvAuthTokenSafetyPadding.begin(), pin::kPinUvAuthTokenSafetyPadding.end()); pin_auth.insert(pin_auth.end(), kLargeBlobPinPrefix.begin(),
diff --git a/device/fido/pin.h b/device/fido/pin.h index 1449442..bda30b1 100644 --- a/device/fido/pin.h +++ b/device/fido/pin.h
@@ -287,6 +287,7 @@ base::span<const uint8_t> client_data_hash) const; PINUVAuthProtocol protocol() const { return protocol_; } + const std::vector<uint8_t>& token_for_testing() const { return token_; } private: explicit TokenResponse(PINUVAuthProtocol protocol);
diff --git a/device/fido/virtual_ctap2_device.cc b/device/fido/virtual_ctap2_device.cc index 4f71fcf8..68a21a48 100644 --- a/device/fido/virtual_ctap2_device.cc +++ b/device/fido/virtual_ctap2_device.cc
@@ -2281,7 +2281,11 @@ const size_t max_fragment_length = kLargeBlobDefaultMaxFragmentLength; if (get_it != request_map.end()) { - if (length_it != request_map.end()) { + if (length_it != request_map.end() || + request_map.find(cbor::Value(static_cast<uint8_t>( + LargeBlobsRequestKey::kPinUvAuthParam))) != request_map.end() || + request_map.find(cbor::Value(static_cast<uint8_t>( + LargeBlobsRequestKey::kPinUvAuthProtocol))) != request_map.end()) { return CtapDeviceResponseCode::kCtap1ErrInvalidParameter; } const uint64_t get = get_it->second.GetUnsigned();
diff --git a/docs/vscode_python.md b/docs/vscode_python.md index f640e7a..47c973b 100644 --- a/docs/vscode_python.md +++ b/docs/vscode_python.md
@@ -52,31 +52,4 @@ ## Locally -1. On the debug tab, on the drop-down next to the play button, select “Add - Config” -2. Add the following to the configurations array in “launch”: - -``` -{ - "name":"Python: Local", - "type":"python", - "request":"attach", - "processId":"${command:pickProcess}" -} -``` - -3. Add the following to your program: - -``` -import debugpy - -# Your code here! - -print("Wait for attach...") -debugpy.wait_for_attach() -debugpy.brerakpoint() -``` - -4. Start your program. -5. Start the debugger. A dialog box will pop up asking you to select your - running program. +Follow the same steps as above, but start from step 5.
diff --git a/extensions/browser/extension_web_contents_observer.cc b/extensions/browser/extension_web_contents_observer.cc index 90bba91d..c66cf55f 100644 --- a/extensions/browser/extension_web_contents_observer.cc +++ b/extensions/browser/extension_web_contents_observer.cc
@@ -292,12 +292,14 @@ if (verify_url) { const url::Origin& origin(render_frame_host->GetLastCommittedOrigin()); - // Without site isolation, this check is needed to eliminate non-extension - // schemes. With site isolation, this is still needed to exclude sandboxed - // extension frames with an opaque origin. - const GURL site_url(render_frame_host->GetSiteInstance()->GetSiteURL()); - if (origin.opaque() || site_url != content::SiteInstance::GetSiteForURL( - browser_context, origin.GetURL())) + // This check is needed to eliminate origins that are not within a + // hosted-app's web extent, and sandboxed extension frames with an opaque + // origin. + // TODO(1139108) See if extension check is still needed after bug is fixed. + auto* extension_for_origin = ExtensionRegistry::Get(browser_context) + ->enabled_extensions() + .GetExtensionOrAppByURL(origin.GetURL()); + if (origin.opaque() || extension_for_origin != extension) return nullptr; }
diff --git a/extensions/components/native_app_window/native_app_window_views.cc b/extensions/components/native_app_window/native_app_window_views.cc index 7f61f12..0b01393e 100644 --- a/extensions/components/native_app_window/native_app_window_views.cc +++ b/extensions/components/native_app_window/native_app_window_views.cc
@@ -41,6 +41,10 @@ web_view_ = AddChildView(std::make_unique<views::WebView>(nullptr)); web_view_->SetWebContents(app_window_->web_contents()); + SetCanMinimize(!app_window_->show_on_lock_screen()); + SetCanMaximize(CanMaximizeWindow()); + SetCanResize(CanResizeWindow()); + widget_ = new views::Widget; widget_->AddObserver(this); InitializeWindow(app_window, create_params); @@ -183,20 +187,6 @@ return web_view_; } -bool NativeAppWindowViews::CanResize() const { - return resizable_ && !size_constraints_.HasFixedSize() && - !WidgetHasHitTestMask(); -} - -bool NativeAppWindowViews::CanMaximize() const { - return resizable_ && !size_constraints_.HasMaximumSize() && - !WidgetHasHitTestMask(); -} - -bool NativeAppWindowViews::CanMinimize() const { - return !app_window_->show_on_lock_screen(); -} - base::string16 NativeAppWindowViews::GetWindowTitle() const { return app_window_->GetTitle(); } @@ -384,6 +374,8 @@ const gfx::Size& max_size) { size_constraints_.set_minimum_size(min_size); size_constraints_.set_maximum_size(max_size); + SetCanMaximize(CanMaximizeWindow()); + SetCanResize(CanResizeWindow()); widget_->OnSizeConstraintsChanged(); } @@ -420,9 +412,24 @@ observer_list_.RemoveObserver(observer); } +void NativeAppWindowViews::OnWidgetHasHitTestMaskChanged() { + SetCanMaximize(CanMaximizeWindow()); + SetCanResize(CanResizeWindow()); +} + void NativeAppWindowViews::OnViewWasResized() { for (auto& observer : observer_list_) observer.OnPositionRequiresUpdate(); } +bool NativeAppWindowViews::CanResizeWindow() const { + return resizable_ && !size_constraints_.HasFixedSize() && + !WidgetHasHitTestMask(); +} + +bool NativeAppWindowViews::CanMaximizeWindow() const { + return resizable_ && !size_constraints_.HasMaximumSize() && + !WidgetHasHitTestMask(); +} + } // namespace native_app_window
diff --git a/extensions/components/native_app_window/native_app_window_views.h b/extensions/components/native_app_window/native_app_window_views.h index db06ef0..438b197 100644 --- a/extensions/components/native_app_window/native_app_window_views.h +++ b/extensions/components/native_app_window/native_app_window_views.h
@@ -91,9 +91,6 @@ // WidgetDelegate: void OnWidgetMove() override; views::View* GetInitiallyFocusedView() override; - bool CanResize() const override; - bool CanMaximize() const override; - bool CanMinimize() const override; base::string16 GetWindowTitle() const override; bool ShouldShowWindowTitle() const override; void SaveWindowPlacement(const gfx::Rect& bounds, @@ -150,10 +147,15 @@ void AddObserver(web_modal::ModalDialogHostObserver* observer) override; void RemoveObserver(web_modal::ModalDialogHostObserver* observer) override; + void OnWidgetHasHitTestMaskChanged(); + private: // Informs modal dialogs that they need to update their positions. void OnViewWasResized(); + bool CanMaximizeWindow() const; + bool CanResizeWindow() const; + extensions::AppWindow* app_window_ = nullptr; // Not owned. views::WebView* web_view_ = nullptr; views::Widget* widget_ = nullptr;
diff --git a/fuchsia/base/context_provider_test_connector.cc b/fuchsia/base/context_provider_test_connector.cc index 6796771..90301612 100644 --- a/fuchsia/base/context_provider_test_connector.cc +++ b/fuchsia/base/context_provider_test_connector.cc
@@ -8,6 +8,7 @@ #include <fuchsia/sys/cpp/fidl.h> #include <lib/fdio/directory.h> +#include <lib/fdio/fd.h> #include <lib/sys/cpp/component_context.h> #include <zircon/processargs.h> #include <utility>
diff --git a/gpu/command_buffer/service/external_vk_image_factory_unittest.cc b/gpu/command_buffer/service/external_vk_image_factory_unittest.cc index 36587be2..bcd7759 100644 --- a/gpu/command_buffer/service/external_vk_image_factory_unittest.cc +++ b/gpu/command_buffer/service/external_vk_image_factory_unittest.cc
@@ -41,7 +41,15 @@ class ExternalVkImageFactoryTest : public testing::Test { protected: + bool VulkanSupported() const { + // crbug.com(941685, 1139366): Vulkan driver crashes on Linux FYI Release + // (AMD R7 240). + return !GPUTestBotConfig::CurrentConfigMatches("Linux AMD"); + } void SetUp() override { + if (!VulkanSupported()) { + return; + } // Set up the Vulkan implementation and context provider. vulkan_implementation_ = gpu::CreateVulkanImplementation(); DCHECK(vulkan_implementation_) << "Failed to create Vulkan implementation"; @@ -129,6 +137,10 @@ #if BUILDFLAG(USE_DAWN) TEST_F(ExternalVkImageFactoryTest, DawnWrite_SkiaVulkanRead) { + if (!VulkanSupported()) { + DLOG(ERROR) << "Test skipped because Vulkan isn't supported."; + return; + } // Create a backing using mailbox. auto mailbox = Mailbox::GenerateForSharedImage(); const auto format = viz::ResourceFormat::RGBA_8888; @@ -242,6 +254,10 @@ } TEST_F(ExternalVkImageFactoryTest, SkiaVulkanWrite_DawnRead) { + if (!VulkanSupported()) { + DLOG(ERROR) << "Test skipped because Vulkan isn't supported."; + return; + } // Create a backing using mailbox. auto mailbox = Mailbox::GenerateForSharedImage(); const auto format = viz::ResourceFormat::RGBA_8888;
diff --git a/gpu/command_buffer/service/gpu_command_buffer_memory_tracker.cc b/gpu/command_buffer/service/gpu_command_buffer_memory_tracker.cc index 97b6d43..e30519a 100644 --- a/gpu/command_buffer/service/gpu_command_buffer_memory_tracker.cc +++ b/gpu/command_buffer/service/gpu_command_buffer_memory_tracker.cc
@@ -11,58 +11,19 @@ #include "gpu/ipc/common/command_buffer_id.h" #include "gpu/ipc/common/gpu_peak_memory.h" -// Macro to reduce code duplication when logging memory in -// GpuCommandBufferMemoryTracker. This is needed as the UMA_HISTOGRAM_* macros -// require a unique call-site per histogram (you can't funnel multiple strings -// into the same call-site). -#define GPU_COMMAND_BUFFER_MEMORY_BLOCK(category) \ - do { \ - uint64_t mb_used = size_ / (1024 * 1024); \ - switch (context_type_) { \ - case CONTEXT_TYPE_WEBGL1: \ - case CONTEXT_TYPE_WEBGL2: \ - case CONTEXT_TYPE_WEBGL2_COMPUTE: \ - UMA_HISTOGRAM_MEMORY_LARGE_MB("GPU.ContextMemory.WebGL." category, \ - mb_used); \ - break; \ - case CONTEXT_TYPE_OPENGLES2: \ - case CONTEXT_TYPE_OPENGLES3: \ - UMA_HISTOGRAM_MEMORY_LARGE_MB("GPU.ContextMemory.GLES." category, \ - mb_used); \ - break; \ - case CONTEXT_TYPE_WEBGPU: \ - break; \ - } \ - } while (false) - namespace gpu { GpuCommandBufferMemoryTracker::GpuCommandBufferMemoryTracker( CommandBufferId command_buffer_id, uint64_t client_tracing_id, - ContextType context_type, scoped_refptr<base::SingleThreadTaskRunner> task_runner, Observer* observer) : command_buffer_id_(command_buffer_id), client_tracing_id_(client_tracing_id), - context_type_(context_type), - memory_pressure_listener_( - FROM_HERE, - base::BindRepeating( - &GpuCommandBufferMemoryTracker::LogMemoryStatsPressure, - base::Unretained(this))), observer_(observer) { - // Set up |memory_stats_timer_| to call LogMemoryPeriodic periodically - // via the provided |task_runner|. - memory_stats_timer_.SetTaskRunner(std::move(task_runner)); - memory_stats_timer_.Start( - FROM_HERE, base::TimeDelta::FromSeconds(30), this, - &GpuCommandBufferMemoryTracker::LogMemoryStatsPeriodic); } -GpuCommandBufferMemoryTracker::~GpuCommandBufferMemoryTracker() { - LogMemoryStatsShutdown(); -} +GpuCommandBufferMemoryTracker::~GpuCommandBufferMemoryTracker() = default; void GpuCommandBufferMemoryTracker::TrackMemoryAllocatedChange(int64_t delta) { DCHECK(delta >= 0 || size_ >= static_cast<uint64_t>(-delta)); @@ -90,21 +51,4 @@ return command_buffer_id_.GetUnsafeValue(); } -void GpuCommandBufferMemoryTracker::LogMemoryStatsPeriodic() { - GPU_COMMAND_BUFFER_MEMORY_BLOCK("Periodic"); -} - -void GpuCommandBufferMemoryTracker::LogMemoryStatsShutdown() { - GPU_COMMAND_BUFFER_MEMORY_BLOCK("Shutdown"); -} - -void GpuCommandBufferMemoryTracker::LogMemoryStatsPressure( - base::MemoryPressureListener::MemoryPressureLevel pressure_level) { - // Only log on CRITICAL memory pressure. - if (pressure_level == - base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) { - GPU_COMMAND_BUFFER_MEMORY_BLOCK("Pressure"); - } -} - } // namespace gpu
diff --git a/gpu/command_buffer/service/gpu_command_buffer_memory_tracker.h b/gpu/command_buffer/service/gpu_command_buffer_memory_tracker.h index 731b0b1..4161af9 100644 --- a/gpu/command_buffer/service/gpu_command_buffer_memory_tracker.h +++ b/gpu/command_buffer/service/gpu_command_buffer_memory_tracker.h
@@ -24,7 +24,6 @@ GpuCommandBufferMemoryTracker( CommandBufferId command_buffer_id, uint64_t client_tracing_id, - ContextType context_type, scoped_refptr<base::SingleThreadTaskRunner> task_runner, Observer* observer); ~GpuCommandBufferMemoryTracker() override; @@ -37,20 +36,10 @@ uint64_t ContextGroupTracingId() const override; private: - void LogMemoryStatsPeriodic(); - void LogMemoryStatsShutdown(); - void LogMemoryStatsPressure( - base::MemoryPressureListener::MemoryPressureLevel pressure_level); - uint64_t size_ = 0; const CommandBufferId command_buffer_id_; const uint64_t client_tracing_id_; - // Variables used in memory stat histogram logging. - const ContextType context_type_; - base::RepeatingTimer memory_stats_timer_; - base::MemoryPressureListener memory_pressure_listener_; - MemoryTracker::Observer* const observer_; DISALLOW_COPY_AND_ASSIGN(GpuCommandBufferMemoryTracker);
diff --git a/gpu/command_buffer/tests/shared_image_gl_backing_produce_dawn_unittest.cc b/gpu/command_buffer/tests/shared_image_gl_backing_produce_dawn_unittest.cc index 6eb7757e..ac165e5e 100644 --- a/gpu/command_buffer/tests/shared_image_gl_backing_produce_dawn_unittest.cc +++ b/gpu/command_buffer/tests/shared_image_gl_backing_produce_dawn_unittest.cc
@@ -40,6 +40,10 @@ WebGPUTest::Options option; Initialize(option); + if (ShouldSkipTest()) { + return; + } + gpu::ContextCreationAttribs attributes; attributes.alpha_size = 8; attributes.depth_size = 24;
diff --git a/gpu/command_buffer/tests/webgpu_test.cc b/gpu/command_buffer/tests/webgpu_test.cc index c25739ce..58f8e24 100644 --- a/gpu/command_buffer/tests/webgpu_test.cc +++ b/gpu/command_buffer/tests/webgpu_test.cc
@@ -39,8 +39,6 @@ WebGPUTest::~WebGPUTest() = default; bool WebGPUTest::WebGPUSupported() const { - DCHECK(is_initialized_); // Did you call WebGPUTest::Initialize? - // crbug.com(941685): Vulkan driver crashes on Linux FYI Release (AMD R7 240). // Win7 does not support WebGPU if (GPUTestBotConfig::CurrentConfigMatches("Linux AMD") || @@ -63,6 +61,10 @@ } void WebGPUTest::SetUp() { + if (!WebGPUSupported()) { + return; + } + gpu::GpuPreferences gpu_preferences; gpu_preferences.enable_webgpu = true; #if (defined(OS_LINUX) || defined(OS_CHROMEOS)) && BUILDFLAG(USE_DAWN) @@ -81,8 +83,6 @@ } void WebGPUTest::Initialize(const Options& options) { - is_initialized_ = true; - if (!WebGPUSupported()) { return; } @@ -175,25 +175,25 @@ } TEST_F(WebGPUTest, FlushNoCommands) { - Initialize(WebGPUTest::Options()); - if (!WebGPUSupported()) { LOG(ERROR) << "Test skipped because WebGPU isn't supported"; return; } + Initialize(WebGPUTest::Options()); + webgpu()->FlushCommands(); } // Referred from GLES2ImplementationTest/ReportLoss TEST_F(WebGPUTest, ReportLoss) { - Initialize(WebGPUTest::Options()); - if (!WebGPUSupported()) { LOG(ERROR) << "Test skipped because WebGPU isn't supported"; return; } + Initialize(WebGPUTest::Options()); + GpuControlClient* webgpu_as_client = webgpu(); int lost_count = 0; webgpu()->SetLostContextCallback(base::BindOnce(&CountCallback, &lost_count)); @@ -207,13 +207,13 @@ // Referred from GLES2ImplementationTest/ReportLossReentrant TEST_F(WebGPUTest, ReportLossReentrant) { - Initialize(WebGPUTest::Options()); - if (!WebGPUSupported()) { LOG(ERROR) << "Test skipped because WebGPU isn't supported"; return; } + Initialize(WebGPUTest::Options()); + GpuControlClient* webgpu_as_client = webgpu(); int lost_count = 0; webgpu()->SetLostContextCallback(base::BindOnce(&CountCallback, &lost_count)); @@ -226,13 +226,13 @@ } TEST_F(WebGPUTest, RequestAdapterAfterContextLost) { - Initialize(WebGPUTest::Options()); - if (!WebGPUSupported()) { LOG(ERROR) << "Test skipped because WebGPU isn't supported"; return; } + Initialize(WebGPUTest::Options()); + webgpu()->OnGpuControlLostContext(); ASSERT_FALSE( webgpu()->RequestAdapterAsync(webgpu::PowerPreference::kDefault, @@ -240,13 +240,13 @@ } TEST_F(WebGPUTest, RequestDeviceAfterContextLost) { - Initialize(WebGPUTest::Options()); - if (!WebGPUSupported()) { LOG(ERROR) << "Test skipped because WebGPU isn't supported"; return; } + Initialize(WebGPUTest::Options()); + webgpu()->OnGpuControlLostContext(); ASSERT_FALSE(webgpu()->RequestDeviceAsync( kAdapterServiceID, {},
diff --git a/gpu/command_buffer/tests/webgpu_test.h b/gpu/command_buffer/tests/webgpu_test.h index af7e58e2..cacc34f 100644 --- a/gpu/command_buffer/tests/webgpu_test.h +++ b/gpu/command_buffer/tests/webgpu_test.h
@@ -86,7 +86,6 @@ // SharedImages on macOS require a valid image factory. GpuMemoryBufferFactoryIOSurface image_factory_; #endif - bool is_initialized_ = false; webgpu::DawnDeviceClientID next_device_client_id_ = 1; };
diff --git a/gpu/ipc/in_process_command_buffer.cc b/gpu/ipc/in_process_command_buffer.cc index 462ec1550..74db6a8 100644 --- a/gpu/ipc/in_process_command_buffer.cc +++ b/gpu/ipc/in_process_command_buffer.cc
@@ -358,7 +358,7 @@ base::trace_event::MemoryDumpManager::GetInstance() ->GetTracingProcessId(); memory_tracker = std::make_unique<GpuCommandBufferMemoryTracker>( - command_buffer_id_, client_tracing_id, params.attribs.context_type, + command_buffer_id_, client_tracing_id, base::ThreadTaskRunnerHandle::Get(), /* obserer=*/nullptr); }
diff --git a/gpu/ipc/service/command_buffer_stub.cc b/gpu/ipc/service/command_buffer_stub.cc index dea796c9..8ba84ade 100644 --- a/gpu/ipc/service/command_buffer_stub.cc +++ b/gpu/ipc/service/command_buffer_stub.cc
@@ -649,15 +649,14 @@ destruction_observers_.RemoveObserver(observer); } -std::unique_ptr<MemoryTracker> CommandBufferStub::CreateMemoryTracker( - const GPUCreateCommandBufferConfig& init_params) const { +std::unique_ptr<MemoryTracker> CommandBufferStub::CreateMemoryTracker() const { MemoryTrackerFactory current_factory = GetMemoryTrackerFactory(); if (current_factory) - return current_factory.Run(init_params); + return current_factory.Run(); return std::make_unique<GpuCommandBufferMemoryTracker>( command_buffer_id_, channel_->client_tracing_id(), - init_params.attribs.context_type, channel_->task_runner(), + channel_->task_runner(), channel_->gpu_channel_manager()->peak_memory_monitor()); }
diff --git a/gpu/ipc/service/command_buffer_stub.h b/gpu/ipc/service/command_buffer_stub.h index 641306f..3e829e4 100644 --- a/gpu/ipc/service/command_buffer_stub.h +++ b/gpu/ipc/service/command_buffer_stub.h
@@ -106,8 +106,7 @@ void HandleReturnData(base::span<const uint8_t> data) override; using MemoryTrackerFactory = - base::RepeatingCallback<std::unique_ptr<MemoryTracker>( - const GPUCreateCommandBufferConfig&)>; + base::RepeatingCallback<std::unique_ptr<MemoryTracker>()>; // Overrides the way CreateMemoryTracker() uses to create a MemoryTracker. // This is intended for mocking the MemoryTracker in tests. @@ -146,8 +145,7 @@ protected: virtual bool HandleMessage(const IPC::Message& message) = 0; - std::unique_ptr<MemoryTracker> CreateMemoryTracker( - const GPUCreateCommandBufferConfig& init_params) const; + std::unique_ptr<MemoryTracker> CreateMemoryTracker() const; // Must be called during Initialize(). Takes ownership to co-ordinate // teardown in Destroy().
diff --git a/gpu/ipc/service/gles2_command_buffer_stub.cc b/gpu/ipc/service/gles2_command_buffer_stub.cc index 9ccf7ef..f0d3b58 100644 --- a/gpu/ipc/service/gles2_command_buffer_stub.cc +++ b/gpu/ipc/service/gles2_command_buffer_stub.cc
@@ -107,7 +107,7 @@ manager->gpu_memory_buffer_factory(); context_group_ = new gles2::ContextGroup( manager->gpu_preferences(), gles2::PassthroughCommandDecoderSupported(), - manager->mailbox_manager(), CreateMemoryTracker(init_params), + manager->mailbox_manager(), CreateMemoryTracker(), manager->shader_translator_cache(), manager->framebuffer_completeness_cache(), feature_info, init_params.attribs.bind_generates_resource, channel_->image_manager(),
diff --git a/gpu/ipc/service/image_decode_accelerator_stub_unittest.cc b/gpu/ipc/service/image_decode_accelerator_stub_unittest.cc index 626b6f0..8861813 100644 --- a/gpu/ipc/service/image_decode_accelerator_stub_unittest.cc +++ b/gpu/ipc/service/image_decode_accelerator_stub_unittest.cc
@@ -100,8 +100,7 @@ SkISize dimensions; }; -std::unique_ptr<MemoryTracker> CreateMockMemoryTracker( - const GPUCreateCommandBufferConfig& init_params) { +std::unique_ptr<MemoryTracker> CreateMockMemoryTracker() { return std::make_unique<NiceMock<gles2::MockMemoryTracker>>(); }
diff --git a/gpu/ipc/service/raster_command_buffer_stub.cc b/gpu/ipc/service/raster_command_buffer_stub.cc index e56d432..70e63c3 100644 --- a/gpu/ipc/service/raster_command_buffer_stub.cc +++ b/gpu/ipc/service/raster_command_buffer_stub.cc
@@ -119,7 +119,7 @@ use_virtualized_gl_context_ = shared_context_state->use_virtualized_gl_contexts(); - memory_tracker_ = CreateMemoryTracker(init_params); + memory_tracker_ = CreateMemoryTracker(); command_buffer_ = std::make_unique<CommandBufferService>(this, memory_tracker_.get());
diff --git a/gpu/ipc/service/webgpu_command_buffer_stub.cc b/gpu/ipc/service/webgpu_command_buffer_stub.cc index 790ebc7..88fb12f 100644 --- a/gpu/ipc/service/webgpu_command_buffer_stub.cc +++ b/gpu/ipc/service/webgpu_command_buffer_stub.cc
@@ -106,7 +106,7 @@ share_group_ = manager->share_group(); use_virtualized_gl_context_ = false; - memory_tracker_ = CreateMemoryTracker(init_params); + memory_tracker_ = CreateMemoryTracker(); command_buffer_ = std::make_unique<CommandBufferService>(this, memory_tracker_.get());
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index 1134fa35..01e06d66 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg
@@ -11109,7 +11109,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/code_coverage\":{\"use_java_coverage\":true},\"$build/goma\":{\"enable_ats\":true,\"jobs\":300,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"jobs\":300,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -11144,7 +11144,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/code_coverage\":{\"use_java_coverage\":true},\"$build/goma\":{\"enable_ats\":true,\"jobs\":300,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"jobs\":300,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -12759,7 +12759,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/code_coverage\":{\"use_clang_coverage\":true},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -12794,7 +12794,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/code_coverage\":{\"use_clang_coverage\":true},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -12829,7 +12829,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/code_coverage\":{\"use_clang_coverage\":true},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -14440,7 +14440,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 + execution_timeout_secs: 21600 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -15000,7 +15000,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/code_coverage\":{\"use_clang_coverage\":true},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -15035,7 +15035,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/code_coverage\":{\"use_clang_coverage\":true},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -15070,7 +15070,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/code_coverage\":{\"use_clang_coverage\":true},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -25291,11 +25291,11 @@ swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" dimensions: "builderless:1" - dimensions: "cores:8" + dimensions: "cores:16" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-16.04" dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" + dimensions: "ssd:1" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master"
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star index 8bbecf7..f811df7 100644 --- a/infra/config/subprojects/chromium/ci.star +++ b/infra/config/subprojects/chromium/ci.star
@@ -2300,7 +2300,6 @@ builderless = False, cores = None, goma_jobs = goma.jobs.J300, - use_java_coverage = True, ) ci.fyi_builder( @@ -2312,7 +2311,6 @@ builderless = False, cores = None, goma_jobs = goma.jobs.J300, - use_java_coverage = True, ) ci.fyi_builder( @@ -2585,7 +2583,6 @@ ), builderless = False, cores = None, - use_clang_coverage = True, goma_jobs = goma.jobs.J150, ) @@ -2597,7 +2594,6 @@ ), builderless = False, cores = None, - use_clang_coverage = True, goma_jobs = goma.jobs.J150, ) @@ -2609,7 +2605,6 @@ ), builderless = False, cores = None, - use_clang_coverage = True, goma_jobs = goma.jobs.J150, ) @@ -2779,7 +2774,6 @@ ), builderless = False, cores = None, - use_clang_coverage = True, goma_jobs = goma.jobs.J150, ) @@ -2791,7 +2785,6 @@ ), builderless = False, cores = None, - use_clang_coverage = True, goma_jobs = goma.jobs.J150, ) @@ -2803,7 +2796,6 @@ ), builderless = False, cores = None, - use_clang_coverage = True, goma_jobs = goma.jobs.J150, ) @@ -4328,6 +4320,9 @@ category = "mac", short_name = "a64", ), + # TODO(gbeaty) Once we have sufficient test capacity to not need to + # serialize tests, use the default execution_timout + execution_timeout = 6 * time.hour, tree_closing = False, triggered_by = [builder_name("mac-arm64-rel")], )
diff --git a/infra/config/subprojects/chromium/try.star b/infra/config/subprojects/chromium/try.star index 7fbf5f4..59ea7df5 100644 --- a/infra/config/subprojects/chromium/try.star +++ b/infra/config/subprojects/chromium/try.star
@@ -678,6 +678,8 @@ try_.chromium_chromiumos_builder( name = "linux-lacros-rel", + cores = 16, + ssd = True, goma_jobs = goma.jobs.J150, main_list_view = "try", tryjob = try_.job(),
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index 5c065ee..5287606 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -49,8 +49,7 @@ #include "ios/chrome/browser/chrome_paths.h" #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.h" #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service_factory.h" -#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service.h" -#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service_factory.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_manager.h" #include "ios/chrome/browser/crash_report/breadcrumbs/features.h" #include "ios/chrome/browser/crash_report/breakpad_helper.h" #include "ios/chrome/browser/crash_report/crash_keys_helper.h" @@ -689,14 +688,19 @@ if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) { if (self.appState.mainBrowserState->HasOffTheRecordChromeBrowserState()) { - breakpad::StopMonitoringBreadcrumbManagerService( + BreadcrumbManagerKeyedService* service = BreadcrumbManagerKeyedServiceFactory::GetForBrowserState( self.appState.mainBrowserState - ->GetOffTheRecordChromeBrowserState())); + ->GetOffTheRecordChromeBrowserState()); + service->StopPersisting(); + breakpad::StopMonitoringBreadcrumbManagerService(service); } - breakpad::StopMonitoringBreadcrumbManagerService( + + BreadcrumbManagerKeyedService* service = BreadcrumbManagerKeyedServiceFactory::GetForBrowserState( - self.appState.mainBrowserState)); + self.appState.mainBrowserState); + service->StopPersisting(); + breakpad::StopMonitoringBreadcrumbManagerService(service); } _extensionSearchEngineDataUpdater = nullptr; @@ -949,29 +953,19 @@ self.appState.mainBrowserState); breakpad::MonitorBreadcrumbManagerService(breadcrumbService); - __weak __typeof(self) weakSelf = self; - BreadcrumbPersistentStorageKeyedService* persistentStorageService = - BreadcrumbPersistentStorageKeyedServiceFactory::GetForBrowserState( - self.appState.mainBrowserState); - // Get stored persistent breadcrumbs from last run and set them on the - // breadcrumb manager. - persistentStorageService->GetStoredEvents( + BreadcrumbPersistentStorageManager* persistentStorageManager = + GetApplicationContext()->GetBreadcrumbPersistentStorageManager(); + + // Application context can return a null persistent storage manager if + // breadcrumbs are not being persisted. + if (persistentStorageManager) { + breadcrumbService->StartPersisting(persistentStorageManager); + } + + // Get stored persistent breadcrumbs from last run to set on crash reports. + persistentStorageManager->GetStoredEvents( base::BindOnce(^(std::vector<std::string> events) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - if (!strongSelf || !strongSelf.appState.mainBrowserState) { - return; - } - - BreadcrumbManagerKeyedServiceFactory::GetForBrowserState( - strongSelf.appState.mainBrowserState) - ->SetPreviousEvents(events); breakpad::SetPreviousSessionEvents(events); - - // Notify persistent breadcrumb service to clear old breadcrumbs and - // start storing breadcrumbs for this session. - BreadcrumbPersistentStorageKeyedServiceFactory::GetForBrowserState( - strongSelf.appState.mainBrowserState) - ->StartStoringEvents(); })); }
diff --git a/ios/chrome/browser/application_context.h b/ios/chrome/browser/application_context.h index 000d44d..ee32f71 100644 --- a/ios/chrome/browser/application_context.h +++ b/ios/chrome/browser/application_context.h
@@ -64,6 +64,7 @@ } class ApplicationContext; +class BreadcrumbPersistentStorageManager; class BrowserPolicyConnectorIOS; class IOSChromeIOThread; class PrefService; @@ -155,6 +156,11 @@ // system. May be |nullptr| if policy is not enabled. virtual BrowserPolicyConnectorIOS* GetBrowserPolicyConnector() = 0; + // Returns the BreadcrumbPersistentStorageManager writing breadcrumbs to disk. + // Will be null if breadcrumb collection is not enabled. + virtual BreadcrumbPersistentStorageManager* + GetBreadcrumbPersistentStorageManager() = 0; + protected: // Sets the global ApplicationContext instance. static void SetApplicationContext(ApplicationContext* context);
diff --git a/ios/chrome/browser/application_context_impl.h b/ios/chrome/browser/application_context_impl.h index 5cd6926..026c01e 100644 --- a/ios/chrome/browser/application_context_impl.h +++ b/ios/chrome/browser/application_context_impl.h
@@ -18,8 +18,9 @@ class SequencedTaskRunner; } -class BreadcrumbManager; class ApplicationBreadcrumbsLogger; +class BreadcrumbManager; +class BreadcrumbPersistentStorageManager; namespace network { class NetworkChangeManager; @@ -73,6 +74,8 @@ SafeBrowsingService* GetSafeBrowsingService() override; network::NetworkConnectionTracker* GetNetworkConnectionTracker() override; BrowserPolicyConnectorIOS* GetBrowserPolicyConnector() override; + BreadcrumbPersistentStorageManager* GetBreadcrumbPersistentStorageManager() + override; private: // Sets the locale used by the application. @@ -92,6 +95,10 @@ // Logger which observers and logs application wide events to // |breadcrumb_manager_|. Will be null if breadcrumbs feature is not enabled. std::unique_ptr<ApplicationBreadcrumbsLogger> application_breadcrumbs_logger_; + // Persistent storage manager to write breadcrumbs to disk for storage + // between sessions. Will be null if breadcrumbs feature is not enabled. + std::unique_ptr<BreadcrumbPersistentStorageManager> + breadcrumb_persistent_storage_manager_; // Must be destroyed after |local_state_|. std::unique_ptr<BrowserPolicyConnectorIOS> browser_policy_connector_;
diff --git a/ios/chrome/browser/application_context_impl.mm b/ios/chrome/browser/application_context_impl.mm index f2d1668c9..705f9dee 100644 --- a/ios/chrome/browser/application_context_impl.mm +++ b/ios/chrome/browser/application_context_impl.mm
@@ -49,6 +49,7 @@ #include "ios/chrome/browser/component_updater/ios_component_updater_configurator.h" #import "ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.h" #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_manager.h" #include "ios/chrome/browser/crash_report/breadcrumbs/features.h" #include "ios/chrome/browser/gcm/ios_chrome_gcm_profile_service_factory.h" #include "ios/chrome/browser/history/history_service_factory.h" @@ -229,6 +230,15 @@ application_breadcrumbs_logger_ = std::make_unique<ApplicationBreadcrumbsLogger>( breadcrumb_manager_.get()); + + base::FilePath storage_dir; + bool result = base::PathService::Get(ios::DIR_USER_DATA, &storage_dir); + DCHECK(result); + breadcrumb_persistent_storage_manager_ = + std::make_unique<BreadcrumbPersistentStorageManager>(storage_dir); + + application_breadcrumbs_logger_->SetPersistentStorageManager( + breadcrumb_persistent_storage_manager_.get()); } } @@ -455,6 +465,12 @@ return browser_policy_connector_.get(); } +BreadcrumbPersistentStorageManager* +ApplicationContextImpl::GetBreadcrumbPersistentStorageManager() { + DCHECK(thread_checker_.CalledOnValidThread()); + return breadcrumb_persistent_storage_manager_.get(); +} + void ApplicationContextImpl::SetApplicationLocale(const std::string& locale) { DCHECK(thread_checker_.CalledOnValidThread()); application_locale_ = locale;
diff --git a/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm b/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm index fddb4249..c460e9d 100644 --- a/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm +++ b/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm
@@ -14,7 +14,6 @@ #include "ios/chrome/browser/browsing_data/browsing_data_remover_factory.h" #include "ios/chrome/browser/content_settings/cookie_settings_factory.h" #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service_factory.h" -#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service_factory.h" #include "ios/chrome/browser/credential_provider/credential_provider_service_factory.h" #import "ios/chrome/browser/device_sharing/device_sharing_manager_factory.h" #include "ios/chrome/browser/discover_feed/discover_feed_service_factory.h" @@ -106,7 +105,6 @@ suggestions::SuggestionsServiceFactory::GetInstance(); AuthenticationServiceFactory::GetInstance(); BreadcrumbManagerKeyedServiceFactory::GetInstance(); - BreadcrumbPersistentStorageKeyedServiceFactory::GetInstance(); BrowserDownloadServiceFactory::GetInstance(); BrowsingDataRemoverFactory::GetInstance(); ConsentAuditorFactory::GetInstance();
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/BUILD.gn b/ios/chrome/browser/crash_report/breadcrumbs/BUILD.gn index 640bba3..df027900 100644 --- a/ios/chrome/browser/crash_report/breadcrumbs/BUILD.gn +++ b/ios/chrome/browser/crash_report/breadcrumbs/BUILD.gn
@@ -46,10 +46,8 @@ "breadcrumb_manager_observer_bridge.mm", "breadcrumb_manager_tab_helper.h", "breadcrumb_manager_tab_helper.mm", - "breadcrumb_persistent_storage_keyed_service.cc", - "breadcrumb_persistent_storage_keyed_service.h", - "breadcrumb_persistent_storage_keyed_service_factory.cc", - "breadcrumb_persistent_storage_keyed_service_factory.h", + "breadcrumb_persistent_storage_manager.h", + "breadcrumb_persistent_storage_manager.mm", "breadcrumb_persistent_storage_util.cc", "breadcrumb_persistent_storage_util.h", ] @@ -114,7 +112,7 @@ "breadcrumb_manager_observer_unittest.mm", "breadcrumb_manager_tab_helper_unittest.mm", "breadcrumb_manager_unittest.mm", - "breadcrumb_persistent_storage_keyed_service_unittest.mm", + "breadcrumb_persistent_storage_manager_unittest.mm", "breadcrumb_persistent_storage_util_unittest.mm", ] }
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.h b/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.h index b157b0c..c3d5004 100644 --- a/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.h +++ b/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.h
@@ -17,6 +17,7 @@ } // namespace base class BreadcrumbManager; +class BreadcrumbPersistentStorageManager; // Name of event logged when device orientation is changed. extern const char kBreadcrumbOrientation[]; @@ -28,6 +29,11 @@ explicit ApplicationBreadcrumbsLogger(BreadcrumbManager* breadcrumb_manager); ~ApplicationBreadcrumbsLogger(); + // Sets a BreadcrumbPersistentStorageManager to persist application breadcrumb + // events logged by this ApplicationBreadcrumbsLogger instance. + void SetPersistentStorageManager( + BreadcrumbPersistentStorageManager* persistent_storage_manager); + private: ApplicationBreadcrumbsLogger(const ApplicationBreadcrumbsLogger&) = delete; @@ -52,6 +58,10 @@ // Observes device orientation. id<NSObject> orientation_observer_; + // A weak reference to the persistent breadcrumb manager listening for events + // from |breadcrumb_manager_| to store to disk. + BreadcrumbPersistentStorageManager* persistent_storage_manager_ = nullptr; + // Used to avoid logging the same orientation twice. base::Optional<UIDeviceOrientation> last_orientation_; };
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.mm b/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.mm index 046cd7e3..ef8ae51 100644 --- a/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.mm +++ b/ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.mm
@@ -8,6 +8,7 @@ #include "base/strings/stringprintf.h" #include "ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_not_user_action.inc" #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_manager.h" #import "ios/chrome/browser/crash_report/crash_report_helper.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -27,6 +28,7 @@ base::BindRepeating(&ApplicationBreadcrumbsLogger::OnMemoryPressure, base::Unretained(this)))) { base::AddActionCallback(user_action_callback_); + breakpad::MonitorBreadcrumbManager(breadcrumb_manager_); breadcrumb_manager_->AddEvent("Startup"); @@ -72,6 +74,21 @@ breadcrumb_manager_->AddEvent("Shutdown"); base::RemoveActionCallback(user_action_callback_); breakpad::StopMonitoringBreadcrumbManager(breadcrumb_manager_); + if (persistent_storage_manager_) { + persistent_storage_manager_->StopMonitoringBreadcrumbManager( + breadcrumb_manager_); + } +} + +void ApplicationBreadcrumbsLogger::SetPersistentStorageManager( + BreadcrumbPersistentStorageManager* persistent_storage_manager) { + if (persistent_storage_manager_) { + persistent_storage_manager_->StopMonitoringBreadcrumbManager( + breadcrumb_manager_); + } + + persistent_storage_manager_ = persistent_storage_manager; + persistent_storage_manager->MonitorBreadcrumbManager(breadcrumb_manager_); } void ApplicationBreadcrumbsLogger::OnUserAction(const std::string& action,
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.cc b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.cc index 8845561..ddd0c26 100644 --- a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.cc +++ b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.cc
@@ -73,29 +73,6 @@ return events; } -void BreadcrumbManager::SetPreviousEvents( - const std::vector<std::string>& events) { - if (events.empty()) { - return; - } - - // Create a new bucket with a fake timestamp before the application started. - // This ensures that these initial events will be dropped before new events - // from the current session. - base::TimeDelta time_since_construction = base::Time::Now() - start_time_; - base::Time previous_events_bucket_time = - base::Time::Now() - - base::TimeDelta::FromSeconds(60 + time_since_construction.InSeconds()); - std::pair<base::Time, std::list<std::string>> bucket( - EventBucket(previous_events_bucket_time), std::list<std::string>()); - - for (auto event_it = events.rbegin(); event_it != events.rend(); ++event_it) { - std::string event = *event_it; - bucket.second.push_front(event); - } - event_buckets_.push_front(bucket); -} - void BreadcrumbManager::AddEvent(const std::string& event) { base::Time time = base::Time::Now(); base::Time bucket_time = EventBucket(time);
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.h b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.h index 2ac8462..fe4ae0c 100644 --- a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.h +++ b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.h
@@ -34,9 +34,6 @@ // even if no new events have been added, but time has passed. const std::list<std::string> GetEvents(size_t event_count_limit); - // Sets previous events by inserting them before all existing events. - void SetPreviousEvents(const std::vector<std::string>& events); - // Logs a breadcrumb event with message data |event|. // NOTE: |event| must not include newline characters as newlines are used by // BreadcrumbPersistentStore as a deliminator.
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.cc b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.cc index a61b1ab..47d519c 100644 --- a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.cc +++ b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.cc
@@ -6,13 +6,9 @@ #include "base/strings/stringprintf.h" #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_manager.h" #include "ios/web/public/browser_state.h" -void BreadcrumbManagerKeyedService::SetPreviousEvents( - const std::vector<std::string>& events) { - breadcrumb_manager_->SetPreviousEvents(events); -} - void BreadcrumbManagerKeyedService::AddEvent(const std::string& event) { std::string event_log = base::StringPrintf("%s%s", browsing_mode_.c_str(), event.c_str()); @@ -38,6 +34,32 @@ return breadcrumb_manager_->GetEvents(event_count_limit); } +void BreadcrumbManagerKeyedService::StartPersisting( + BreadcrumbPersistentStorageManager* persistent_storage_manager) { + DCHECK(persistent_storage_manager); + + if (persistent_storage_manager_) { + StopPersisting(); + } + + persistent_storage_manager_ = persistent_storage_manager; + persistent_storage_manager_->MonitorBreadcrumbManagerService(this); +} + +void BreadcrumbManagerKeyedService::StopPersisting() { + if (!persistent_storage_manager_) { + return; + } + + persistent_storage_manager_->StopMonitoringBreadcrumbManagerService(this); + persistent_storage_manager_ = nullptr; +} + +BreadcrumbPersistentStorageManager* +BreadcrumbManagerKeyedService::GetPersistentStorageManager() { + return persistent_storage_manager_; +} + BreadcrumbManagerKeyedService::BreadcrumbManagerKeyedService( web::BrowserState* browser_state) // Set "I" for Incognito (Chrome branded OffTheRecord implementation) and
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.h b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.h index 3f515f8..a0dcca0 100644 --- a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.h +++ b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.h
@@ -13,6 +13,7 @@ class BreadcrumbManager; class BreadcrumbManagerObserver; +class BreadcrumbPersistentStorageManager; namespace web { class BrowserState; @@ -24,9 +25,6 @@ explicit BreadcrumbManagerKeyedService(web::BrowserState* browser_state); ~BreadcrumbManagerKeyedService() override; - // Sets previous events by inserting them before all existing events. - void SetPreviousEvents(const std::vector<std::string>& events); - // Logs a breadcrumb |event| associated with the BrowserState passed in at // initialization of this instance. Prepends the |browsing_mode_| identifier // to the event before passing it to the |breadcrumb_manager_|. @@ -45,6 +43,19 @@ // details. const std::list<std::string> GetEvents(size_t event_count_limit) const; + // Persists all events logged to |breadcrumb_manager_| to + // |persistent_storage_manager|. If StartPersisting has already been called, + // breadcrumbs will no longer be persisted to the previous + // |persistent_storage_manager|. + // NOTE: |persistent_storage_manager| must be non-null. + void StartPersisting( + BreadcrumbPersistentStorageManager* persistent_storage_manager); + // Stops persisting events to |persistent_storage_manager_|. No-op if + // |persistent_storage_manager_| is not set. + void StopPersisting(); + // Returns the current |persistent_storage_manager_|. + BreadcrumbPersistentStorageManager* GetPersistentStorageManager(); + private: // A short string identifying the browser state used to initialize the // receiver. For example, "I" for "I"ncognito browsing mode. This value is @@ -57,6 +68,10 @@ // The associated BreadcrumbManager to store events added with |AddEvent|. std::unique_ptr<BreadcrumbManager> breadcrumb_manager_; + // The current BreadcrumbPersistentStorageManager persisting events logged to + // |breadcrumb_manager_|, set by StartPersisting. May be null. + BreadcrumbPersistentStorageManager* persistent_storage_manager_ = nullptr; + DISALLOW_COPY_AND_ASSIGN(BreadcrumbManagerKeyedService); };
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_unittest.mm b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_unittest.mm index 5704bf4a..7d404af 100644 --- a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_unittest.mm +++ b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_unittest.mm
@@ -86,19 +86,3 @@ std::list<std::string> events = breadcrumb_manager_.GetEvents(0); EXPECT_EQ(2ul, events.size()); } - -// Tests that previous events are set as expected. -TEST_F(BreadcrumbManagerTest, SetPreviousEvents) { - breadcrumb_manager_.SetPreviousEvents({"event1", "event2"}); - ASSERT_EQ(2ul, breadcrumb_manager_.GetEvents(0).size()); - - task_env_.FastForwardBy(base::TimeDelta::FromMinutes(3)); - breadcrumb_manager_.AddEvent("event3"); - - std::list<std::string> events = breadcrumb_manager_.GetEvents(0); - EXPECT_NE(std::string::npos, events.front().find("event1")); - events.pop_front(); - EXPECT_NE(std::string::npos, events.front().find("event2")); - events.pop_front(); - EXPECT_NE(std::string::npos, events.front().find("event3")); -}
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service.cc b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service.cc deleted file mode 100644 index 73cfd51..0000000 --- a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service.cc +++ /dev/null
@@ -1,240 +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 "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service.h" - -#include <string> - -#include "base/bind.h" -#include "base/files/file_util.h" -#include "base/files/memory_mapped_file.h" -#include "base/sequenced_task_runner.h" -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" -#include "base/task/post_task.h" -#include "base/task/thread_pool.h" -#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.h" -#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.h" -#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service_factory.h" -#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_util.h" - -namespace { - -const char kEventSeparator[] = "\n"; - -// Minimum time between breadcrumb writes to disk. -constexpr auto kMinDelayBetweenWrites = base::TimeDelta::FromMilliseconds(250); - -// Writes |events| to |file_path| at |position|. -void DoInsertEventsIntoMemoryMappedFile(const base::FilePath& file_path, - const size_t position, - const std::string& events) { - auto file = std::make_unique<base::MemoryMappedFile>(); - const base::MemoryMappedFile::Region region = {0, kPersistedFilesizeInBytes}; - const bool file_valid = file->Initialize( - base::File(file_path, base::File::FLAG_OPEN_ALWAYS | - base::File::FLAG_READ | base::File::FLAG_WRITE), - region, base::MemoryMappedFile::READ_WRITE_EXTEND); - - if (file_valid) { - char* data = reinterpret_cast<char*>(file->data()); - std::strcpy(&data[position], events.data()); - } -} - -// Writes |events| to |file_path| overwriting any existing data. -void DoWriteEventsToFile(const base::FilePath& file_path, - const std::string& events) { - const base::MemoryMappedFile::Region region = {0, kPersistedFilesizeInBytes}; - base::MemoryMappedFile file; - const bool file_valid = file.Initialize( - base::File(file_path, base::File::FLAG_CREATE_ALWAYS | - base::File::FLAG_READ | base::File::FLAG_WRITE), - region, base::MemoryMappedFile::READ_WRITE_EXTEND); - - if (file_valid) { - char* data = reinterpret_cast<char*>(file.data()); - std::strcpy(data, events.data()); - } -} - -void DoReplaceFile(const base::FilePath& from_path, - const base::FilePath& to_path) { - base::ReplaceFile(from_path, to_path, nullptr); -} - -// Returns breadcrumb events stored at |file_path|. -std::vector<std::string> DoGetStoredEvents(const base::FilePath& file_path) { - base::File events_file(file_path, - base::File::FLAG_OPEN | base::File::FLAG_READ); - if (!events_file.IsValid()) { - // File may not yet exist. - return std::vector<std::string>(); - } - - size_t file_size = events_file.GetLength(); - if (file_size <= 0) { - return std::vector<std::string>(); - } - - // Do not read more than |kPersistedFilesizeInBytes|, in case the file was - // corrupted. If |kPersistedFilesizeInBytes| has been reduced since the last - // breadcrumbs file was saved, this could result in a one time loss of the - // oldest breadcrumbs which is ok because the decision has already been made - // to reduce the size of the stored breadcrumbs. - if (file_size > kPersistedFilesizeInBytes) { - file_size = kPersistedFilesizeInBytes; - } - - std::vector<uint8_t> data; - data.resize(file_size); - if (!events_file.ReadAndCheck(/*offset=*/0, data)) { - return std::vector<std::string>(); - } - std::string persisted_events(data.begin(), data.end()); - std::string all_events = - persisted_events.substr(/*pos=*/0, strlen(persisted_events.c_str())); - return base::SplitString(all_events, kEventSeparator, base::TRIM_WHITESPACE, - base::SPLIT_WANT_NONEMPTY); -} - -} // namespace - -using breadcrumb_persistent_storage_util:: - GetBreadcrumbPersistentStorageFilePath; -using breadcrumb_persistent_storage_util:: - GetBreadcrumbPersistentStorageTempFilePath; - -BreadcrumbPersistentStorageKeyedService:: - BreadcrumbPersistentStorageKeyedService(web::BrowserState* browser_state) - : // Ensure first event will not be delayed by initializing with a time in - // the past. - last_written_time_(base::TimeTicks::Now() - kMinDelayBetweenWrites), - browser_state_(browser_state), - breadcrumbs_file_path_( - GetBreadcrumbPersistentStorageFilePath(browser_state_)), - task_runner_(base::ThreadPool::CreateSequencedTaskRunner( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, - base::TaskShutdownBehavior::BLOCK_SHUTDOWN})), - weak_factory_(this) {} - -BreadcrumbPersistentStorageKeyedService:: - ~BreadcrumbPersistentStorageKeyedService() = default; - -void BreadcrumbPersistentStorageKeyedService::GetStoredEvents( - base::OnceCallback<void(std::vector<std::string>)> callback) { - task_runner_->PostTaskAndReplyWithResult( - FROM_HERE, base::BindOnce(&DoGetStoredEvents, breadcrumbs_file_path_), - std::move(callback)); -} - -void BreadcrumbPersistentStorageKeyedService::StartStoringEvents() { - RewriteAllExistingBreadcrumbs(); - - BreadcrumbManagerKeyedServiceFactory::GetForBrowserState(browser_state_) - ->AddObserver(this); -} - -void BreadcrumbPersistentStorageKeyedService::RewriteAllExistingBreadcrumbs() { - // Cancel writing out individual breadcrumbs as they are all being re-written. - pending_breadcrumbs_.clear(); - write_timer_.Stop(); - - last_written_time_ = base::TimeTicks::Now(); - - current_mapped_file_position_ = 0; - - std::list<std::string> events = - BreadcrumbManagerKeyedServiceFactory::GetForBrowserState(browser_state_) - ->GetEvents(/*event_count_limit=*/0); - - std::vector<std::string> breadcrumbs; - for (auto event_it = events.rbegin(); event_it != events.rend(); ++event_it) { - // Reduce saved events to only fill the amount which would be included on - // a crash log. This allows future events to be appended individually up to - // |kPersistedFilesizeInBytes|, which is more efficient than writing out the - const int event_with_seperator_size = - event_it->size() + strlen(kEventSeparator); - if (event_with_seperator_size + current_mapped_file_position_ >= - kMaxBreadcrumbsDataLength) { - break; - } - - breadcrumbs.push_back(kEventSeparator); - breadcrumbs.push_back(*event_it); - current_mapped_file_position_ += event_with_seperator_size; - } - - std::reverse(breadcrumbs.begin(), breadcrumbs.end()); - std::string breadcrumbs_string = base::JoinString(breadcrumbs, ""); - - task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&DoWriteEventsToFile, - base::Passed(GetBreadcrumbPersistentStorageTempFilePath( - browser_state_)), - std::string(breadcrumbs_string))); - - task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&DoReplaceFile, - base::Passed(GetBreadcrumbPersistentStorageTempFilePath( - browser_state_)), - breadcrumbs_file_path_)); -} - -void BreadcrumbPersistentStorageKeyedService::WritePendingBreadcrumbs() { - if (pending_breadcrumbs_.empty()) { - return; - } - - task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&DoInsertEventsIntoMemoryMappedFile, - breadcrumbs_file_path_, current_mapped_file_position_, - std::string(pending_breadcrumbs_))); - - current_mapped_file_position_ += pending_breadcrumbs_.size(); - last_written_time_ = base::TimeTicks::Now(); - - pending_breadcrumbs_.clear(); -} - -void BreadcrumbPersistentStorageKeyedService::EventAdded( - BreadcrumbManager* manager, - const std::string& event) { - // If the event doesn not fit within |kPersistedFilesizeInBytes|, rewrite the - // file to trim old events. - if ((current_mapped_file_position_ + pending_breadcrumbs_.size() + - // Use >= here instead of > to allow space for \0 to terminate file. - event.size()) >= kPersistedFilesizeInBytes) { - RewriteAllExistingBreadcrumbs(); - return; - } - - write_timer_.Stop(); - - pending_breadcrumbs_ += event + kEventSeparator; - - const base::TimeDelta time_delta_since_last_write = - base::TimeTicks::Now() - last_written_time_; - // Delay writing the event to disk if an event was just written. - if (time_delta_since_last_write < kMinDelayBetweenWrites) { - write_timer_.Start( - FROM_HERE, kMinDelayBetweenWrites - time_delta_since_last_write, this, - &BreadcrumbPersistentStorageKeyedService::WritePendingBreadcrumbs); - } else { - WritePendingBreadcrumbs(); - } -} - -void BreadcrumbPersistentStorageKeyedService::OldEventsRemoved( - BreadcrumbManager* manager) { - RewriteAllExistingBreadcrumbs(); -} - -void BreadcrumbPersistentStorageKeyedService::Shutdown() { - BreadcrumbManagerKeyedServiceFactory::GetForBrowserState(browser_state_) - ->RemoveObserver(this); -}
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service.h b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service.h deleted file mode 100644 index b7e22e4..0000000 --- a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service.h +++ /dev/null
@@ -1,102 +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 IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_BREADCRUMB_PERSISTENT_STORAGE_KEYED_SERVICE_H_ -#define IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_BREADCRUMB_PERSISTENT_STORAGE_KEYED_SERVICE_H_ - -#include <memory> -#include <string> -#include <vector> - -#include "base/callback.h" -#include "base/files/file.h" -#include "base/files/file_path.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/timer/timer.h" -#include "components/keyed_service/core/keyed_service.h" -#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_observer.h" -#include "ios/chrome/browser/crash_report/crash_reporter_breadcrumb_constants.h" - -namespace web { -class BrowserState; -} // namespace web - -// The filesize for the file at |breadcrumbs_file_path_|. The file will always -// be this constant size because it is accessed using a memory mapped file. The -// file is twice as large as |kMaxBreadcrumbsDataLength| which leaves room for -// appending breadcrumb events. Once the file is full of events, the contents -// will be reduced to kMaxBreadcrumbsDataLength. -constexpr size_t kPersistedFilesizeInBytes = kMaxBreadcrumbsDataLength * 2; - -// Saves and retrieves breadcrumb events to and from disk. -class BreadcrumbPersistentStorageKeyedService - : public BreadcrumbManagerObserver, - public KeyedService { - public: - // Creates an instance to save and retrieve breadcrumb events from the file at - // |file_path|. The file will be created if necessary. - // explicit BreadcrumbPersistentStorageKeyedService(const base::FilePath& - // file_path); - explicit BreadcrumbPersistentStorageKeyedService( - web::BrowserState* browser_state); - ~BreadcrumbPersistentStorageKeyedService() override; - - // Returns the stored breadcrumb events from disk to |callback|. If called - // before |StartStoringEvents|, these events (if any) will be from the prior - // application session. After |StartStoringEvents| has been called, the - // returned events will be from the current application session. - void GetStoredEvents( - base::OnceCallback<void(std::vector<std::string>)> callback); - - // Starts persisting breadcrumbs from the BreadcrumbManagerKeyedService - // associated with |browser_state_|. This will overwrite any breadcrumbs which - // may be stored from a previous application run. - void StartStoringEvents(); - - private: - // Writes events from |observered_manager_| to |breadcrumbs_file_|, - // overwriting any existing persisted breadcrumbs. - void RewriteAllExistingBreadcrumbs(); - - // Writes breadcrumbs stored in |pending_breadcrumbs_| to |breadcrumbs_file_|. - void WritePendingBreadcrumbs(); - - // BreadcrumbManagerObserver - void EventAdded(BreadcrumbManager* manager, - const std::string& event) override; - void OldEventsRemoved(BreadcrumbManager* manager) override; - - // KeyedService overrides - void Shutdown() override; - - // Individual beadcrumbs which have not yet been written to disk. - std::string pending_breadcrumbs_; - - // The last time a breadcrumb was written to |breadcrumbs_file_|. This - // timestamp prevents breadcrumbs from being written to disk too often. - base::TimeTicks last_written_time_; - - // A timer to delay writing to disk too often. - base::OneShotTimer write_timer_; - - // The associated browser state. - web::BrowserState* browser_state_ = nullptr; - - // The path to the file for storing persisted breadcrumbs. - base::FilePath breadcrumbs_file_path_; - - // NOTE: Since this value represents the breadcrumbs written during this - // session, it will remain 0 until |StartStoringEvents| is called. - size_t current_mapped_file_position_ = 0; - - // The SequencedTaskRunner on which File IO operations are performed. - scoped_refptr<base::SequencedTaskRunner> task_runner_; - - base::WeakPtrFactory<BreadcrumbPersistentStorageKeyedService> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(BreadcrumbPersistentStorageKeyedService); -}; - -#endif // IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_BREADCRUMB_PERSISTENT_STORAGE_KEYED_SERVICE_H_
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service_factory.cc b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service_factory.cc deleted file mode 100644 index 1ea1406..0000000 --- a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service_factory.cc +++ /dev/null
@@ -1,47 +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 "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service_factory.h" - -#include "components/keyed_service/ios/browser_state_dependency_manager.h" -#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service.h" -#include "ios/web/public/browser_state.h" - -// static -BreadcrumbPersistentStorageKeyedServiceFactory* -BreadcrumbPersistentStorageKeyedServiceFactory::GetInstance() { - static base::NoDestructor<BreadcrumbPersistentStorageKeyedServiceFactory> - instance; - return instance.get(); -} - -// static -BreadcrumbPersistentStorageKeyedService* -BreadcrumbPersistentStorageKeyedServiceFactory::GetForBrowserState( - web::BrowserState* browser_state) { - return static_cast<BreadcrumbPersistentStorageKeyedService*>( - GetInstance()->GetServiceForBrowserState(browser_state, true)); -} - -BreadcrumbPersistentStorageKeyedServiceFactory:: - BreadcrumbPersistentStorageKeyedServiceFactory() - : BrowserStateKeyedServiceFactory( - "BreadcrumbPersistentStorageService", - BrowserStateDependencyManager::GetInstance()) {} - -BreadcrumbPersistentStorageKeyedServiceFactory:: - ~BreadcrumbPersistentStorageKeyedServiceFactory() {} - -std::unique_ptr<KeyedService> -BreadcrumbPersistentStorageKeyedServiceFactory::BuildServiceInstanceFor( - web::BrowserState* context) const { - return std::make_unique<BreadcrumbPersistentStorageKeyedService>(context); -} - -web::BrowserState* -BreadcrumbPersistentStorageKeyedServiceFactory::GetBrowserStateToUse( - web::BrowserState* context) const { - // Create the service for both normal and incognito browser states. - return context; -}
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service_factory.h b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service_factory.h deleted file mode 100644 index a4045c3..0000000 --- a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service_factory.h +++ /dev/null
@@ -1,41 +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 IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_BREADCRUMB_PERSISTENT_STORAGE_KEYED_SERVICE_FACTORY_H_ -#define IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_BREADCRUMB_PERSISTENT_STORAGE_KEYED_SERVICE_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/ios/browser_state_keyed_service_factory.h" - -class BreadcrumbPersistentStorageKeyedService; - -namespace web { -class BrowserState; -} // namespace web - -class BreadcrumbPersistentStorageKeyedServiceFactory - : public BrowserStateKeyedServiceFactory { - public: - static BreadcrumbPersistentStorageKeyedServiceFactory* GetInstance(); - static BreadcrumbPersistentStorageKeyedService* GetForBrowserState( - web::BrowserState* browser_state); - - private: - friend class base::NoDestructor< - BreadcrumbPersistentStorageKeyedServiceFactory>; - - BreadcrumbPersistentStorageKeyedServiceFactory(); - ~BreadcrumbPersistentStorageKeyedServiceFactory() override; - - // BrowserStateKeyedServiceFactory implementation. - std::unique_ptr<KeyedService> BuildServiceInstanceFor( - web::BrowserState* context) const override; - web::BrowserState* GetBrowserStateToUse( - web::BrowserState* context) const override; - - BreadcrumbPersistentStorageKeyedServiceFactory( - const BreadcrumbPersistentStorageKeyedServiceFactory&) = delete; -}; - -#endif // IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_BREADCRUMB_PERSISTENT_STORAGE_KEYED_SERVICE_FACTORY_H_
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_manager.h b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_manager.h new file mode 100644 index 0000000..a68270a --- /dev/null +++ b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_manager.h
@@ -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. + +#ifndef IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_BREADCRUMB_PERSISTENT_STORAGE_MANAGER_H_ +#define IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_BREADCRUMB_PERSISTENT_STORAGE_MANAGER_H_ + +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/files/file_path.h" +#include "base/timer/timer.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_observer.h" +#include "ios/chrome/browser/crash_report/crash_reporter_breadcrumb_constants.h" + +// The filesize for the file at |breadcrumbs_file_path_|. The file will always +// be this constant size because it is accessed using a memory mapped file. The +// file is twice as large as |kMaxBreadcrumbsDataLength| which leaves room for +// appending breadcrumb events. Once the file is full of events, the contents +// will be reduced to kMaxBreadcrumbsDataLength. +constexpr size_t kPersistedFilesizeInBytes = kMaxBreadcrumbsDataLength * 2; + +namespace base { +class FilePath; +} // namespace base + +class BreadcrumbManagerKeyedService; + +// Stores breadcrumb events to and retireves them from a file on disk. +// Persisting these events allows access to breadcrumb events from previous +// application sessions. +class BreadcrumbPersistentStorageManager : public BreadcrumbManagerObserver { + public: + explicit BreadcrumbPersistentStorageManager(base::FilePath directory); + ~BreadcrumbPersistentStorageManager() override; + + // Returns the stored breadcrumb events from disk to |callback|. + void GetStoredEvents( + base::OnceCallback<void(std::vector<std::string>)> callback); + + // Starts observing |manager| for events. Existing events will be persisted + // immediately. + void MonitorBreadcrumbManager(BreadcrumbManager* manager); + // Starts observing |service| for events. Existing events will be persisted + // immediately. + void MonitorBreadcrumbManagerService(BreadcrumbManagerKeyedService* service); + + // Stops observing |manager|. + void StopMonitoringBreadcrumbManager(BreadcrumbManager* manager); + // Stops observing |service|. + void StopMonitoringBreadcrumbManagerService( + BreadcrumbManagerKeyedService* service); + + private: + // Writes |pending_breadcrumbs_| to |breadcrumbs_file_| if it fits, otherwise + // rewrites the file. NOTE: Writing may be delayed if the file has recently + // been written into. + void WriteEvents(); + + // Writes events from |observered_manager_| to |breadcrumbs_file_|, + // overwriting any existing persisted breadcrumbs. + void RewriteAllExistingBreadcrumbs(); + + // Writes breadcrumbs stored in |pending_breadcrumbs_| to |breadcrumbs_file_|. + void WritePendingBreadcrumbs(); + + // Writes |event| to |breadcrumbs_file_|. + // NOTE: Writing may be delayed if the file has recently been written into. + void WriteEvent(const std::string& event); + + // BreadcrumbManagerObserver + void EventAdded(BreadcrumbManager* manager, + const std::string& event) override; + void OldEventsRemoved(BreadcrumbManager* manager) override; + + // Individual beadcrumbs which have not yet been written to disk. + std::string pending_breadcrumbs_; + + // The last time a breadcrumb was written to |breadcrumbs_file_|. This + // timestamp prevents breadcrumbs from being written to disk too often. + base::TimeTicks last_written_time_; + + // A timer to delay writing to disk too often. + base::OneShotTimer write_timer_; + + // The path to the file for storing persisted breadcrumbs. + base::FilePath breadcrumbs_file_path_; + + // The path to the temporary file for writing persisted breadcrumbs. + base::FilePath breadcrumbs_temp_file_path_; + + // NOTE: Since this value represents the breadcrumbs written during this + // session, it will remain 0 until |StartStoringEvents| is called. + size_t current_mapped_file_position_ = 0; + + // The SequencedTaskRunner on which File IO operations are performed. + scoped_refptr<base::SequencedTaskRunner> task_runner_; + + BreadcrumbPersistentStorageManager( + const BreadcrumbPersistentStorageManager&) = delete; + BreadcrumbPersistentStorageManager& operator=( + const BreadcrumbPersistentStorageManager&) = delete; +}; + +#endif // IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_BREADCRUMB_PERSISTENT_STORAGE_MANAGER_H_
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_manager.mm b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_manager.mm new file mode 100644 index 0000000..61fafa8 --- /dev/null +++ b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_manager.mm
@@ -0,0 +1,276 @@ +// 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 "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_manager.h" + +#include <memory> + +#include "base/bind.h" +#include "base/files/file_util.h" +#include "base/files/memory_mapped_file.h" +#include "base/sequenced_task_runner.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "base/task/post_task.h" +#include "base/task/thread_pool.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_util.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { + +const char kEventSeparator[] = "\n"; + +// Minimum time between breadcrumb writes to disk. +constexpr auto kMinDelayBetweenWrites = base::TimeDelta::FromMilliseconds(250); + +// Writes |events| to |file_path| at |position|. +void DoInsertEventsIntoMemoryMappedFile(const base::FilePath& file_path, + const size_t position, + const std::string& events) { + auto file = std::make_unique<base::MemoryMappedFile>(); + const base::MemoryMappedFile::Region region = {0, kPersistedFilesizeInBytes}; + const bool file_valid = file->Initialize( + base::File(file_path, base::File::FLAG_OPEN_ALWAYS | + base::File::FLAG_READ | base::File::FLAG_WRITE), + region, base::MemoryMappedFile::READ_WRITE_EXTEND); + + if (file_valid) { + char* data = reinterpret_cast<char*>(file->data()); + std::strcpy(&data[position], events.data()); + } +} + +// Writes |events| to |file_path| overwriting any existing data. +void DoWriteEventsToFile(const base::FilePath& file_path, + const std::string& events) { + const base::MemoryMappedFile::Region region = {0, kPersistedFilesizeInBytes}; + base::MemoryMappedFile file; + const bool file_valid = file.Initialize( + base::File(file_path, base::File::FLAG_CREATE_ALWAYS | + base::File::FLAG_READ | base::File::FLAG_WRITE), + region, base::MemoryMappedFile::READ_WRITE_EXTEND); + + if (file_valid) { + char* data = reinterpret_cast<char*>(file.data()); + std::strcpy(data, events.data()); + } +} + +void DoReplaceFile(const base::FilePath& from_path, + const base::FilePath& to_path) { + base::ReplaceFile(from_path, to_path, nullptr); +} + +// Returns breadcrumb events stored at |file_path|. +std::vector<std::string> DoGetStoredEvents(const base::FilePath& file_path) { + base::File events_file(file_path, + base::File::FLAG_OPEN | base::File::FLAG_READ); + if (!events_file.IsValid()) { + // File may not yet exist. + return std::vector<std::string>(); + } + + size_t file_size = events_file.GetLength(); + if (file_size <= 0) { + return std::vector<std::string>(); + } + + // Do not read more than |kPersistedFilesizeInBytes|, in case the file was + // corrupted. If |kPersistedFilesizeInBytes| has been reduced since the last + // breadcrumbs file was saved, this could result in a one time loss of the + // oldest breadcrumbs which is ok because the decision has already been made + // to reduce the size of the stored breadcrumbs. + if (file_size > kPersistedFilesizeInBytes) { + file_size = kPersistedFilesizeInBytes; + } + + std::vector<uint8_t> data; + data.resize(file_size); + if (!events_file.ReadAndCheck(/*offset=*/0, data)) { + return std::vector<std::string>(); + } + std::string persisted_events(data.begin(), data.end()); + std::string all_events = + persisted_events.substr(/*pos=*/0, strlen(persisted_events.c_str())); + return base::SplitString(all_events, kEventSeparator, base::TRIM_WHITESPACE, + base::SPLIT_WANT_NONEMPTY); +} + +} // namespace + +using breadcrumb_persistent_storage_util:: + GetBreadcrumbPersistentStorageFilePath; +using breadcrumb_persistent_storage_util:: + GetBreadcrumbPersistentStorageTempFilePath; + +BreadcrumbPersistentStorageManager::BreadcrumbPersistentStorageManager( + base::FilePath directory) + : // Ensure first event will not be delayed by initializing with a time in + // the past. + last_written_time_(base::TimeTicks::Now() - kMinDelayBetweenWrites), + breadcrumbs_file_path_(GetBreadcrumbPersistentStorageFilePath(directory)), + breadcrumbs_temp_file_path_( + GetBreadcrumbPersistentStorageTempFilePath(directory)), + task_runner_(base::ThreadPool::CreateSequencedTaskRunner( + {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + base::TaskShutdownBehavior::BLOCK_SHUTDOWN})) {} + +BreadcrumbPersistentStorageManager::~BreadcrumbPersistentStorageManager() = + default; + +void BreadcrumbPersistentStorageManager::GetStoredEvents( + base::OnceCallback<void(std::vector<std::string>)> callback) { + task_runner_->PostTaskAndReplyWithResult( + FROM_HERE, base::BindOnce(&DoGetStoredEvents, breadcrumbs_file_path_), + std::move(callback)); +} + +void BreadcrumbPersistentStorageManager::MonitorBreadcrumbManager( + BreadcrumbManager* manager) { + // Write already existing events. + std::list<std::string> events = manager->GetEvents(/*event_count_limit=*/0); + for (auto event : events) { + WriteEvent(event); + } + + manager->AddObserver(this); +} + +void BreadcrumbPersistentStorageManager::MonitorBreadcrumbManagerService( + BreadcrumbManagerKeyedService* service) { + // Write already existing events. + std::list<std::string> events = service->GetEvents(/*event_count_limit=*/0); + for (auto event : events) { + WriteEvent(event); + } + + service->AddObserver(this); +} + +void BreadcrumbPersistentStorageManager::StopMonitoringBreadcrumbManager( + BreadcrumbManager* manager) { + manager->RemoveObserver(this); +} + +void BreadcrumbPersistentStorageManager::StopMonitoringBreadcrumbManagerService( + BreadcrumbManagerKeyedService* service) { + service->RemoveObserver(this); +} + +void BreadcrumbPersistentStorageManager::RewriteAllExistingBreadcrumbs() { + // Collect breadcrumbs which haven't been written yet to include in this full + // re-write. + std::vector<std::string> pending_breadcrumbs = + base::SplitString(pending_breadcrumbs_, kEventSeparator, + base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + pending_breadcrumbs_.clear(); + write_timer_.Stop(); + + last_written_time_ = base::TimeTicks::Now(); + current_mapped_file_position_ = 0; + + // Load persisted events directly from file because the correct order can not + // be reconstructed from the multiple BreadcrumbManagers with the partial + // timestamps embedded in each event. + GetStoredEvents(base::BindOnce(^(std::vector<std::string> events) { + // Add events which had not yet been written. + for (auto event : pending_breadcrumbs) { + events.push_back(event); + } + + std::vector<std::string> breadcrumbs; + for (auto event_it = events.rbegin(); event_it != events.rend(); + ++event_it) { + // Reduce saved events to only fill the amount which would be included on + // a crash log. This allows future events to be appended individually up + // to |kPersistedFilesizeInBytes|, which is more efficient than writing + // out the + const int event_with_seperator_size = + event_it->size() + strlen(kEventSeparator); + if (event_with_seperator_size + current_mapped_file_position_ >= + kMaxBreadcrumbsDataLength) { + break; + } + + breadcrumbs.push_back(kEventSeparator); + breadcrumbs.push_back(*event_it); + current_mapped_file_position_ += event_with_seperator_size; + } + + std::reverse(breadcrumbs.begin(), breadcrumbs.end()); + std::string breadcrumbs_string = base::JoinString(breadcrumbs, ""); + + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&DoWriteEventsToFile, breadcrumbs_temp_file_path_, + std::string(breadcrumbs_string))); + + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&DoReplaceFile, breadcrumbs_temp_file_path_, + breadcrumbs_file_path_)); + })); +} + +void BreadcrumbPersistentStorageManager::WritePendingBreadcrumbs() { + if (pending_breadcrumbs_.empty()) { + return; + } + + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&DoInsertEventsIntoMemoryMappedFile, + breadcrumbs_file_path_, current_mapped_file_position_, + std::string(pending_breadcrumbs_))); + + current_mapped_file_position_ += pending_breadcrumbs_.size(); + last_written_time_ = base::TimeTicks::Now(); + + pending_breadcrumbs_.clear(); +} + +void BreadcrumbPersistentStorageManager::EventAdded(BreadcrumbManager* manager, + const std::string& event) { + WriteEvent(event); +} + +void BreadcrumbPersistentStorageManager::WriteEvent(const std::string& event) { + pending_breadcrumbs_ += event + kEventSeparator; + + WriteEvents(); +} + +void BreadcrumbPersistentStorageManager::WriteEvents() { + write_timer_.Stop(); + + const base::TimeDelta time_delta_since_last_write = + base::TimeTicks::Now() - last_written_time_; + // Delay writing the event to disk if an event was just written. + if (time_delta_since_last_write < kMinDelayBetweenWrites) { + write_timer_.Start(FROM_HERE, + kMinDelayBetweenWrites - time_delta_since_last_write, + this, &BreadcrumbPersistentStorageManager::WriteEvents); + } else { + // If the event does not fit within |kPersistedFilesizeInBytes|, rewrite the + // file to trim old events. + if ((current_mapped_file_position_ + pending_breadcrumbs_.size()) + // Use >= here instead of > to allow space for \0 to terminate file. + >= kPersistedFilesizeInBytes) { + RewriteAllExistingBreadcrumbs(); + return; + } + + // Otherwise, simply append the pending breadcrumbs. + WritePendingBreadcrumbs(); + } +} + +void BreadcrumbPersistentStorageManager::OldEventsRemoved( + BreadcrumbManager* manager) { + RewriteAllExistingBreadcrumbs(); +}
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service_unittest.mm b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_manager_unittest.mm similarity index 83% rename from ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service_unittest.mm rename to ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_manager_unittest.mm index 3b7b81b..1ba6304 100644 --- a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service_unittest.mm +++ b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_manager_unittest.mm
@@ -1,8 +1,8 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// 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 "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service.h" +#import "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_manager.h" #include <string> #include <vector> @@ -17,7 +17,6 @@ #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.h" #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.h" #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service_factory.h" -#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_keyed_service_factory.h" #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_util.h" #import "ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer.h" #include "ios/chrome/test/ios_chrome_scoped_testing_chrome_browser_state_manager.h" @@ -42,13 +41,6 @@ return std::make_unique<BreadcrumbManagerKeyedService>(browser_state); } -// Creates a new BreadcrumbPersistentStorageKeyedService for |browser_state|. -std::unique_ptr<KeyedService> BuildBreadcrumbPersistentStorageKeyedService( - web::BrowserState* browser_state) { - return std::make_unique<BreadcrumbPersistentStorageKeyedService>( - browser_state); -} - // Validates that the events in |persisted_events| are contiguous and that the // |last_logged_event| matches the last persisted event. bool ValidatePersistedEvents(std::string last_logged_event, @@ -87,9 +79,9 @@ } // namespace -class BreadcrumbPersistentStorageKeyedServiceTest : public PlatformTest { +class BreadcrumbPersistentStorageManagerTest : public PlatformTest { protected: - BreadcrumbPersistentStorageKeyedServiceTest() + BreadcrumbPersistentStorageManagerTest() : scoped_browser_state_manager_( std::make_unique<TestChromeBrowserStateManager>(base::FilePath())) { EXPECT_TRUE(scoped_temp_directory_.CreateUniqueTempDir()); @@ -100,19 +92,19 @@ test_cbs_builder.AddTestingFactory( BreadcrumbManagerKeyedServiceFactory::GetInstance(), base::BindRepeating(&BuildBreadcrumbManagerKeyedService)); - test_cbs_builder.AddTestingFactory( - BreadcrumbPersistentStorageKeyedServiceFactory::GetInstance(), - base::BindRepeating(&BuildBreadcrumbPersistentStorageKeyedService)); chrome_browser_state_ = test_cbs_builder.Build(); breadcrumb_manager_service_ = static_cast<BreadcrumbManagerKeyedService*>( BreadcrumbManagerKeyedServiceFactory::GetForBrowserState( chrome_browser_state_.get())); - persistent_storage_ = static_cast<BreadcrumbPersistentStorageKeyedService*>( - BreadcrumbPersistentStorageKeyedServiceFactory::GetForBrowserState( - chrome_browser_state_.get())); + persistent_storage_ = + std::make_unique<BreadcrumbPersistentStorageManager>(directory_name); + breadcrumb_manager_service_->StartPersisting(persistent_storage_.get()); } - ~BreadcrumbPersistentStorageKeyedServiceTest() override = default; + + ~BreadcrumbPersistentStorageManagerTest() override { + breadcrumb_manager_service_->StopPersisting(); + } web::WebTaskEnvironment task_env_{ web::WebTaskEnvironment::Options::DEFAULT, @@ -121,13 +113,15 @@ std::unique_ptr<TestChromeBrowserState> chrome_browser_state_; base::ScopedTempDir scoped_temp_directory_; BreadcrumbManagerKeyedService* breadcrumb_manager_service_; - BreadcrumbPersistentStorageKeyedService* persistent_storage_; + std::unique_ptr<BreadcrumbPersistentStorageManager> persistent_storage_; }; -// Ensures that logged events are persisted. -TEST_F(BreadcrumbPersistentStorageKeyedServiceTest, PersistEvents) { - persistent_storage_->StartStoringEvents(); +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif +// Ensures that logged events are persisted. +TEST_F(BreadcrumbPersistentStorageManagerTest, PersistEvents) { breadcrumb_manager_service_->AddEvent("event"); // Advance clock to trigger writing final events. @@ -149,9 +143,7 @@ // Ensures that persisted events do not grow too large for a single large event // bucket when events are logged very quickly one after the other. -TEST_F(BreadcrumbPersistentStorageKeyedServiceTest, PersistLargeBucket) { - persistent_storage_->StartStoringEvents(); - +TEST_F(BreadcrumbPersistentStorageManagerTest, PersistLargeBucket) { std::string event; unsigned long event_count = 0; while (event_count < kEventCountTooManyForPersisting) { @@ -182,9 +174,7 @@ // Ensures that persisted events do not grow too large for events logged a few // seconds apart from each other. -TEST_F(BreadcrumbPersistentStorageKeyedServiceTest, PersistManyEventsOverTime) { - persistent_storage_->StartStoringEvents(); - +TEST_F(BreadcrumbPersistentStorageManagerTest, PersistManyEventsOverTime) { std::string event; unsigned long event_count = 0; while (event_count < kEventCountTooManyForPersisting) { @@ -217,10 +207,8 @@ // Ensures that old events are removed from the persisted file when old buckets // are dropped. -TEST_F(BreadcrumbPersistentStorageKeyedServiceTest, +TEST_F(BreadcrumbPersistentStorageManagerTest, OldEventsRemovedFromPersistedFile) { - persistent_storage_->StartStoringEvents(); - std::string event; unsigned long event_counter = 0; const int kNumEventsPerBucket = 200; @@ -259,12 +247,12 @@ } // Ensures that events are read correctly if the persisted file becomes -// corrupted by losing the EOF token or if kPersistedFilesizeInBytes is reduced. -TEST_F(BreadcrumbPersistentStorageKeyedServiceTest, +// corrupted by losing the EOF token or if kPersistedFilesizeInBytes is +// reduced. +TEST_F(BreadcrumbPersistentStorageManagerTest, GetStoredEventsAfterFilesizeReduction) { const base::FilePath breadcrumbs_file_path = - breadcrumb_persistent_storage_util:: - GetBreadcrumbPersistentStorageFilePath(chrome_browser_state_.get()); + GetBreadcrumbPersistentStorageFilePath(scoped_temp_directory_.GetPath()); auto file = std::make_unique<base::File>( breadcrumbs_file_path,
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_util.cc b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_util.cc index 76187090..32dc9e0d 100644 --- a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_util.cc +++ b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_util.cc
@@ -5,7 +5,6 @@ #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_util.h" #include "base/path_service.h" -#include "ios/web/public/browser_state.h" namespace breadcrumb_persistent_storage_util { @@ -16,13 +15,13 @@ FILE_PATH_LITERAL("iOS Breadcrumbs.temp"); base::FilePath GetBreadcrumbPersistentStorageFilePath( - web::BrowserState* browser_state) { - return browser_state->GetStatePath().Append(kBreadcrumbsFile); + base::FilePath storage_dir) { + return storage_dir.Append(kBreadcrumbsFile); } base::FilePath GetBreadcrumbPersistentStorageTempFilePath( - web::BrowserState* browser_state) { - return browser_state->GetStatePath().Append(kBreadcrumbsTempFile); + base::FilePath storage_dir) { + return storage_dir.Append(kBreadcrumbsTempFile); } } // namespace breadcrumb_persistent_storage_util
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_util.h b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_util.h index ce374ca0..e7ca6c62 100644 --- a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_util.h +++ b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_util.h
@@ -7,27 +7,21 @@ #include "base/files/file_path.h" -namespace web { -class BrowserState; -} // namespace web - namespace breadcrumb_persistent_storage_util { -// Returns the path to a file for storing breadcrumbs within |browser_state|'s -// storage directory. +// Returns the path to a file for storing breadcrumbs within |storage_dir|. base::FilePath GetBreadcrumbPersistentStorageFilePath( - web::BrowserState* browser_state); + base::FilePath storage_dir); -// Returns the path to a file for storing breadcrumbs within |browser_state|'s -// storage directory. This second file is used to write the new breadcrumbs to -// so that the primary breadcrumbs file at -// |GetBreadcrumbPersistentStorageFilePath()| is always in a state correctly -// describing the application. (If the contents of a single file was instead -// cleared and re-written, the most recent breadcrumbs would be missing if the -// application crashed during this timeframe which will happen often whenever -// old breadcrumbs are removed.) +// Returns the path to a file for storing breadcrumbs within ||storage_dir||. +// This second file is used to write the new breadcrumbs to so that the primary +// breadcrumbs file at |GetBreadcrumbPersistentStorageFilePath()| is always in a +// state correctly describing the application. (If the contents of a single file +// was instead cleared and re-written, the most recent breadcrumbs would be +// missing if the application crashed during this timeframe which will happen +// often whenever old breadcrumbs are removed.) base::FilePath GetBreadcrumbPersistentStorageTempFilePath( - web::BrowserState* browser_state); + base::FilePath storage_dir); } // namespace breadcrumb_persistent_storage_util
diff --git a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_util_unittest.mm b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_util_unittest.mm index cbbf8ab..a144a07 100644 --- a/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_util_unittest.mm +++ b/ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_util_unittest.mm
@@ -4,9 +4,8 @@ #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_util.h" -#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" -#include "ios/chrome/browser/web/chrome_web_test.h" -#include "ios/web/public/browser_state.h" +#include "base/files/scoped_temp_dir.h" +#include "testing/platform_test.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -14,49 +13,19 @@ using breadcrumb_persistent_storage_util:: GetBreadcrumbPersistentStorageFilePath; - using breadcrumb_persistent_storage_util:: GetBreadcrumbPersistentStorageTempFilePath; // Test fixture to test BreadcrumbPersistentStorageUtil. -typedef ChromeWebTest BreadcrumbPersistentStorageUtilTest; +typedef PlatformTest BreadcrumbPersistentStorageUtilTest; -// Tests that the storage paths are unique for different BrowserStates. -TEST_F(BreadcrumbPersistentStorageUtilTest, UniqueStorage) { - base::FilePath path1 = - GetBreadcrumbPersistentStorageFilePath(GetBrowserState()); - base::FilePath tempFilePath1 = - GetBreadcrumbPersistentStorageTempFilePath(GetBrowserState()); - // Verify that the temp file path is different. - EXPECT_NE(path1, tempFilePath1); +// Tests that the breadcrumb storage file path is different from the temp file +// path. +TEST_F(BreadcrumbPersistentStorageUtilTest, UniqueTempStorage) { + base::ScopedTempDir scoped_temp_directory; + EXPECT_TRUE(scoped_temp_directory.CreateUniqueTempDir()); - std::unique_ptr<TestChromeBrowserState> local_browser_state = - TestChromeBrowserState::Builder().Build(); - base::FilePath path2 = - GetBreadcrumbPersistentStorageFilePath(local_browser_state.get()); - base::FilePath tempFilePath2 = - GetBreadcrumbPersistentStorageTempFilePath(local_browser_state.get()); - - EXPECT_NE(path1, path2); - EXPECT_NE(tempFilePath1, tempFilePath2); -} - -// Tests that the BrowserState returned by -// |BrowserState::GetOffTheRecordChromeBrowserState| does not share a storage -// path with the original BrowserState. -TEST_F(BreadcrumbPersistentStorageUtilTest, UniqueIncognitoStorage) { - base::FilePath path1 = - GetBreadcrumbPersistentStorageFilePath(GetBrowserState()); - base::FilePath tempFilePath1 = - GetBreadcrumbPersistentStorageTempFilePath(GetBrowserState()); - - ChromeBrowserState* off_the_record_browser_state = - chrome_browser_state_->GetOffTheRecordChromeBrowserState(); - base::FilePath path2 = - GetBreadcrumbPersistentStorageFilePath(off_the_record_browser_state); - base::FilePath tempFilePath2 = - GetBreadcrumbPersistentStorageTempFilePath(off_the_record_browser_state); - - EXPECT_NE(path1, path2); - EXPECT_NE(tempFilePath1, tempFilePath2); + base::FilePath directory = scoped_temp_directory.GetPath(); + EXPECT_NE(GetBreadcrumbPersistentStorageFilePath(directory), + GetBreadcrumbPersistentStorageTempFilePath(directory)); }
diff --git a/ios/chrome/browser/sync/profile_sync_service_factory.cc b/ios/chrome/browser/sync/profile_sync_service_factory.cc index 0d0aa87..176f390 100644 --- a/ios/chrome/browser/sync/profile_sync_service_factory.cc +++ b/ios/chrome/browser/sync/profile_sync_service_factory.cc
@@ -7,19 +7,15 @@ #include <utility> #include "base/bind.h" -#include "base/feature_list.h" #include "base/no_destructor.h" #include "base/task/post_task.h" #include "base/time/time.h" #include "components/autofill/core/browser/personal_data_manager.h" -#include "components/autofill/core/common/autofill_features.h" -#include "components/invalidation/impl/invalidation_switches.h" #include "components/invalidation/impl/profile_invalidation_provider.h" #include "components/keyed_service/ios/browser_state_dependency_manager.h" #include "components/network_time/network_time_tracker.h" #include "components/sync/base/sync_util.h" #include "components/sync/driver/profile_sync_service.h" -#include "components/sync/driver/startup_controller.h" #include "components/sync/driver/sync_driver_switches.h" #include "components/sync/driver/sync_service.h" #include "ios/chrome/browser/application_context.h" @@ -171,9 +167,6 @@ GetApplicationContext()->GetNetworkConnectionTracker(); init_params.channel = ::GetChannel(); init_params.debug_identifier = browser_state->GetDebugName(); - init_params.autofill_enable_account_wallet_storage = - base::FeatureList::IsEnabled( - autofill::features::kAutofillEnableAccountWalletStorage); auto* fcm_invalidation_provider = IOSChromeProfileInvalidationProviderFactory::GetForBrowserState(
diff --git a/ios/chrome/browser/ui/main/scene_controller.mm b/ios/chrome/browser/ui/main/scene_controller.mm index 7ca7917d..8d8ccf7 100644 --- a/ios/chrome/browser/ui/main/scene_controller.mm +++ b/ios/chrome/browser/ui/main/scene_controller.mm
@@ -32,6 +32,7 @@ #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_browser_agent.h" #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.h" #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service_factory.h" +#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_manager.h" #include "ios/chrome/browser/crash_report/breadcrumbs/features.h" #include "ios/chrome/browser/crash_report/crash_keys_helper.h" #include "ios/chrome/browser/crash_report/crash_report_helper.h" @@ -2363,10 +2364,14 @@ [sceneController willDestroyIncognitoBrowserState]; } + BreadcrumbPersistentStorageManager* persistentStorageManager = nullptr; if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) { - breakpad::StopMonitoringBreadcrumbManagerService( + BreadcrumbManagerKeyedService* service = BreadcrumbManagerKeyedServiceFactory::GetForBrowserState( - mainBrowserState->GetOffTheRecordChromeBrowserState())); + mainBrowserState->GetOffTheRecordChromeBrowserState()); + persistentStorageManager = service->GetPersistentStorageManager(); + breakpad::StopMonitoringBreadcrumbManagerService(service); + service->StopPersisting(); } // Record off-the-record metrics before detroying the BrowserState. @@ -2387,9 +2392,14 @@ } if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) { - breakpad::MonitorBreadcrumbManagerService( + BreadcrumbManagerKeyedService* service = BreadcrumbManagerKeyedServiceFactory::GetForBrowserState( - mainBrowserState->GetOffTheRecordChromeBrowserState())); + mainBrowserState->GetOffTheRecordChromeBrowserState()); + + if (persistentStorageManager) { + service->StartPersisting(persistentStorageManager); + } + breakpad::MonitorBreadcrumbManagerService(service); } // This seems the best place to deem the destroying and rebuilding the
diff --git a/ios/chrome/browser/ui/settings/google_services/accounts_table_egtest.mm b/ios/chrome/browser/ui/settings/google_services/accounts_table_egtest.mm index bcfa5e0..b58c41c 100644 --- a/ios/chrome/browser/ui/settings/google_services/accounts_table_egtest.mm +++ b/ios/chrome/browser/ui/settings/google_services/accounts_table_egtest.mm
@@ -23,8 +23,8 @@ #error "This file requires ARC support." #endif -using chrome_test_util::AddAccountButton; using chrome_test_util::ButtonWithAccessibilityLabel; +using chrome_test_util::ButtonWithAccessibilityLabelId; using chrome_test_util::PrimarySignInButton; using chrome_test_util::SettingsAccountButton; using chrome_test_util::SettingsDoneButton; @@ -153,27 +153,6 @@ performAction:grey_tap()]; } -// Tests that the Settings screen is displayed after the user signs in through -// the add account flow from the account list screen entrypoint. -- (void)testSSOAddAccount { - FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1]; - [SigninEarlGreyUI signinWithFakeIdentity:fakeIdentity]; - - [ChromeEarlGreyUI openSettingsMenu]; - [ChromeEarlGreyUI tapSettingsMenuButton:SettingsAccountButton()]; - [[EarlGrey selectElementWithMatcher:AddAccountButton()] - performAction:grey_tap()]; - [[EarlGrey - selectElementWithMatcher:grey_allOf( - ButtonWithAccessibilityLabel(@"Sign in"), - grey_sufficientlyVisible(), nil)] - performAction:grey_tap()]; - - [ChromeEarlGreyUI waitForAppToIdle]; - [[EarlGrey selectElementWithMatcher:SettingsAccountButton()] - assertWithMatcher:grey_sufficientlyVisible()]; -} - // Tests that the Account Settings screen is popped and the user signed out // when the account is removed. - (void)testSignOutOnRemoveAccount {
diff --git a/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm b/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm index a3aa98f5..2485838 100644 --- a/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm
@@ -389,16 +389,9 @@ - (void)onEndBatchOfRefreshTokenStateChanges { [self reloadData]; - if (self.authService->IsAuthenticated() || - _authenticationOperationInProgress) { - // The signed out state might be temporary (e.g. account switch, ...). - // Don't pop this view based on intermediary values. - return; - } - - [self dismissSelfAnimated:NO]; - - if (_dimissAccountDetailsViewControllerBlock) { + [self popViewIfSignedOut]; + if (![self authService] -> IsAuthenticated() && + _dimissAccountDetailsViewControllerBlock) { _dimissAccountDetailsViewControllerBlock(/*animated=*/YES); _dimissAccountDetailsViewControllerBlock = nil; } @@ -425,12 +418,8 @@ } - (void)handleDidAddAccount:(BOOL)success { - if (!success) { - return; - } - [self handleAuthenticationOperationDidFinish]; - if (_closeSettingsOnAddAccount) { + if (success && _closeSettingsOnAddAccount) { [self.dispatcher closeSettingsUI]; } } @@ -580,10 +569,23 @@ } } -// Finishes the authentication flow and dismisses the accounts view. +// Sets |_authenticationOperationInProgress| to NO and pops this accounts +// table view controller if the user is signed out. - (void)handleAuthenticationOperationDidFinish { DCHECK(_authenticationOperationInProgress); _authenticationOperationInProgress = NO; + [self popViewIfSignedOut]; +} + +- (void)popViewIfSignedOut { + if ([self authService] -> IsAuthenticated()) { + return; + } + if (_authenticationOperationInProgress) { + // The signed out state might be temporary (e.g. account switch, ...). + // Don't pop this view based on intermediary values. + return; + } [self dismissSelfAnimated:NO]; }
diff --git a/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.mm b/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.mm index d66cf595..41b1f7d8 100644 --- a/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.mm
@@ -328,7 +328,6 @@ [self hideDecryptionProgress]; } } else { - service->GetUserSettings()->EnableEncryptEverything(); service->GetUserSettings()->SetEncryptionPassphrase(passphrase); } [self reloadData];
diff --git a/ios/chrome/test/testing_application_context.h b/ios/chrome/test/testing_application_context.h index 9b78e5e..ebdcd6b 100644 --- a/ios/chrome/test/testing_application_context.h +++ b/ios/chrome/test/testing_application_context.h
@@ -63,6 +63,8 @@ SafeBrowsingService* GetSafeBrowsingService() override; network::NetworkConnectionTracker* GetNetworkConnectionTracker() override; BrowserPolicyConnectorIOS* GetBrowserPolicyConnector() override; + BreadcrumbPersistentStorageManager* GetBreadcrumbPersistentStorageManager() + override; private: base::ThreadChecker thread_checker_;
diff --git a/ios/chrome/test/testing_application_context.mm b/ios/chrome/test/testing_application_context.mm index b75a9db..0011950 100644 --- a/ios/chrome/test/testing_application_context.mm +++ b/ios/chrome/test/testing_application_context.mm
@@ -213,3 +213,9 @@ // unittesting and return a mock or fake here. return nullptr; } + +BreadcrumbPersistentStorageManager* +TestingApplicationContext::GetBreadcrumbPersistentStorageManager() { + DCHECK(thread_checker_.CalledOnValidThread()); + return nullptr; +}
diff --git a/ios/public/provider/chrome/browser/signin/fake_chrome_identity_interaction_manager.mm b/ios/public/provider/chrome/browser/signin/fake_chrome_identity_interaction_manager.mm index 331ada5..2b0272a 100644 --- a/ios/public/provider/chrome/browser/signin/fake_chrome_identity_interaction_manager.mm +++ b/ios/public/provider/chrome/browser/signin/fake_chrome_identity_interaction_manager.mm
@@ -125,12 +125,8 @@ } - (void)addAccountViewControllerDidTapSignIn { - // Fake sign-in is used to show a fake add an account screen. In this - // case _fakeIdentity will be nil. - if (_fakeIdentity) { - ios::FakeChromeIdentityService::GetInstanceFromChromeProvider() - ->AddIdentity(_fakeIdentity); - } + ios::FakeChromeIdentityService::GetInstanceFromChromeProvider() + ->AddIdentity(_fakeIdentity); [self dismissAndRunCompletionCallbackWithError:nil animated:YES completion:nil];
diff --git a/ios/web_view/internal/sync/web_view_profile_sync_service_factory.mm b/ios/web_view/internal/sync/web_view_profile_sync_service_factory.mm index d5c3b0c..837daff 100644 --- a/ios/web_view/internal/sync/web_view_profile_sync_service_factory.mm +++ b/ios/web_view/internal/sync/web_view_profile_sync_service_factory.mm
@@ -7,19 +7,15 @@ #include <utility> #include "base/bind_helpers.h" -#include "base/feature_list.h" #include "base/no_destructor.h" #include "base/time/time.h" #include "components/autofill/core/browser/personal_data_manager.h" -#include "components/autofill/core/common/autofill_features.h" #include "components/invalidation/impl/profile_invalidation_provider.h" #include "components/keyed_service/ios/browser_state_dependency_manager.h" -#include "components/password_manager/core/common/password_manager_features.h" #include "components/signin/public/identity_manager/identity_manager.h" #include "components/sync/base/model_type.h" #include "components/sync/base/sync_util.h" #include "components/sync/driver/profile_sync_service.h" -#include "components/sync/driver/startup_controller.h" #include "components/sync/driver/sync_service.h" #include "ios/web/public/thread/web_thread.h" #include "ios/web_view/internal/app/application_context.h" @@ -103,11 +99,6 @@ WebViewProfileInvalidationProviderFactory::GetForBrowserState( browser_state) ->GetIdentityProvider(); - init_params.autofill_enable_account_wallet_storage = - base::FeatureList::IsEnabled( - autofill::features::kAutofillEnableAccountWalletStorage); - init_params.enable_passwords_account_storage = base::FeatureList::IsEnabled( - password_manager::features::kEnablePasswordsAccountStorage); auto profile_sync_service = std::make_unique<syncer::ProfileSyncService>(std::move(init_params));
diff --git a/media/renderers/paint_canvas_video_renderer.cc b/media/renderers/paint_canvas_video_renderer.cc index c09fc76..a9fc4e8 100644 --- a/media/renderers/paint_canvas_video_renderer.cc +++ b/media/renderers/paint_canvas_video_renderer.cc
@@ -254,10 +254,10 @@ texture_info.fFormat = GL_RGBA8_OES; GrBackendTexture backend_texture(size.width(), size.height(), GrMipMapped::kNo, texture_info); - return SkImage::MakeFromTexture( + return SkImage::MakeFromAdoptedTexture( raster_context_provider->GrContext(), backend_texture, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kPremul_SkAlphaType, - color_space.ToSkColorSpace(), nullptr, nullptr); + color_space.ToSkColorSpace()); } void VideoFrameCopyTextureOrSubTexture(gpu::gles2::GLES2Interface* gl, @@ -854,7 +854,7 @@ const bool need_rotation = video_transformation.rotation != VIDEO_ROTATION_0; const bool need_scaling = - dest_rect.size() != gfx::SizeF(image.width(), image.height()); + dest_rect.size() != gfx::SizeF(video_frame->visible_rect().size()); const bool need_translation = !dest_rect.origin().IsOrigin(); // TODO(tmathmeyer): apply horizontal / vertical mirroring if needed. bool need_transform = need_rotation || need_scaling || need_translation; @@ -885,10 +885,13 @@ rotated_dest_size = gfx::SizeF(rotated_dest_size.height(), rotated_dest_size.width()); } - canvas->scale(SkFloatToScalar(rotated_dest_size.width() / image.width()), - SkFloatToScalar(rotated_dest_size.height() / image.height())); - canvas->translate(-SkFloatToScalar(image.width() * 0.5f), - -SkFloatToScalar(image.height() * 0.5f)); + canvas->scale(SkFloatToScalar(rotated_dest_size.width() / + video_frame->visible_rect().width()), + SkFloatToScalar(rotated_dest_size.height() / + video_frame->visible_rect().height())); + canvas->translate( + -SkFloatToScalar(video_frame->visible_rect().width() * 0.5f), + -SkFloatToScalar(video_frame->visible_rect().height() * 0.5f)); } SkImageInfo info; @@ -907,7 +910,15 @@ const size_t offset = info.computeOffset(origin.x(), origin.y(), row_bytes); void* const pixels_offset = reinterpret_cast<char*>(pixels) + offset; ConvertVideoFrameToRGBPixels(video_frame.get(), pixels_offset, row_bytes); + } else if (video_frame->HasTextures()) { + DCHECK_EQ(video_frame->coded_size(), + gfx::Size(image.width(), image.height())); + canvas->drawImageRect(image, gfx::RectToSkRect(video_frame->visible_rect()), + dest, &video_flags, + SkCanvas::kStrict_SrcRectConstraint); } else { + DCHECK_EQ(video_frame->visible_rect().size(), + gfx::Size(image.width(), image.height())); canvas->drawImage(image, 0, 0, &video_flags); } @@ -1636,8 +1647,6 @@ DCHECK(!source_mailbox.IsZero()); DCHECK(source_texture); auto* ri = raster_context_provider->RasterInterface(); - if (!texture_ownership_in_skia) - ri->DeleteGpuRasterTexture(source_texture); if (!wraps_video_frame_texture) { gpu::SyncToken sync_token; ri->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData()); @@ -1647,9 +1656,7 @@ } bool PaintCanvasVideoRenderer::Cache::Recycle() { - if (!texture_ownership_in_skia) - return true; - + DCHECK(!wraps_video_frame_texture); if (!paint_image.HasExclusiveTextureAccess()) return false; @@ -1659,7 +1666,6 @@ paint_image = cc::PaintImage(); // We need a new texture ID because skia will destroy the previous one with // the SkImage. - texture_ownership_in_skia = false; source_texture = 0; return true; } @@ -1705,7 +1711,6 @@ } else { cache_.emplace(video_frame->unique_id()); auto* sii = raster_context_provider->SharedImageInterface(); - // TODO(nazabris): Sort out what to do when GLES2 is needed but the // cached shared image is created without it. uint32_t flags = @@ -1721,8 +1726,6 @@ ri->WaitSyncTokenCHROMIUM( sii->GenUnverifiedSyncToken().GetConstData()); } - - DCHECK(!cache_->texture_ownership_in_skia); if (video_frame->NumTextures() == 1) { auto frame_mailbox = SynchronizeVideoFrameSingleMailbox(ri, video_frame.get()); @@ -1763,35 +1766,10 @@ cache_->raster_context_provider = raster_context_provider; cache_->coded_size = video_frame->coded_size(); cache_->visible_rect = video_frame->visible_rect(); - GrDirectContext* direct = - GrAsDirectContext(raster_context_provider->GrContext()); - sk_sp<SkImage> source_subset = source_image->makeSubset( - gfx::RectToSkIRect(cache_->visible_rect), direct); - if (source_subset) { - // We use the flushPendingGrContextIO = true so we can flush any pending - // GPU work on the GrContext to ensure that skia exectues the work for - // generating the subset and it can be safely destroyed. - GrBackendTexture image_backend = - source_image->getBackendTexture(/*flushPendingGrContextIO*/ true); - GrBackendTexture subset_backend = - source_subset->getBackendTexture(/*flushPendingGrContextIO*/ true); -#if DCHECK_IS_ON() - GrGLTextureInfo backend_info; - if (image_backend.getGLTextureInfo(&backend_info)) - DCHECK_EQ(backend_info.fID, cache_->source_texture); -#endif - if (subset_backend.isValid() && - subset_backend.isSameTexture(image_backend)) { - cache_->texture_ownership_in_skia = true; - source_subset = SkImage::MakeFromAdoptedTexture( - cache_->raster_context_provider->GrContext(), image_backend, - kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, - kPremul_SkAlphaType, source_image->imageInfo().refColorSpace()); - } - } + paint_image_builder.set_texture_backing( sk_sp<VideoTextureBacking>(new VideoTextureBacking( - std::move(source_subset), raster_context_provider)), + std::move(source_image), raster_context_provider)), cc::PaintImage::GetNextContentId()); } else { cache_.emplace(video_frame->unique_id());
diff --git a/media/renderers/paint_canvas_video_renderer.h b/media/renderers/paint_canvas_video_renderer.h index 943cc37..a422e23 100644 --- a/media/renderers/paint_canvas_video_renderer.h +++ b/media/renderers/paint_canvas_video_renderer.h
@@ -239,9 +239,6 @@ // (if true), or to an allocated shared image (if false). bool wraps_video_frame_texture = false; - // Whether the texture pointed by |paint_image| is owned by skia or not. - bool texture_ownership_in_skia = false; - // Used to allow recycling of the previous shared image. This requires that // no external users have access to this resource via SkImage. Returns true // if the existing resource can be recycled.
diff --git a/media/renderers/video_resource_updater.cc b/media/renderers/video_resource_updater.cc index da01bca..558f840 100644 --- a/media/renderers/video_resource_updater.cc +++ b/media/renderers/video_resource_updater.cc
@@ -528,23 +528,24 @@ frame_resources_.clear(); } -void VideoResourceUpdater::AppendQuads(viz::CompositorRenderPass* render_pass, - scoped_refptr<VideoFrame> frame, - gfx::Transform transform, - gfx::Rect quad_rect, - gfx::Rect visible_quad_rect, - const gfx::RRectF& rounded_corner_bounds, - gfx::Rect clip_rect, - bool is_clipped, - bool contents_opaque, - float draw_opacity, - int sorting_context_id) { +void VideoResourceUpdater::AppendQuads( + viz::CompositorRenderPass* render_pass, + scoped_refptr<VideoFrame> frame, + gfx::Transform transform, + gfx::Rect quad_rect, + gfx::Rect visible_quad_rect, + const gfx::MaskFilterInfo& mask_filter_info, + gfx::Rect clip_rect, + bool is_clipped, + bool contents_opaque, + float draw_opacity, + int sorting_context_id) { DCHECK(frame.get()); viz::SharedQuadState* shared_quad_state = render_pass->CreateAndAppendSharedQuadState(); shared_quad_state->SetAll(transform, quad_rect, visible_quad_rect, - rounded_corner_bounds, clip_rect, is_clipped, + mask_filter_info, clip_rect, is_clipped, contents_opaque, draw_opacity, SkBlendMode::kSrcOver, sorting_context_id);
diff --git a/media/renderers/video_resource_updater.h b/media/renderers/video_resource_updater.h index ec732002..ab49f3c2 100644 --- a/media/renderers/video_resource_updater.h +++ b/media/renderers/video_resource_updater.h
@@ -29,7 +29,6 @@ namespace gfx { class Rect; -class RRectF; class Transform; } // namespace gfx @@ -45,6 +44,10 @@ class SharedBitmapReporter; } // namespace viz +namespace gfx { +class MaskFilterInfo; +} + namespace media { class PaintCanvasVideoRenderer; class VideoFrame; @@ -120,7 +123,7 @@ gfx::Transform transform, gfx::Rect quad_rect, gfx::Rect visible_quad_rect, - const gfx::RRectF& rounded_corner_bounds, + const gfx::MaskFilterInfo& mask_filter_info, gfx::Rect clip_rect, bool is_clipped, bool context_opaque,
diff --git a/net/base/network_isolation_key.cc b/net/base/network_isolation_key.cc index 175ee3a02..a621586 100644 --- a/net/base/network_isolation_key.cc +++ b/net/base/network_isolation_key.cc
@@ -67,6 +67,9 @@ NetworkIsolationKey::NetworkIsolationKey( const NetworkIsolationKey& network_isolation_key) = default; +NetworkIsolationKey::NetworkIsolationKey( + NetworkIsolationKey&& network_isolation_key) = default; + NetworkIsolationKey::~NetworkIsolationKey() = default; NetworkIsolationKey& NetworkIsolationKey::operator=(
diff --git a/net/base/network_isolation_key.h b/net/base/network_isolation_key.h index 0f661f7..2304f5d5 100644 --- a/net/base/network_isolation_key.h +++ b/net/base/network_isolation_key.h
@@ -41,6 +41,7 @@ NetworkIsolationKey(); NetworkIsolationKey(const NetworkIsolationKey& network_isolation_key); + NetworkIsolationKey(NetworkIsolationKey&& network_isolation_key); ~NetworkIsolationKey();
diff --git a/net/dns/context_host_resolver_unittest.cc b/net/dns/context_host_resolver_unittest.cc index e50efce..3612768 100644 --- a/net/dns/context_host_resolver_unittest.cc +++ b/net/dns/context_host_resolver_unittest.cc
@@ -96,7 +96,7 @@ MockDnsClientRuleList rules; rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */, - MockDnsClientRule::Result(BuildTestDnsResponse( + MockDnsClientRule::Result(BuildTestDnsAddressResponse( "example.com", kEndpoint.address())), false /* delay */, &context); rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */, @@ -126,7 +126,7 @@ // Set up delayed results for "example.com". MockDnsClientRuleList rules; rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */, - MockDnsClientRule::Result(BuildTestDnsResponse( + MockDnsClientRule::Result(BuildTestDnsAddressResponse( "example.com", IPAddress(1, 2, 3, 4))), true /* delay */); rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */, @@ -222,14 +222,14 @@ // Set up delayed results for "example.com" and "google.com". MockDnsClientRuleList rules; rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */, - MockDnsClientRule::Result(BuildTestDnsResponse( + MockDnsClientRule::Result(BuildTestDnsAddressResponse( "example.com", IPAddress(2, 3, 4, 5))), true /* delay */); rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */, MockDnsClientRule::Result(MockDnsClientRule::EMPTY), false /* delay */); rules.emplace_back("google.com", dns_protocol::kTypeA, false /* secure */, - MockDnsClientRule::Result(BuildTestDnsResponse( + MockDnsClientRule::Result(BuildTestDnsAddressResponse( "google.com", kEndpoint.address())), true /* delay */); rules.emplace_back("google.com", dns_protocol::kTypeAAAA, false /* secure */, @@ -278,7 +278,7 @@ TEST_F(ContextHostResolverTest, DestroyResolver_CompletedRequests) { MockDnsClientRuleList rules; rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */, - MockDnsClientRule::Result(BuildTestDnsResponse( + MockDnsClientRule::Result(BuildTestDnsAddressResponse( "example.com", kEndpoint.address())), false /* delay */); rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */, @@ -334,7 +334,7 @@ // Set up delayed result for "example.com". MockDnsClientRuleList rules; rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */, - MockDnsClientRule::Result(BuildTestDnsResponse( + MockDnsClientRule::Result(BuildTestDnsAddressResponse( "example.com", IPAddress(2, 3, 4, 5))), true /* delay */); rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */, @@ -384,7 +384,7 @@ // Set up delayed result for "example.com". MockDnsClientRuleList rules; rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */, - MockDnsClientRule::Result(BuildTestDnsResponse( + MockDnsClientRule::Result(BuildTestDnsAddressResponse( "example.com", IPAddress(2, 3, 4, 5))), true /* delay */); rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */, @@ -440,7 +440,7 @@ TEST_F(ContextHostResolverTest, OnShutdown_CompletedRequests) { MockDnsClientRuleList rules; rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */, - MockDnsClientRule::Result(BuildTestDnsResponse( + MockDnsClientRule::Result(BuildTestDnsAddressResponse( "example.com", kEndpoint.address())), false /* delay */); rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */, @@ -526,7 +526,7 @@ // Set up delayed result for "example.com". MockDnsClientRuleList rules; rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */, - MockDnsClientRule::Result(BuildTestDnsResponse( + MockDnsClientRule::Result(BuildTestDnsAddressResponse( "example.com", IPAddress(2, 3, 4, 5))), true /* delay */); rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */, @@ -621,7 +621,7 @@ TEST_F(ContextHostResolverTest, ResultsAddedToCache) { MockDnsClientRuleList rules; rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */, - MockDnsClientRule::Result(BuildTestDnsResponse( + MockDnsClientRule::Result(BuildTestDnsAddressResponse( "example.com", kEndpoint.address())), false /* delay */); rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */, @@ -670,7 +670,7 @@ MockDnsClientRuleList rules; rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */, - MockDnsClientRule::Result(BuildTestDnsResponse( + MockDnsClientRule::Result(BuildTestDnsAddressResponse( "example.com", kEndpoint.address())), false /* delay */); rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */,
diff --git a/net/dns/dns_response.cc b/net/dns/dns_response.cc index e34e0c8..f4a01c3 100644 --- a/net/dns/dns_response.cc +++ b/net/dns/dns_response.cc
@@ -355,6 +355,9 @@ memcpy(io_buffer_->data(), data, length); } +DnsResponse::DnsResponse(DnsResponse&& other) = default; +DnsResponse& DnsResponse::operator=(DnsResponse&& other) = default; + DnsResponse::~DnsResponse() = default; bool DnsResponse::InitParse(size_t nbytes, const DnsQuery& query) {
diff --git a/net/dns/dns_response.h b/net/dns/dns_response.h index 7eda8076..c6320ae 100644 --- a/net/dns/dns_response.h +++ b/net/dns/dns_response.h
@@ -150,11 +150,16 @@ // Constructs a response from |data|. Used for testing purposes only! DnsResponse(const void* data, size_t length, size_t answer_offset); + // Move-only. + DnsResponse(DnsResponse&& other); + DnsResponse& operator=(DnsResponse&& other); + ~DnsResponse(); // Internal buffer accessor into which actual bytes of response will be // read. IOBuffer* io_buffer() { return io_buffer_.get(); } + const IOBuffer* io_buffer() const { return io_buffer_.get(); } // Size of the internal buffer. size_t io_buffer_size() const { return io_buffer_size_; } @@ -229,8 +234,6 @@ // It is never updated afterwards, so can be used in accessors. DnsRecordParser parser_; bool id_available_ = false; - - DISALLOW_COPY_AND_ASSIGN(DnsResponse); }; } // namespace net
diff --git a/net/dns/dns_test_util.cc b/net/dns/dns_test_util.cc index 00ff9ea..e9ed2d7 100644 --- a/net/dns/dns_test_util.cc +++ b/net/dns/dns_test_util.cc
@@ -38,8 +38,7 @@ // Create a response containing a valid question (as would normally be validated // in DnsTransaction) but completely missing a header-declared answer. -std::unique_ptr<DnsResponse> CreateMalformedResponse(std::string hostname, - uint16_t type) { +DnsResponse CreateMalformedResponse(std::string hostname, uint16_t type) { std::string dns_name; CHECK(DNSDomainFromDot(hostname, &dns_name)); DnsQuery query(0x14 /* id */, dns_name, type); @@ -53,8 +52,8 @@ memcpy(buffer->data() + sizeof(kMalformedResponseHeader), query.question().data(), query.question().size()); - auto response = std::make_unique<DnsResponse>(buffer, buffer->size()); - CHECK(response->InitParseWithoutQuery(buffer->size())); + DnsResponse response(buffer, buffer->size()); + CHECK(response.InitParseWithoutQuery(buffer->size())); return response; } @@ -206,9 +205,7 @@ return record; } - -std::unique_ptr<DnsResponse> BuildTestDnsResponse(std::string name, - const IPAddress& ip) { +DnsResponse BuildTestDnsAddressResponse(std::string name, const IPAddress& ip) { DCHECK(ip.IsValid()); std::vector<DnsResourceRecord> answers = {BuildTestAddressRecord(name, ip)}; @@ -217,16 +214,15 @@ base::Optional<DnsQuery> query( base::in_place, 0, dns_name, ip.IsIPv4() ? dns_protocol::kTypeA : dns_protocol::kTypeAAAA); - return std::make_unique<DnsResponse>( - 0, false, std::move(answers), - std::vector<DnsResourceRecord>() /* authority_records */, - std::vector<DnsResourceRecord>() /* additional_records */, query); + return DnsResponse(0, false, std::move(answers), + std::vector<DnsResourceRecord>() /* authority_records */, + std::vector<DnsResourceRecord>() /* additional_records */, + query); } -std::unique_ptr<DnsResponse> BuildTestDnsResponseWithCname( - std::string name, - const IPAddress& ip, - std::string cannonname) { +DnsResponse BuildTestDnsAddressResponseWithCname(std::string name, + const IPAddress& ip, + std::string cannonname) { DCHECK(ip.IsValid()); DCHECK(!cannonname.empty()); @@ -238,13 +234,13 @@ base::Optional<DnsQuery> query( base::in_place, 0, dns_name, ip.IsIPv4() ? dns_protocol::kTypeA : dns_protocol::kTypeAAAA); - return std::make_unique<DnsResponse>( - 0, false, std::move(answers), - std::vector<DnsResourceRecord>() /* authority_records */, - std::vector<DnsResourceRecord>() /* additional_records */, query); + return DnsResponse(0, false, std::move(answers), + std::vector<DnsResourceRecord>() /* authority_records */, + std::vector<DnsResourceRecord>() /* additional_records */, + query); } -std::unique_ptr<DnsResponse> BuildTestDnsTextResponse( +DnsResponse BuildTestDnsTextResponse( std::string name, std::vector<std::vector<std::string>> text_records, std::string answer_name) { @@ -261,16 +257,15 @@ base::Optional<DnsQuery> query(base::in_place, 0, dns_name, dns_protocol::kTypeTXT); - return std::make_unique<DnsResponse>( - 0, false, std::move(answers), - std::vector<DnsResourceRecord>() /* authority_records */, - std::vector<DnsResourceRecord>() /* additional_records */, query); + return DnsResponse(0, false, std::move(answers), + std::vector<DnsResourceRecord>() /* authority_records */, + std::vector<DnsResourceRecord>() /* additional_records */, + query); } -std::unique_ptr<DnsResponse> BuildTestDnsPointerResponse( - std::string name, - std::vector<std::string> pointer_names, - std::string answer_name) { +DnsResponse BuildTestDnsPointerResponse(std::string name, + std::vector<std::string> pointer_names, + std::string answer_name) { if (answer_name.empty()) answer_name = name; @@ -284,13 +279,13 @@ base::Optional<DnsQuery> query(base::in_place, 0, dns_name, dns_protocol::kTypePTR); - return std::make_unique<DnsResponse>( - 0, false, std::move(answers), - std::vector<DnsResourceRecord>() /* authority_records */, - std::vector<DnsResourceRecord>() /* additional_records */, query); + return DnsResponse(0, false, std::move(answers), + std::vector<DnsResourceRecord>() /* authority_records */, + std::vector<DnsResourceRecord>() /* additional_records */, + query); } -std::unique_ptr<DnsResponse> BuildTestDnsServiceResponse( +DnsResponse BuildTestDnsServiceResponse( std::string name, std::vector<TestServiceRecord> service_records, std::string answer_name) { @@ -308,13 +303,13 @@ base::Optional<DnsQuery> query(base::in_place, 0, dns_name, dns_protocol::kTypeSRV); - return std::make_unique<DnsResponse>( - 0, false, std::move(answers), - std::vector<DnsResourceRecord>() /* authority_records */, - std::vector<DnsResourceRecord>() /* additional_records */, query); + return DnsResponse(0, false, std::move(answers), + std::vector<DnsResourceRecord>() /* authority_records */, + std::vector<DnsResourceRecord>() /* additional_records */, + query); } -std::unique_ptr<DnsResponse> BuildTestDnsIntegrityResponse( +DnsResponse BuildTestDnsIntegrityResponse( std::string hostname, const std::vector<uint8_t>& serialized_rdata) { CHECK(!hostname.empty()); @@ -327,17 +322,17 @@ base::Optional<DnsQuery> query(base::in_place, 0, dns_name, dns_protocol::kExperimentalTypeIntegrity); - return std::make_unique<DnsResponse>( - 0, false, std::move(answers), - std::vector<DnsResourceRecord>() /* authority_records */, - std::vector<DnsResourceRecord>() /* additional_records */, query); + return DnsResponse(0, false, std::move(answers), + std::vector<DnsResourceRecord>() /* authority_records */, + std::vector<DnsResourceRecord>() /* additional_records */, + query); } MockDnsClientRule::Result::Result(ResultType type, - std::unique_ptr<DnsResponse> response) + base::Optional<DnsResponse> response) : type(type), response(std::move(response)) {} -MockDnsClientRule::Result::Result(std::unique_ptr<DnsResponse> response) +MockDnsClientRule::Result::Result(DnsResponse response) : type(OK), response(std::move(response)) {} MockDnsClientRule::Result::Result(Result&& result) = default; @@ -412,7 +407,7 @@ case MockDnsClientRule::EMPTY: DCHECK(!result->response); // Not expected to be provided. authority_records = {BuildSoaRecord(hostname_)}; - result_.response = std::make_unique<DnsResponse>( + result_.response = DnsResponse( 22 /* id */, false /* is_authoritative */, std::vector<DnsResourceRecord>() /* answers */, authority_records, @@ -472,18 +467,22 @@ if (result->response) { // Copy response in case |result| is destroyed before the transaction // completes. - result_.response = std::make_unique<DnsResponse>( - result->response->io_buffer(), result->response->io_buffer_size()); + auto buffer_copy = + base::MakeRefCounted<IOBuffer>(result->response->io_buffer_size()); + memcpy(buffer_copy->data(), result->response->io_buffer()->data(), + result->response->io_buffer_size()); + result_.response = DnsResponse(std::move(buffer_copy), + result->response->io_buffer_size()); CHECK(result_.response->InitParseWithoutQuery( result->response->io_buffer_size())); } else { // Generated response only available for address types. DCHECK(qtype_ == dns_protocol::kTypeA || qtype_ == dns_protocol::kTypeAAAA); - result_.response = - BuildTestDnsResponse(hostname_, qtype_ == dns_protocol::kTypeA - ? IPAddress::IPv4Localhost() - : IPAddress::IPv6Localhost()); + result_.response = BuildTestDnsAddressResponse( + hostname_, qtype_ == dns_protocol::kTypeA + ? IPAddress::IPv4Localhost() + : IPAddress::IPv6Localhost()); } } @@ -491,14 +490,17 @@ switch (result_.type) { case MockDnsClientRule::NODOMAIN: case MockDnsClientRule::FAIL: - std::move(callback_).Run(this, ERR_NAME_NOT_RESOLVED, - result_.response.get(), base::nullopt); + std::move(callback_).Run( + this, ERR_NAME_NOT_RESOLVED, + result_.response ? &result_.response.value() : nullptr, + base::nullopt); break; case MockDnsClientRule::EMPTY: case MockDnsClientRule::OK: case MockDnsClientRule::MALFORMED: - std::move(callback_).Run(this, OK, result_.response.get(), - base::nullopt); + std::move(callback_).Run( + this, OK, result_.response ? &result_.response.value() : nullptr, + base::nullopt); break; case MockDnsClientRule::TIMEOUT: std::move(callback_).Run(this, ERR_DNS_TIMED_OUT, nullptr, @@ -506,8 +508,9 @@ break; case MockDnsClientRule::SLOW: if (result_.response) { - std::move(callback_).Run(this, OK, result_.response.get(), - base::nullopt); + std::move(callback_).Run( + this, OK, result_.response ? &result_.response.value() : nullptr, + base::nullopt); } else { std::move(callback_).Run(this, ERR_DNS_TIMED_OUT, nullptr, base::nullopt);
diff --git a/net/dns/dns_test_util.h b/net/dns/dns_test_util.h index 2cc0928..a3e74b9 100644 --- a/net/dns/dns_test_util.h +++ b/net/dns/dns_test_util.h
@@ -16,6 +16,7 @@ #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" +#include "base/optional.h" #include "base/stl_util.h" #include "base/time/time.h" #include "net/dns/dns_client.h" @@ -195,23 +196,20 @@ DnsResourceRecord BuildTestAddressRecord(std::string name, const IPAddress& ip); // Builds a DNS response that includes address records. -std::unique_ptr<DnsResponse> BuildTestDnsResponse(std::string name, - const IPAddress& ip); -std::unique_ptr<DnsResponse> BuildTestDnsResponseWithCname( - std::string name, - const IPAddress& ip, - std::string cannonname); +DnsResponse BuildTestDnsAddressResponse(std::string name, const IPAddress& ip); +DnsResponse BuildTestDnsAddressResponseWithCname(std::string name, + const IPAddress& ip, + std::string cannonname); // If |answer_name| is empty, |name| will be used for all answer records, as is // the normal behavior. -std::unique_ptr<DnsResponse> BuildTestDnsTextResponse( +DnsResponse BuildTestDnsTextResponse( std::string name, std::vector<std::vector<std::string>> text_records, std::string answer_name = ""); -std::unique_ptr<DnsResponse> BuildTestDnsPointerResponse( - std::string name, - std::vector<std::string> pointer_names, - std::string answer_name = ""); +DnsResponse BuildTestDnsPointerResponse(std::string name, + std::vector<std::string> pointer_names, + std::string answer_name = ""); struct TestServiceRecord { uint16_t priority; @@ -220,12 +218,12 @@ std::string target; }; -std::unique_ptr<DnsResponse> BuildTestDnsServiceResponse( +DnsResponse BuildTestDnsServiceResponse( std::string name, std::vector<TestServiceRecord> service_records, std::string answer_name = ""); -std::unique_ptr<DnsResponse> BuildTestDnsIntegrityResponse( +DnsResponse BuildTestDnsIntegrityResponse( std::string hostname, const std::vector<uint8_t>& serialized_rdata); @@ -254,15 +252,15 @@ struct Result { explicit Result(ResultType type, - std::unique_ptr<DnsResponse> response = nullptr); - explicit Result(std::unique_ptr<DnsResponse> response); + base::Optional<DnsResponse> response = base::nullopt); + explicit Result(DnsResponse response); Result(Result&& result); ~Result(); Result& operator=(Result&& result); ResultType type; - std::unique_ptr<DnsResponse> response; + base::Optional<DnsResponse> response; }; // If |delay| is true, matching transactions will be delayed until triggered
diff --git a/net/dns/host_resolver_manager_unittest.cc b/net/dns/host_resolver_manager_unittest.cc index cd1af040..99aacc2 100644 --- a/net/dns/host_resolver_manager_unittest.cc +++ b/net/dns/host_resolver_manager_unittest.cc
@@ -3991,10 +3991,10 @@ uint16_t qtype, const IPAddress& result_ip, bool delay) { - rules->emplace_back( - prefix, qtype, false /* secure */, - MockDnsClientRule::Result(BuildTestDnsResponse(prefix, result_ip)), - delay); + rules->emplace_back(prefix, qtype, false /* secure */, + MockDnsClientRule::Result( + BuildTestDnsAddressResponse(prefix, result_ip)), + delay); } static void AddDnsRule(MockDnsClientRuleList* rules, @@ -4003,10 +4003,11 @@ IPAddress result_ip, std::string cannonname, bool delay) { - rules->emplace_back(prefix, qtype, false /* secure */, - MockDnsClientRule::Result(BuildTestDnsResponseWithCname( - prefix, result_ip, std::move(cannonname))), - delay); + rules->emplace_back( + prefix, qtype, false /* secure */, + MockDnsClientRule::Result(BuildTestDnsAddressResponseWithCname( + prefix, result_ip, std::move(cannonname))), + delay); } static void AddSecureDnsRule(MockDnsClientRuleList* rules, @@ -6898,7 +6899,7 @@ rules.emplace_back( "duplicate", dns_protocol::kTypeA, false /* secure */, - MockDnsClientRule::Result(std::make_unique<DnsResponse>( + MockDnsClientRule::Result(DnsResponse( 0, false, std::move(answers), std::vector<DnsResourceRecord>() /* authority_records */, std::vector<DnsResourceRecord>() /* additional_records */, query)), @@ -6915,7 +6916,7 @@ rules.emplace_back( "duplicate", dns_protocol::kTypeAAAA, false /* secure */, - MockDnsClientRule::Result(std::make_unique<DnsResponse>( + MockDnsClientRule::Result(DnsResponse( 0, false, std::move(answers), std::vector<DnsResourceRecord>() /* authority_records */, std::vector<DnsResourceRecord>() /* additional_records */, query)), @@ -8165,8 +8166,8 @@ // Respond to a TXT query with an A response. MockDnsClientRuleList rules; rules.emplace_back("host", dns_protocol::kTypeTXT, false /* secure */, - MockDnsClientRule::Result( - BuildTestDnsResponse("host", IPAddress(1, 2, 3, 4))), + MockDnsClientRule::Result(BuildTestDnsAddressResponse( + "host", IPAddress(1, 2, 3, 4))), false /* delay */); CreateResolver(); @@ -8469,8 +8470,8 @@ // Respond to a TXT query with an A response. MockDnsClientRuleList rules; rules.emplace_back("host", dns_protocol::kTypePTR, false /* secure */, - MockDnsClientRule::Result( - BuildTestDnsResponse("host", IPAddress(1, 2, 3, 4))), + MockDnsClientRule::Result(BuildTestDnsAddressResponse( + "host", IPAddress(1, 2, 3, 4))), false /* delay */); CreateResolver(); @@ -8761,8 +8762,8 @@ // Respond to a SRV query with an A response. MockDnsClientRuleList rules; rules.emplace_back("host", dns_protocol::kTypeSRV, false /* secure */, - MockDnsClientRule::Result( - BuildTestDnsResponse("host", IPAddress(1, 2, 3, 4))), + MockDnsClientRule::Result(BuildTestDnsAddressResponse( + "host", IPAddress(1, 2, 3, 4))), false /* delay */); CreateResolver();
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store.cc b/net/extras/sqlite/sqlite_persistent_cookie_store.cc index 474db6e..9a05110 100644 --- a/net/extras/sqlite/sqlite_persistent_cookie_store.cc +++ b/net/extras/sqlite/sqlite_persistent_cookie_store.cc
@@ -1023,7 +1023,6 @@ } if (cur_version == 10) { - SCOPED_UMA_HISTOGRAM_TIMER("Cookie.TimeDatabaseMigrationToV11"); sql::Transaction transaction(db()); if (!transaction.Begin()) return base::nullopt;
diff --git a/net/quic/quic_flags_list.h b/net/quic/quic_flags_list.h index 4d568f6..d644abf 100644 --- a/net/quic/quic_flags_list.h +++ b/net/quic/quic_flags_list.h
@@ -475,3 +475,28 @@ // If true, address is validated by successfully processing a HANDSHAKE or 1-RTT // packet. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_fix_address_validation, false) + +// If true, QuicStream will explicitly specify which RST_STREAM, STOP_SENDING +// frame to send. +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_split_up_send_rst, false) + +// If true, send HTTP/3 GOAWAY frame when sending CONNECTION_CLOSE. +QUIC_FLAG(bool, + FLAGS_quic_reloadable_flag_quic_send_goaway_with_connection_close, + false) + +// If true, ack frequency frame can be sent from server to client. +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_can_send_ack_frequency, false) + +// If true, QUIC BBRv2 will support NetworkParams.max_initial_congestion_window +// when bootstrapping cwnd. +QUIC_FLAG(bool, + FLAGS_quic_reloadable_flag_quic_bbr2_support_max_bootstrap_cwnd, + false) + +// If true, QUIC BBR2 will not exit STARTUP on excessive loss, if there was +// enough bandwidth growth in round. +QUIC_FLAG( + bool, + FLAGS_quic_reloadable_flag_quic_bbr2_no_exit_startup_on_loss_with_bw_growth, + false)
diff --git a/services/DIR_METADATA b/services/DIR_METADATA new file mode 100644 index 0000000..52d3644 --- /dev/null +++ b/services/DIR_METADATA
@@ -0,0 +1,11 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Internals>Services" +} \ No newline at end of file
diff --git a/services/OWNERS b/services/OWNERS index 1bcc466..aa84af86 100644 --- a/services/OWNERS +++ b/services/OWNERS
@@ -1,5 +1,4 @@ blundell@chromium.org jam@chromium.org rockot@google.com -sky@chromium.org -# COMPONENT: Internals>Services +sky@chromium.org \ No newline at end of file
diff --git a/services/audio/DIR_METADATA b/services/audio/DIR_METADATA new file mode 100644 index 0000000..99031e0 --- /dev/null +++ b/services/audio/DIR_METADATA
@@ -0,0 +1,11 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Internals>Media>Audio" +} \ No newline at end of file
diff --git a/services/audio/OWNERS b/services/audio/OWNERS index dfd776d..0d82a02 100644 --- a/services/audio/OWNERS +++ b/services/audio/OWNERS
@@ -3,5 +3,3 @@ miu@chromium.org per-file audio_sandbox_hook_linux.*=file://sandbox/linux/OWNERS - -# COMPONENT: Internals>Media>Audio
diff --git a/services/content/DIR_METADATA b/services/content/DIR_METADATA new file mode 100644 index 0000000..ac7f3a4 --- /dev/null +++ b/services/content/DIR_METADATA
@@ -0,0 +1,11 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Internals>Services>Content" +} \ No newline at end of file
diff --git a/services/content/OWNERS b/services/content/OWNERS index 672cb65..9624e1d 100644 --- a/services/content/OWNERS +++ b/services/content/OWNERS
@@ -1,5 +1,4 @@ alexmos@chromium.org clamy@chromium.org jam@chromium.org -rockot@google.com -# COMPONENT: Internals>Services>Content +rockot@google.com \ No newline at end of file
diff --git a/services/data_decoder/DIR_METADATA b/services/data_decoder/DIR_METADATA new file mode 100644 index 0000000..1af08c8 --- /dev/null +++ b/services/data_decoder/DIR_METADATA
@@ -0,0 +1,12 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Internals>Mojo>Bindings" +} +team_email: "chrome-security@google.com" \ No newline at end of file
diff --git a/services/data_decoder/OWNERS b/services/data_decoder/OWNERS index 915d04e..e645ed54 100644 --- a/services/data_decoder/OWNERS +++ b/services/data_decoder/OWNERS
@@ -1,4 +1,2 @@ palmer@chromium.org -rsesek@chromium.org -# COMPONENT: Internals>Mojo>Bindings -# TEAM: chrome-security@google.com +rsesek@chromium.org \ No newline at end of file
diff --git a/services/media_session/DIR_METADATA b/services/media_session/DIR_METADATA new file mode 100644 index 0000000..e278b5a0 --- /dev/null +++ b/services/media_session/DIR_METADATA
@@ -0,0 +1,12 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Internals>Media>Session" +} +team_email: "media-dev@chromium.org" \ No newline at end of file
diff --git a/services/media_session/OWNERS b/services/media_session/OWNERS index 0728e3a..70313512 100644 --- a/services/media_session/OWNERS +++ b/services/media_session/OWNERS
@@ -1,7 +1,2 @@ beccahughes@chromium.org mlamouri@chromium.org - - - -# COMPONENT: Internals>Media>Session -# TEAM: media-dev@chromium.org
diff --git a/services/metrics/DIR_METADATA b/services/metrics/DIR_METADATA new file mode 100644 index 0000000..35d6bbc8 --- /dev/null +++ b/services/metrics/DIR_METADATA
@@ -0,0 +1,11 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Internals>Metrics" +} \ No newline at end of file
diff --git a/services/metrics/OWNERS b/services/metrics/OWNERS index f4be013..9795904 100644 --- a/services/metrics/OWNERS +++ b/services/metrics/OWNERS
@@ -1,5 +1 @@ file://base/metrics/OWNERS - - -# COMPONENT: Internals>Metrics -# TEAM: chromium-dev@chromium.org
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc index e7b3686..040bdaa 100644 --- a/services/network/network_context_unittest.cc +++ b/services/network/network_context_unittest.cc
@@ -3730,11 +3730,11 @@ net::IPAddress result; CHECK(result.AssignFromIPLiteral(kResult)); net::MockDnsClientRuleList rules; - rules.emplace_back(kQueryHostname, net::dns_protocol::kTypeA, - false /* secure */, - net::MockDnsClientRule::Result( - net::BuildTestDnsResponse(kQueryHostname, result)), - false /* delay */); + rules.emplace_back( + kQueryHostname, net::dns_protocol::kTypeA, false /* secure */, + net::MockDnsClientRule::Result( + net::BuildTestDnsAddressResponse(kQueryHostname, result)), + false /* delay */); rules.emplace_back( kQueryHostname, net::dns_protocol::kTypeAAAA, false /* secure */, net::MockDnsClientRule::Result(net::MockDnsClientRule::ResultType::EMPTY),
diff --git a/services/preferences/DIR_METADATA b/services/preferences/DIR_METADATA new file mode 100644 index 0000000..3b080ff --- /dev/null +++ b/services/preferences/DIR_METADATA
@@ -0,0 +1,11 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Internals>Preferences>Service" +} \ No newline at end of file
diff --git a/services/preferences/OWNERS b/services/preferences/OWNERS index b1261bd..6662cdd 100644 --- a/services/preferences/OWNERS +++ b/services/preferences/OWNERS
@@ -1,4 +1,2 @@ jonross@chromium.org sammc@chromium.org - -# COMPONENT: Internals>Preferences>Service
diff --git a/services/proxy_resolver/DIR_METADATA b/services/proxy_resolver/DIR_METADATA new file mode 100644 index 0000000..e05317a --- /dev/null +++ b/services/proxy_resolver/DIR_METADATA
@@ -0,0 +1,11 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Internals>Network>Proxy" +} \ No newline at end of file
diff --git a/services/proxy_resolver/OWNERS b/services/proxy_resolver/OWNERS index d8ae3263..2fdb6e7 100644 --- a/services/proxy_resolver/OWNERS +++ b/services/proxy_resolver/OWNERS
@@ -1,2 +1 @@ -file://services/network/OWNERS -# COMPONENT: Internals>Network>Proxy +file://services/network/OWNERS \ No newline at end of file
diff --git a/services/resource_coordinator/DIR_METADATA b/services/resource_coordinator/DIR_METADATA new file mode 100644 index 0000000..07ecfd7 --- /dev/null +++ b/services/resource_coordinator/DIR_METADATA
@@ -0,0 +1,12 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Internals>ResourceCoordinator" +} +team_email: "catan-team@chromium.org" \ No newline at end of file
diff --git a/services/resource_coordinator/OWNERS b/services/resource_coordinator/OWNERS index 2b8c9bcc..021ff20 100644 --- a/services/resource_coordinator/OWNERS +++ b/services/resource_coordinator/OWNERS
@@ -8,6 +8,3 @@ zhenw@chromium.org per-file BUILD.gn=file://services/resource_coordinator/memory_instrumentation/OWNERS - -# TEAM: catan-team@chromium.org -# COMPONENT: Internals>ResourceCoordinator
diff --git a/services/resource_coordinator/memory_instrumentation/DIR_METADATA b/services/resource_coordinator/memory_instrumentation/DIR_METADATA new file mode 100644 index 0000000..970fc89 --- /dev/null +++ b/services/resource_coordinator/memory_instrumentation/DIR_METADATA
@@ -0,0 +1,11 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Internals>Instrumentation>Memory" +} \ No newline at end of file
diff --git a/services/resource_coordinator/memory_instrumentation/OWNERS b/services/resource_coordinator/memory_instrumentation/OWNERS index e13658d..822acf15 100644 --- a/services/resource_coordinator/memory_instrumentation/OWNERS +++ b/services/resource_coordinator/memory_instrumentation/OWNERS
@@ -1,4 +1,3 @@ hjd@chromium.org primiano@chromium.org -ssid@chromium.org -# COMPONENT: Internals>Instrumentation>Memory +ssid@chromium.org \ No newline at end of file
diff --git a/services/service_manager/OWNERS b/services/service_manager/OWNERS index db7d7c4..fd5952b 100644 --- a/services/service_manager/OWNERS +++ b/services/service_manager/OWNERS
@@ -1,5 +1,3 @@ jam@chromium.org rockot@google.com sky@chromium.org - -# COMPONENT: Internals>Services
diff --git a/services/shape_detection/DIR_METADATA b/services/shape_detection/DIR_METADATA new file mode 100644 index 0000000..88c96d75 --- /dev/null +++ b/services/shape_detection/DIR_METADATA
@@ -0,0 +1,12 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Blink>ShapeDetection" +} +team_email: "device-dev@chromium.org" \ No newline at end of file
diff --git a/services/shape_detection/OWNERS b/services/shape_detection/OWNERS index aee8252f..47d63bc 100644 --- a/services/shape_detection/OWNERS +++ b/services/shape_detection/OWNERS
@@ -1,4 +1 @@ file://third_party/blink/renderer/modules/shapedetection/OWNERS - -# COMPONENT: Blink>ShapeDetection -# TEAM: device-dev@chromium.org
diff --git a/services/test/OWNERS b/services/test/OWNERS deleted file mode 100644 index eaf0589..0000000 --- a/services/test/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -# COMPONENT: Internals>Services
diff --git a/services/test/data/DIR_METADATA b/services/test/data/DIR_METADATA new file mode 100644 index 0000000..5bd66c6 --- /dev/null +++ b/services/test/data/DIR_METADATA
@@ -0,0 +1,11 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Test" +} \ No newline at end of file
diff --git a/services/test/data/OWNERS b/services/test/data/OWNERS index 177e36d..f59ec20 100644 --- a/services/test/data/OWNERS +++ b/services/test/data/OWNERS
@@ -1,2 +1 @@ -* -# COMPONENT: Test +* \ No newline at end of file
diff --git a/services/test/echo/OWNERS b/services/test/echo/OWNERS deleted file mode 100644 index eaf0589..0000000 --- a/services/test/echo/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -# COMPONENT: Internals>Services
diff --git a/services/tracing/DIR_METADATA b/services/tracing/DIR_METADATA new file mode 100644 index 0000000..2b8a972 --- /dev/null +++ b/services/tracing/DIR_METADATA
@@ -0,0 +1,11 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Speed>Tracing" +} \ No newline at end of file
diff --git a/services/tracing/OWNERS b/services/tracing/OWNERS index 2f82ce6..2c2f79b 100644 --- a/services/tracing/OWNERS +++ b/services/tracing/OWNERS
@@ -1,2 +1 @@ -file://base/trace_event/OWNERS -# COMPONENT: Speed>Tracing +file://base/trace_event/OWNERS \ No newline at end of file
diff --git a/services/video_capture/DIR_METADATA b/services/video_capture/DIR_METADATA new file mode 100644 index 0000000..f49aeaf --- /dev/null +++ b/services/video_capture/DIR_METADATA
@@ -0,0 +1,12 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Blink>GetUserMedia" +} +team_email: "webrtc-dev@chromium.org" \ No newline at end of file
diff --git a/services/video_capture/OWNERS b/services/video_capture/OWNERS index 7e7e66b..a7bd387 100644 --- a/services/video_capture/OWNERS +++ b/services/video_capture/OWNERS
@@ -3,6 +3,3 @@ # Original (legacy) owners. chfremer@chromium.org per-file *video*=mcasas@chromium.org - -# COMPONENT: Blink>GetUserMedia -# TEAM: webrtc-dev@chromium.org
diff --git a/services/viz/DIR_METADATA b/services/viz/DIR_METADATA new file mode 100644 index 0000000..e72351b34 --- /dev/null +++ b/services/viz/DIR_METADATA
@@ -0,0 +1,11 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Internals>Services>Viz" +} \ No newline at end of file
diff --git a/services/viz/OWNERS b/services/viz/OWNERS index 0452193..d60220b 100644 --- a/services/viz/OWNERS +++ b/services/viz/OWNERS
@@ -1,3 +1 @@ file://components/viz/OWNERS - -# COMPONENT: Internals>Services>Viz
diff --git a/services/viz/public/cpp/compositing/mojom_traits_perftest.cc b/services/viz/public/cpp/compositing/mojom_traits_perftest.cc index ec6e512..815f0c2 100644 --- a/services/viz/public/cpp/compositing/mojom_traits_perftest.cc +++ b/services/viz/public/cpp/compositing/mojom_traits_perftest.cc
@@ -217,8 +217,9 @@ pass_in->CreateAndAppendSharedQuadState(); shared_state1_in->SetAll( arbitrary_matrix1, arbitrary_rect1, arbitrary_rect1, - arbitrary_rrectf1, arbitrary_rect2, arbitrary_bool1, arbitrary_bool1, - arbitrary_float1, arbitrary_blend_mode1, arbitrary_context_id1); + gfx::MaskFilterInfo(arbitrary_rrectf1, false), arbitrary_rect2, + arbitrary_bool1, arbitrary_bool1, arbitrary_float1, + arbitrary_blend_mode1, arbitrary_context_id1); auto* texture_in = pass_in->CreateAndAppendDrawQuad<TextureDrawQuad>(); texture_in->SetAll( @@ -259,8 +260,9 @@ pass_in->CreateAndAppendSharedQuadState(); shared_state2_in->SetAll( arbitrary_matrix2, arbitrary_rect2, arbitrary_rect2, - arbitrary_rrectf2, arbitrary_rect3, arbitrary_bool1, arbitrary_bool1, - arbitrary_float2, arbitrary_blend_mode2, arbitrary_context_id2); + gfx::MaskFilterInfo(arbitrary_rrectf2, false), arbitrary_rect3, + arbitrary_bool1, arbitrary_bool1, arbitrary_float2, + arbitrary_blend_mode2, arbitrary_context_id2); for (uint32_t j = 0; j < 6; ++j) { auto* tile_in = pass_in->CreateAndAppendDrawQuad<TileDrawQuad>(); tile_in->SetAll( @@ -276,8 +278,9 @@ pass_in->CreateAndAppendSharedQuadState(); shared_state3_in->SetAll( arbitrary_matrix1, arbitrary_rect3, arbitrary_rect3, - arbitrary_rrectf3, arbitrary_rect1, arbitrary_bool1, arbitrary_bool1, - arbitrary_float3, arbitrary_blend_mode3, arbitrary_context_id3); + gfx::MaskFilterInfo(arbitrary_rrectf3, false), arbitrary_rect1, + arbitrary_bool1, arbitrary_bool1, arbitrary_float3, + arbitrary_blend_mode3, arbitrary_context_id3); for (uint32_t j = 0; j < 5; ++j) { auto* solidcolor_in = pass_in->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
diff --git a/services/viz/public/cpp/compositing/mojom_traits_unittest.cc b/services/viz/public/cpp/compositing/mojom_traits_unittest.cc index 90e3b112..326f6af 100644 --- a/services/viz/public/cpp/compositing/mojom_traits_unittest.cc +++ b/services/viz/public/cpp/compositing/mojom_traits_unittest.cc
@@ -416,33 +416,34 @@ 13.f, 14.f, 15.f, 16.f); const gfx::Rect layer_rect(1234, 5678); const gfx::Rect visible_layer_rect(12, 34, 56, 78); - const gfx::RRectF rounded_corner_bounds(gfx::RectF(1.f, 2.f, 30.f, 40.f), 5); + bool is_fast_rounded_corner = true; + const gfx::MaskFilterInfo mask_filter_info( + gfx::RRectF(gfx::RectF(1.f, 2.f, 30.f, 40.f), 5), is_fast_rounded_corner); const gfx::Rect clip_rect(123, 456, 789, 101112); const bool is_clipped = true; bool are_contents_opaque = true; const float opacity = 0.9f; const SkBlendMode blend_mode = SkBlendMode::kSrcOver; const int sorting_context_id = 1337; - bool is_fast_rounded_corner = true; SharedQuadState input_sqs; input_sqs.SetAll(quad_to_target_transform, layer_rect, visible_layer_rect, - rounded_corner_bounds, clip_rect, is_clipped, - are_contents_opaque, opacity, blend_mode, - sorting_context_id); - input_sqs.is_fast_rounded_corner = is_fast_rounded_corner; + mask_filter_info, clip_rect, is_clipped, are_contents_opaque, + opacity, blend_mode, sorting_context_id); SharedQuadState output_sqs; mojo::test::SerializeAndDeserialize<mojom::SharedQuadState>(&input_sqs, &output_sqs); EXPECT_EQ(quad_to_target_transform, output_sqs.quad_to_target_transform); EXPECT_EQ(layer_rect, output_sqs.quad_layer_rect); EXPECT_EQ(visible_layer_rect, output_sqs.visible_quad_layer_rect); - EXPECT_EQ(rounded_corner_bounds, output_sqs.rounded_corner_bounds); + EXPECT_EQ(mask_filter_info.rounded_corner_bounds(), + output_sqs.mask_filter_info.rounded_corner_bounds()); + EXPECT_EQ(is_fast_rounded_corner, + output_sqs.mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(clip_rect, output_sqs.clip_rect); EXPECT_EQ(is_clipped, output_sqs.is_clipped); EXPECT_EQ(opacity, output_sqs.opacity); EXPECT_EQ(blend_mode, output_sqs.blend_mode); EXPECT_EQ(sorting_context_id, output_sqs.sorting_context_id); - EXPECT_EQ(is_fast_rounded_corner, output_sqs.is_fast_rounded_corner); } // Note that this is a fairly trivial test of CompositorFrame serialization as @@ -459,8 +460,8 @@ 15.f, 16.f); const gfx::Rect sqs_layer_rect(1234, 5678); const gfx::Rect sqs_visible_layer_rect(12, 34, 56, 78); - const gfx::RRectF sqs_rounded_corner_bounds(gfx::RectF(3.f, 4.f, 50.f, 15.f), - 3); + const gfx::MaskFilterInfo sqs_mask_filter_info( + gfx::RRectF(gfx::RectF(3.f, 4.f, 50.f, 15.f), 3), false); const gfx::Rect sqs_clip_rect(123, 456, 789, 101112); const bool sqs_is_clipped = true; bool sqs_are_contents_opaque = false; @@ -469,7 +470,7 @@ const int sqs_sorting_context_id = 1337; SharedQuadState* sqs = render_pass->CreateAndAppendSharedQuadState(); sqs->SetAll(sqs_quad_to_target_transform, sqs_layer_rect, - sqs_visible_layer_rect, sqs_rounded_corner_bounds, sqs_clip_rect, + sqs_visible_layer_rect, sqs_mask_filter_info, sqs_clip_rect, sqs_is_clipped, sqs_are_contents_opaque, sqs_opacity, sqs_blend_mode, sqs_sorting_context_id); @@ -544,7 +545,7 @@ EXPECT_EQ(sqs_quad_to_target_transform, out_sqs->quad_to_target_transform); EXPECT_EQ(sqs_layer_rect, out_sqs->quad_layer_rect); EXPECT_EQ(sqs_visible_layer_rect, out_sqs->visible_quad_layer_rect); - EXPECT_EQ(sqs_rounded_corner_bounds, out_sqs->rounded_corner_bounds); + EXPECT_EQ(sqs_mask_filter_info, out_sqs->mask_filter_info); EXPECT_EQ(sqs_clip_rect, out_sqs->clip_rect); EXPECT_EQ(sqs_is_clipped, out_sqs->is_clipped); EXPECT_EQ(sqs_are_contents_opaque, out_sqs->are_contents_opaque); @@ -723,7 +724,8 @@ gfx::Transform(16.1f, 15.3f, 14.3f, 13.7f, 12.2f, 11.4f, 10.4f, 9.8f, 8.1f, 7.3f, 6.3f, 5.7f, 4.8f, 3.4f, 2.4f, 1.2f), gfx::Rect(1, 2), gfx::Rect(1337, 5679, 9101112, 131415), - gfx::RRectF(gfx::RectF(5.f, 6.f, 70.f, 89.f), 10.f), + gfx::MaskFilterInfo(gfx::RRectF(gfx::RectF(5.f, 6.f, 70.f, 89.f), 10.f), + false), gfx::Rect(1357, 2468, 121314, 1337), true, true, 2, SkBlendMode::kSrcOver, 1); @@ -732,7 +734,8 @@ gfx::Transform(1.1f, 2.3f, 3.3f, 4.7f, 5.2f, 6.4f, 7.4f, 8.8f, 9.1f, 10.3f, 11.3f, 12.7f, 13.8f, 14.4f, 15.4f, 16.2f), gfx::Rect(1337, 1234), gfx::Rect(1234, 5678, 9101112, 13141516), - gfx::RRectF(gfx::RectF(23.f, 45.f, 60.f, 70.f), 8.f), + gfx::MaskFilterInfo(gfx::RRectF(gfx::RectF(23.f, 45.f, 60.f, 70.f), 8.f), + false), gfx::Rect(1357, 2468, 121314, 1337), true, true, 2, SkBlendMode::kSrcOver, 1); @@ -792,8 +795,7 @@ EXPECT_EQ(shared_state_1->quad_layer_rect, out_sqs1->quad_layer_rect); EXPECT_EQ(shared_state_1->visible_quad_layer_rect, out_sqs1->visible_quad_layer_rect); - EXPECT_EQ(shared_state_1->rounded_corner_bounds, - out_sqs1->rounded_corner_bounds); + EXPECT_EQ(shared_state_1->mask_filter_info, out_sqs1->mask_filter_info); EXPECT_EQ(shared_state_1->clip_rect, out_sqs1->clip_rect); EXPECT_EQ(shared_state_1->is_clipped, out_sqs1->is_clipped); EXPECT_EQ(shared_state_1->opacity, out_sqs1->opacity); @@ -806,8 +808,7 @@ EXPECT_EQ(shared_state_2->quad_layer_rect, out_sqs2->quad_layer_rect); EXPECT_EQ(shared_state_2->visible_quad_layer_rect, out_sqs2->visible_quad_layer_rect); - EXPECT_EQ(shared_state_2->rounded_corner_bounds, - out_sqs2->rounded_corner_bounds); + EXPECT_EQ(shared_state_2->mask_filter_info, out_sqs2->mask_filter_info); EXPECT_EQ(shared_state_2->clip_rect, out_sqs2->clip_rect); EXPECT_EQ(shared_state_2->is_clipped, out_sqs2->is_clipped); EXPECT_EQ(shared_state_2->opacity, out_sqs2->opacity);
diff --git a/services/viz/public/cpp/compositing/shared_quad_state_mojom_traits.h b/services/viz/public/cpp/compositing/shared_quad_state_mojom_traits.h index 830191111..66f70ec 100644 --- a/services/viz/public/cpp/compositing/shared_quad_state_mojom_traits.h +++ b/services/viz/public/cpp/compositing/shared_quad_state_mojom_traits.h
@@ -7,6 +7,7 @@ #include "components/viz/common/quads/shared_quad_state.h" #include "services/viz/public/mojom/compositing/shared_quad_state.mojom-shared.h" +#include "ui/gfx/mojom/mask_filter_info_mojom_traits.h" #include "ui/gfx/mojom/rrect_f_mojom_traits.h" namespace mojo { @@ -35,9 +36,9 @@ return input.sqs->visible_quad_layer_rect; } - static const gfx::RRectF& rounded_corner_bounds( + static const gfx::MaskFilterInfo& mask_filter_info( const OptSharedQuadState& input) { - return input.sqs->rounded_corner_bounds; + return input.sqs->mask_filter_info; } static const gfx::Rect& clip_rect(const OptSharedQuadState& input) { @@ -64,10 +65,6 @@ return input.sqs->sorting_context_id; } - static bool is_fast_rounded_corner(const OptSharedQuadState& input) { - return input.sqs->is_fast_rounded_corner; - } - static float de_jelly_delta_y(const OptSharedQuadState& input) { return input.sqs->de_jelly_delta_y; } @@ -93,9 +90,9 @@ return sqs.visible_quad_layer_rect; } - static const gfx::RRectF& rounded_corner_bounds( + static const gfx::MaskFilterInfo& mask_filter_info( const viz::SharedQuadState& sqs) { - return sqs.rounded_corner_bounds; + return sqs.mask_filter_info; } static const gfx::Rect& clip_rect(const viz::SharedQuadState& sqs) { @@ -120,10 +117,6 @@ return sqs.sorting_context_id; } - static bool is_fast_rounded_corner(const viz::SharedQuadState& sqs) { - return sqs.is_fast_rounded_corner; - } - static float de_jelly_delta_y(const viz::SharedQuadState& sqs) { return sqs.de_jelly_delta_y; } @@ -137,7 +130,7 @@ if (!data.ReadQuadToTargetTransform(&out->quad_to_target_transform) || !data.ReadQuadLayerRect(&out->quad_layer_rect) || !data.ReadVisibleQuadLayerRect(&out->visible_quad_layer_rect) || - !data.ReadRoundedCornerBounds(&out->rounded_corner_bounds) || + !data.ReadMaskFilterInfo(&out->mask_filter_info) || !data.ReadClipRect(&out->clip_rect)) { return false; } @@ -149,7 +142,6 @@ return false; out->blend_mode = static_cast<SkBlendMode>(data.blend_mode()); out->sorting_context_id = data.sorting_context_id(); - out->is_fast_rounded_corner = data.is_fast_rounded_corner(); out->de_jelly_delta_y = data.de_jelly_delta_y(); out->no_damage = data.no_damage(); return true;
diff --git a/services/viz/public/cpp/gpu/DIR_METADATA b/services/viz/public/cpp/gpu/DIR_METADATA new file mode 100644 index 0000000..8e87cca --- /dev/null +++ b/services/viz/public/cpp/gpu/DIR_METADATA
@@ -0,0 +1,11 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Internals>GPU>Internals" +} \ No newline at end of file
diff --git a/services/viz/public/cpp/gpu/OWNERS b/services/viz/public/cpp/gpu/OWNERS index 50daca7..1db50ad 100644 --- a/services/viz/public/cpp/gpu/OWNERS +++ b/services/viz/public/cpp/gpu/OWNERS
@@ -1,3 +1 @@ file://gpu/OWNERS - -# COMPONENT: Internals>GPU>Internals
diff --git a/services/viz/public/mojom/compositing/shared_quad_state.mojom b/services/viz/public/mojom/compositing/shared_quad_state.mojom index 214f508b..95ea9dd 100644 --- a/services/viz/public/mojom/compositing/shared_quad_state.mojom +++ b/services/viz/public/mojom/compositing/shared_quad_state.mojom
@@ -7,6 +7,7 @@ import "ui/gfx/geometry/mojom/geometry.mojom"; import "ui/gfx/mojom/rrect_f.mojom"; import "ui/gfx/mojom/transform.mojom"; +import "ui/gfx/mojom/mask_filter_info.mojom"; // See viz::SharedQuadState. struct SharedQuadState { @@ -20,9 +21,10 @@ // of the quad rects. gfx.mojom.Rect visible_quad_layer_rect; - // This rect lives in the target content space. It defines the corner radius - // to clip the quads with. - gfx.mojom.RRectF rounded_corner_bounds; + // This rect lives in the target content space. It defines the mask filter + // info applied to the quad, and also defines rounded corner rects to clip the + // quads with. + gfx.mojom.MaskFilterInfo mask_filter_info; // This rect lives in the target content space. gfx.mojom.Rect clip_rect; @@ -38,8 +40,6 @@ uint32 blend_mode; int32 sorting_context_id; - bool is_fast_rounded_corner; - // The y offset by which to skew quads in this layer. For experimental // de-jelly effect. float de_jelly_delta_y;
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index e29b1b7..36b92545 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -2708,9 +2708,8 @@ { "args": [ "--enable-features=NetworkService,NetworkServiceInProcess", - "--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter", - "--avd-config=../../tools/android/avd/proto/generic_android28.textpb", - "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.webview_instrumentation_test_apk.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter;../../testing/buildbot/filters/android.emulator.webview_instrumentation_test_apk.filter", + "--avd-config=../../tools/android/avd/proto/generic_android28.textpb" ], "merge": { "args": [],
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 79aeb81..3c925102 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -42851,11 +42851,10 @@ { "args": [ "--enable-features=NetworkService,NetworkServiceInProcess", - "--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter", + "--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter;../../testing/buildbot/filters/android.emulator.webview_instrumentation_test_apk.filter", "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_android28.textpb", - "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.webview_instrumentation_test_apk.filter" + "--avd-config=../../tools/android/avd/proto/generic_android28.textpb" ], "merge": { "args": [
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index 5ef1182..781bf61 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -13146,8 +13146,8 @@ "gtest_tests": [ { "args": [ - "--no-xvfb", - "--test-launcher-filter-file=../../testing/buildbot/filters/gpu.linux.skiarenderer_dawn_cc_unittests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/gpu.skiarenderer_dawn_cc_unittests.filter;../../testing/buildbot/filters/gpu.linux.skiarenderer_dawn_cc_unittests.filter", + "--no-xvfb" ], "merge": { "args": [], @@ -31923,6 +31923,9 @@ "Win10 FYI x64 SkiaRenderer Dawn Release (NVIDIA)": { "gtest_tests": [ { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/gpu.skiarenderer_dawn_cc_unittests.filter" + ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index be4f8a1d..ccada60 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -4869,8 +4869,7 @@ { "args": [ "--ozone-platform=x11", - "--enable-features=UseOzonePlatform", - "--test-launcher-filter-file=../../testing/buildbot/filters/ozone-linux.x11_browser_tests.filter" + "--enable-features=UseOzonePlatform" ], "merge": { "args": [], @@ -5010,6 +5009,28 @@ "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, + "name": "interactive_ui_tests_x11", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "interactive_ui_tests", + "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" + }, + { + "args": [ + "--ozone-platform=x11", + "--enable-features=UseOzonePlatform" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, "name": "ozone_x11_unittests_x11", "swarming": { "can_use_on_swarming_builders": true,
diff --git a/testing/buildbot/chromium.swangle.json b/testing/buildbot/chromium.swangle.json index 64cfc67..e4e4ab8 100644 --- a/testing/buildbot/chromium.swangle.json +++ b/testing/buildbot/chromium.swangle.json
@@ -1562,7 +1562,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -1594,7 +1594,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -1623,7 +1623,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -1650,7 +1650,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -1678,7 +1678,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -1706,7 +1706,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -1734,7 +1734,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -1761,7 +1761,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -1788,7 +1788,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -1815,7 +1815,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -1847,7 +1847,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -1874,7 +1874,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -1902,7 +1902,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -1930,7 +1930,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -1958,7 +1958,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -1985,7 +1985,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2012,7 +2012,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2039,7 +2039,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2071,7 +2071,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2098,7 +2098,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2126,7 +2126,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2154,7 +2154,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2182,7 +2182,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2209,7 +2209,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2236,7 +2236,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2263,7 +2263,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2295,7 +2295,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2322,7 +2322,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2350,7 +2350,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2378,7 +2378,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2406,7 +2406,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2433,7 +2433,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2460,7 +2460,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2487,7 +2487,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2519,7 +2519,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2546,7 +2546,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2574,7 +2574,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2602,7 +2602,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2630,7 +2630,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2657,7 +2657,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2684,7 +2684,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2711,7 +2711,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2743,7 +2743,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2770,7 +2770,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2798,7 +2798,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2826,7 +2826,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2854,7 +2854,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2881,7 +2881,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2908,7 +2908,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ], @@ -2935,7 +2935,7 @@ { "cpu": "x86-64", "gpu": "none", - "os": "Windows-10-15063", + "os": "Windows-10", "pool": "chromium.tests.gpu" } ],
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn index ba29e82a..17411e1 100644 --- a/testing/buildbot/filters/BUILD.gn +++ b/testing/buildbot/filters/BUILD.gn
@@ -22,6 +22,7 @@ data = [ "//testing/buildbot/filters/android.emulator.cc_unittests.filter", "//testing/buildbot/filters/gpu.linux.skiarenderer_dawn_cc_unittests.filter", + "//testing/buildbot/filters/gpu.skiarenderer_dawn_cc_unittests.filter", ] } @@ -48,7 +49,6 @@ "//testing/buildbot/filters/code_coverage.browser_tests.filter", "//testing/buildbot/filters/lacros.browser_tests.filter", "//testing/buildbot/filters/ozone-linux.wayland_browser_tests.filter", - "//testing/buildbot/filters/ozone-linux.x11_browser_tests.filter", "//testing/buildbot/filters/pixel_browser_tests.filter", "//testing/buildbot/filters/webrtc_functional.browser_tests.filter", ]
diff --git a/testing/buildbot/filters/gpu.skiarenderer_dawn_cc_unittests.filter b/testing/buildbot/filters/gpu.skiarenderer_dawn_cc_unittests.filter new file mode 100644 index 0000000..31e6b40 --- /dev/null +++ b/testing/buildbot/filters/gpu.skiarenderer_dawn_cc_unittests.filter
@@ -0,0 +1,3 @@ +# crbug.com/1139118: new blur algorithm +-All/LayerTreeHostFiltersPixelTest.BackdropFilterBlurRadius/SkiaDawn +-All/LayerTreeHostFiltersPixelTest.BackdropFilterRotated/SkiaDawn
diff --git a/testing/buildbot/filters/ozone-linux.x11_browser_tests.filter b/testing/buildbot/filters/ozone-linux.x11_browser_tests.filter deleted file mode 100644 index 66d18d3..0000000 --- a/testing/buildbot/filters/ozone-linux.x11_browser_tests.filter +++ /dev/null
@@ -1,25 +0,0 @@ -# TODO(https://crbug.com/1084472): fix these failing tests. - -# Failed --DesktopCaptureApiTest.ChooseDesktopMedia --OutOfProcessPPAPITest.FlashClipboard --WebRtcDesktopCaptureBrowserTest.RunsScreenshareFromOneTabToAnother --WebRtcGetDisplayMediaBrowserTestWithPicker.GetDisplayMediaVideo --WebRtcGetDisplayMediaBrowserTestWithPicker.GetDisplayMediaVideoAndAudio --SaveType/SavePageOriginalVsSavedComparisonTest.CrossSiteObject/0 - -# Flaky --AutofillProviderBrowserTestWithSkipFlagOff.InferredLabelChangeImpactFormComparing --AutofillProviderBrowserTestWithSkipFlagOn.LabelTagChangeImpactFormComparing --ExecuteScriptApiTest/DestructiveScriptTest.SynchronousRemoval/0 --ExtensionInstallDialogViewTest.InstallButtonDelay --OmniboxPopupContentsViewTest.ClickOmnibox --PageInfoBubbleViewBrowserTest.FocusDoesNotReturnToContentsOnReloadPrompt --PaymentRequestCreditCardEditorTest.EditingExpiredCard --PaymentRequestShippingAddressEditorTest.FocusFirstField_Name --PrintPreviewScalingSettingsTest.SetScaling --SaveCardBubbleViewsFullFormBrowserTestForStatusChip.Local_ClickingSaveShowsSigninPromo --TranslateLanguageBrowserTestWithTranslateRecentTarget.RecentTargetLanguage --WebViewTest.Shim_TestLoadAbortIllegalChromeURL --WebViewTest.Shim_testFindInMultipleWebViews --WebViewTest.TestPlugin
diff --git a/testing/buildbot/generate_buildbot_json.py b/testing/buildbot/generate_buildbot_json.py index b967485..607f48b 100755 --- a/testing/buildbot/generate_buildbot_json.py +++ b/testing/buildbot/generate_buildbot_json.py
@@ -460,6 +460,7 @@ # --extra-browser-args=arg1 arg2 arr = self.merge_command_line_args(arr, '--enable-features=', ',') arr = self.merge_command_line_args(arr, '--extra-browser-args=', ' ') + arr = self.merge_command_line_args(arr, '--test-launcher-filter-file=', ';') return arr def substitute_magic_args(self, test_config):
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl index 0079343a..584c316 100644 --- a/testing/buildbot/mixins.pyl +++ b/testing/buildbot/mixins.pyl
@@ -825,6 +825,16 @@ }, }, }, + 'win10_gce_gpu_pool': { + 'swarming': { + 'dimensions': { + 'cpu': 'x86-64', + 'gpu': 'none', + 'os': 'Windows-10', + 'pool': 'chromium.tests.gpu', + }, + }, + }, 'win10_intel_hd_630_experimental': { 'swarming': { 'dimensions': {
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index bf0997f..45043ea 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -602,15 +602,6 @@ }, }, }, - 'browser_tests_x11': { - 'modifications': { - 'Linux Ozone Tester (X11)': { - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/ozone-linux.x11_browser_tests.filter', - ], - }, - }, - }, 'cc_unittests': { 'modifications': { 'Linux TSan Tests': {
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 5fb1e07..2ff2794 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -2555,6 +2555,9 @@ '--no-xvfb', '--test-launcher-filter-file=../../testing/buildbot/filters/gpu.linux.skiarenderer_dawn_cc_unittests.filter', ], + 'args': [ + '--test-launcher-filter-file=../../testing/buildbot/filters/gpu.skiarenderer_dawn_cc_unittests.filter', + ], }, 'viz_unittests': { 'linux_args': [ @@ -3465,6 +3468,7 @@ }, 'linux_ozone_x11_only_gtests': { + 'interactive_ui_tests': {}, 'ozone_x11_unittests': {}, 'x11_unittests': {}, },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index d2791e8..ff484db 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -5109,10 +5109,7 @@ 'os_type': 'win', 'browser_config': 'release', 'mixins': [ - 'gpu-swarming-pool', - 'no_gpu', - 'x86-64', - 'win10', + 'win10_gce_gpu_pool', ], 'test_suites': { 'gpu_telemetry_tests': 'gpu_swangle_telemetry_tests', @@ -5121,10 +5118,7 @@ 'win-swangle-tot-angle-x64' : { 'os_type': 'win', 'mixins': [ - 'gpu-swarming-pool', - 'no_gpu', - 'x86-64', - 'win10', + 'win10_gce_gpu_pool', 'timeout_15m', ], 'test_suites': { @@ -5134,10 +5128,7 @@ 'win-swangle-tot-angle-x86' : { 'os_type': 'win', 'mixins': [ - 'gpu-swarming-pool', - 'no_gpu', - 'x86-64', - 'win10', + 'win10_gce_gpu_pool', 'timeout_15m', ], 'test_suites': { @@ -5147,10 +5138,7 @@ 'win-swangle-tot-swiftshader-x64' : { 'os_type': 'win', 'mixins': [ - 'gpu-swarming-pool', - 'no_gpu', - 'x86-64', - 'win10', + 'win10_gce_gpu_pool', 'timeout_15m', ], 'test_suites': { @@ -5160,10 +5148,7 @@ 'win-swangle-tot-swiftshader-x86' : { 'os_type': 'win', 'mixins': [ - 'gpu-swarming-pool', - 'no_gpu', - 'x86-64', - 'win10', + 'win10_gce_gpu_pool', 'timeout_15m', ], 'test_suites': { @@ -5173,10 +5158,7 @@ 'win-swangle-x64' : { 'os_type': 'win', 'mixins': [ - 'gpu-swarming-pool', - 'no_gpu', - 'x86-64', - 'win10', + 'win10_gce_gpu_pool', 'timeout_15m', ], 'test_suites': { @@ -5186,10 +5168,7 @@ 'win-swangle-x86' : { 'os_type': 'win', 'mixins': [ - 'gpu-swarming-pool', - 'no_gpu', - 'x86-64', - 'win10', + 'win10_gce_gpu_pool', 'timeout_15m', ], 'test_suites': {
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 9069f63..a915c46 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -147,6 +147,27 @@ ] } ], + "AndroidInProductHelpContextualSearchPromoteLongpress": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "PromoteLongpressExperiment", + "params": { + "availability": "any", + "event_trigger": "name:longpress_bubble_shown;comparator:<6;window:90;storage:90", + "event_used": "name:contextual_search_panel_opened_after_longpress;comparator:==0;window:365;storage:365", + "session_rate": "<1" + }, + "enable_features": [ + "IPH_ContextualSearchTappedButShouldLongpress" + ] + } + ] + } + ], "AndroidInProductHelpContextualSearchPromotePanelOpen": [ { "platforms": [ @@ -1829,16 +1850,8 @@ "experiments": [ { "name": "ContextualSearchLongpressResolve", - "params": { - "availability": "any", - "event_longpress_opened": "name:contextual_search_panel_opened_after_longpress;comparator:==0;window:365;storage:365", - "event_trigger": "name:longpress_bubble_shown;comparator:<3;window:90;storage:90", - "event_used": "name:contextual_search_triggered_by_longpress;comparator:==0;window:90;storage:90", - "session_rate": "any" - }, "enable_features": [ - "ContextualSearchLongpressResolve", - "IPH_ContextualSearchTappedButShouldLongpress" + "ContextualSearchLongpressResolve" ] } ] @@ -1852,8 +1865,15 @@ "experiments": [ { "name": "ContextualSearchTranslations", + "params": { + "availability": "any", + "event_trigger": "name:translations_bubble_shown;comparator:<5;window:90;storage:90", + "event_used": "name:contextual_search_enabled_opt_in;comparator:==0;window:365;storage:365", + "session_rate": "<1" + }, "enable_features": [ - "ContextualSearchTranslations" + "ContextualSearchTranslations", + "IPH_ContextualSearchTranslationEnable" ] } ]
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index efd13fc..6e43d421 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -521,6 +521,10 @@ const base::Feature kDawn2dCanvas{"Dawn2dCanvas", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enables small accelerated canvases for webview (crbug.com/1004304) +const base::Feature kWebviewAccelerateSmallCanvases{ + "WebviewAccelerateSmallCanvases", base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kCSSReducedFontLoadingLayoutInvalidations{ "CSSReducedFontLoadingLayoutInvalidations", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index eb42c94..0576d8a 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -158,6 +158,8 @@ BLINK_COMMON_EXPORT extern const base::Feature kDawn2dCanvas; +BLINK_COMMON_EXPORT extern const base::Feature kWebviewAccelerateSmallCanvases; + BLINK_COMMON_EXPORT extern const base::Feature kCSSReducedFontLoadingLayoutInvalidations;
diff --git a/third_party/blink/public/web/web_navigation_params.h b/third_party/blink/public/web/web_navigation_params.h index 122b5e7..1ea6790 100644 --- a/third_party/blink/public/web/web_navigation_params.h +++ b/third_party/blink/public/web/web_navigation_params.h
@@ -172,8 +172,8 @@ network::mojom::IPAddressSpace::kUnknown; // The frame policy specified by the frame owner element. - // Should be base::nullopt for top level navigations - base::Optional<FramePolicy> frame_policy; + // For top-level window with no opener, this is the default lax FramePolicy. + FramePolicy frame_policy; }; // This structure holds all information provided by the embedder that is
diff --git a/third_party/blink/renderer/core/accessibility/ax_context.cc b/third_party/blink/renderer/core/accessibility/ax_context.cc index 8fb146c..deb84151 100644 --- a/third_party/blink/renderer/core/accessibility/ax_context.cc +++ b/third_party/blink/renderer/core/accessibility/ax_context.cc
@@ -29,4 +29,8 @@ return document_ && document_->IsActive(); } +Document* AXContext::GetDocument() { + return document_; +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/accessibility/ax_context.h b/third_party/blink/renderer/core/accessibility/ax_context.h index 55a4dcaa..5d99362a 100644 --- a/third_party/blink/renderer/core/accessibility/ax_context.h +++ b/third_party/blink/renderer/core/accessibility/ax_context.h
@@ -34,6 +34,8 @@ // (i.e. document has been initialized and hasn't been detached yet). bool HasActiveDocument(); + Document* GetDocument(); + protected: WeakPersistent<Document> document_; };
diff --git a/third_party/blink/renderer/core/animation/css_default_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_default_interpolation_type.cc index ab08978..95656fdb 100644 --- a/third_party/blink/renderer/core/animation/css_default_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_default_interpolation_type.cc
@@ -7,7 +7,6 @@ #include "third_party/blink/renderer/core/animation/css_interpolation_environment.h" #include "third_party/blink/renderer/core/animation/string_keyframe.h" #include "third_party/blink/renderer/core/css/resolver/style_builder.h" -#include "third_party/blink/renderer/core/css/scoped_css_value.h" namespace blink { @@ -49,9 +48,7 @@ StyleBuilder::ApplyProperty( GetProperty().GetCSSPropertyName(), To<CSSInterpolationEnvironment>(environment).GetState(), - ScopedCSSValue(*To<CSSDefaultNonInterpolableValue>(non_interpolable_value) - ->CssValue(), - nullptr)); + *To<CSSDefaultNonInterpolableValue>(non_interpolable_value)->CssValue()); } } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/css_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_interpolation_type.cc index 69d289d..ffe1dab 100644 --- a/third_party/blink/renderer/core/animation/css_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_interpolation_type.cc
@@ -24,7 +24,6 @@ #include "third_party/blink/renderer/core/css/resolver/style_builder.h" #include "third_party/blink/renderer/core/css/resolver/style_cascade.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" -#include "third_party/blink/renderer/core/css/scoped_css_value.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/style/data_equivalency.h" #include "third_party/blink/renderer/core/style_property_shorthand.h" @@ -337,7 +336,7 @@ const CSSValue* value = MakeGarbageCollected<CSSCustomPropertyDeclaration>( property.CustomPropertyName(), std::move(variable_data)); StyleBuilder::ApplyProperty(GetProperty().GetCSSPropertyName(), state, - ScopedCSSValue(*value, nullptr)); + *value); } } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc index 12c18f3..93b6a92 100644 --- a/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc
@@ -13,7 +13,6 @@ #include "third_party/blink/renderer/core/css/css_identifier_value.h" #include "third_party/blink/renderer/core/css/resolver/style_builder.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" -#include "third_party/blink/renderer/core/css/scoped_css_value.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/platform/geometry/length_functions.h" @@ -146,9 +145,8 @@ Length before; Length after; DCHECK(LengthPropertyFunctions::GetLength(CssProperty(), style, before)); - StyleBuilder::ApplyProperty( - GetProperty().GetCSSProperty(), state, - ScopedCSSValue(*CSSValue::Create(length, zoom), nullptr)); + StyleBuilder::ApplyProperty(GetProperty().GetCSSProperty(), state, + *CSSValue::Create(length, zoom)); DCHECK(LengthPropertyFunctions::GetLength(CssProperty(), style, after)); DCHECK(before.IsSpecified()); DCHECK(after.IsSpecified()); @@ -164,9 +162,8 @@ #endif return; } - StyleBuilder::ApplyProperty( - GetProperty().GetCSSProperty(), state, - ScopedCSSValue(*CSSValue::Create(length, zoom), nullptr)); + StyleBuilder::ApplyProperty(GetProperty().GetCSSProperty(), state, + *CSSValue::Create(length, zoom)); } } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc index 4d9393f..e24be066 100644 --- a/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc
@@ -12,7 +12,6 @@ #include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/resolver/style_builder.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" -#include "third_party/blink/renderer/core/css/scoped_css_value.h" namespace blink { @@ -111,10 +110,8 @@ clamped_number)) { StyleBuilder::ApplyProperty( GetProperty().GetCSSProperty(), state, - ScopedCSSValue( - *CSSNumericLiteralValue::Create( - clamped_number, CSSPrimitiveValue::UnitType::kNumber), - nullptr)); + *CSSNumericLiteralValue::Create(clamped_number, + CSSPrimitiveValue::UnitType::kNumber)); } }
diff --git a/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc index 226e20f..ecf85c20 100644 --- a/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc
@@ -14,7 +14,6 @@ #include "third_party/blink/renderer/core/css/property_registration.h" #include "third_party/blink/renderer/core/css/resolver/style_builder.h" #include "third_party/blink/renderer/core/css/resolver/style_cascade.h" -#include "third_party/blink/renderer/core/css/scoped_css_value.h" #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { @@ -117,10 +116,8 @@ StyleBuilder::ApplyProperty( GetProperty().GetCSSPropertyName(), To<CSSInterpolationEnvironment>(environment).GetState(), - ScopedCSSValue( - *MakeGarbageCollected<CSSCustomPropertyDeclaration>( - GetProperty().CustomPropertyName(), CSSValueID::kUnset), - nullptr)); + *MakeGarbageCollected<CSSCustomPropertyDeclaration>( + GetProperty().CustomPropertyName(), CSSValueID::kUnset)); } } // namespace blink
diff --git a/third_party/blink/renderer/core/css/BUILD.gn b/third_party/blink/renderer/core/css/BUILD.gn index 3f40690..a694146 100644 --- a/third_party/blink/renderer/core/css/BUILD.gn +++ b/third_party/blink/renderer/core/css/BUILD.gn
@@ -533,7 +533,6 @@ "rule_feature_set.h", "rule_set.cc", "rule_set.h", - "scoped_css_value.h", "select_rule_feature_set.cc", "select_rule_feature_set.h", "selector_checker.cc",
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 4cbee31..5b94719 100644 --- a/third_party/blink/renderer/core/css/media_query_evaluator.cc +++ b/third_party/blink/renderer/core/css/media_query_evaluator.cc
@@ -159,6 +159,7 @@ bool MediaQueryEvaluator::DidResultsChange( const MediaQueryResultList& results) const { + base::AutoReset<bool> skip(&skip_ukm_reporting_, true); for (auto& result : results) { if (Eval(result.Expression()) != result.Result()) return true; @@ -166,6 +167,16 @@ return false; } +bool MediaQueryEvaluator::DidResultsChange( + const Vector<MediaQuerySetResult>& results) const { + base::AutoReset<bool> skip(&skip_ukm_reporting_, true); + for (const auto& result : results) { + if (result.Result() != Eval(result.MediaQueries())) + return true; + } + return false; +} + template <typename T> bool CompareValue(T a, T b, MediaFeaturePrefix op) { switch (op) {
diff --git a/third_party/blink/renderer/core/css/media_query_evaluator.h b/third_party/blink/renderer/core/css/media_query_evaluator.h index a5502987..3a2f09d 100644 --- a/third_party/blink/renderer/core/css/media_query_evaluator.h +++ b/third_party/blink/renderer/core/css/media_query_evaluator.h
@@ -38,6 +38,7 @@ class MediaQueryExp; class MediaQueryResult; class MediaQuerySet; +class MediaQuerySetResult; class MediaValues; class MediaValuesInitialViewport; @@ -98,6 +99,10 @@ // evaluation. bool DidResultsChange(const MediaQueryResultList& results) const; + // Returns true if any of the media queries in the results lists changed its + // evaluation. + bool DidResultsChange(const Vector<MediaQuerySetResult>& results) const; + void Trace(Visitor*) const; private: @@ -105,6 +110,10 @@ String media_type_; Member<MediaValues> media_values_; + + // Even if UKM reporting is enabled, do not report any media query evaluation + // results if this is set to true. + mutable bool skip_ukm_reporting_{false}; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/css_property_test.cc b/third_party/blink/renderer/core/css/properties/css_property_test.cc index 7495249a..eda96e1 100644 --- a/third_party/blink/renderer/core/css/properties/css_property_test.cc +++ b/third_party/blink/renderer/core/css/properties/css_property_test.cc
@@ -10,7 +10,6 @@ #include "third_party/blink/renderer/core/css/properties/css_property_ref.h" #include "third_party/blink/renderer/core/css/resolver/style_builder.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" -#include "third_party/blink/renderer/core/css/scoped_css_value.h" #include "third_party/blink/renderer/core/html/html_element.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/style/data_equivalency.h" @@ -43,8 +42,7 @@ state.Style()->SetBorderRightStyle(EBorderStyle::kSolid); state.Style()->SetBorderTopStyle(EBorderStyle::kSolid); - StyleBuilder::ApplyProperty(property, state, - ScopedCSSValue(value, &GetDocument())); + StyleBuilder::ApplyProperty(property, state, value); return state.TakeStyle(); } };
diff --git a/third_party/blink/renderer/core/css/resolver/cascade_expansion.cc b/third_party/blink/renderer/core/css/resolver/cascade_expansion.cc index 29185ff..6162211 100644 --- a/third_party/blink/renderer/core/css/resolver/cascade_expansion.cc +++ b/third_party/blink/renderer/core/css/resolver/cascade_expansion.cc
@@ -186,8 +186,4 @@ return matched_properties_.properties->PropertyAt(index_); } -uint16_t CascadeExpansion::TreeOrder() const { - return matched_properties_.types_.tree_order; -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/css/resolver/cascade_expansion.h b/third_party/blink/renderer/core/css/resolver/cascade_expansion.h index f1090cd..af6d8d2c 100644 --- a/third_party/blink/renderer/core/css/resolver/cascade_expansion.h +++ b/third_party/blink/renderer/core/css/resolver/cascade_expansion.h
@@ -98,7 +98,6 @@ return PropertyAt(index_).Value(); } inline CascadePriority Priority() const { return priority_; } - uint16_t TreeOrder() const; private: static bool IsAffectedByAll(CSSPropertyID);
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder.cc b/third_party/blink/renderer/core/css/resolver/style_builder.cc index 29ea83ab..7b72837 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder.cc +++ b/third_party/blink/renderer/core/css/resolver/style_builder.cc
@@ -48,29 +48,27 @@ #include "third_party/blink/renderer/core/css/properties/longhands/variable.h" #include "third_party/blink/renderer/core/css/resolver/style_builder.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" -#include "third_party/blink/renderer/core/css/scoped_css_value.h" #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { void StyleBuilder::ApplyProperty(const CSSPropertyName& name, StyleResolverState& state, - const ScopedCSSValue& scoped_value) { + const CSSValue& value) { CSSPropertyRef ref(name, state.GetDocument()); DCHECK(ref.IsValid()); - ApplyProperty(ref.GetProperty(), state, scoped_value); + ApplyProperty(ref.GetProperty(), state, value); } void StyleBuilder::ApplyProperty(const CSSProperty& property, StyleResolverState& state, - const ScopedCSSValue& scoped_value) { + const CSSValue& value) { DCHECK(!Variable::IsStaticInstance(property)) << "Please use a CustomProperty instance to apply custom properties"; CSSPropertyID id = property.PropertyID(); bool is_inherited = property.IsInherited(); - const CSSValue& value = scoped_value.GetCSSValue(); // These values must be resolved by StyleCascade before application: DCHECK(!value.IsVariableReferenceValue());
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder.h b/third_party/blink/renderer/core/css/resolver/style_builder.h index 5b20d50..455e2f8 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder.h +++ b/third_party/blink/renderer/core/css/resolver/style_builder.h
@@ -39,7 +39,7 @@ namespace blink { class CSSPropertyName; -class ScopedCSSValue; +class CSSValue; class StyleResolverState; class CORE_EXPORT StyleBuilder { @@ -52,7 +52,7 @@ // CustomProperty instance is created to carry out the application. static void ApplyProperty(const CSSPropertyName&, StyleResolverState&, - const ScopedCSSValue&); + const CSSValue&); // Apply a property/value pair to the ComputedStyle. // @@ -61,7 +61,7 @@ // instance. See Variable::IsStaticInstance. static void ApplyProperty(const CSSProperty&, StyleResolverState&, - const ScopedCSSValue&); + const CSSValue&); }; } // namespace blink
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_test.cc b/third_party/blink/renderer/core/css/resolver/style_builder_test.cc index 323666b..4952293 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder_test.cc +++ b/third_party/blink/renderer/core/css/resolver/style_builder_test.cc
@@ -7,7 +7,6 @@ #include "third_party/blink/renderer/core/css/css_inherited_value.h" #include "third_party/blink/renderer/core/css/css_initial_value.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" -#include "third_party/blink/renderer/core/css/scoped_css_value.h" #include "third_party/blink/renderer/core/html/html_element.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" @@ -42,8 +41,7 @@ state.SetStyle(style); ASSERT_FALSE(state.GetFontBuilder().FontDirty()); - StyleBuilder::ApplyProperty(*property, state, - ScopedCSSValue(*value, &GetDocument())); + StyleBuilder::ApplyProperty(*property, state, *value); EXPECT_TRUE(state.GetFontBuilder().FontDirty()); } } @@ -74,8 +72,7 @@ state.SetStyle(style); ASSERT_FALSE(state.GetFontBuilder().FontDirty()); - StyleBuilder::ApplyProperty(*property, state, - ScopedCSSValue(*value, &GetDocument())); + StyleBuilder::ApplyProperty(*property, state, *value); EXPECT_TRUE(state.GetFontBuilder().FontDirty()); } } @@ -89,14 +86,13 @@ state.SetStyle(style); EXPECT_FALSE(style->HasExplicitInheritance()); - ScopedCSSValue inherited(*CSSInheritedValue::Create(), &GetDocument()); - // Flag should not be set for properties which are inherited. - StyleBuilder::ApplyProperty(GetCSSPropertyColor(), state, inherited); + StyleBuilder::ApplyProperty(GetCSSPropertyColor(), state, + *CSSInheritedValue::Create()); EXPECT_FALSE(style->HasExplicitInheritance()); StyleBuilder::ApplyProperty(GetCSSPropertyBackgroundColor(), state, - inherited); + *CSSInheritedValue::Create()); EXPECT_TRUE(style->HasExplicitInheritance()); }
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade.cc b/third_party/blink/renderer/core/css/resolver/style_cascade.cc index a8bd278..34237b59 100644 --- a/third_party/blink/renderer/core/css/resolver/style_cascade.cc +++ b/third_party/blink/renderer/core/css/resolver/style_cascade.cc
@@ -28,7 +28,6 @@ #include "third_party/blink/renderer/core/css/resolver/cascade_resolver.h" #include "third_party/blink/renderer/core/css/resolver/style_builder.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" -#include "third_party/blink/renderer/core/css/scoped_css_value.h" #include "third_party/blink/renderer/core/css/style_engine.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/frame/web_feature.h" @@ -81,14 +80,6 @@ return &set->PropertyAt(declaration_index).Value(); } -const TreeScope& TreeScopeAt(const MatchResult& result, uint32_t position) { - size_t matched_properties_index = DecodeMatchedPropertiesIndex(position); - const MatchedProperties& properties = - result.GetMatchedProperties()[matched_properties_index]; - DCHECK_EQ(properties.types_.origin, CascadeOrigin::kAuthor); - return result.ScopeFromTreeOrder(properties.types_.tree_order); -} - PropertyHandle ToPropertyHandle(const CSSProperty& property, CascadePriority priority) { uint32_t position = priority.GetPosition(); @@ -406,14 +397,7 @@ *p = priority; CascadeOrigin origin = priority.GetOrigin(); const CSSValue* value = Resolve(property, e.Value(), origin, resolver); - // TODO(futhark): Use a user scope TreeScope to support tree-scoped names - // for animations in user stylesheets. - const TreeScope* tree_scope = - origin == CascadeOrigin::kAuthor - ? &match_result_.ScopeFromTreeOrder(e.TreeOrder()) - : nullptr; - StyleBuilder::ApplyProperty(property, state_, - ScopedCSSValue(*value, tree_scope)); + StyleBuilder::ApplyProperty(property, state_, *value); } } } @@ -540,11 +524,7 @@ value = Resolve(property, *value, origin, resolver); DCHECK(!value->IsVariableReferenceValue()); DCHECK(!value->IsPendingSubstitutionValue()); - const TreeScope* tree_scope{nullptr}; - if (origin == CascadeOrigin::kAuthor) - tree_scope = &TreeScopeAt(match_result_, priority.GetPosition()); - StyleBuilder::ApplyProperty(property, state_, - ScopedCSSValue(*value, tree_scope)); + StyleBuilder::ApplyProperty(property, state_, *value); } void StyleCascade::LookupAndApplyInterpolation(const CSSProperty& property, @@ -622,14 +602,11 @@ MaybeForceColor(GetCSSPropertyInternalVisitedTextEmphasisColor(), style->InternalVisitedTextEmphasisColor()); - ScopedCSSValue scoped_none(*CSSIdentifierValue::Create(CSSValueID::kNone), - nullptr); - StyleBuilder::ApplyProperty(GetCSSPropertyTextShadow(), state_, scoped_none); - StyleBuilder::ApplyProperty(GetCSSPropertyBoxShadow(), state_, scoped_none); - if (!style->HasUrlBackgroundImage()) { - StyleBuilder::ApplyProperty(GetCSSPropertyBackgroundImage(), state_, - scoped_none); - } + auto* none = CSSIdentifierValue::Create(CSSValueID::kNone); + StyleBuilder::ApplyProperty(GetCSSPropertyTextShadow(), state_, *none); + StyleBuilder::ApplyProperty(GetCSSPropertyBoxShadow(), state_, *none); + if (!style->HasUrlBackgroundImage()) + StyleBuilder::ApplyProperty(GetCSSPropertyBackgroundImage(), state_, *none); // Preserve the author/user defined background alpha channel. style->SetBackgroundColor( @@ -651,9 +628,7 @@ return; StyleBuilder::ApplyProperty( - property, state_, - ScopedCSSValue(*GetForcedColorValue(property.GetCSSPropertyName()), - nullptr)); + property, state_, *GetForcedColorValue(property.GetCSSPropertyName())); } const CSSValue* StyleCascade::GetForcedColorValue(CSSPropertyName name) {
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc b/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc index 66c2f1ec..4eccc4d 100644 --- a/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc +++ b/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc
@@ -125,12 +125,12 @@ } void Apply(CascadeFilter filter = CascadeFilter()) { - EnsureAtLeast(CascadeOrigin::kAnimation); + EnsureAtLeast(CascadeOrigin::kAuthor); cascade_.Apply(filter); } void ApplySingle(const CSSProperty& property) { - EnsureAtLeast(CascadeOrigin::kAnimation); + EnsureAtLeast(CascadeOrigin::kAuthor); cascade_.AnalyzeIfNeeded(); TestCascadeResolver resolver(++cascade_.generation_); cascade_.LookupAndApply(property, resolver.InnerResolver()); @@ -234,12 +234,6 @@ current_origin_ = CascadeOrigin::kAuthor; break; case CascadeOrigin::kAuthor: - cascade_.MutableMatchResult().FinishAddingAuthorRulesForTreeScope( - GetDocument()); - current_origin_ = CascadeOrigin::kAnimation; - break; - case CascadeOrigin::kAnimation: - break; default: NOTREACHED(); break;
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc index 76d6f2df..8717609 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -62,7 +62,6 @@ #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver_stats.h" #include "third_party/blink/renderer/core/css/resolver/style_rule_usage_tracker.h" -#include "third_party/blink/renderer/core/css/scoped_css_value.h" #include "third_party/blink/renderer/core/css/style_engine.h" #include "third_party/blink/renderer/core/css/style_rule_import.h" #include "third_party/blink/renderer/core/css/style_sheet_contents.h" @@ -1083,8 +1082,6 @@ cascade.MutableMatchResult().FinishAddingUARules(); cascade.MutableMatchResult().FinishAddingUserRules(); cascade.MutableMatchResult().AddMatchedProperties(set); - cascade.MutableMatchResult().FinishAddingAuthorRulesForTreeScope( - element.GetTreeScope()); cascade.Apply(); } return CompositorKeyframeValueFactory::Create(property, *state.Style()); @@ -1663,8 +1660,6 @@ cascade.MutableMatchResult().FinishAddingUARules(); cascade.MutableMatchResult().FinishAddingUserRules(); cascade.MutableMatchResult().AddMatchedProperties(set); - cascade.MutableMatchResult().FinishAddingAuthorRulesForTreeScope( - element->GetTreeScope()); cascade.Apply(); CSSPropertyRef property_ref(property_name, element->GetDocument()); @@ -1790,14 +1785,9 @@ for (const CSSProperty* property : properties) { if (property->IDEquals(CSSPropertyID::kLineHeight)) UpdateFont(state); - // TODO(futhark): If we start supporting fonts on ShadowRoot.fonts in - // addition to Document.fonts, we need to pass the correct TreeScope instead - // of GetDocument() in the ScopedCSSValue below. StyleBuilder::ApplyProperty( *property, state, - ScopedCSSValue( - *property_set.GetPropertyCSSValue(property->PropertyID()), - &GetDocument())); + *property_set.GetPropertyCSSValue(property->PropertyID())); } }
diff --git a/third_party/blink/renderer/core/css/rule_set.cc b/third_party/blink/renderer/core/css/rule_set.cc index 185cc3e34..afbca72f 100644 --- a/third_party/blink/renderer/core/css/rule_set.cc +++ b/third_party/blink/renderer/core/css/rule_set.cc
@@ -431,11 +431,7 @@ bool RuleSet::DidMediaQueryResultsChange( const MediaQueryEvaluator& evaluator) const { - for (const auto& result : media_query_set_results_) { - if (result.Result() != evaluator.Eval(result.MediaQueries())) - return true; - } - return false; + return evaluator.DidResultsChange(media_query_set_results_); } void MinimalRuleData::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/core/css/scoped_css_value.h b/third_party/blink/renderer/core/css/scoped_css_value.h deleted file mode 100644 index 8c9f1f7..0000000 --- a/third_party/blink/renderer/core/css/scoped_css_value.h +++ /dev/null
@@ -1,33 +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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_SCOPED_CSS_VALUE_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_SCOPED_CSS_VALUE_H_ - -namespace blink { - -class CSSValue; -class TreeScope; - -// Store a CSSValue along with a TreeScope to support tree-scoped names and -// references for e.g. @font-face/font-family and @keyframes/animation-name. -// If the TreeScope pointer is null, we do not support such references, for -// instance for UA stylesheets. -class ScopedCSSValue { - STACK_ALLOCATED(); - - public: - ScopedCSSValue(const CSSValue& value, const TreeScope* tree_scope) - : value_(value), tree_scope_(tree_scope) {} - const CSSValue& GetCSSValue() const { return value_; } - const TreeScope* GetTreeScope() const { return tree_scope_; } - - private: - const CSSValue& value_; - const TreeScope* tree_scope_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_SCOPED_CSS_VALUE_H_
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index a113cc58b..06c24ca 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -2195,10 +2195,7 @@ } } else if (name == html_names::kClassAttr) { ClassAttributeChanged(params.new_value); - if (HasRareData() && GetElementRareData()->GetClassList()) { - GetElementRareData()->GetClassList()->DidUpdateAttributeValue( - params.old_value, params.new_value); - } + UpdateClassList(params.old_value, params.new_value); } else if (name == html_names::kNameAttr) { SetHasName(!params.new_value.IsNull()); } else if (name == html_names::kPartAttr) { @@ -2302,6 +2299,14 @@ } } +void Element::UpdateClassList(const AtomicString& old_class_string, + const AtomicString& new_class_string) { + if (!HasRareData()) + return; + if (DOMTokenList* class_list = GetElementRareData()->GetClassList()) + class_list->DidUpdateAttributeValue(old_class_string, new_class_string); +} + bool Element::ShouldInvalidateDistributionWhenAttributeChanged( ShadowRoot& shadow_root, const QualifiedName& name,
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h index 39d31f21..3229ad32 100644 --- a/third_party/blink/renderer/core/dom/element.h +++ b/third_party/blink/renderer/core/dom/element.h
@@ -975,10 +975,13 @@ // create layout objects is completed (e.g. in display-locked trees). bool IsFocusableStyleAfterUpdate() const; - // classAttributeChanged() exists to share code between - // parseAttribute (called via setAttribute()) and - // svgAttributeChanged (called when element.className.baseValue is set) + // ClassAttributeChanged() and UpdateClassList() exist to share code between + // ParseAttribute (called via setAttribute()) and SvgAttributeChanged (called + // when element.className.baseVal is set or when the 'class' attribute is + // animated by SMIL). void ClassAttributeChanged(const AtomicString& new_class_string); + void UpdateClassList(const AtomicString& old_class_string, + const AtomicString& new_class_string); static bool AttributeValueIsJavaScriptURL(const Attribute&);
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc index 168056e4..b7388db 100644 --- a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc +++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
@@ -691,7 +691,7 @@ auto* owner = ToCoreFrame(web_frame_)->Owner(); navigation_info->frame_policy = - owner ? base::make_optional(owner->GetFramePolicy()) : base::nullopt; + owner ? owner->GetFramePolicy() : FramePolicy(); navigation_info->href_translate = href_translate;
diff --git a/third_party/blink/renderer/core/frame/history.cc b/third_party/blink/renderer/core/frame/history.cc index 49b0c1b..022ca524 100644 --- a/third_party/blink/renderer/core/frame/history.cc +++ b/third_party/blink/renderer/core/frame/history.cc
@@ -28,20 +28,16 @@ #include "third_party/blink/public/mojom/web_feature/web_feature.mojom-shared.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" -#include "third_party/blink/renderer/core/frame/frame_console.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_client.h" -#include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/core/loader/document_loader.h" -#include "third_party/blink/renderer/core/loader/frame_loader.h" #include "third_party/blink/renderer/core/loader/history_item.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/heap/heap.h" -#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/wtf/text/string_view.h" @@ -71,13 +67,13 @@ } unsigned History::length(ExceptionState& exception_state) const { - if (!GetFrame() || !GetFrame()->Client()) { + if (!DomWindow()) { exception_state.ThrowSecurityError( "May not use a History object associated with a Document that is not " "fully active"); return 0; } - return GetFrame()->Client()->BackForwardLength(); + return DomWindow()->GetFrame()->Client()->BackForwardLength(); } ScriptValue History::state(ScriptState* script_state, @@ -101,7 +97,7 @@ return ScriptValue(isolate, v8_state); } - if (!GetFrame()) { + if (!DomWindow()) { exception_state.ThrowSecurityError( "May not use a History object associated with a Document that is " "not fully active"); @@ -119,21 +115,15 @@ } SerializedScriptValue* History::StateInternal() const { - if (!GetFrame() || !GetFrame()->Loader().GetDocumentLoader()) - return nullptr; - - if (HistoryItem* history_item = - GetFrame()->Loader().GetDocumentLoader()->GetHistoryItem()) { + if (HistoryItem* history_item = GetHistoryItem()) return history_item->StateObject(); - } - return nullptr; } void History::setScrollRestoration(const String& value, ExceptionState& exception_state) { DCHECK(value == "manual" || value == "auto"); - if (!GetFrame() || !GetFrame()->Client()) { + if (!DomWindow()) { exception_state.ThrowSecurityError( "May not use a History object associated with a Document that is not " "fully active"); @@ -146,15 +136,12 @@ if (scroll_restoration == ScrollRestorationInternal()) return; - if (HistoryItem* history_item = - GetFrame()->Loader().GetDocumentLoader()->GetHistoryItem()) { - history_item->SetScrollRestorationType(scroll_restoration); - GetFrame()->Client()->DidUpdateCurrentHistoryItem(); - } + GetHistoryItem()->SetScrollRestorationType(scroll_restoration); + DomWindow()->GetFrame()->Client()->DidUpdateCurrentHistoryItem(); } String History::scrollRestoration(ExceptionState& exception_state) { - if (!GetFrame() || !GetFrame()->Client()) { + if (!DomWindow()) { exception_state.ThrowSecurityError( "May not use a History object associated with a Document that is not " "fully active"); @@ -167,22 +154,14 @@ } mojom::blink::ScrollRestorationType History::ScrollRestorationInternal() const { - constexpr mojom::blink::ScrollRestorationType default_type = - mojom::blink::ScrollRestorationType::kAuto; + if (HistoryItem* history_item = GetHistoryItem()) + return history_item->ScrollRestorationType(); + return mojom::blink::ScrollRestorationType::kAuto; +} - LocalFrame* frame = GetFrame(); - if (!frame) - return default_type; - - DocumentLoader* document_loader = frame->Loader().GetDocumentLoader(); - if (!document_loader) - return default_type; - - HistoryItem* history_item = document_loader->GetHistoryItem(); - if (!history_item) - return default_type; - - return history_item->ScrollRestorationType(); +HistoryItem* History::GetHistoryItem() const { + return DomWindow() ? DomWindow()->document()->Loader()->GetHistoryItem() + : nullptr; } bool History::IsSameAsCurrentState(SerializedScriptValue* state) const { @@ -201,7 +180,7 @@ void History::go(ScriptState* script_state, int delta, ExceptionState& exception_state) { - if (!GetFrame() || !GetFrame()->Client()) { + if (!DomWindow()) { exception_state.ThrowSecurityError( "May not use a History object associated with a Document that is not " "fully active"); @@ -216,16 +195,16 @@ if (!active_window->GetFrame() || !active_window->GetFrame()->CanNavigate(*GetFrame()) || !active_window->GetFrame()->IsNavigationAllowed() || - !GetFrame()->IsNavigationAllowed()) { + !DomWindow()->GetFrame()->IsNavigationAllowed()) { return; } - if (!GetFrame()->navigation_rate_limiter().CanProceed()) + if (!DomWindow()->GetFrame()->navigation_rate_limiter().CanProceed()) return; if (delta) { - if (GetFrame()->Client()->NavigateBackForward(delta)) { - if (Page* page = GetFrame()->GetPage()) + if (DomWindow()->GetFrame()->Client()->NavigateBackForward(delta)) { + if (Page* page = DomWindow()->GetFrame()->GetPage()) page->HistoryNavigationVirtualTimePauser().PauseVirtualTime(); } } else { @@ -233,7 +212,7 @@ // Otherwise, navigation happens on the root frame. // This behavior is designed in the following spec. // https://html.spec.whatwg.org/C/#dom-history-go - GetFrame()->Reload(WebFrameLoadType::kReload); + DomWindow()->GetFrame()->Reload(WebFrameLoadType::kReload); } } @@ -244,9 +223,8 @@ ExceptionState& exception_state) { WebFrameLoadType load_type = WebFrameLoadType::kStandard; // Navigations in portal contexts do not create back/forward entries. - if (GetFrame() && GetFrame()->GetPage() && - GetFrame()->GetPage()->InsidePortal()) { - GetFrame()->GetDocument()->AddConsoleMessage( + if (DomWindow() && DomWindow()->GetFrame()->GetPage()->InsidePortal()) { + DomWindow()->AddConsoleMessage( MakeGarbageCollected<ConsoleMessage>( mojom::ConsoleMessageSource::kJavaScript, mojom::ConsoleMessageLevel::kWarning, @@ -287,14 +265,12 @@ } KURL History::UrlForState(const String& url_string) { - Document* document = GetFrame()->GetDocument(); - if (url_string.IsNull()) - return document->Url(); + return DomWindow()->Url(); if (url_string.IsEmpty()) - return document->BaseURL(); + return DomWindow()->BaseURL(); - return KURL(document->BaseURL(), url_string); + return KURL(DomWindow()->BaseURL(), url_string); } bool History::CanChangeToUrl(const KURL& url, @@ -332,8 +308,7 @@ mojom::blink::ScrollRestorationType restoration_type, WebFrameLoadType type, ExceptionState& exception_state) { - if (!GetFrame() || !GetFrame()->GetPage() || - !GetFrame()->Loader().GetDocumentLoader()) { + if (!DomWindow()) { exception_state.ThrowSecurityError( "May not use a History object associated with a Document that is not " "fully active"); @@ -341,20 +316,20 @@ } KURL full_url = UrlForState(url_string); - if (!CanChangeToUrl(full_url, GetFrame()->DomWindow()->GetSecurityOrigin(), - GetFrame()->GetDocument()->Url())) { + if (!CanChangeToUrl(full_url, DomWindow()->GetSecurityOrigin(), + DomWindow()->Url())) { // We can safely expose the URL to JavaScript, as a) no redirection takes // place: JavaScript already had this URL, b) JavaScript can only access a // same-origin History object. exception_state.ThrowSecurityError( "A history state object with URL '" + full_url.ElidedString() + "' cannot be created in a document with origin '" + - GetFrame()->DomWindow()->GetSecurityOrigin()->ToString() + - "' and URL '" + GetFrame()->GetDocument()->Url().ElidedString() + "'."); + DomWindow()->GetSecurityOrigin()->ToString() + "' and URL '" + + DomWindow()->Url().ElidedString() + "'."); return; } - if (!GetFrame()->navigation_rate_limiter().CanProceed()) { + if (!DomWindow()->GetFrame()->navigation_rate_limiter().CanProceed()) { // TODO(769592): Get an API spec change so that we can throw an exception: // // exception_state.ThrowDOMException(DOMExceptionCode::kQuotaExceededError, @@ -365,9 +340,9 @@ return; } - GetFrame()->GetDocument()->Loader()->UpdateForSameDocumentNavigation( + DomWindow()->document()->Loader()->UpdateForSameDocumentNavigation( full_url, kSameDocumentNavigationHistoryApi, std::move(data), - restoration_type, type, GetFrame()->GetDocument()); + restoration_type, type, DomWindow()->document()); } } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/history.h b/third_party/blink/renderer/core/frame/history.h index a228714..84d8edd 100644 --- a/third_party/blink/renderer/core/frame/history.h +++ b/third_party/blink/renderer/core/frame/history.h
@@ -41,6 +41,7 @@ class LocalFrame; class KURL; class ExceptionState; +class HistoryItem; class SecurityOrigin; class ScriptState; @@ -97,6 +98,7 @@ ExceptionState&); SerializedScriptValue* StateInternal() const; mojom::blink::ScrollRestorationType ScrollRestorationInternal() const; + HistoryItem* GetHistoryItem() const; scoped_refptr<SerializedScriptValue> last_state_object_requested_; };
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc index 62f85d6e..7587a08 100644 --- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc +++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
@@ -1136,8 +1136,11 @@ return false; } - // Webview crashes with accelerated small canvases TODO(crbug.com/1004304) - if (!RuntimeEnabledFeatures::AcceleratedSmallCanvasesEnabled()) { + // Webview crashes with accelerated small canvases (crbug.com/1004304) + // Experimenting to see if this still causes crashes (crbug.com/1136603) + if (!RuntimeEnabledFeatures::AcceleratedSmallCanvasesEnabled() && + !base::FeatureList::IsEnabled( + features::kWebviewAccelerateSmallCanvases)) { base::CheckedNumeric<int> checked_canvas_pixel_count = Size().Width() * Size().Height(); if (!checked_canvas_pixel_count.IsValid())
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc index 6911d05..435b7be 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc
@@ -35,6 +35,7 @@ SetSpecifiedTracks(); DetermineExplicitTrackStarts(); ConstructAndAppendGridItems(); + // TODO(janewman): Split placement into its own GridLayoutAlgorithmState NGGridPlacement( automatic_row_repetitions_, automatic_column_repetitions_, @@ -61,6 +62,7 @@ algorithm_row_track_collection_ = NGGridLayoutAlgorithmTrackCollection( block_row_track_collection_, is_content_box_block_size_indefinite); + CacheItemSetIndices(); state_ = GridLayoutAlgorithmState::kResolvingInlineSize; break; } @@ -155,10 +157,19 @@ return span.EndLine(); } +wtf_size_t NGGridLayoutAlgorithm::GridItemData::SpanSize( + GridTrackSizingDirection track_direction) const { + const GridSpan& span = (track_direction == kForColumns) + ? resolved_position.columns + : resolved_position.rows; + DCHECK(span.IsTranslatedDefinite()); + return span.IntegerSpan(); +} + const GridSpan& NGGridLayoutAlgorithm::GridItemData::Span( - GridTrackSizingDirection direction) const { - return (direction == kForColumns) ? resolved_position.columns - : resolved_position.rows; + GridTrackSizingDirection track_direction) const { + return (track_direction == kForColumns) ? resolved_position.columns + : resolved_position.rows; } void NGGridLayoutAlgorithm::GridItemData::SetSpan( @@ -184,6 +195,12 @@ return items_ != other.items_ || current_index_ != other.current_index_; } +NGGridLayoutAlgorithm::GridItemData* +NGGridLayoutAlgorithm::ReorderedGridItems::Iterator::operator->() { + DCHECK_LT(*current_index_, items_->size()); + return &(items_->at(*current_index_)); +} + NGGridLayoutAlgorithm::GridItemData& NGGridLayoutAlgorithm::ReorderedGridItems::Iterator::operator*() { DCHECK_LT(*current_index_, items_->size()); @@ -222,6 +239,43 @@ : algorithm_row_track_collection_; } +NGGridLayoutAlgorithmTrackCollection::SetIterator +NGGridLayoutAlgorithm::GetSetIteratorForItem( + const GridItemData& item, + GridTrackSizingDirection track_direction) { + auto& track_collection = TrackCollection(track_direction); + return track_collection.GetSetIterator( + (track_direction == kForColumns) ? item.columns_begin_set_index + : item.rows_begin_set_index, + (track_direction == kForColumns) ? item.columns_end_set_index + : item.rows_end_set_index); +} + +// TODO(ethavar): Current implementation of this method simply returns the +// preferred size of the grid item in the relevant direction. We should follow +// the definitions from https://drafts.csswg.org/css-grid-1/#algo-spanning-items +// (i.e. compute minimum, min-content, and max-content contributions). +LayoutUnit NGGridLayoutAlgorithm::ContributionSizeForGridItem( + const GridItemData& grid_item, + GridTrackSizingDirection track_direction, + NGGridItemContributionType contribution_type) const { + const ComputedStyle& grid_item_style = grid_item.node.Style(); + GridTrackSizingDirection grid_item_track_direction = track_direction; + + bool is_orthogonal_grid_item = Style().IsHorizontalWritingMode() == + grid_item_style.IsHorizontalWritingMode(); + if (is_orthogonal_grid_item) { + grid_item_track_direction = + (track_direction == kForColumns) ? kForRows : kForColumns; + } + + Length length = (grid_item_track_direction == kForColumns) + ? grid_item_style.LogicalWidth() + : grid_item_style.LogicalHeight(); + return length.IsFixed() ? MinimumValueForLength(length, kIndefiniteSize) + : LayoutUnit(); +} + void NGGridLayoutAlgorithm::ConstructAndAppendGridItems() { NGGridChildIterator iterator(Node()); for (NGBlockNode child = iterator.NextChild(); child; @@ -346,6 +400,41 @@ } } +void NGGridLayoutAlgorithm::CacheItemSetIndices() { + auto CacheItemSetIndices = [this](GridTrackSizingDirection track_direction) { + const auto& track_collection = TrackCollection(track_direction); + for (GridItemData& item : items_) { + wtf_size_t first_spanned_range = + track_collection.RangeIndexFromTrackNumber( + item.StartLine(track_direction)); + wtf_size_t last_spanned_range = + track_collection.RangeIndexFromTrackNumber( + item.EndLine(track_direction) - 1); + + DCHECK_LE(first_spanned_range, last_spanned_range); + wtf_size_t begin_set_index = + track_collection.RangeStartingSetIndex(first_spanned_range); + wtf_size_t end_set_index = + track_collection.RangeStartingSetIndex(last_spanned_range) + + track_collection.RangeSetCount(last_spanned_range); + + DCHECK_LE(begin_set_index, end_set_index); + DCHECK_LE(end_set_index, track_collection.SetCount()); + + if (track_direction == kForColumns) { + item.columns_begin_set_index = begin_set_index; + item.columns_end_set_index = end_set_index; + } else { + item.rows_begin_set_index = begin_set_index; + item.rows_end_set_index = end_set_index; + } + } + }; + + CacheItemSetIndices(kForColumns); + CacheItemSetIndices(kForRows); +} + void NGGridLayoutAlgorithm::DetermineGridItemsSpanningIntrinsicOrFlexTracks( GridTrackSizingDirection track_direction) { auto CompareGridItemsByStartLine = @@ -410,8 +499,7 @@ // https://drafts.csswg.org/css-grid-1/#algo-track-sizing void NGGridLayoutAlgorithm::ComputeUsedTrackSizes( GridTrackSizingDirection track_direction) { - NGGridLayoutAlgorithmTrackCollection& track_collection = - TrackCollection(track_direction); + auto& track_collection = TrackCollection(track_direction); LayoutUnit content_box_size = (track_direction == kForColumns) ? child_percentage_size_.inline_size : child_percentage_size_.block_size; @@ -429,7 +517,7 @@ // A fixed sizing function: Resolve to an absolute length and use that // size as the track’s initial base size. - LayoutUnit fixed_min_breadth = ValueForLength( + LayoutUnit fixed_min_breadth = MinimumValueForLength( track_size.MinTrackBreadth().length(), content_box_size); current_set.SetBaseSize(fixed_min_breadth * current_set.TrackCount()); } else { @@ -438,6 +526,8 @@ current_set.SetBaseSize(LayoutUnit()); } + // Note that, since |NGGridSet| initializes its growth limit as indefinite, + // an intrinsic or flexible sizing function needs no further resolution. if (track_size.HasFixedMaxTrackBreadth()) { DCHECK(!track_size.MaxTrackBreadth().HasPercentage() || content_box_size != kIndefiniteSize); @@ -445,17 +535,434 @@ // A fixed sizing function: Resolve to an absolute length and use that // size as the track’s initial growth limit; if the growth limit is less // than the base size, increase the growth limit to match the base size. - LayoutUnit fixed_max_breadth = ValueForLength( + LayoutUnit fixed_max_breadth = MinimumValueForLength( track_size.MaxTrackBreadth().length(), content_box_size); current_set.SetGrowthLimit( std::max(current_set.BaseSize(), fixed_max_breadth * current_set.TrackCount())); - } else { - // An intrinsic or flexible sizing function: Use an initial growth limit - // of infinity. - current_set.SetGrowthLimit(kIndefiniteSize); } } + + // 2. Resolve intrinsic track sizing functions to absolute lengths. + DetermineGridItemsSpanningIntrinsicOrFlexTracks(track_direction); + ResolveIntrinsicTrackSizes(track_direction); +} + +// Helpers for the track sizing algorithm. +namespace { + +// Returns the corresponding size to be increased by accommodating a grid item's +// contribution; for intrinsic min track sizing functions, return the base size. +// For intrinsic max track sizing functions, return the growth limit. +static LayoutUnit AffectedSizeForContribution( + const NGGridSet& set, + NGGridItemContributionType contribution_type) { + switch (contribution_type) { + case NGGridItemContributionType::kForIntrinsicMinimums: + case NGGridItemContributionType::kForContentBasedMinimums: + case NGGridItemContributionType::kForMaxContentMinimums: + return set.BaseSize(); + case NGGridItemContributionType::kForIntrinsicMaximums: + case NGGridItemContributionType::kForMaxContentMaximums: + LayoutUnit growth_limit = set.GrowthLimit(); + // For infinite growth limits, substitute with the track's base size. + if (growth_limit == kIndefiniteSize) + return set.BaseSize(); + return growth_limit; + } +} + +static void GrowAffectedSizeByPlannedIncrease( + NGGridSet& set, + NGGridItemContributionType contribution_type) { + switch (contribution_type) { + case NGGridItemContributionType::kForIntrinsicMinimums: + case NGGridItemContributionType::kForContentBasedMinimums: + case NGGridItemContributionType::kForMaxContentMinimums: + set.SetBaseSize(set.BaseSize() + set.PlannedIncrease()); + break; + case NGGridItemContributionType::kForIntrinsicMaximums: + case NGGridItemContributionType::kForMaxContentMaximums: + LayoutUnit growth_limit = set.GrowthLimit(); + // If the affected size to grow is an infinite growth limit, set it to the + // track's base size plus the planned increase. + if (growth_limit == kIndefiniteSize) + set.SetGrowthLimit(set.BaseSize() + set.PlannedIncrease()); + else + set.SetGrowthLimit(growth_limit + set.PlannedIncrease()); + break; + } +} + +// Returns true if a set should increase its used size according to the steps in +// https://drafts.csswg.org/css-grid-1/#algo-spanning-items; false otherwise. +static bool IsContributionAppliedToSet( + const NGGridSet& set, + NGGridItemContributionType contribution_type) { + switch (contribution_type) { + case NGGridItemContributionType::kForIntrinsicMinimums: + return set.TrackSize().HasIntrinsicMinTrackBreadth(); + case NGGridItemContributionType::kForContentBasedMinimums: + return set.TrackSize().HasMinOrMaxContentMinTrackBreadth(); + case NGGridItemContributionType::kForMaxContentMinimums: + // TODO(ethavar): Check if the grid container is being sized under a + // 'max-content' constraint to consider 'auto' min track sizing functions, + // see https://drafts.csswg.org/css-grid-1/#track-size-max-content-min. + return set.TrackSize().HasMaxContentMinTrackBreadth(); + case NGGridItemContributionType::kForIntrinsicMaximums: + return set.TrackSize().HasIntrinsicMaxTrackBreadth(); + case NGGridItemContributionType::kForMaxContentMaximums: + return set.TrackSize().HasMaxContentOrAutoMaxTrackBreadth(); + } +} + +// https://drafts.csswg.org/css-grid-1/#extra-space +// Returns true if a set's used size should be consider to grow beyond its limit +// (see the "Distribute space beyond limits" section); otherwise, false. +// Note that we will deliberately return false in cases where we don't have a +// collection of tracks different than "all affected tracks". +static bool ShouldUsedSizeGrowBeyondLimit( + const NGGridSet& set, + NGGridItemContributionType contribution_type) { + // This function assumes that we already determined that extra space + // distribution will be applied to the specified set. + DCHECK(IsContributionAppliedToSet(set, contribution_type)); + + switch (contribution_type) { + case NGGridItemContributionType::kForIntrinsicMinimums: + case NGGridItemContributionType::kForContentBasedMinimums: + return set.TrackSize().HasIntrinsicMaxTrackBreadth(); + case NGGridItemContributionType::kForMaxContentMinimums: + return set.TrackSize().HasMaxContentMaxTrackBreadth(); + case NGGridItemContributionType::kForIntrinsicMaximums: + case NGGridItemContributionType::kForMaxContentMaximums: + return false; + } +} + +static bool IsDistributionForGrowthLimits( + NGGridItemContributionType contribution_type) { + switch (contribution_type) { + case NGGridItemContributionType::kForIntrinsicMinimums: + case NGGridItemContributionType::kForContentBasedMinimums: + case NGGridItemContributionType::kForMaxContentMinimums: + return false; + case NGGridItemContributionType::kForIntrinsicMaximums: + case NGGridItemContributionType::kForMaxContentMaximums: + return true; + } +} + +enum class InfinitelyGrowableBehavior { kEnforce, kIgnore }; + +// We define growth potential = limit - affected size; for base sizes, the limit +// is its growth limit. For growth limits, the limit is infinity if it is marked +// as "infinitely growable", and equal to the growth limit otherwise. +static LayoutUnit GrowthPotentialForSet( + const NGGridSet& set, + NGGridItemContributionType contribution_type, + InfinitelyGrowableBehavior infinitely_growable_behavior = + InfinitelyGrowableBehavior::kEnforce) { + switch (contribution_type) { + case NGGridItemContributionType::kForIntrinsicMinimums: + case NGGridItemContributionType::kForContentBasedMinimums: + case NGGridItemContributionType::kForMaxContentMinimums: { + LayoutUnit growth_limit = set.GrowthLimit(); + return (growth_limit == kIndefiniteSize) ? kIndefiniteSize + : growth_limit - set.BaseSize(); + } + case NGGridItemContributionType::kForIntrinsicMaximums: + case NGGridItemContributionType::kForMaxContentMaximums: { + if (infinitely_growable_behavior == + InfinitelyGrowableBehavior::kEnforce && + !set.IsInfinitelyGrowable()) { + // If the affected size was a growth limit and the track is not marked + // infinitely growable, then the item-incurred increase will be zero. + return LayoutUnit(); + } + + LayoutUnit growth_limit = set.GrowthLimit(); + LayoutUnit fit_content_limit = set.FitContentLimit(); + DCHECK(growth_limit >= 0 || growth_limit == kIndefiniteSize); + DCHECK(fit_content_limit >= 0 || fit_content_limit == kIndefiniteSize); + + // The max track sizing function of a 'fit-content' track is treated as + // 'max-content' until it reaches the limit specified as the 'fit-content' + // argument, after which it is treated as having a fixed sizing function + // of that argument (with a growth potential of zero). + if (fit_content_limit != kIndefiniteSize) { + LayoutUnit growth_potential = (growth_limit != kIndefiniteSize) + ? fit_content_limit - growth_limit + : fit_content_limit; + return growth_potential.ClampNegativeToZero(); + } + // Otherwise, this set has infinite growth potential. + return kIndefiniteSize; + } + } +} + +} // namespace + +// Follow the definitions from https://drafts.csswg.org/css-grid-1/#extra-space; +// notice that this method replaces the notion of "tracks" with "sets". +void NGGridLayoutAlgorithm::DistributeExtraSpaceToSets( + LayoutUnit extra_space, + NGGridItemContributionType contribution_type, + NGGridSetVector* sets_to_grow, + NGGridSetVector* sets_to_grow_beyond_limit) { + DCHECK(sets_to_grow && extra_space >= 0); + if (!extra_space) + return; + +#if DCHECK_IS_ON() + if (IsDistributionForGrowthLimits(contribution_type)) + DCHECK_EQ(sets_to_grow, sets_to_grow_beyond_limit); +#endif + + wtf_size_t total_track_count = 0; + for (NGGridSet* set : *sets_to_grow) { + set->SetItemIncurredIncrease(LayoutUnit()); + + // From the first note in https://drafts.csswg.org/css-grid-1/#extra-space: + // - If the affected size was a growth limit and the track is not marked + // "infinitely growable", then each item-incurred increase will be zero. + // + // When distributing space to growth limits, we need to increase each track + // up to its 'fit-content' limit. However, because of the note above, first + // we should only grow tracks marked as "infinitely growable" up to limits + // and then grow all affected tracks beyond limits. + // + // We can correctly resolve every scenario by doing a single sort of + // |sets_to_grow|, purposely ignoring the "infinitely growable" flag, then + // filtering out which sets count toward the total track count at each step; + // for base sizes this is not required, but if there are no tracks with + // growth potential > 0, we can optimize by not sorting the sets. + LayoutUnit growth_potential = + GrowthPotentialForSet(*set, contribution_type); + DCHECK(growth_potential >= 0 || growth_potential == kIndefiniteSize); + if (growth_potential) + total_track_count += set->TrackCount(); + } + + // We will sort the tracks by growth potential in non-decreasing order to + // distribute space up to limits; notice that if we start distributing space + // equally among all tracks we will eventually reach the limit of a track or + // run out of space to distribute. If the former scenario happens, it should + // be easy to see that the group of tracks that will reach its limit first + // will be that with the least growth potential. Otherwise, if tracks in such + // group does not reach their limit, every upcoming track with greater growth + // potential must be able to increase its size by the same amount. + if (total_track_count || IsDistributionForGrowthLimits(contribution_type)) { + auto CompareSetsByGrowthPotential = [contribution_type](NGGridSet* set_a, + NGGridSet* set_b) { + LayoutUnit growth_potential_a = GrowthPotentialForSet( + *set_a, contribution_type, InfinitelyGrowableBehavior::kIgnore); + LayoutUnit growth_potential_b = GrowthPotentialForSet( + *set_b, contribution_type, InfinitelyGrowableBehavior::kIgnore); + + if (growth_potential_a == kIndefiniteSize || + growth_potential_b == kIndefiniteSize) { + // At this point we know that there is at least one set with infinite + // growth potential; if |set_a| has a definite value, then |set_b| must + // have infinite growth potential, and thus, |set_a| < |set_b|. + return growth_potential_a != kIndefiniteSize; + } + // Straightforward comparison of definite growth potentials. + return growth_potential_a < growth_potential_b; + }; + std::sort(sets_to_grow->begin(), sets_to_grow->end(), + CompareSetsByGrowthPotential); + } + + auto ClampSize = [](LayoutUnit& size, LayoutUnit limit) { + size = (limit != kIndefiniteSize) ? std::min(size, limit) : size; + }; + + // Distribute space up to limits: + // - For base sizes, grow the base size up to the growth limit. + // - For growth limits, the only case where a growth limit should grow at + // this step is when the set has already been marked "infinitely growable". + // Increase the growth limit up to the 'fit-content' argument (if any); note + // that these arguments could prevent this step to fulfill the entirety of + // the extra space and further distribution would be needed. + if (total_track_count) { + for (NGGridSet* set : *sets_to_grow) { + LayoutUnit growth_potential = + GrowthPotentialForSet(*set, contribution_type); + + if (growth_potential) { + wtf_size_t set_track_count = set->TrackCount(); + LayoutUnit extra_space_share = + (extra_space * set_track_count) / total_track_count; + DCHECK_GE(extra_space_share, 0); + + ClampSize(extra_space_share, growth_potential); + set->SetItemIncurredIncrease(extra_space_share); + + total_track_count -= set_track_count; + extra_space -= extra_space_share; + DCHECK_GE(total_track_count, 0u); + DCHECK_GE(extra_space, 0); + } + } + } + + // Distribute space beyond limits: + // - For base sizes, every affected track can grow indefinitely. + // - For growth limits, grow tracks up to their 'fit-content' argument. + if (sets_to_grow_beyond_limit && extra_space) { + total_track_count = 0; + for (NGGridSet* set : *sets_to_grow_beyond_limit) + total_track_count += set->TrackCount(); + + for (NGGridSet* set : *sets_to_grow_beyond_limit) { + wtf_size_t set_track_count = set->TrackCount(); + LayoutUnit extra_space_share = + (extra_space * set_track_count) / total_track_count; + DCHECK_GE(extra_space_share, 0); + + // Ignore the "infinitely growable" flag and grow all affected tracks. + if (IsDistributionForGrowthLimits(contribution_type)) { + LayoutUnit growth_potential = GrowthPotentialForSet( + *set, contribution_type, InfinitelyGrowableBehavior::kIgnore); + ClampSize(extra_space_share, growth_potential); + } + set->SetItemIncurredIncrease(set->ItemIncurredIncrease() + + extra_space_share); + + total_track_count -= set_track_count; + extra_space -= extra_space_share; + DCHECK_GE(total_track_count, 0u); + DCHECK_GE(extra_space, 0); + } + } + + // For each affected track, if the track's item-incurred increase is larger + // than its planned increase, set the planned increase to that value. + for (NGGridSet* set : *sets_to_grow) { + set->SetPlannedIncrease( + std::max(set->ItemIncurredIncrease(), set->PlannedIncrease())); + } +} + +void NGGridLayoutAlgorithm::IncreaseTrackSizesToAccommodateGridItems( + GridTrackSizingDirection track_direction, + ReorderedGridItems::Iterator group_begin, + ReorderedGridItems::Iterator group_end, + NGGridItemContributionType contribution_type) { + auto& track_collection = TrackCollection(track_direction); + for (auto set_iterator = track_collection.GetSetIterator(); + !set_iterator.IsAtEnd(); set_iterator.MoveToNextSet()) { + set_iterator.CurrentSet().SetPlannedIncrease(LayoutUnit()); + } + + NGGridSetVector sets_to_grow; + NGGridSetVector sets_to_grow_beyond_limit; + for (auto grid_item = group_begin; grid_item != group_end; ++grid_item) { + // TODO(ethavar): Remove the |IsOutOfFlowPositioned| condition once the + // out-of-flow items are stored separately. + if (!grid_item->is_spanning_intrinsic_track || + grid_item->node.IsOutOfFlowPositioned()) { + // Don't consider items not spanning intrinsic tracks in this step; + // absolute positioned items don't affect track sizing. + continue; + } + + sets_to_grow.Shrink(0); + sets_to_grow_beyond_limit.Shrink(0); + + LayoutUnit spanned_tracks_size = + GridGap(track_direction) * (grid_item->SpanSize(track_direction) - 1); + for (auto set_iterator = GetSetIteratorForItem(*grid_item, track_direction); + !set_iterator.IsAtEnd(); set_iterator.MoveToNextSet()) { + NGGridSet& current_set = set_iterator.CurrentSet(); + + spanned_tracks_size += + AffectedSizeForContribution(current_set, contribution_type); + if (IsContributionAppliedToSet(current_set, contribution_type)) { + sets_to_grow.push_back(¤t_set); + if (ShouldUsedSizeGrowBeyondLimit(current_set, contribution_type)) + sets_to_grow_beyond_limit.push_back(¤t_set); + } + } + + if (sets_to_grow.IsEmpty()) + continue; + + // Subtract the corresponding size (base size or growth limit) of every + // spanned track from the grid item's size contribution to find the item's + // remaining size contribution. For infinite growth limits, substitute with + // the track's base size. This is the space to distribute, floor it at zero. + LayoutUnit extra_space = ContributionSizeForGridItem( + *grid_item, track_direction, contribution_type); + extra_space -= spanned_tracks_size; + + DistributeExtraSpaceToSets( + extra_space.ClampNegativeToZero(), contribution_type, &sets_to_grow, + sets_to_grow_beyond_limit.IsEmpty() ? &sets_to_grow + : &sets_to_grow_beyond_limit); + } + + for (auto set_iterator = track_collection.GetSetIterator(); + !set_iterator.IsAtEnd(); set_iterator.MoveToNextSet()) { + GrowAffectedSizeByPlannedIncrease(set_iterator.CurrentSet(), + contribution_type); + } +} + +// https://drafts.csswg.org/css-grid-1/#algo-content +void NGGridLayoutAlgorithm::ResolveIntrinsicTrackSizes( + GridTrackSizingDirection track_direction) { + // Reorder grid items to process them as follows: + // - First, consider items spanning a single non-flexible track. + // - Next, consider items with span size of 2 not spanning a flexible track. + // - Repeat incrementally for items with greater span sizes until all items + // not spanning a flexible track have been considered. + // - Finally, consider all items spanning a flexible track. + auto CompareGridItemsForIntrinsicTrackResolution = + [this, track_direction](wtf_size_t index_a, wtf_size_t index_b) -> bool { + if (items_[index_a].is_spanning_flex_track || + items_[index_b].is_spanning_flex_track) { + // Ignore span sizes if one of the items spans a track with a flexible + // sizing function; items not spanning such tracks should come first. + return !items_[index_a].is_spanning_flex_track; + } + return items_[index_a].SpanSize(track_direction) < + items_[index_b].SpanSize(track_direction); + }; + std::sort(reordered_item_indices_.begin(), reordered_item_indices_.end(), + CompareGridItemsForIntrinsicTrackResolution); + + // First, process the items that don't span a flexible track. + ReorderedGridItems grid_items = GetReorderedGridItems(); + ReorderedGridItems::Iterator current_group_begin = grid_items.begin(); + + while (current_group_begin != grid_items.end() && + !current_group_begin->is_spanning_flex_track) { + // Each iteration considers all items with the same span size. + wtf_size_t current_group_span_size = + current_group_begin->SpanSize(track_direction); + ReorderedGridItems::Iterator current_group_end = current_group_begin; + do { + DCHECK(!current_group_end->is_spanning_flex_track); + ++current_group_end; + } while (current_group_end != grid_items.end() && + !current_group_end->is_spanning_flex_track && + current_group_end->SpanSize(track_direction) == + current_group_span_size); + + IncreaseTrackSizesToAccommodateGridItems( + track_direction, current_group_begin, current_group_end, + NGGridItemContributionType::kForIntrinsicMinimums); + + // TODO(ethavar): Add remaining stages, mark infinitely growable sets... + current_group_begin = current_group_end; + } + + // TODO(ethavar): drafts.csswg.org/css-grid-1/#algo-spanning-flex-items + // Repeat the previous step instead considering (together, rather than grouped + // by span) all items that do span a track with a flexible sizing function. } void NGGridLayoutAlgorithm::SetAutomaticTrackRepetitionsForTesting( @@ -559,7 +1066,7 @@ // auto-sized grids. if (gap->IsPercentOrCalc() && available_size == kIndefiniteSize) return LayoutUnit(); - return ValueForLength(*gap, available_size); + return MinimumValueForLength(*gap, available_size); } } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h index aa1b4c029..1e565d1b5 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h
@@ -14,11 +14,24 @@ namespace blink { +// This enum corresponds to each step used to accommodate grid items across +// intrinsic tracks according to their min and max track sizing functions, as +// defined in https://drafts.csswg.org/css-grid-1/#algo-spanning-items. +enum class NGGridItemContributionType { + kForIntrinsicMinimums, + kForContentBasedMinimums, + kForMaxContentMinimums, + kForIntrinsicMaximums, + kForMaxContentMaximums +}; + class CORE_EXPORT NGGridLayoutAlgorithm : public NGLayoutAlgorithm<NGBlockNode, NGBoxFragmentBuilder, NGBlockBreakToken> { public: + // TODO(janewman): Move this enum out of |NGGridLayoutAlgorithm| to be + // consistent with |NGGridItemContributionType|. enum class AutoPlacementType { kNotNeeded, kMajor, kMinor, kBoth }; struct GridItemData { @@ -26,10 +39,14 @@ AutoPlacementType AutoPlacement( GridTrackSizingDirection flow_direction) const; - wtf_size_t StartLine(GridTrackSizingDirection direction) const; - wtf_size_t EndLine(GridTrackSizingDirection direction) const; - const GridSpan& Span(GridTrackSizingDirection direction) const; - void SetSpan(const GridSpan& span, GridTrackSizingDirection direction); + const GridSpan& Span(GridTrackSizingDirection track_direction) const; + void SetSpan(const GridSpan& span, + GridTrackSizingDirection track_direction); + + wtf_size_t StartLine(GridTrackSizingDirection track_direction) const; + wtf_size_t EndLine(GridTrackSizingDirection track_direction) const; + wtf_size_t SpanSize(GridTrackSizingDirection track_direction) const; + const NGBlockNode node; GridArea resolved_position; @@ -37,6 +54,13 @@ LayoutUnit inline_size; MinMaxSizes min_max_sizes; + // These fields are used to determine the sets this item spans in the + // respective track collection; see |CacheItemSetIndices|. + wtf_size_t columns_begin_set_index; + wtf_size_t columns_end_set_index; + wtf_size_t rows_begin_set_index; + wtf_size_t rows_end_set_index; + bool is_spanning_flex_track : 1; bool is_spanning_intrinsic_track : 1; }; @@ -51,6 +75,8 @@ const NGGridLayoutAlgorithmTrackCollection& RowTrackCollection() const; private: + using NGGridSetVector = Vector<NGGridSet*, 16>; + friend class NGGridLayoutAlgorithmTest; enum class GridLayoutAlgorithmState { @@ -70,6 +96,7 @@ Vector<GridItemData>* items); bool operator!=(const Iterator& other) const; + GridItemData* operator->(); GridItemData& operator*(); Iterator& operator++(); @@ -92,18 +119,32 @@ NGGridLayoutAlgorithmTrackCollection& TrackCollection( GridTrackSizingDirection track_direction); + // Returns an iterator for every |NGGridSet| contained within an item's span + // in the relevant track collection. + NGGridLayoutAlgorithmTrackCollection::SetIterator GetSetIteratorForItem( + const GridItemData& item, + GridTrackSizingDirection track_direction); + + // Returns the size that a grid item will distribute across the tracks with an + // intrinsic sizing function it spans in the relevant track direction. + LayoutUnit ContributionSizeForGridItem( + const GridItemData& grid_item, + GridTrackSizingDirection track_direction, + NGGridItemContributionType contribution_type) const; + void ConstructAndAppendGridItems(); GridItemData MeasureGridItem(const NGBlockNode node); NGConstraintSpace BuildSpaceForGridItem(const NGBlockNode node) const; // Sets the specified tracks for row and column track lists. void SetSpecifiedTracks(); - // Ensures a range boundary will exist on the start and end of the grid item. - void EnsureTrackCoverageForGridItem(GridTrackSizingDirection track_direction, - GridItemData& grid_item); // Determines the explicit column and row track starts. void DetermineExplicitTrackStarts(); + // For every item and track direction, computes and stores the pair of indices + // "begin" and "end" such that the item spans every set from the respective + // collection's |sets_| with an index in the range [begin, end). + void CacheItemSetIndices(); // For every grid item, determines if it spans a track with an intrinsic or // flexible sizing function and caches the answer in its |GridItemData|. void DetermineGridItemsSpanningIntrinsicOrFlexTracks( @@ -112,6 +153,19 @@ // Calculates from the min and max track sizing functions the used track size. void ComputeUsedTrackSizes(GridTrackSizingDirection track_direction); + // These methods implement the steps of the algorithm for intrinsic track size + // resolution defined in https://drafts.csswg.org/css-grid-1/#algo-content. + void ResolveIntrinsicTrackSizes(GridTrackSizingDirection track_direction); + void IncreaseTrackSizesToAccommodateGridItems( + GridTrackSizingDirection track_direction, + ReorderedGridItems::Iterator group_begin, + ReorderedGridItems::Iterator group_end, + NGGridItemContributionType contribution_type); + void DistributeExtraSpaceToSets(LayoutUnit extra_space, + NGGridItemContributionType contribution_type, + NGGridSetVector* sets_to_grow, + NGGridSetVector* sets_to_grow_beyond_limit); + // Allows a test to set the value for automatic track repetition. void SetAutomaticTrackRepetitionsForTesting(wtf_size_t auto_column, wtf_size_t auto_row);
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc index 95d5d478..5976eb70 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc
@@ -379,7 +379,10 @@ // 'auto', but we will normalize it directly as 'minmax(auto, max-content)'. NGGridSet::NGGridSet(wtf_size_t track_count, bool is_collapsed) : track_count_(track_count), - track_size_(Length::Auto(), Length::MaxContent()) { + track_size_(Length::Auto(), Length::MaxContent()), + growth_limit_(kIndefiniteSize), + fit_content_limit_(kIndefiniteSize), + is_infinitely_growable_(false) { if (is_collapsed) { // From https://drafts.csswg.org/css-grid-1/#collapsed-track: "A collapsed // track is treated as having a fixed track sizing function of '0px'". @@ -390,7 +393,11 @@ NGGridSet::NGGridSet(wtf_size_t track_count, const GridTrackSize& track_size, bool is_content_box_size_indefinite) - : track_count_(track_count), track_size_(track_size) { + : track_count_(track_count), + track_size_(track_size), + growth_limit_(kIndefiniteSize), + fit_content_limit_(kIndefiniteSize), + is_infinitely_growable_(false) { if (track_size_.IsFitContent()) { DCHECK(track_size_.FitContentTrackBreadth().IsLength()); @@ -430,15 +437,39 @@ track_size_.GetType() == kMinMaxTrackSizing); } +bool NGGridSet::IsGrowthLimitLessThanBaseSize() const { + return growth_limit_ != kIndefiniteSize && growth_limit_ < base_size_; +} + +void NGGridSet::EnsureGrowthLimitIsNotLessThanBaseSize() { + if (IsGrowthLimitLessThanBaseSize()) + growth_limit_ = base_size_; +} + +LayoutUnit NGGridSet::BaseSize() const { + DCHECK(!IsGrowthLimitLessThanBaseSize()); + return base_size_; +} + void NGGridSet::SetBaseSize(LayoutUnit base_size) { - DCHECK_NE(base_size_, kIndefiniteSize); + // Expect base size to always grow monotonically. + DCHECK_NE(base_size, kIndefiniteSize); DCHECK_LE(base_size_, base_size); base_size_ = base_size; + EnsureGrowthLimitIsNotLessThanBaseSize(); +} + +LayoutUnit NGGridSet::GrowthLimit() const { + DCHECK(!IsGrowthLimitLessThanBaseSize()); + return growth_limit_; } void NGGridSet::SetGrowthLimit(LayoutUnit growth_limit) { - DCHECK(growth_limit_ == kIndefiniteSize || growth_limit == kIndefiniteSize || - growth_limit_ <= growth_limit); + // Growth limit is initialized as infinity; expect it to change from infinity + // to a definite value and then to always grow monotonically. + DCHECK_NE(growth_limit, kIndefiniteSize); + DCHECK(!IsGrowthLimitLessThanBaseSize()); + DCHECK(growth_limit_ == kIndefiniteSize || growth_limit_ <= growth_limit); growth_limit_ = growth_limit; } @@ -577,13 +608,23 @@ } NGGridLayoutAlgorithmTrackCollection::SetIterator -NGGridLayoutAlgorithmTrackCollection::IteratorForRange(wtf_size_t range_index) { - DCHECK_LT(range_index, RangeCount()); +NGGridLayoutAlgorithmTrackCollection::GetSetIterator(wtf_size_t begin_set_index, + wtf_size_t end_set_index) { + DCHECK_LE(end_set_index, SetCount()); + DCHECK_LE(begin_set_index, end_set_index); + return SetIterator(this, begin_set_index, end_set_index); +} - const Range& range = ranges_[range_index]; - DCHECK_LE(range.starting_set_index + range.set_count, SetCount()); - return SetIterator(this, range.starting_set_index, - range.starting_set_index + range.set_count); +wtf_size_t NGGridLayoutAlgorithmTrackCollection::RangeSetCount( + wtf_size_t range_index) const { + DCHECK_LT(range_index, RangeCount()); + return ranges_[range_index].set_count; +} + +wtf_size_t NGGridLayoutAlgorithmTrackCollection::RangeStartingSetIndex( + wtf_size_t range_index) const { + DCHECK_LT(range_index, RangeCount()); + return ranges_[range_index].starting_set_index; } bool NGGridLayoutAlgorithmTrackCollection::IsRangeSpanningIntrinsicTrack(
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.h b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.h index 905e9eb..aa0791f 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.h +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.h
@@ -180,21 +180,39 @@ wtf_size_t TrackCount() const { return track_count_; } const GridTrackSize& TrackSize() const { return track_size_; } - LayoutUnit BaseSize() const { return base_size_; } - LayoutUnit GrowthLimit() const { return growth_limit_; } + LayoutUnit BaseSize() const; + LayoutUnit GrowthLimit() const; + LayoutUnit PlannedIncrease() const { return planned_increase_; } + LayoutUnit FitContentLimit() const { return fit_content_limit_; } + LayoutUnit ItemIncurredIncrease() const { return item_incurred_increase_; } + bool IsInfinitelyGrowable() const { return is_infinitely_growable_; } - // The following setters expect their respective member variables to grow - // monotonically; however, |growth_limit_| can also change from a definite - // value to |kIndefiniteSize| and vice versa. void SetBaseSize(LayoutUnit base_size); void SetGrowthLimit(LayoutUnit growth_limit); + void SetPlannedIncrease(LayoutUnit planned_increase) { + planned_increase_ = planned_increase; + } + void SetItemIncurredIncrease(LayoutUnit item_incurred_increase) { + item_incurred_increase_ = item_incurred_increase; + } + void SetInfinitelyGrowable(bool infinitely_growable) { + is_infinitely_growable_ = infinitely_growable; + } private: + bool IsGrowthLimitLessThanBaseSize() const; + void EnsureGrowthLimitIsNotLessThanBaseSize(); + wtf_size_t track_count_; GridTrackSize track_size_; + // Fields used by the track sizing algorithm. LayoutUnit base_size_; LayoutUnit growth_limit_; + LayoutUnit planned_increase_; + LayoutUnit fit_content_limit_; + LayoutUnit item_incurred_increase_; + bool is_infinitely_growable_ : 1; }; class CORE_EXPORT NGGridLayoutAlgorithmTrackCollection @@ -215,6 +233,7 @@ bool is_collapsed : 1; }; + // Note that this iterator can alter any set's data. class CORE_EXPORT SetIterator { public: SetIterator(NGGridLayoutAlgorithmTrackCollection* collection, @@ -238,13 +257,19 @@ const NGGridBlockTrackCollection& block_track_collection, bool is_content_box_size_indefinite); + // Returns the number of sets in the collection. + wtf_size_t SetCount() const; // Returns a reference to the set located at position |set_index|. NGGridSet& SetAt(wtf_size_t set_index); // Returns an iterator for all the sets contained in this collection. SetIterator GetSetIterator(); - // Returns an iterator for all the sets contained within the |range_index|-th - // range of the collection. Note that this iterator can alter any set's data. - SetIterator IteratorForRange(wtf_size_t range_index); + // Returns an iterator for every set in this collection's |sets_| located at + // an index in the interval [begin_set_index, end_set_index). + SetIterator GetSetIterator(wtf_size_t begin_set_index, + wtf_size_t end_set_index); + + wtf_size_t RangeSetCount(wtf_size_t range_index) const; + wtf_size_t RangeStartingSetIndex(wtf_size_t range_index) const; // Returns true if the range contains a set with an intrinsic sizing function. bool IsRangeSpanningIntrinsicTrack(wtf_size_t range_index) const; @@ -264,9 +289,6 @@ const NGGridTrackList& specified_track_list, bool is_content_box_size_indefinite); - // Returns the number of sets in the collection. - wtf_size_t SetCount() const; - Vector<Range> ranges_; // A vector of every set element that compose the entire collection's ranges; // track definitions from the same set are stored in consecutive positions,
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection_test.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection_test.cc index 36cf894..8819b003 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection_test.cc +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection_test.cc
@@ -67,6 +67,16 @@ Vector<GridTrackSize> CreateTrackSizes(wtf_size_t track_count) { return {track_count, GridTrackSize(Length::Auto())}; } + + NGGridLayoutAlgorithmTrackCollection::SetIterator IteratorForRange( + NGGridLayoutAlgorithmTrackCollection& algorithm_collection, + wtf_size_t range_index) { + wtf_size_t starting_set_index = + algorithm_collection.RangeStartingSetIndex(range_index); + return algorithm_collection.GetSetIterator( + starting_set_index, + starting_set_index + algorithm_collection.RangeSetCount(range_index)); + } }; TEST_F(NGGridTrackCollectionTest, TestRangeIndexFromTrackNumber) { @@ -347,8 +357,8 @@ EXPECT_RANGE(set_count, set_counts[range_count], range_iterator); wtf_size_t current_range_set_count = 0; - for (auto set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + for (auto set_iterator = IteratorForRange(algorithm_collection, + range_iterator.RangeIndex()); !set_iterator.IsAtEnd(); set_iterator.MoveToNextSet()) { EXPECT_SET(GridTrackSize(GridLength(set_count++)), 1u, set_iterator); ++current_range_set_count; @@ -394,7 +404,7 @@ EXPECT_RANGE(0u, 2u, range_iterator); NGGridLayoutAlgorithmTrackCollection::SetIterator set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + IteratorForRange(algorithm_collection, range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(1)), 1u, set_iterator); EXPECT_TRUE(set_iterator.MoveToNextSet()); EXPECT_SET(GridTrackSize(Length::Fixed(2)), 1u, set_iterator); @@ -403,7 +413,7 @@ EXPECT_RANGE(2u, 4u, range_iterator); set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + IteratorForRange(algorithm_collection, range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(3)), 2u, set_iterator); EXPECT_TRUE(set_iterator.MoveToNextSet()); EXPECT_SET(GridTrackSize(Length::Fixed(1)), 1u, set_iterator); @@ -414,7 +424,7 @@ EXPECT_RANGE(6u, 3u, range_iterator); set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + IteratorForRange(algorithm_collection, range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(1)), 1u, set_iterator); EXPECT_TRUE(set_iterator.MoveToNextSet()); EXPECT_SET(GridTrackSize(Length::Fixed(2)), 1u, set_iterator); @@ -425,14 +435,14 @@ EXPECT_COLLAPSED_RANGE(9u, 3u, range_iterator); set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + IteratorForRange(algorithm_collection, range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(0)), 3u, set_iterator); EXPECT_FALSE(set_iterator.MoveToNextSet()); EXPECT_TRUE(range_iterator.MoveToNextRange()); EXPECT_RANGE(12u, 4u, range_iterator); set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + IteratorForRange(algorithm_collection, range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(5)), 2u, set_iterator); EXPECT_TRUE(set_iterator.MoveToNextSet()); EXPECT_SET(GridTrackSize(Length::Fixed(4)), 2u, set_iterator); @@ -441,14 +451,14 @@ EXPECT_COLLAPSED_RANGE(16u, 1u, range_iterator); set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + IteratorForRange(algorithm_collection, range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(0)), 1u, set_iterator); EXPECT_FALSE(set_iterator.MoveToNextSet()); EXPECT_TRUE(range_iterator.MoveToNextRange()); EXPECT_RANGE(17u, 2u, range_iterator); set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + IteratorForRange(algorithm_collection, range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(4)), 1u, set_iterator); EXPECT_TRUE(set_iterator.MoveToNextSet()); EXPECT_SET(GridTrackSize(Length::Fixed(5)), 1u, set_iterator); @@ -457,21 +467,21 @@ EXPECT_RANGE(19u, 1u, range_iterator); set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + IteratorForRange(algorithm_collection, range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Auto()), 1u, set_iterator); EXPECT_FALSE(set_iterator.MoveToNextSet()); EXPECT_TRUE(range_iterator.MoveToNextRange()); EXPECT_RANGE(20u, 2u, range_iterator); set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + IteratorForRange(algorithm_collection, range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Auto()), 2u, set_iterator); EXPECT_FALSE(set_iterator.MoveToNextSet()); EXPECT_TRUE(range_iterator.MoveToNextRange()); EXPECT_RANGE(22u, 5u, range_iterator); set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + IteratorForRange(algorithm_collection, range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Auto()), 5u, set_iterator); EXPECT_FALSE(set_iterator.MoveToNextSet()); EXPECT_FALSE(range_iterator.MoveToNextRange()); @@ -510,7 +520,7 @@ EXPECT_RANGE(0u, 2u, range_iterator); NGGridLayoutAlgorithmTrackCollection::SetIterator set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + IteratorForRange(algorithm_collection, range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(1)), 1u, set_iterator); EXPECT_TRUE(set_iterator.MoveToNextSet()); EXPECT_SET(GridTrackSize(Length::Fixed(2)), 1u, set_iterator); @@ -519,7 +529,7 @@ EXPECT_RANGE(2u, 2u, range_iterator); set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + IteratorForRange(algorithm_collection, range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(3)), 1u, set_iterator); EXPECT_TRUE(set_iterator.MoveToNextSet()); EXPECT_SET(GridTrackSize(Length::Fixed(4)), 1u, set_iterator); @@ -528,7 +538,7 @@ EXPECT_RANGE(4u, 11u, range_iterator); set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + IteratorForRange(algorithm_collection, range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(5)), 4u, set_iterator); EXPECT_TRUE(set_iterator.MoveToNextSet()); EXPECT_SET(GridTrackSize(Length::Fixed(6)), 4u, set_iterator); @@ -539,7 +549,7 @@ EXPECT_RANGE(15u, 8u, range_iterator); set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + IteratorForRange(algorithm_collection, range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(7)), 3u, set_iterator); EXPECT_TRUE(set_iterator.MoveToNextSet()); EXPECT_SET(GridTrackSize(Length::Fixed(5)), 3u, set_iterator); @@ -550,7 +560,7 @@ EXPECT_RANGE(23u, 2u, range_iterator); set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + IteratorForRange(algorithm_collection, range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(6)), 1u, set_iterator); EXPECT_TRUE(set_iterator.MoveToNextSet()); EXPECT_SET(GridTrackSize(Length::Fixed(7)), 1u, set_iterator); @@ -585,7 +595,7 @@ EXPECT_RANGE(0u, 1u, range_iterator); NGGridLayoutAlgorithmTrackCollection::SetIterator set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + IteratorForRange(algorithm_collection, range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::MinContent()), 1u, set_iterator); EXPECT_FALSE(set_iterator.MoveToNextSet()); wtf_size_t current_range_index = range_iterator.RangeIndex(); @@ -597,7 +607,7 @@ EXPECT_RANGE(1u, 2u, range_iterator); set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + IteratorForRange(algorithm_collection, range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(GridLength(1.0)), 1u, set_iterator); EXPECT_TRUE(set_iterator.MoveToNextSet()); EXPECT_SET(GridTrackSize(Length::Fixed(2)), 1u, set_iterator); @@ -611,7 +621,7 @@ EXPECT_RANGE(3u, 4u, range_iterator); set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + IteratorForRange(algorithm_collection, range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(3)), 1u, set_iterator); EXPECT_TRUE(set_iterator.MoveToNextSet()); EXPECT_SET(GridTrackSize(Length::MinContent()), 1u, set_iterator); @@ -629,7 +639,7 @@ EXPECT_RANGE(7u, 1u, range_iterator); set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + IteratorForRange(algorithm_collection, range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(3)), 1u, set_iterator); EXPECT_FALSE(set_iterator.MoveToNextSet()); current_range_index = range_iterator.RangeIndex(); @@ -641,7 +651,7 @@ EXPECT_RANGE(8u, 3u, range_iterator); set_iterator = - algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); + IteratorForRange(algorithm_collection, range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Auto()), 3u, set_iterator); EXPECT_FALSE(set_iterator.MoveToNextSet()); current_range_index = range_iterator.RangeIndex();
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index 2a6b072..c64be52c 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -252,8 +252,7 @@ auto navigation_params = std::make_unique<WebNavigationParams>(); navigation_params->url = KURL(g_empty_string); navigation_params->frame_policy = - frame_->Owner() ? base::make_optional(frame_->Owner()->GetFramePolicy()) - : base::nullopt; + frame_->Owner() ? frame_->Owner()->GetFramePolicy() : FramePolicy(); DocumentLoader* new_document_loader = Client()->CreateDocumentLoader( frame_, kWebNavigationTypeOther, CreateCSPForInitialEmptyDocument(),
diff --git a/third_party/blink/renderer/core/svg/properties/svg_animated_property.cc b/third_party/blink/renderer/core/svg/properties/svg_animated_property.cc index 16d907e..a35a865 100644 --- a/third_party/blink/renderer/core/svg/properties/svg_animated_property.cc +++ b/third_party/blink/renderer/core/svg/properties/svg_animated_property.cc
@@ -79,8 +79,7 @@ DCHECK(context_element_); DCHECK(attribute_name_ != QualifiedName::Null()); base_value_needs_synchronization_ = true; - context_element_->InvalidateSVGAttributes(); - context_element_->SvgAttributeBaseValChanged(attribute_name_); + context_element_->BaseValueChanged(*this); } void SVGAnimatedPropertyBase::EnsureAnimValUpdated() {
diff --git a/third_party/blink/renderer/core/svg/svg_element.cc b/third_party/blink/renderer/core/svg/svg_element.cc index 1d700e7..53f7d1f1 100644 --- a/third_party/blink/renderer/core/svg/svg_element.cc +++ b/third_party/blink/renderer/core/svg/svg_element.cc
@@ -926,7 +926,8 @@ if (params.name == html_names::kStyleAttr) return; - SvgAttributeBaseValChanged(params.name); + SvgAttributeChanged(params.name); + UpdateWebAnimatedAttributeOnBaseValChange(params.name); } void SVGElement::SvgAttributeChanged(const QualifiedName& attr_name) { @@ -944,8 +945,15 @@ } } -void SVGElement::SvgAttributeBaseValChanged(const QualifiedName& attribute) { +void SVGElement::BaseValueChanged( + const SVGAnimatedPropertyBase& animated_property) { + const QualifiedName& attribute = animated_property.AttributeName(); + EnsureUniqueElementData().SetSvgAttributesAreDirty(true); SvgAttributeChanged(attribute); + if (class_name_ == &animated_property) { + UpdateClassList(g_null_atom, + AtomicString(class_name_->BaseValue()->Value())); + } UpdateWebAnimatedAttributeOnBaseValChange(attribute); }
diff --git a/third_party/blink/renderer/core/svg/svg_element.h b/third_party/blink/renderer/core/svg/svg_element.h index f02a552..c92be82 100644 --- a/third_party/blink/renderer/core/svg/svg_element.h +++ b/third_party/blink/renderer/core/svg/svg_element.h
@@ -93,6 +93,7 @@ void SetWebAnimationsPending(); void ApplyActiveWebAnimations(); + void BaseValueChanged(const SVGAnimatedPropertyBase&); void EnsureAttributeAnimValUpdated(); void SetWebAnimatedAttribute(const QualifiedName& attribute, @@ -122,7 +123,6 @@ virtual bool IsValid() const { return true; } virtual void SvgAttributeChanged(const QualifiedName&); - void SvgAttributeBaseValChanged(const QualifiedName&); SVGAnimatedPropertyBase* PropertyFromAttribute( const QualifiedName& attribute_name) const; @@ -134,9 +134,6 @@ virtual AffineTransform* AnimateMotionTransform() { return nullptr; } - void InvalidateSVGAttributes() { - EnsureUniqueElementData().SetSvgAttributesAreDirty(true); - } void InvalidateSVGPresentationAttributeStyle() { EnsureUniqueElementData().SetPresentationAttributeStyleIsDirty(true); }
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc index e067e23..54a7d0d 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc
@@ -8,7 +8,6 @@ #include "third_party/blink/renderer/core/css/resolver/filter_operation_resolver.h" #include "third_party/blink/renderer/core/css/resolver/style_builder.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" -#include "third_party/blink/renderer/core/css/scoped_css_value.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h" #include "third_party/blink/renderer/core/paint/filter_effect_builder.h" @@ -366,9 +365,8 @@ filter_style.get(), filter_style.get()); resolver_state.SetStyle(filter_style); - StyleBuilder::ApplyProperty( - GetCSSPropertyFilter(), resolver_state, - ScopedCSSValue(*filter_value_, &style_resolution_host->GetDocument())); + StyleBuilder::ApplyProperty(GetCSSPropertyFilter(), resolver_state, + *filter_value_); resolver_state.LoadPendingResources(); // We can't reuse m_fillFlags and m_strokeFlags for the filter, since these
diff --git a/third_party/blink/renderer/modules/exported/web_ax_context.cc b/third_party/blink/renderer/modules/exported/web_ax_context.cc index f6e94b1a..5553fb8b 100644 --- a/third_party/blink/renderer/modules/exported/web_ax_context.cc +++ b/third_party/blink/renderer/modules/exported/web_ax_context.cc
@@ -24,6 +24,9 @@ if (!private_->HasActiveDocument()) return WebAXObject(); + // Make sure that layout is updated before a root ax object is created. + WebAXObject::UpdateLayout(WebDocument(private_->GetDocument())); + return WebAXObject( static_cast<AXObjectCacheImpl*>(&private_->GetAXObjectCache())->Root()); }
diff --git a/third_party/blink/renderer/modules/webgpu/BUILD.gn b/third_party/blink/renderer/modules/webgpu/BUILD.gn index 1099c436..0bb8627 100644 --- a/third_party/blink/renderer/modules/webgpu/BUILD.gn +++ b/third_party/blink/renderer/modules/webgpu/BUILD.gn
@@ -6,8 +6,6 @@ blink_modules_sources("webgpu") { sources = [ - "client_validation.cc", - "client_validation.h", "dawn_callback.h", "dawn_conversions.cc", "dawn_conversions.h",
diff --git a/third_party/blink/renderer/modules/webgpu/client_validation.cc b/third_party/blink/renderer/modules/webgpu/client_validation.cc deleted file mode 100644 index 6a8ffb2..0000000 --- a/third_party/blink/renderer/modules/webgpu/client_validation.cc +++ /dev/null
@@ -1,43 +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 "third_party/blink/renderer/modules/webgpu/client_validation.h" - -#include <dawn/webgpu.h> - -#include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_enforce_range_sequence_or_gpu_extent_3d_dict.h" -#include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_enforce_range_sequence_or_gpu_origin_2d_dict.h" -#include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_enforce_range_sequence_or_gpu_origin_3d_dict.h" -#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_copy_view.h" -#include "third_party/blink/renderer/platform/bindings/exception_state.h" - -namespace blink { - -bool ValidateCopySize( - UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict& copy_size, - ExceptionState& exception_state) { - if (copy_size.IsUnsignedLongEnforceRangeSequence() && - copy_size.GetAsUnsignedLongEnforceRangeSequence().size() != 3) { - exception_state.ThrowRangeError("copySize length must be 3"); - return false; - } - return true; -} - -bool ValidateTextureCopyView(GPUTextureCopyView* texture_copy_view, - ExceptionState& exception_state) { - DCHECK(texture_copy_view); - - const UnsignedLongEnforceRangeSequenceOrGPUOrigin3DDict origin = - texture_copy_view->origin(); - if (origin.IsUnsignedLongEnforceRangeSequence() && - origin.GetAsUnsignedLongEnforceRangeSequence().size() != 3) { - exception_state.ThrowRangeError( - "texture copy view origin length must be 3"); - return false; - } - return true; -} - -} // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/client_validation.h b/third_party/blink/renderer/modules/webgpu/client_validation.h deleted file mode 100644 index 47179e4..0000000 --- a/third_party/blink/renderer/modules/webgpu/client_validation.h +++ /dev/null
@@ -1,25 +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 THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_CLIENT_VALIDATION_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_CLIENT_VALIDATION_H_ - -#include <dawn/webgpu.h> - -// This file provides helpers for validating copy operation in WebGPU. - -namespace blink { - -class ExceptionState; -class GPUTextureCopyView; -class UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict; - -bool ValidateCopySize( - UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict& copy_size, - ExceptionState& exception_state); -bool ValidateTextureCopyView(GPUTextureCopyView* texture_copy_view, - ExceptionState& exception_state); -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_CLIENT_VALIDATION_H_
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc b/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc index 22bab49..d209724 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc +++ b/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc
@@ -764,15 +764,27 @@ const UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict* webgpu_extent) { DCHECK(webgpu_extent); - WGPUExtent3D dawn_extent = {}; + WGPUExtent3D dawn_extent = {1, 1, 1}; if (webgpu_extent->IsUnsignedLongEnforceRangeSequence()) { const Vector<uint32_t>& webgpu_extent_sequence = webgpu_extent->GetAsUnsignedLongEnforceRangeSequence(); - DCHECK_EQ(webgpu_extent_sequence.size(), 3UL); - dawn_extent.width = webgpu_extent_sequence[0]; - dawn_extent.height = webgpu_extent_sequence[1]; - dawn_extent.depth = webgpu_extent_sequence[2]; + + // The WebGPU spec states that if the sequence isn't big enough then the + // default values of 1 are used (which are set above). + switch (webgpu_extent_sequence.size()) { + default: + dawn_extent.depth = webgpu_extent_sequence[2]; + FALLTHROUGH; + case 2: + dawn_extent.height = webgpu_extent_sequence[1]; + FALLTHROUGH; + case 1: + dawn_extent.width = webgpu_extent_sequence[0]; + FALLTHROUGH; + case 0: + break; + } } else if (webgpu_extent->IsGPUExtent3DDict()) { const GPUExtent3DDict* webgpu_extent_3d_dict = @@ -792,15 +804,27 @@ const UnsignedLongEnforceRangeSequenceOrGPUOrigin3DDict* webgpu_origin) { DCHECK(webgpu_origin); - WGPUOrigin3D dawn_origin = {}; + WGPUOrigin3D dawn_origin = {0, 0, 0}; if (webgpu_origin->IsUnsignedLongEnforceRangeSequence()) { const Vector<uint32_t>& webgpu_origin_sequence = webgpu_origin->GetAsUnsignedLongEnforceRangeSequence(); - DCHECK_EQ(webgpu_origin_sequence.size(), 3UL); - dawn_origin.x = webgpu_origin_sequence[0]; - dawn_origin.y = webgpu_origin_sequence[1]; - dawn_origin.z = webgpu_origin_sequence[2]; + + // The WebGPU spec states that if the sequence isn't big enough then the + // default values of 0 are used (which are set above). + switch (webgpu_origin_sequence.size()) { + default: + dawn_origin.z = webgpu_origin_sequence[2]; + FALLTHROUGH; + case 2: + dawn_origin.y = webgpu_origin_sequence[1]; + FALLTHROUGH; + case 1: + dawn_origin.x = webgpu_origin_sequence[0]; + FALLTHROUGH; + case 0: + break; + } } else if (webgpu_origin->IsGPUOrigin3DDict()) { const GPUOrigin3DDict* webgpu_origin_3d_dict =
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc index 6569866..eecf83e 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc
@@ -15,7 +15,6 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_render_pass_depth_stencil_attachment_descriptor.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_render_pass_descriptor.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_copy_view.h" -#include "third_party/blink/renderer/modules/webgpu/client_validation.h" #include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h" #include "third_party/blink/renderer/modules/webgpu/gpu_buffer.h" #include "third_party/blink/renderer/modules/webgpu/gpu_command_buffer.h" @@ -254,11 +253,6 @@ GPUTextureCopyView* destination, UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict& copy_size, ExceptionState& exception_state) { - if (!ValidateCopySize(copy_size, exception_state) || - !ValidateTextureCopyView(destination, exception_state)) { - return; - } - base::Optional<WGPUBufferCopyView> dawn_source = AsDawnType(source); if (!dawn_source) { return; @@ -275,11 +269,6 @@ GPUBufferCopyView* destination, UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict& copy_size, ExceptionState& exception_state) { - if (!ValidateCopySize(copy_size, exception_state) || - !ValidateTextureCopyView(source, exception_state)) { - return; - } - WGPUTextureCopyView dawn_source = AsDawnType(source, device_); base::Optional<WGPUBufferCopyView> dawn_destination = AsDawnType(destination); if (!dawn_destination) { @@ -296,12 +285,6 @@ GPUTextureCopyView* destination, UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict& copy_size, ExceptionState& exception_state) { - if (!ValidateCopySize(copy_size, exception_state) || - !ValidateTextureCopyView(source, exception_state) || - !ValidateTextureCopyView(destination, exception_state)) { - return; - } - WGPUTextureCopyView dawn_source = AsDawnType(source, device_); WGPUTextureCopyView dawn_destination = AsDawnType(destination, device_); WGPUExtent3D dawn_copy_size = AsDawnType(©_size);
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_extent_3d_dict.idl b/third_party/blink/renderer/modules/webgpu/gpu_extent_3d_dict.idl index a1ac2c84..6fc1fe2 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_extent_3d_dict.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_extent_3d_dict.idl
@@ -5,7 +5,7 @@ // https://gpuweb.github.io/gpuweb/ dictionary GPUExtent3DDict { - required GPUIntegerCoordinate width; - required GPUIntegerCoordinate height; - required GPUIntegerCoordinate depth; + GPUIntegerCoordinate width = 1; + GPUIntegerCoordinate height = 1; + GPUIntegerCoordinate depth = 1; };
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc index 4ae0188..d11e0eb 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
@@ -17,7 +17,6 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_copy_view.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" -#include "third_party/blink/renderer/modules/webgpu/client_validation.h" #include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h" #include "third_party/blink/renderer/modules/webgpu/gpu_buffer.h" #include "third_party/blink/renderer/modules/webgpu/gpu_command_buffer.h" @@ -305,11 +304,6 @@ GPUTextureDataLayout* data_layout, UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict& write_size, ExceptionState& exception_state) { - if (!ValidateCopySize(write_size, exception_state) || - !ValidateTextureCopyView(destination, exception_state)) { - return; - } - WGPUTextureCopyView dawn_destination = AsDawnType(destination, device_); WGPUTextureDataLayout dawn_data_layout = AsDawnType(data_layout); WGPUExtent3D dawn_write_size = AsDawnType(&write_size); @@ -330,13 +324,6 @@ return; } - // TODO(shaobo.yan@intel.com): only the same color format texture copy allowed - // now. Need to Explore compatible texture format copy. - if (!ValidateCopySize(copy_size, exception_state) || - !ValidateTextureCopyView(destination, exception_state)) { - return; - } - // ImageBitmap shouldn't in closed state. if (source->imageBitmap()->IsNeutered()) { exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
diff --git a/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc b/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc index 435969f..f8cff9f 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc
@@ -47,7 +47,6 @@ #include "third_party/blink/renderer/platform/fonts/simple_font_data.h" #include "third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.h" #include "third_party/blink/renderer/platform/fonts/unicode_range_set.h" -#include "third_party/blink/renderer/platform/instrumentation/histogram.h" #include "third_party/blink/renderer/platform/resolution_units.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" @@ -368,8 +367,6 @@ hb_face_t* HarfBuzzFace::CreateFace() { hb_face_t* face = nullptr; - DEFINE_THREAD_SAFE_STATIC_LOCAL(BooleanHistogram, zero_copy_success_histogram, - ("Blink.Fonts.HarfBuzzFaceZeroCopyAccess")); SkTypeface* typeface = platform_data_->Typeface(); CHECK(typeface); // The attempt of doing zero copy-mmaped memory access to the font blobs does @@ -394,9 +391,6 @@ if (!face) { face = hb_face_create_for_tables(HarfBuzzSkiaGetTable, platform_data_->Typeface(), nullptr); - zero_copy_success_histogram.Count(false); - } else { - zero_copy_success_histogram.Count(true); } DCHECK(face);
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc index b784445b..8828439 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc
@@ -237,7 +237,7 @@ gfx::Transform()); viz::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState(); - sqs->SetAll(gfx::Transform(), bounds, bounds, gfx::RRectF(), bounds, + sqs->SetAll(gfx::Transform(), bounds, bounds, gfx::MaskFilterInfo(), bounds, is_clipped, is_opaque, 1.f, SkBlendMode::kSrcOver, 0); viz::TransferableResource resource;
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc index 5188b066..7637eb1 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
@@ -1383,7 +1383,8 @@ // of antialiasing issues on the rounded corner edges. // is_fast_rounded_corner means to intentionally prefer faster compositing // and less memory over highest quality. - if (!effect.rounded_corner_bounds.IsEmpty() && !effect.is_fast_rounded_corner) + if (effect.mask_filter_info.HasRoundedCorners() && + !effect.mask_filter_info.is_fast_rounded_corner()) return cc::RenderSurfaceReason::kRoundedCorner; return cc::RenderSurfaceReason::kNone; }
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc index c38add2..58c990d 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
@@ -3048,9 +3048,9 @@ *GetPropertyTrees().effect_tree.Node(mask_isolation_0_id); ASSERT_EQ(e0_id, mask_isolation_0.parent_id); EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode); - EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner); + EXPECT_TRUE(mask_isolation_0.mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5), - mask_isolation_0.rounded_corner_bounds); + mask_isolation_0.mask_filter_info.rounded_corner_bounds()); EXPECT_FALSE(mask_isolation_0.HasRenderSurface()); } @@ -3147,9 +3147,9 @@ *GetPropertyTrees().effect_tree.Node(mask_isolation_0_id); ASSERT_EQ(e0_id, mask_isolation_0.parent_id); EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode); - EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner); + EXPECT_TRUE(mask_isolation_0.mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5), - mask_isolation_0.rounded_corner_bounds); + mask_isolation_0.mask_filter_info.rounded_corner_bounds()); EXPECT_FALSE(mask_isolation_0.HasRenderSurface()); } @@ -3302,27 +3302,27 @@ ASSERT_EQ(e0_id, mask_isolation_0.parent_id); EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode); - EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner); + EXPECT_TRUE(mask_isolation_0.mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5), - mask_isolation_0.rounded_corner_bounds); + mask_isolation_0.mask_filter_info.rounded_corner_bounds()); EXPECT_FALSE(mask_isolation_0.HasRenderSurface()); ASSERT_EQ(e1_id, cc_filter.parent_id); EXPECT_EQ(cc_filter.id, content0->effect_tree_index()); EXPECT_EQ(SkBlendMode::kSrcOver, cc_filter.blend_mode); - EXPECT_FALSE(cc_filter.is_fast_rounded_corner); + EXPECT_FALSE(cc_filter.mask_filter_info.is_fast_rounded_corner()); EXPECT_TRUE(cc_filter.HasRenderSurface()); EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_1.blend_mode); - EXPECT_TRUE(mask_isolation_1.is_fast_rounded_corner); + EXPECT_TRUE(mask_isolation_1.mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5), - mask_isolation_1.rounded_corner_bounds); + mask_isolation_1.mask_filter_info.rounded_corner_bounds()); EXPECT_TRUE(mask_isolation_1.HasRenderSurface()); EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_2.blend_mode); - EXPECT_TRUE(mask_isolation_2.is_fast_rounded_corner); + EXPECT_TRUE(mask_isolation_2.mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5), - mask_isolation_2.rounded_corner_bounds); + mask_isolation_2.mask_filter_info.rounded_corner_bounds()); EXPECT_FALSE(mask_isolation_2.HasRenderSurface()); } @@ -3507,9 +3507,9 @@ EXPECT_EQ(c1_id, content1->clip_tree_index()); EXPECT_EQ(mask_isolation_0_id, content1->effect_tree_index()); - EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner); + EXPECT_TRUE(mask_isolation_0.mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5), - mask_isolation_0.rounded_corner_bounds); + mask_isolation_0.mask_filter_info.rounded_corner_bounds()); EXPECT_FALSE(mask_isolation_0.HasRenderSurface()); } @@ -3560,9 +3560,9 @@ *GetPropertyTrees().effect_tree.Node(mask_isolation_0_id); ASSERT_EQ(e0_id, mask_isolation_0.parent_id); EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode); - EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner); + EXPECT_TRUE(mask_isolation_0.mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5), - mask_isolation_0.rounded_corner_bounds); + mask_isolation_0.mask_filter_info.rounded_corner_bounds()); EXPECT_FALSE(mask_isolation_0.HasRenderSurface()); int t1_id = content1->transform_tree_index(); @@ -3580,9 +3580,9 @@ EXPECT_NE(mask_isolation_0_id, mask_isolation_1_id); ASSERT_EQ(e0_id, mask_isolation_1.parent_id); EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_1.blend_mode); - EXPECT_TRUE(mask_isolation_1.is_fast_rounded_corner); + EXPECT_TRUE(mask_isolation_1.mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5), - mask_isolation_1.rounded_corner_bounds); + mask_isolation_1.mask_filter_info.rounded_corner_bounds()); EXPECT_FALSE(mask_isolation_1.HasRenderSurface()); } @@ -3641,9 +3641,9 @@ int e2_id = content2->effect_tree_index(); const cc::EffectNode& cc_e2 = *GetPropertyTrees().effect_tree.Node(e2_id); - EXPECT_TRUE(cc_e2.is_fast_rounded_corner); + EXPECT_TRUE(cc_e2.mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5), - mask_isolation_0.rounded_corner_bounds); + mask_isolation_0.mask_filter_info.rounded_corner_bounds()); } TEST_P(PaintArtifactCompositorTest, SynthesizedClipRespectOutputClip) { @@ -3696,9 +3696,9 @@ *GetPropertyTrees().effect_tree.Node(mask_isolation_0_id); ASSERT_EQ(e0_id, mask_isolation_0.parent_id); EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode); - EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner); + EXPECT_TRUE(mask_isolation_0.mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5), - mask_isolation_0.rounded_corner_bounds); + mask_isolation_0.mask_filter_info.rounded_corner_bounds()); EXPECT_FALSE(mask_isolation_0.HasRenderSurface()); EXPECT_EQ(c1_id, content1->clip_tree_index()); @@ -3710,9 +3710,9 @@ int e1_id = mask_isolation_1.parent_id; const cc::EffectNode& cc_e1 = *GetPropertyTrees().effect_tree.Node(e1_id); ASSERT_EQ(e0_id, cc_e1.parent_id); - EXPECT_TRUE(mask_isolation_1.is_fast_rounded_corner); + EXPECT_TRUE(mask_isolation_1.mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5), - mask_isolation_1.rounded_corner_bounds); + mask_isolation_1.mask_filter_info.rounded_corner_bounds()); EXPECT_FALSE(mask_isolation_1.HasRenderSurface()); EXPECT_EQ(c1_id, content2->clip_tree_index()); @@ -3723,9 +3723,9 @@ EXPECT_NE(mask_isolation_1_id, mask_isolation_2_id); ASSERT_EQ(e0_id, mask_isolation_2.parent_id); EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_2.blend_mode); - EXPECT_TRUE(mask_isolation_2.is_fast_rounded_corner); + EXPECT_TRUE(mask_isolation_2.mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5), - mask_isolation_2.rounded_corner_bounds); + mask_isolation_2.mask_filter_info.rounded_corner_bounds()); EXPECT_FALSE(mask_isolation_2.HasRenderSurface()); } @@ -3781,9 +3781,9 @@ *GetPropertyTrees().effect_tree.Node(mask_isolation_0_id); ASSERT_EQ(e0_id, mask_isolation_0.parent_id); EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode); - EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner); + EXPECT_TRUE(mask_isolation_0.mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5), - mask_isolation_0.rounded_corner_bounds); + mask_isolation_0.mask_filter_info.rounded_corner_bounds()); EXPECT_EQ(c1_id, content1->clip_tree_index()); int e1_id = content1->effect_tree_index(); @@ -3795,9 +3795,9 @@ EXPECT_NE(mask_isolation_0_id, mask_isolation_1_id); ASSERT_EQ(e0_id, mask_isolation_1.parent_id); EXPECT_EQ(SkBlendMode::kMultiply, mask_isolation_1.blend_mode); - EXPECT_TRUE(mask_isolation_1.is_fast_rounded_corner); + EXPECT_TRUE(mask_isolation_1.mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5), - mask_isolation_1.rounded_corner_bounds); + mask_isolation_1.mask_filter_info.rounded_corner_bounds()); EXPECT_EQ(c1_id, content2->clip_tree_index()); int mask_isolation_2_id = content2->effect_tree_index(); @@ -3807,9 +3807,9 @@ EXPECT_NE(mask_isolation_1_id, mask_isolation_2_id); ASSERT_EQ(e0_id, mask_isolation_2.parent_id); EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode); - EXPECT_TRUE(mask_isolation_2.is_fast_rounded_corner); + EXPECT_TRUE(mask_isolation_2.mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5), - mask_isolation_2.rounded_corner_bounds); + mask_isolation_2.mask_filter_info.rounded_corner_bounds()); } TEST_P(PaintArtifactCompositorTest, SynthesizedClipDelegateBackdropFilter) { @@ -3878,10 +3878,10 @@ EXPECT_EQ(t0_id, mask_isolation_0.transform_id); EXPECT_EQ(c1_id, mask_isolation_0.clip_id); EXPECT_TRUE(mask_isolation_0.backdrop_filters.IsEmpty()); - EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner); + EXPECT_TRUE(mask_isolation_0.mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(1.0f, mask_isolation_0.opacity); EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5), - mask_isolation_0.rounded_corner_bounds); + mask_isolation_0.mask_filter_info.rounded_corner_bounds()); EXPECT_EQ(t1_id, content1->transform_tree_index()); int c2_id = content1->clip_tree_index(); @@ -3905,10 +3905,11 @@ EXPECT_EQ(t1_id, mask_isolation_1.transform_id); EXPECT_EQ(c2_id, mask_isolation_1.clip_id); EXPECT_FALSE(mask_isolation_1.backdrop_filters.IsEmpty()); - EXPECT_FALSE(mask_isolation_1.is_fast_rounded_corner); + EXPECT_FALSE(mask_isolation_1.mask_filter_info.is_fast_rounded_corner()); // Opacity should also be moved to mask_isolation_1. EXPECT_EQ(0.5f, mask_isolation_1.opacity); - EXPECT_EQ(gfx::RRectF(), mask_isolation_1.rounded_corner_bounds); + EXPECT_EQ(gfx::RRectF(), + mask_isolation_1.mask_filter_info.rounded_corner_bounds()); EXPECT_EQ(t0_id, clip_mask1->transform_tree_index()); EXPECT_EQ(c2_id, clip_mask1->clip_tree_index()); @@ -3933,10 +3934,10 @@ EXPECT_EQ(t0_id, mask_isolation_2.transform_id); EXPECT_EQ(c1_id, mask_isolation_2.clip_id); EXPECT_TRUE(mask_isolation_2.backdrop_filters.IsEmpty()); - EXPECT_TRUE(mask_isolation_2.is_fast_rounded_corner); + EXPECT_TRUE(mask_isolation_2.mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(1.0f, mask_isolation_2.opacity); EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5), - mask_isolation_2.rounded_corner_bounds); + mask_isolation_2.mask_filter_info.rounded_corner_bounds()); } TEST_P(PaintArtifactCompositorTest, SynthesizedClipMultipleNonBackdropEffects) { @@ -4002,9 +4003,9 @@ ASSERT_EQ(e0_id, mask_isolation.parent_id); EXPECT_EQ(c1_id, mask_isolation.clip_id); - EXPECT_TRUE(mask_isolation.is_fast_rounded_corner); + EXPECT_TRUE(mask_isolation.mask_filter_info.is_fast_rounded_corner()); EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5), - mask_isolation.rounded_corner_bounds); + mask_isolation.mask_filter_info.rounded_corner_bounds()); EXPECT_EQ(c0_id, content2->clip_tree_index()); EXPECT_EQ(e0_id, content2->effect_tree_index());
diff --git a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc index bb9b299..ab79469 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
@@ -639,7 +639,7 @@ DCHECK(mask_isolation); bool needs_layer = !pending_synthetic_mask_layers_.Contains(mask_isolation->id) && - mask_isolation->rounded_corner_bounds.IsEmpty(); + mask_isolation->mask_filter_info.IsEmpty(); CompositorElementId mask_isolation_id, mask_effect_id; SynthesizedClip& clip = client_.CreateOrReuseSynthesizedClipLayer( @@ -984,9 +984,9 @@ // is used. See PropertyTreeManager::EmitClipMaskLayer(). if (SupportsShaderBasedRoundedCorner(*pending_clip.clip, pending_clip.type, next_effect)) { - synthetic_effect.rounded_corner_bounds = - gfx::RRectF(pending_clip.clip->PixelSnappedClipRect()); - synthetic_effect.is_fast_rounded_corner = true; + synthetic_effect.mask_filter_info = gfx::MaskFilterInfo( + gfx::RRectF(pending_clip.clip->PixelSnappedClipRect()), + /*is_fast_rounded_corner=*/true); // Nested rounded corner clips need to force render surfaces for // clips other than the leaf ones, because the compositor doesn't
diff --git a/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc b/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc index b902879..4d090c9 100644 --- a/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc +++ b/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc
@@ -110,15 +110,15 @@ gfx::Rect visible_quad_rect = quad_rect; gfx::Rect clip_rect; - gfx::RRectF rounded_corner_bounds; + gfx::MaskFilterInfo mask_filter_info; bool is_clipped = false; float draw_opacity = 1.0f; int sorting_context_id = 0; resource_updater_->AppendQuads(render_pass, std::move(frame), transform, - quad_rect, visible_quad_rect, - rounded_corner_bounds, clip_rect, is_clipped, - is_opaque, draw_opacity, sorting_context_id); + quad_rect, visible_quad_rect, mask_filter_info, + clip_rect, is_clipped, is_opaque, draw_opacity, + sorting_context_id); } void VideoFrameResourceProvider::ReleaseFrameResources() {
diff --git a/third_party/blink/renderer/platform/widget/compositing/android_webview/synchronous_layer_tree_frame_sink.cc b/third_party/blink/renderer/platform/widget/compositing/android_webview/synchronous_layer_tree_frame_sink.cc index 64e049c..f7a81e19 100644 --- a/third_party/blink/renderer/platform/widget/compositing/android_webview/synchronous_layer_tree_frame_sink.cc +++ b/third_party/blink/renderer/platform/widget/compositing/android_webview/synchronous_layer_tree_frame_sink.cc
@@ -355,9 +355,10 @@ embed_render_pass->CreateAndAppendDrawQuad<viz::SurfaceDrawQuad>(); shared_quad_state->SetAll( child_transform, gfx::Rect(child_size), gfx::Rect(child_size), - gfx::RRectF() /* rounded_corner_bounds */, gfx::Rect() /* clip_rect */, - false /* is_clipped */, are_contents_opaque /* are_contents_opaque */, - 1.f /* opacity */, SkBlendMode::kSrcOver, 0 /* sorting_context_id */); + gfx::MaskFilterInfo() /* mask_filter_info */, + gfx::Rect() /* clip_rect */, false /* is_clipped */, + are_contents_opaque /* are_contents_opaque */, 1.f /* opacity */, + SkBlendMode::kSrcOver, 0 /* sorting_context_id */); surface_quad->SetNew( shared_quad_state, gfx::Rect(child_size), gfx::Rect(child_size), viz::SurfaceRange(
diff --git a/third_party/blink/tools/BUILD.gn b/third_party/blink/tools/BUILD.gn index 62c41ca..b243b05 100644 --- a/third_party/blink/tools/BUILD.gn +++ b/third_party/blink/tools/BUILD.gn
@@ -58,15 +58,32 @@ ] } -group("wpt_tests_mojo_bindings") { +group("wpt_tests_base_mojo_bindings") { testonly = true data_deps = [ "//:layout_test_data_mojo_bindings", "//:layout_test_data_mojo_bindings_lite", + "//content/test:mojo_bindings_web_test_mojom_js_data_deps", "//content/test:mojo_web_test_bindings_js_data_deps", - "//device/vr/public/mojom:mojom_js_data_deps", "//mojo/public/interfaces/bindings/tests:test_data_deps", "//mojo/public/js/ts/bindings/tests:test_interfaces_js_data_deps", "//mojo/public/mojom/base:base_js_data_deps", ] } + +group("wpt_tests_mojo_bindings") { + testonly = true + data_deps = [ + ":wpt_tests_base_mojo_bindings", + "//device/bluetooth/public/mojom:fake_bluetooth_interfaces_js_data_deps", + "//device/vr/public/mojom:mojom_js_data_deps", + "//media/capture/mojom:image_capture_js_data_deps", + "//media/midi:mojo_js_data_deps", + "//services/device/public/mojom:generic_sensor_js_data_deps", + "//services/device/public/mojom:mojom_js_data_deps", + "//services/device/public/mojom:usb_js_data_deps", + "//services/shape_detection/public/mojom:mojom_js_data_deps", + "//skia/public/mojom:mojom_js_data_deps", + "//third_party/blink/public/mojom:mojom_platform_js_data_deps", + ] +}
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index bae503e..86e27df 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -3393,7 +3393,6 @@ crbug.com/618969 external/wpt/css/css-grid/subgrid/* [ Skip ] # [layout-ng-grid] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/abspos/absolute-positioning-changing-containing-block-001.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/abspos/absolute-positioning-definite-sizes-001.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/abspos/absolute-positioning-grid-container-containing-block-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/abspos/absolute-positioning-grid-container-parent-001.html [ Failure ] @@ -3685,9 +3684,6 @@ crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-5.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-6.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-7.html [ Failure Crash ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-8.html [ Failure Crash ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-9.html [ Failure Crash ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-10.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-place-content-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-row-axis-alignment-positioned-items-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/alignment/grid-row-axis-alignment-positioned-items-002.html [ Failure Crash ] @@ -3893,11 +3889,6 @@ crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-definition/grid-template-columns-rows-resolved-values-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-definition/grid-template-columns-rows-resolved-values-001.tentative.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-definition/grid-template-rows-fit-content-001.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-item-non-auto-height-stretch-001.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-item-non-auto-height-stretch-002.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-item-non-auto-height-stretch-003.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-item-non-auto-height-stretch-004.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/anonymous-grid-item-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/explicitly-sized-grid-item-as-table.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-automatic-minimum-intrinsic-aspect-ratio-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-inline-items-001.html [ Failure Crash ] @@ -3925,14 +3916,9 @@ crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-inline-z-axis-ordering-overlapped-items-004.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-inline-z-axis-ordering-overlapped-items-005.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-inline-z-axis-ordering-overlapped-items-006.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-item-containing-block-001.html [ Pass ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-item-containing-block-002.html [ Pass ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-item-containing-block-003.html [ Pass ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-item-containing-block-004.html [ Pass ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-item-dynamic-min-contribution-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-item-flex-container-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-item-margins-and-writing-modes-001.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-item-min-auto-size-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-item-percentage-sizes-001.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-item-percentage-sizes-002.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-item-percentage-sizes-003.html [ Failure ] @@ -3974,8 +3960,6 @@ crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-005.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-006.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-007.html [ Failure Crash ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-008.html [ Failure Crash ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-009.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-010.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-011.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-012.html [ Failure Crash ] @@ -3991,17 +3975,13 @@ crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-layout-grid-in-grid.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-layout-z-order-a.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-layout-z-order-b.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-minimum-size-grid-items-007.html [ Failure Crash ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-minimum-size-grid-items-009.html [ Failure Crash ] +crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-minimum-size-grid-items-007.html [ Failure ] +crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-minimum-size-grid-items-009.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-minimum-size-grid-items-010.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-minimum-size-grid-items-011.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-minimum-size-grid-items-012.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-minimum-size-grid-items-013.html [ Pass ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-minimum-size-grid-items-014.html [ Pass ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-minimum-size-grid-items-015.html [ Pass ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-minimum-size-grid-items-016.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-minimum-size-grid-items-017.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-minimum-size-grid-items-018.html [ Pass ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-minimum-size-grid-items-019.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-minimum-size-grid-items-020.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-minimum-size-grid-items-021.html [ Failure ] @@ -4021,22 +4001,17 @@ crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-z-axis-ordering-overlapped-items-004.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-z-axis-ordering-overlapped-items-005.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/grid-z-axis-ordering-overlapped-items-006.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/item-with-table-with-infinite-max-intrinsic-width.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/percentage-size-replaced-subitems-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/percentage-size-subitems-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/remove-svg-grid-item-001.html [ Failure Crash ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-items/table-with-infinite-max-intrinsic-width.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-layout-properties.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/column-property-should-not-apply-on-grid-container-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/compute-intrinsic-widths-scrollbar-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/display-grid.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/display-inline-grid.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/fixed-width-intrinsic-width-should-exclude-scrollbar-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-areas-overflowing-grid-container-004.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-areas-overflowing-grid-container-005.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-areas-overflowing-grid-container-006.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-areas-overflowing-grid-container-007.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-areas-overflowing-grid-container-008.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-box-sizing-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-button-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-container-ignores-first-letter-001.html [ Failure Crash ] @@ -4049,7 +4024,6 @@ crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-container-scrollbars-sizing-002.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-container-sizing-constraints-001.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-display-grid-001.html [ Failure Crash ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-display-inline-grid-001.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-first-letter-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-first-letter-002.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-first-letter-003.html [ Failure Crash ] @@ -4069,7 +4043,6 @@ crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-inline-first-line-002.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-inline-first-line-003.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-inline-float-001.html [ Failure Crash ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-inline-floats-no-intrude-001.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-inline-margins-no-collapse-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-inline-vertical-align-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-model/grid-item-accepts-first-letter-001.html [ Failure Crash ] @@ -4100,7 +4073,6 @@ crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-as-flex-item-should-not-shrink-to-fit-005.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-as-flex-item-should-not-shrink-to-fit-006.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-as-flex-item-should-not-shrink-to-fit-007.html [ Failure Crash ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-as-flex-item-should-not-shrink-to-fit-008.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-automatic-minimum-for-auto-columns-001.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-container-percentage-001.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/layout-algorithm/grid-container-percentage-002.html [ Failure ] @@ -4137,7 +4109,7 @@ crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/placement/grid-auto-flow-sparse-001.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/placement/grid-auto-placement-implicit-tracks-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/placement/grid-container-change-grid-tracks-recompute-child-positions-001.html [ Failure Crash ] -crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/placement/grid-container-change-named-grid-recompute-child-positions-001.html [ Failure ] +crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/placement/grid-container-change-named-grid-recompute-child-positions-001.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/placement/grid-layout-grid-span.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/placement/grid-layout-lines-shorthands.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/placement/grid-layout-lines.html [ Failure Crash ] @@ -4153,20 +4125,15 @@ crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/placement/grid-placement-using-named-grid-lines-009.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/auto-content-resolution-columns.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/auto-content-resolution-rows.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/breadth-size-resolution-grid.html [ Pass ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/calc-resolution-grid-item.html [ Pass ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/containing-block-grids.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/flex-and-content-sized-resolution-columns.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/flex-and-intrinsic-sizes.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/flex-content-sized-column-use-available-width.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/flex-content-sized-columns-resize.html [ Failure Timeout ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/floating-empty-grids.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-auto-columns-rows-auto-flow-resolution.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-auto-columns-rows-get-set.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-auto-columns-rows-resolution.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-auto-columns-rows-update.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-auto-flow-resolution.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-auto-flow-update.html [ Failure ] +crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-auto-flow-resolution.html [ Failure Crash ] +crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-auto-flow-update.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-auto-repeat-huge-grid.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-columns-rows-get-set-multiple.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-columns-rows-get-set.html [ Failure Crash ] @@ -4204,7 +4171,7 @@ crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-item-negative-indexes.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-item-negative-integer-explicit-grid-resolution.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-item-negative-position-resolution.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-item-order-auto-flow-resolution.html [ Failure ] +crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-item-order-auto-flow-resolution.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-item-order-paint-order.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-item-overflow-paint.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-item-overflow.html [ Failure Crash ] @@ -4223,7 +4190,6 @@ crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-item-text-background-not-interleaved.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-item-unknown-named-grid-line-resolution.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-item-with-border-in-fr.html [ Failure Crash ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-item-with-border-in-intrinsic.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-item-with-percent-height-in-auto-height-grid-resolution.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-item-with-percent-height-replaced-element.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-item-with-percent-min-max-height-dynamic.html [ Failure ] @@ -4277,14 +4243,11 @@ crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/named-grid-areas-dynamic-with-media-query.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/named-grid-line-get-set.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/named-grid-lines-computed-style-implicit-tracks.html [ Failure Crash ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/named-grid-lines-with-named-grid-areas-dynamic-get-set.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/named-grid-lines-with-named-grid-areas-resolution.html [ Failure ] +crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/named-grid-lines-with-named-grid-areas-dynamic-get-set.html [ Failure Crash ] +crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/named-grid-lines-with-named-grid-areas-resolution.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/negative-growth-share-as-infinity-crash.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/non-grid-columns-rows-get-set.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/painting-item-marginbox-overflowing-grid-area.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-update.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/percent-grid-item-in-percent-grid-track.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/percent-intrinsic-track-breadth.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/percent-of-indefinite-track-size-in-auto.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/percent-of-indefinite-track-size.html [ Failure Crash ] @@ -4293,7 +4256,6 @@ crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/percent-resolution-grid-item-children.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/percent-track-breadths-regarding-container-size.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/place-cell-by-index.html [ Failure ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/positioned-grid-container-item-percentage-size.html [ Pass ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/positioned-grid-container-percentage-tracks.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/preferred-width-computed-after-layout.html [ Failure Crash ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/relayout-align-items-changed.html [ Failure ] @@ -4302,17 +4264,10 @@ crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/relayout-justify-items-changed.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/relayout-justify-self-changed.html [ Failure ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/repeating-layout-must-produce-the-same-results.html [ Failure Crash ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/scrolled-grid-painting-overflow.html [ Pass ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/scrolled-grid-painting.html [ Pass ] # These pass but hit DCHECKS -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/changing-content-property-on-nested-grid-should-not-crash.html [ Crash ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-item-stretching-must-not-depend-on-previous-layouts.html [ Crash ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-self-baseline-and-flex-tracks-with-indefinite-container-crash.html [ Crash ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/grid-self-baseline-followed-by-item-style-change-should-not-crash.html [ Crash ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/percent-resolution-grid-item.html [ Crash ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/quirks-mode-percent-resolution-grid-item.html [ Crash ] -crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/setting-node-properties-to-null-during-layout-should-not-crash.html [ Crash ] +crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-definition/grid-add-item-with-positioned-items-crash.html [ Crash ] +crbug.com/1045599 virtual/layout-ng-grid/external/wpt/css/css-grid/grid-definition/grid-add-positioned-block-item-after-inline-item-crash.html [ Crash ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/mozilla/grid-repeat-auto-fill-fit-001.html [ Crash ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/mozilla/grid-repeat-auto-fill-fit-002.html [ Crash ] crbug.com/1045599 virtual/layout-ng-grid/fast/css-grid-layout/mozilla/grid-repeat-auto-fill-fit-003.html [ Crash ]
diff --git a/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGElement.className-01.svg b/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGElement.className-01.svg new file mode 100644 index 0000000..3812135 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGElement.className-01.svg
@@ -0,0 +1,15 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml"> + <title>SVGElement.prototype.className: Reflects to .classList</title> + <h:link rel="help" href="https://svgwg.org/svg2-draft/types.html#__svg__SVGElement__className"/> + <h:script src="/resources/testharness.js"/> + <h:script src="/resources/testharnessreport.js"/> + <script> + test(() => { + const element = document.createElementNS('http://www.w3.org/2000/svg', 'g'); + + assert_false(element.classList.contains('one'), "classList is initially empty"); + element.className.baseVal = 'one'; + assert_true(element.classList.contains('one'), "className should reflect to classList"); + }); +</script> +</svg>
diff --git a/third_party/blink/web_tests/fast/events/mouse-cursor-image-set-svg.html b/third_party/blink/web_tests/fast/events/mouse-cursor-image-set-svg.html index 90e2464..35f566a 100644 --- a/third_party/blink/web_tests/fast/events/mouse-cursor-image-set-svg.html +++ b/third_party/blink/web_tests/fast/events/mouse-cursor-image-set-svg.html
@@ -52,6 +52,13 @@ checkCursors(); // Repeat in high-dpi mode testRunner.setBackingScaleFactor(2, function() { + // Flush style (and layout) to ensure that requests for the (cursor) resources + // referenced by style has been issued. This means that the ordering request performed + // below will be able to re-use the same (internal) resource if it is still pending. + // If the actual cursor request has already completed before the ordering request is + // issued then the ordering request will not re-use the same resource, but ordering is + // still guaranteed in that case. + testContainer.offsetTop; // Failed images are apparently reset on scale factor change. loadImages([{ url: 'doesntexist.svg', error: true }], function() {
diff --git a/third_party/blink/web_tests/fast/events/mouse-cursor-image-set.html b/third_party/blink/web_tests/fast/events/mouse-cursor-image-set.html index 08d8341..9ab3a6a5 100644 --- a/third_party/blink/web_tests/fast/events/mouse-cursor-image-set.html +++ b/third_party/blink/web_tests/fast/events/mouse-cursor-image-set.html
@@ -53,6 +53,13 @@ checkCursors(); // Repeat in high-dpi mode testRunner.setBackingScaleFactor(2, function() { + // Flush style (and layout) to ensure that requests for the (cursor) resources + // referenced by style has been issued. This means that the ordering request performed + // below will be able to re-use the same (internal) resource if it is still pending. + // If the actual cursor request has already completed before the ordering request is + // issued then the ordering request will not re-use the same resource, but ordering is + // still guaranteed in that case. + testContainer.offsetTop; // Failed images are apparently reset on scale factor change. loadImages([{ url: 'doesntexist.png', error: true }], function() {
diff --git a/third_party/d3/OWNERS b/third_party/d3/OWNERS index 47ddd432..1cebebb 100644 --- a/third_party/d3/OWNERS +++ b/third_party/d3/OWNERS
@@ -1,4 +1,6 @@ siggi@chromium.org chrisha@chromium.org +joonbug@chromium.org # COMPONENT: Internals>ResourceCoordinator +# COMPONENT: OS>Systems>Diagnostics \ No newline at end of file
diff --git a/tools/android/dependency_analysis/print_class_dependencies.py b/tools/android/dependency_analysis/print_class_dependencies.py index ce9bae7..e017b2b 100755 --- a/tools/android/dependency_analysis/print_class_dependencies.py +++ b/tools/android/dependency_analysis/print_class_dependencies.py
@@ -16,12 +16,19 @@ import serialization +# Return values of categorize_dependency(). +IGNORE = 'ignore' +CLEAR = 'clear' +PRINT = 'print' + + @dataclass class PrintMode: """Options of how and which dependencies to output.""" inbound: bool outbound: bool ignore_modularized: bool + ignore_same_package: bool fully_qualified: bool @@ -100,15 +107,35 @@ return class_name in IGNORED_CLASSES -def print_class_nodes(class_nodes: List[class_dependency.JavaClass], - print_mode: PrintMode, class_name: str, - direction: str) -> TargetDependencies: +def categorize_dependency(from_class: class_dependency.JavaClass, + to_class: class_dependency.JavaClass, + ignore_modularized: bool, + ignore_same_package: bool) -> str: + """Decides if a class dependency should be printed, cleared, or ignored.""" + if is_ignored_class_dependency(to_class.name): + return IGNORE + if ignore_modularized and all( + is_allowed_target_dependency(target) + for target in to_class.build_targets): + return CLEAR + if ignore_same_package and to_class.package == from_class.package: + return IGNORE + return PRINT + + +def print_class_dependencies(to_classes: List[class_dependency.JavaClass], + print_mode: PrintMode, + from_class: class_dependency.JavaClass, + direction: str) -> TargetDependencies: """Prints the class dependencies to or from a class, grouped by target. If direction is OUTBOUND and print_mode.ignore_modularized is True, omits modularized outbound dependencies and returns the build targets that need to be added for those dependencies. In other cases, returns an empty TargetDependencies. + + If print_mode.ignore_same_package is True, omits outbound dependencies in + the same package. """ ignore_modularized = direction == OUTBOUND and print_mode.ignore_modularized bullet_point = '<-' if direction == INBOUND else '->' @@ -121,43 +148,48 @@ suspect_dependencies = 0 target_dependencies = TargetDependencies() - class_nodes = sorted(class_nodes, key=lambda c: str(c.build_targets)) + to_classes = sorted(to_classes, key=lambda c: str(c.build_targets)) last_build_target = None - for class_node in class_nodes: - if is_ignored_class_dependency(class_node.name): + + for to_class in to_classes: + # Check if dependency should be ignored due to --ignore-modularized, + # --ignore-same-package, or due to being an ignored class. + # Check if dependency should be listed as a cleared dep. + ignore_allow = categorize_dependency(from_class, to_class, + ignore_modularized, + print_mode.ignore_same_package) + if ignore_allow == CLEAR: + target_dependencies.update_with_class_node(to_class) continue - if ignore_modularized: - if all( - is_allowed_target_dependency(target) - for target in class_node.build_targets): - target_dependencies.update_with_class_node(class_node) - continue - else: - suspect_dependencies += 1 - build_target = str(class_node.build_targets) + elif ignore_allow == IGNORE: + continue + + # Print the dependency + suspect_dependencies += 1 + build_target = str(to_class.build_targets) if last_build_target != build_target: build_target_names = [ get_build_target_name_to_display(target, print_mode) - for target in class_node.build_targets + for target in to_class.build_targets ] build_target_names_string = ", ".join(build_target_names) print_backlog.append((4, f'[{build_target_names_string}]')) last_build_target = build_target - display_name = get_class_name_to_display(class_node.name, print_mode) + display_name = get_class_name_to_display(to_class.name, print_mode) print_backlog.append((8, f'{bullet_point} {display_name}')) # Print header + class_name = get_class_name_to_display(from_class.name, print_mode) if ignore_modularized: - cleared = len(class_nodes) - suspect_dependencies + cleared = len(to_classes) - suspect_dependencies print(f'{class_name} has {suspect_dependencies} outbound dependencies ' f'that may need to be broken (omitted {cleared} cleared ' f'dependencies):') else: if direction == INBOUND: - print(f'{class_name} has {len(class_nodes)} inbound dependencies:') + print(f'{class_name} has {len(to_classes)} inbound dependencies:') else: - print( - f'{class_name} has {len(class_nodes)} outbound dependencies:') + print(f'{class_name} has {len(to_classes)} outbound dependencies:') # Print build targets and dependencies for indent, message in print_backlog: @@ -173,15 +205,14 @@ """Prints dependencies for a valid key into the class graph.""" target_dependencies = TargetDependencies() node: class_dependency.JavaClass = class_graph.get_node_by_key(key) - class_name = get_class_name_to_display(node.name, print_mode) if print_mode.inbound: - print_class_nodes(graph.sorted_nodes_by_name(node.inbound), print_mode, - class_name, INBOUND) + print_class_dependencies(graph.sorted_nodes_by_name(node.inbound), + print_mode, node, INBOUND) if print_mode.outbound: - target_dependencies = print_class_nodes( - graph.sorted_nodes_by_name(node.outbound), print_mode, class_name, + target_dependencies = print_class_dependencies( + graph.sorted_nodes_by_name(node.outbound), print_mode, node, OUTBOUND) return target_dependencies @@ -235,6 +266,10 @@ help='Do not print outbound dependencies on ' 'allowed (modules, components, base, etc.) ' 'dependencies.') + arg_parser.add_argument('--ignore-same-package', + action='store_true', + help='Do not print outbound dependencies on ' + 'classes in the same package.') arguments = arg_parser.parse_args() if not arguments.class_names and not arguments.package_names: @@ -244,6 +279,7 @@ print_mode = PrintMode(inbound=not arguments.outbound_only, outbound=not arguments.inbound_only, ignore_modularized=arguments.ignore_modularized, + ignore_same_package=arguments.ignore_same_package, fully_qualified=arguments.fully_qualified) class_graph, package_graph = \
diff --git a/tools/binary_size/libsupersize/static/auth.js b/tools/binary_size/libsupersize/static/auth.js index 537d21a..4a9a75e 100644 --- a/tools/binary_size/libsupersize/static/auth.js +++ b/tools/binary_size/libsupersize/static/auth.js
@@ -38,6 +38,9 @@ } function requiresAuthentication() { - let urlParams = new URLSearchParams(window.location.search); - return !!urlParams.get('authenticate'); + // Assume everything requires auth except public trybot and one-offs. + const isPublicTrybot = window.location.search.indexOf( + 'chromium-binary-size-trybot-results%2Fandroid-binary-size') != -1; + const isOneOff = window.location.search.indexOf('%2Foneoffs%2F') != -1; + return !isPublicTrybot && !isOneOff; }
diff --git a/tools/binary_size/libsupersize/static/index.js b/tools/binary_size/libsupersize/static/index.js index 329fc44..bce93c64 100644 --- a/tools/binary_size/libsupersize/static/index.js +++ b/tools/binary_size/libsupersize/static/index.js
@@ -30,7 +30,7 @@ event.preventDefault(); const dataUrl = fetchDataUrl(); window.open( - `${FIREBASE_HOST}/viewer.html?load_url=${dataUrl}&authenticate=1`); + `${FIREBASE_HOST}/viewer.html?load_url=${dataUrl}`); }); }
diff --git a/tools/binary_size/trybot_commit_size_checker.py b/tools/binary_size/trybot_commit_size_checker.py index 2846ae9..d60c9cf 100755 --- a/tools/binary_size/trybot_commit_size_checker.py +++ b/tools/binary_size/trybot_commit_size_checker.py
@@ -26,8 +26,9 @@ _FOR_TESTING_LOG = 'for_test_log' _DEX_SYMBOLS_LOG = 'dex_symbols_log' _SIZEDIFF_FILENAME = 'supersize_diff.sizediff' -_HTML_REPORT_BASE_URL = ( - 'https://chrome-supersize.firebaseapp.com/viewer.html?load_url=') +_HTML_REPORT_URL = ( + 'https://chrome-supersize.firebaseapp.com/viewer.html?load_url={{' + + _SIZEDIFF_FILENAME + '}}') _MAX_DEX_METHOD_COUNT_INCREASE = 50 _MAX_NORMALIZED_INCREASE = 16 * 1024 _MAX_PAK_INCREASE = 1024 @@ -207,14 +208,7 @@ return None -def _CreateTigerViewerUrl(apk_name, sizediff_path): - ret = _HTML_REPORT_BASE_URL + sizediff_path - if 'Public' not in apk_name: - ret += '&authenticate=1' - return ret - - -def _GenerateBinarySizePluginDetails(apk_name, metrics): +def _GenerateBinarySizePluginDetails(metrics): binary_size_listings = [] for delta, log_name in metrics: listing = { @@ -237,8 +231,7 @@ binary_size_extras = [ { 'text': 'APK Breakdown', - 'url': _CreateTigerViewerUrl(apk_name, - '{{' + _SIZEDIFF_FILENAME + '}}') + 'url': _HTML_REPORT_URL }, ] @@ -359,8 +352,6 @@ status_code = 0 summary = '<br>' + checks_text.replace('\n', '<br>') - supersize_url = _CreateTigerViewerUrl(args.apk_name, - '{{' + _SIZEDIFF_FILENAME + '}}') links_json = [ { 'name': 'Binary Size Details', @@ -388,14 +379,13 @@ }, { 'name': 'SuperSize HTML Diff', - 'url': supersize_url, + 'url': _HTML_REPORT_URL, }, ] # Remove empty diffs (Mutable Constants, Dex Method, ...). links_json = [o for o in links_json if o.get('lines') or o.get('url')] - binary_size_plugin_json = _GenerateBinarySizePluginDetails( - args.apk_name, metrics) + binary_size_plugin_json = _GenerateBinarySizePluginDetails(metrics) results_json = { 'status_code': status_code,
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec index c996129..e00d9a1 100644 --- a/tools/gritsettings/resource_ids.spec +++ b/tools/gritsettings/resource_ids.spec
@@ -188,8 +188,8 @@ "chrome/browser/resources/tab_search/tab_search_resources.grd": { "includes": [1880], }, - "chrome/browser/resources/tab_strip/tab_strip_resources.grd": { - "structures": [1900], + "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/tab_strip/tab_strip_resources.grd": { + "META": {"sizes": {"includes": [20]}}, "includes": [1920], }, "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/welcome/welcome_resources.grd": { @@ -265,6 +265,13 @@ "chrome/browser/resources/webapks/webapks_ui_resources.grd": { "includes": [2220], }, + "chrome/browser/resources/webui_js_exception/webui_js_exception_resources.grd": { + "includes": [2230], + "structures": [2231], + }, + "chrome/browser/resources/webui_js_exception/webui_js_exception_resources_vulcanized.grd": { + "includes": [2232], + }, "components/sync/driver/resources.grd": { "includes": [2240], },
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 3b90b45..0bd19e8 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -275,8 +275,8 @@ 'Win10 Tests x64 1909': 'gpu_tests_release_bot_minimal_symbols', 'android-code-coverage': 'gpu_tests_android_release_bot_minimal_symbols_arm64_fastbuild_java_coverage', 'android-code-coverage-native': 'gpu_tests_android_release_bot_minimal_symbols_arm64_fastbuild_native_coverage', - 'android-marshmallow-arm64-16-core': 'gpu_tests_android_release_trybot_arm64_resource_whitelisting_fastbuild_java_coverage', - 'android-marshmallow-arm64-32-core': 'gpu_tests_android_release_trybot_arm64_resource_whitelisting_fastbuild_java_coverage', + 'android-marshmallow-arm64-16-core': 'gpu_tests_android_release_trybot_arm64_fastbuild', + 'android-marshmallow-arm64-32-core': 'gpu_tests_android_release_trybot_arm64_fastbuild', 'chromeos-amd64-generic-lacros-rel': 'chromeos_amd64-generic_lacros_rel', 'fuchsia-fyi-arm64-dbg': 'debug_bot_fuchsia_arm64', 'fuchsia-fyi-arm64-rel': 'release_bot_fuchsia_arm64', @@ -294,9 +294,9 @@ 'ios-simulator-cronet': 'ios_cronet_xctest', 'ios-simulator-multi-window': 'ios_simulator_debug_static_bot_multi_window_xctest', 'ios-webkit-tot': 'ios_simulator_debug_static_rbe_bot_xctest', - 'linux-8-core': 'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange_code_coverage', - 'linux-16-core': 'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange_code_coverage', - 'linux-32-core': 'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange_code_coverage', + 'linux-8-core': 'gpu_tests_release_trybot_no_symbols', + 'linux-16-core': 'gpu_tests_release_trybot_no_symbols', + 'linux-32-core': 'gpu_tests_release_trybot_no_symbols', 'linux-annotator-rel': 'release_bot', 'linux-blink-animation-use-time-delta': 'debug_bot_enable_blink_animation_use_time_delta', 'linux-blink-heap-concurrent-marking-tsan-rel': 'release_trybot_tsan', @@ -319,9 +319,9 @@ 'mac-hermetic-upgrade-rel': 'release_bot', 'mac-omaha-builder-rel': 'updater_release_bot', 'mac-upload-perfetto': 'release_bot', - 'win-8-core': 'gpu_tests_release_trybot_resource_whitelisting_code_coverage', - 'win-16-core': 'gpu_tests_release_trybot_resource_whitelisting_code_coverage', - 'win-32-core': 'gpu_tests_release_trybot_resource_whitelisting_code_coverage', + 'win-8-core': 'gpu_tests_release_trybot', + 'win-16-core': 'gpu_tests_release_trybot', + 'win-32-core': 'gpu_tests_release_trybot', 'win-annotator-rel': 'release_bot', 'win-celab-builder-rel': 'release_bot_minimal_symbols', 'win-omaha-builder-rel': 'updater_release_bot', @@ -1983,6 +1983,10 @@ 'use_clang_coverage', 'partial_code_coverage_instrumentation', ], + 'gpu_tests_release_trybot_no_symbols': [ + 'gpu_tests', 'release_trybot', 'no_symbols', + ], + 'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange': [ 'gpu_tests', 'release_trybot', 'no_symbols', 'use_dummy_lastchange', ],
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json index 12a51d81..c591e96 100644 --- a/tools/mb/mb_config_expectations/chromium.fyi.json +++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -253,41 +253,33 @@ }, "android-marshmallow-arm64-16-core": { "gn_args": { - "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt", "dcheck_always_on": true, "disable_android_lint": true, - "enable_resource_allowlist_generation": true, "ffmpeg_branding": "Chrome", "is_component_build": false, "is_debug": false, "proprietary_codecs": true, "symbol_level": 1, - "system_webview_package_name": "com.google.android.webview", "target_cpu": "arm64", "target_os": "android", "use_errorprone_java_compiler": false, "use_goma": true, - "use_jacoco_coverage": true, "use_static_angle": true } }, "android-marshmallow-arm64-32-core": { "gn_args": { - "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt", "dcheck_always_on": true, "disable_android_lint": true, - "enable_resource_allowlist_generation": true, "ffmpeg_branding": "Chrome", "is_component_build": false, "is_debug": false, "proprietary_codecs": true, "symbol_level": 1, - "system_webview_package_name": "com.google.android.webview", "target_cpu": "arm64", "target_os": "android", "use_errorprone_java_compiler": false, "use_goma": true, - "use_jacoco_coverage": true, "use_static_angle": true } }, @@ -499,43 +491,34 @@ }, "linux-16-core": { "gn_args": { - "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt", "dcheck_always_on": true, "ffmpeg_branding": "Chrome", "is_component_build": false, "is_debug": false, "proprietary_codecs": true, "symbol_level": 0, - "use_clang_coverage": true, - "use_dummy_lastchange": true, "use_goma": true } }, "linux-32-core": { "gn_args": { - "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt", "dcheck_always_on": true, "ffmpeg_branding": "Chrome", "is_component_build": false, "is_debug": false, "proprietary_codecs": true, "symbol_level": 0, - "use_clang_coverage": true, - "use_dummy_lastchange": true, "use_goma": true } }, "linux-8-core": { "gn_args": { - "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt", "dcheck_always_on": true, "ffmpeg_branding": "Chrome", "is_component_build": false, "is_debug": false, "proprietary_codecs": true, "symbol_level": 0, - "use_clang_coverage": true, - "use_dummy_lastchange": true, "use_goma": true } }, @@ -774,43 +757,34 @@ }, "win-16-core": { "gn_args": { - "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt", "dcheck_always_on": true, - "enable_resource_allowlist_generation": true, "ffmpeg_branding": "Chrome", "is_component_build": false, "is_debug": false, "proprietary_codecs": true, "symbol_level": 1, - "use_clang_coverage": true, "use_goma": true } }, "win-32-core": { "gn_args": { - "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt", "dcheck_always_on": true, - "enable_resource_allowlist_generation": true, "ffmpeg_branding": "Chrome", "is_component_build": false, "is_debug": false, "proprietary_codecs": true, "symbol_level": 1, - "use_clang_coverage": true, "use_goma": true } }, "win-8-core": { "gn_args": { - "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt", "dcheck_always_on": true, - "enable_resource_allowlist_generation": true, "ffmpeg_branding": "Chrome", "is_component_build": false, "is_debug": false, "proprietary_codecs": true, "symbol_level": 1, - "use_clang_coverage": true, "use_goma": true } },
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 32cc42d..ac91895 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -990,6 +990,10 @@ <int value="13" label="GenericErrorShown"> The generic error screen was shown to the user. </int> + <int value="14" label="DismissedButton"> + User has dismissed the promo by tapping on the dismissal button in the + bottom sheet. + </int> </enum> <enum name="AccountManagerAccountAdditionSource"> @@ -22253,6 +22257,7 @@ <int value="795" label="PhoneHubAllowed"/> <int value="796" label="PhoneHubNotificationsAllowed"/> <int value="797" label="PhoneHubTaskContinuationAllowed"/> + <int value="798" label="WifiSyncAndroidAllowed"/> </enum> <enum name="EnterprisePolicyDeviceIdValidity"> @@ -35966,6 +35971,9 @@ </enum> <enum name="HomeButtonPreferenceStateType"> + <obsolete> + Removed from code as of 10/2020. + </obsolete> <int value="0" label="User Disabled"/> <int value="1" label="User Enabled"/> <int value="2" label="Managed Disabled"/>
diff --git a/tools/metrics/histograms/histograms_xml/blink/histograms.xml b/tools/metrics/histograms/histograms_xml/blink/histograms.xml index 60d1c81..f305fb5 100644 --- a/tools/metrics/histograms/histograms_xml/blink/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/blink/histograms.xml
@@ -702,18 +702,6 @@ </summary> </histogram> -<histogram name="Blink.Fonts.HarfBuzzFaceZeroCopyAccess" enum="BooleanSuccess" - expires_after="M88"> - <owner>drott@chromium.org</owner> - <owner>layout-dev@chromium.org</owner> - <summary> - Counts success or failure of attempting to access font tables using the zero - copy instantiation method in the HarfBuzz integration layer. This value is - only recorded on non-Mac platforms. Reported each time a HarfBuzz face - object is created. - </summary> -</histogram> - <histogram name="Blink.Fonts.ShapeCache" units="units" expires_after="2021-10-15"> <owner>drott@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/browser/histograms.xml b/tools/metrics/histograms/histograms_xml/browser/histograms.xml index 4486008e..02be1c9 100644 --- a/tools/metrics/histograms/histograms_xml/browser/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/browser/histograms.xml
@@ -576,7 +576,7 @@ </histogram> <histogram name="BrowserServices.BrowsableIntentCheck" units="ms" - expires_after="M88"> + expires_after="M92"> <owner>peconn@chromium.org</owner> <owner>peter@chromium.org</owner> <summary> @@ -587,7 +587,7 @@ </histogram> <histogram name="BrowserServices.ClientAppDataLoad" units="ms" - expires_after="M88"> + expires_after="M92"> <owner>peconn@chromium.org</owner> <owner>peter@chromium.org</owner> <summary> @@ -598,7 +598,7 @@ </histogram> <histogram name="BrowserServices.ServiceTabResolveInfoQuery" units="ms" - expires_after="M88"> + expires_after="M92"> <owner>peconn@chromium.org</owner> <owner>peter@chromium.org</owner> <summary> @@ -607,7 +607,7 @@ </summary> </histogram> -<histogram name="BrowserServices.TwaOpenTime.V2" units="ms" expires_after="M88"> +<histogram name="BrowserServices.TwaOpenTime.V2" units="ms" expires_after="M92"> <owner>peconn@chromium.org</owner> <owner>peter@chromium.org</owner> <summary> @@ -617,7 +617,7 @@ </histogram> <histogram name="BrowserServices.VerificationResult" - enum="BrowserServicesVerificationResult" expires_after="M88"> + enum="BrowserServicesVerificationResult" expires_after="M92"> <owner>peconn@chromium.org</owner> <owner>peter@chromium.org</owner> <summary> @@ -627,7 +627,7 @@ </histogram> <histogram name="BrowserServices.VerificationTime.Offline" units="ms" - expires_after="M88"> + expires_after="M92"> <owner>peconn@chromium.org</owner> <owner>peter@chromium.org</owner> <summary> @@ -638,7 +638,7 @@ </histogram> <histogram name="BrowserServices.VerificationTime.Online" units="ms" - expires_after="M88"> + expires_after="M92"> <owner>peconn@chromium.org</owner> <owner>peter@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/histograms_xml/custom_tabs/histograms.xml b/tools/metrics/histograms/histograms_xml/custom_tabs/histograms.xml index 0d14620..c4c18b92 100644 --- a/tools/metrics/histograms/histograms_xml/custom_tabs/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/custom_tabs/histograms.xml
@@ -64,7 +64,7 @@ </histogram> <histogram name="CustomTabs.ConnectionStatusOnReturn.GSA" - enum="CustomTabsConnection" expires_after="M88"> + enum="CustomTabsConnection" expires_after="M92"> <owner>peconn@chromium.org</owner> <owner>peter@chromium.org</owner> <summary> @@ -77,7 +77,7 @@ </histogram> <histogram name="CustomTabs.ConnectionStatusOnReturn.NonGSA" - enum="CustomTabsConnection" expires_after="M88"> + enum="CustomTabsConnection" expires_after="M92"> <owner>peconn@chromium.org</owner> <owner>peter@chromium.org</owner> <summary> @@ -90,7 +90,7 @@ </histogram> <histogram base="true" name="CustomTabs.DetachedResourceRequest.Duration" - units="ms" expires_after="M87"> + units="ms" expires_after="M92"> <owner>lizeb@chromium.org</owner> <owner>cct-team@google.com</owner> <summary> @@ -101,7 +101,7 @@ </histogram> <histogram name="CustomTabs.DetachedResourceRequest.FinalStatus" - enum="NetErrorCodes" expires_after="M87"> + enum="NetErrorCodes" expires_after="M92"> <owner>lizeb@chromium.org</owner> <owner>cct-team@google.com</owner> <summary> @@ -113,7 +113,7 @@ </histogram> <histogram base="true" name="CustomTabs.DetachedResourceRequest.RedirectsCount" - units="redirects" expires_after="M87"> + units="redirects" expires_after="M92"> <owner>lizeb@chromium.org</owner> <owner>cct-team@google.com</owner> <summary> @@ -165,7 +165,7 @@ </histogram> <histogram name="CustomTabs.ParallelRequestStatusOnStart" - enum="CustomTabsParallelRequestStatusOnStart" expires_after="M87"> + enum="CustomTabsParallelRequestStatusOnStart" expires_after="M92"> <owner>lizeb@chromium.org</owner> <owner>cct-team@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/histograms_xml/gpu/histograms.xml b/tools/metrics/histograms/histograms_xml/gpu/histograms.xml index e173c3d..ece9c804 100644 --- a/tools/metrics/histograms/histograms_xml/gpu/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/gpu/histograms.xml
@@ -273,6 +273,11 @@ </histogram> <histogram name="GPU.ContextMemory" units="MB" expires_after="2020-09-13"> + <obsolete> + Obsoleted since 2020/10/15. Unused and expired. Replaced by + Memory.Gpu.PrivateMemoryFootprint, Memory.GPU.PeakMemoryUsage, and + Memory.GPU.PeakMemoryAllocationSource. + </obsolete> <owner>ericrk@chromium.org</owner> <summary>The amount of memory used by a GL Context.</summary> </histogram>
diff --git a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml index 8ada5cd..0d26252 100644 --- a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml +++ b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
@@ -6820,6 +6820,9 @@ </histogram_suffixes> <histogram_suffixes name="GPU_ContextType" separator="."> + <obsolete> + Expired in 2020/10/15. + </obsolete> <suffix name="GLES" label="GLES Context."/> <suffix name="WebGL" label="WebGL Context."/> <affected-histogram name="GPU.ContextMemory"/> @@ -6835,6 +6838,9 @@ </histogram_suffixes> <histogram_suffixes name="GPU_MemorySamplingTime" separator="."> + <obsolete> + Expired in 2020/10/15. + </obsolete> <suffix name="Periodic" label="Sampled periodically."/> <suffix name="Pressure" label="Sampled on CRITICAL memory pressure signal."/> <suffix name="Shutdown" label="Sampled at shutdown."/>
diff --git a/tools/metrics/histograms/histograms_xml/mobile/histograms.xml b/tools/metrics/histograms/histograms_xml/mobile/histograms.xml index a981400b..4b07bf5 100644 --- a/tools/metrics/histograms/histograms_xml/mobile/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/mobile/histograms.xml
@@ -579,6 +579,13 @@ </summary> </histogram> +<histogram name="MobileDownload.Location.Dialog.SuggestionSelected" + enum="BooleanSelected" expires_after="2021-03-01"> + <owner>xingliu@chromium.org</owner> + <owner>clank-downloads@google.com</owner> + <summary>Records the download location suggestion choice.</summary> +</histogram> + <histogram name="MobileDownload.Location.Dialog.Type" enum="DownloadLocationDialogType" expires_after="2021-03-01"> <owner>xingliu@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/obsolete_histograms.xml b/tools/metrics/histograms/histograms_xml/obsolete_histograms.xml index 1ddeaf6..0ff5c6c 100644 --- a/tools/metrics/histograms/histograms_xml/obsolete_histograms.xml +++ b/tools/metrics/histograms/histograms_xml/obsolete_histograms.xml
@@ -6520,6 +6520,21 @@ </summary> </histogram> +<histogram name="Blink.Fonts.HarfBuzzFaceZeroCopyAccess" enum="BooleanSuccess" + expires_after="M88"> + <obsolete> + Removed as of 10/15/2020. + </obsolete> + <owner>drott@chromium.org</owner> + <owner>layout-dev@chromium.org</owner> + <summary> + Counts success or failure of attempting to access font tables using the zero + copy instantiation method in the HarfBuzz integration layer. This value is + only recorded on non-Mac platforms. Reported each time a HarfBuzz face + object is created. + </summary> +</histogram> + <histogram name="Blink.Gesture.Merged" enum="GestureMergeState" expires_after="M77"> <obsolete>
diff --git a/tools/metrics/histograms/histograms_xml/omnibox/histograms.xml b/tools/metrics/histograms/histograms_xml/omnibox/histograms.xml index 5f71d84..6fa9d932 100644 --- a/tools/metrics/histograms/histograms_xml/omnibox/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/omnibox/histograms.xml
@@ -232,7 +232,8 @@ </histogram> <histogram name="Omnibox.DocumentSuggest.Requests" - enum="OmniboxDocumentSuggestRequests" expires_after="M88"> + enum="OmniboxDocumentSuggestRequests" expires_after="M95"> + <owner>manukh@chromium.org</owner> <owner>mpearson@chromium.org</owner> <owner>jdonnelly@chromium.org</owner> <owner>skare@chromium.org</owner> @@ -243,7 +244,8 @@ </histogram> <histogram name="Omnibox.DocumentSuggest.ResultCount" units="count" - expires_after="M88"> + expires_after="M95"> + <owner>manukh@chromium.org</owner> <owner>mpearson@chromium.org</owner> <owner>jdonnelly@chromium.org</owner> <owner>skare@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml index e2895785..caa09e2 100644 --- a/tools/metrics/histograms/histograms_xml/others/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml
@@ -13258,7 +13258,7 @@ </histogram> <histogram name="SingleWebsitePreferences.NavigatedFromToReset" - enum="SettingsNavigationSources" expires_after="M88"> + enum="SettingsNavigationSources" expires_after="M92"> <owner>peconn@chromium.org</owner> <owner>peter@chromium.org</owner> <summary> @@ -13871,8 +13871,8 @@ </summary> </histogram> -<histogram name="Sqlite.OpenFailure" enum="SqliteErrorCode" expires_after="M88"> - <owner>costan@google.com</owner> +<histogram name="Sqlite.OpenFailure" enum="SqliteErrorCode" expires_after="M95"> + <owner>pwnall@chromium.org</owner> <owner>src/storage/OWNERS</owner> <summary>Error which prevented database open.</summary> </histogram> @@ -14538,14 +14538,14 @@ (e.g. #:=:text=SELECTOR). Indicates source type that navigation originated from. It only know about search engines that come from the pre-populated list installed with Chrome. If the user uses a search engine not on the - list, it won't count as a search engine. This is even true if the user have - a custom search engine. These custom search engines can be created by hand - or auto-generated. In either case, it's not going to count as a search - engine. Also, it only checks to see if the *referrer* is from a domain - associated with search engine. If someone posts a link somewhere on a web - site that happens to have a search engine known to Google and that links - includes the fragment tokens, then if a user clicks that link, it'll look - like it came from a search engine even thought they did not. + list, it will be recorded as Unknown. This is even true if the user have a + custom search engine. These custom search engines can be created by hand or + auto-generated. In either case, it's not going to count as a search engine. + Also, it only checks to see if the *referrer* is from a domain associated + with search engine. If someone posts a link somewhere on a web site that + happens to have a search engine known to Google and that links includes the + fragment tokens, then if a user clicks that link, it'll look like it came + from a search engine even thought they did not. </summary> </histogram> @@ -15410,7 +15410,7 @@ </histogram> <histogram name="TrustedWebActivity.ClearDataDialogOnClearAppDataAccepted" - enum="Boolean" expires_after="M88"> + enum="Boolean" expires_after="M92"> <owner>peconn@chromium.org</owner> <owner>peter@chromium.org</owner> <summary> @@ -15420,7 +15420,7 @@ </histogram> <histogram name="TrustedWebActivity.ClearDataDialogOnUninstallAccepted" - enum="Boolean" expires_after="M88"> + enum="Boolean" expires_after="M92"> <owner>peconn@chromium.org</owner> <owner>peter@chromium.org</owner> <summary> @@ -15431,7 +15431,7 @@ <histogram name="TrustedWebActivity.DelegatedNotificationSmallIconFallback" enum="TrustedWebActivityDelegatedNotificationSmallIconFallback" - expires_after="M88"> + expires_after="M92"> <owner>peconn@chromium.org</owner> <owner>peter@chromium.org</owner> <summary> @@ -15509,14 +15509,14 @@ </histogram> <histogram name="TrustedWebActivity.ShareTargetRequest" - enum="WebShareTargetMethod" expires_after="M88"> + enum="WebShareTargetMethod" expires_after="M92"> <owner>peconn@chromium.org</owner> <owner>peter@chromium.org</owner> <summary>Recorded when data is shared via a Trusted Web Activity.</summary> </histogram> <histogram name="TrustedWebActivity.SplashScreenShown" enum="Boolean" - expires_after="M88"> + expires_after="M92"> <owner>peconn@chromium.org</owner> <owner>peter@chromium.org</owner> <summary> @@ -15526,7 +15526,7 @@ </histogram> <histogram name="TrustedWebActivity.TimeInVerifiedOrigin.V2" units="ms" - expires_after="M88"> + expires_after="M92"> <owner>peconn@chromium.org</owner> <owner>peter@chromium.org</owner> <summary> @@ -15536,7 +15536,7 @@ </histogram> <histogram name="TrustedWebActivity.TimeOutOfVerifiedOrigin.V2" units="ms" - expires_after="M88"> + expires_after="M92"> <owner>peconn@chromium.org</owner> <owner>peter@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/histograms_xml/settings/histograms.xml b/tools/metrics/histograms/histograms_xml/settings/histograms.xml index f7b360f..775cfd9 100644 --- a/tools/metrics/histograms/histograms_xml/settings/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/settings/histograms.xml
@@ -85,6 +85,9 @@ <histogram name="Settings.HomePageIsCustomized" enum="Boolean" expires_after="2020-08-28"> + <obsolete> + Expired and removed from code as of 10/2020. + </obsolete> <owner>twellington@chromium.org</owner> <owner>tedchoc@chromium.org</owner> <summary> @@ -272,6 +275,9 @@ <histogram name="Settings.ShowHomeButtonPreferenceState" enum="BooleanEnabled" expires_after="M85"> + <obsolete> + Expired and removed from code as of 10/2020. + </obsolete> <owner>twellington@chromium.org</owner> <owner>tedchoc@chromium.org</owner> <summary> @@ -287,6 +293,9 @@ <histogram name="Settings.ShowHomeButtonPreferenceStateChanged" enum="BooleanEnabled" expires_after="M88"> + <obsolete> + Removed from code as of 10/2020. + </obsolete> <owner>twellington@chromium.org</owner> <owner>tedchoc@chromium.org</owner> <summary> @@ -297,6 +306,9 @@ <histogram name="Settings.ShowHomeButtonPreferenceStateManaged" enum="HomeButtonPreferenceStateType" expires_after="M88"> + <obsolete> + Removed from code as of 10/2020. + </obsolete> <owner>twellington@chromium.org</owner> <owner>tedchoc@chromium.org</owner> <summary>
diff --git a/ui/aura/native_window_occlusion_tracker_win.cc b/ui/aura/native_window_occlusion_tracker_win.cc index 6dcc8e61..66fd0b9 100644 --- a/ui/aura/native_window_occlusion_tracker_win.cc +++ b/ui/aura/native_window_occlusion_tracker_win.cc
@@ -519,6 +519,10 @@ // maximize and native window restore events. RegisterGlobalEventHook(EVENT_OBJECT_STATECHANGE, EVENT_OBJECT_STATECHANGE); + // Cloaking and uncloaking of windows should trigger an occlusion calculation. + // In particular, switching virtual desktops seems to generate these events. + RegisterGlobalEventHook(EVENT_OBJECT_CLOAKED, EVENT_OBJECT_UNCLOAKED); + // Determine which subset of processes to set EVENT_OBJECT_LOCATIONCHANGE on // because otherwise event throughput is very high, as it generates events // for location changes of all objects, including the mouse moving on top of a
diff --git a/ui/chromeos/OWNERS b/ui/chromeos/OWNERS index f179ceafe..86f9ccc 100644 --- a/ui/chromeos/OWNERS +++ b/ui/chromeos/OWNERS
@@ -1,7 +1,7 @@ afakhry@chromium.org jamescook@chromium.org +khorimoto@chromium.org oshima@chromium.org -stevenjb@chromium.org xiyuan@chromium.org per-file file_manager_strings.grdp=*
diff --git a/ui/events/DIR_METADATA b/ui/events/DIR_METADATA new file mode 100644 index 0000000..27f51aa --- /dev/null +++ b/ui/events/DIR_METADATA
@@ -0,0 +1,11 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "UI>Input" +} \ No newline at end of file
diff --git a/ui/events/OWNERS b/ui/events/OWNERS index ba90608..230180c6 100644 --- a/ui/events/OWNERS +++ b/ui/events/OWNERS
@@ -1,5 +1,4 @@ sadrul@chromium.org # If you're doing structural changes get a review from one of the OWNERS. -per-file BUILD.gn=* -# COMPONENT: UI>Input +per-file BUILD.gn=* \ No newline at end of file
diff --git a/ui/events/android/DIR_METADATA b/ui/events/android/DIR_METADATA new file mode 100644 index 0000000..1c611eb --- /dev/null +++ b/ui/events/android/DIR_METADATA
@@ -0,0 +1,12 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Blink>Input" +} +team_email: "input-dev@chromium.org" \ No newline at end of file
diff --git a/ui/events/android/OWNERS b/ui/events/android/OWNERS index e19954f..6e91dc0e 100644 --- a/ui/events/android/OWNERS +++ b/ui/events/android/OWNERS
@@ -1,5 +1,2 @@ tdresser@chromium.org nzolghadr@chromium.org - -# TEAM: input-dev@chromium.org -# COMPONENT: Blink>Input
diff --git a/ui/events/blink/DIR_METADATA b/ui/events/blink/DIR_METADATA new file mode 100644 index 0000000..1c611eb --- /dev/null +++ b/ui/events/blink/DIR_METADATA
@@ -0,0 +1,12 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Blink>Input" +} +team_email: "input-dev@chromium.org" \ No newline at end of file
diff --git a/ui/events/blink/OWNERS b/ui/events/blink/OWNERS index c81e7a79..8968c2d 100644 --- a/ui/events/blink/OWNERS +++ b/ui/events/blink/OWNERS
@@ -2,6 +2,3 @@ tdresser@chromium.org bokan@chromium.org nzolghadr@chromium.org - -# TEAM: input-dev@chromium.org -# COMPONENT: Blink>Input
diff --git a/ui/events/fuchsia/DIR_METADATA b/ui/events/fuchsia/DIR_METADATA new file mode 100644 index 0000000..de0c11f0 --- /dev/null +++ b/ui/events/fuchsia/DIR_METADATA
@@ -0,0 +1,13 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Fuchsia" +} +team_email: "cr-fuchsia@chromium.org" +os: FUCHSIA \ No newline at end of file
diff --git a/ui/events/fuchsia/OWNERS b/ui/events/fuchsia/OWNERS index c1dc0d5..e69de29 100644 --- a/ui/events/fuchsia/OWNERS +++ b/ui/events/fuchsia/OWNERS
@@ -1,3 +0,0 @@ -# COMPONENT: Fuchsia -# OS: Fuchsia -# TEAM: cr-fuchsia@chromium.org
diff --git a/ui/events/gesture_detection/DIR_METADATA b/ui/events/gesture_detection/DIR_METADATA new file mode 100644 index 0000000..1c611eb --- /dev/null +++ b/ui/events/gesture_detection/DIR_METADATA
@@ -0,0 +1,12 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Blink>Input" +} +team_email: "input-dev@chromium.org" \ No newline at end of file
diff --git a/ui/events/gesture_detection/OWNERS b/ui/events/gesture_detection/OWNERS index 7d088914c..234d059 100644 --- a/ui/events/gesture_detection/OWNERS +++ b/ui/events/gesture_detection/OWNERS
@@ -3,6 +3,3 @@ per-file gesture_configuration_cast.cc=alexst@chromium.org per-file gesture_configuration_cast.cc=kpschoedel@chromium.org - -# TEAM: input-dev@chromium.org -# COMPONENT: Blink>Input
diff --git a/ui/events/gestures/DIR_METADATA b/ui/events/gestures/DIR_METADATA new file mode 100644 index 0000000..44eb665 --- /dev/null +++ b/ui/events/gestures/DIR_METADATA
@@ -0,0 +1,9 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +team_email: "input-dev@chromium.org" \ No newline at end of file
diff --git a/ui/events/gestures/OWNERS b/ui/events/gestures/OWNERS index 4b27ef7..7ac1c37 100644 --- a/ui/events/gestures/OWNERS +++ b/ui/events/gestures/OWNERS
@@ -2,6 +2,3 @@ sadrul@chromium.org tdresser@chromium.org nzolghadr@chromium.org - -# TEAM: input-dev@chromium.org -# COMPONENT: UI>Input
diff --git a/ui/events/keycodes/DIR_METADATA b/ui/events/keycodes/DIR_METADATA new file mode 100644 index 0000000..9a04abcb --- /dev/null +++ b/ui/events/keycodes/DIR_METADATA
@@ -0,0 +1,11 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "IO>Keyboard" +} \ No newline at end of file
diff --git a/ui/events/keycodes/OWNERS b/ui/events/keycodes/OWNERS index 0fe96b8e..a49314c 100644 --- a/ui/events/keycodes/OWNERS +++ b/ui/events/keycodes/OWNERS
@@ -1,4 +1,2 @@ garykac@chromium.org wez@chromium.org - -# COMPONENT: IO>Keyboard
diff --git a/ui/events/ozone/DIR_METADATA b/ui/events/ozone/DIR_METADATA new file mode 100644 index 0000000..b8b9277b --- /dev/null +++ b/ui/events/ozone/DIR_METADATA
@@ -0,0 +1,9 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +team_email: "ozone-dev@chromium.org" \ No newline at end of file
diff --git a/ui/events/ozone/OWNERS b/ui/events/ozone/OWNERS index cee2fef..10c6989 100644 --- a/ui/events/ozone/OWNERS +++ b/ui/events/ozone/OWNERS
@@ -7,5 +7,3 @@ # Touchscreen palm rejection robsc@chromium.org - -# TEAM: ozone-dev@chromium.org
diff --git a/ui/events/x/OWNERS b/ui/events/x/OWNERS index 2f2cf8f..280ba478 100644 --- a/ui/events/x/OWNERS +++ b/ui/events/x/OWNERS
@@ -1,3 +1 @@ thomasanderson@chromium.org - -# COMPONENT: UI>Input
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn index 1d7b3f7..1b1c5f4 100644 --- a/ui/gfx/BUILD.gn +++ b/ui/gfx/BUILD.gn
@@ -39,6 +39,8 @@ component("geometry_skia") { sources = [ "geometry_skia_export.h", + "mask_filter_info.cc", + "mask_filter_info.h", "rrect_f.cc", "rrect_f.h", "rrect_f_builder.cc",
diff --git a/ui/gfx/DIR_METADATA b/ui/gfx/DIR_METADATA new file mode 100644 index 0000000..6618219 --- /dev/null +++ b/ui/gfx/DIR_METADATA
@@ -0,0 +1,12 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "UI>GFX" +} +team_email: "graphics-dev@chromium.org" \ No newline at end of file
diff --git a/ui/gfx/OWNERS b/ui/gfx/OWNERS index 1dbd16ec..e34675cb 100644 --- a/ui/gfx/OWNERS +++ b/ui/gfx/OWNERS
@@ -60,6 +60,3 @@ # If you're doing structural changes get a review from one of the OWNERS. per-file BUILD.gn=* - -# COMPONENT: UI>GFX -# TEAM: graphics-dev@chromium.org
diff --git a/ui/gfx/android/OWNERS b/ui/gfx/android/OWNERS index 8e64bbe..15a182a6 100644 --- a/ui/gfx/android/OWNERS +++ b/ui/gfx/android/OWNERS
@@ -1,3 +1 @@ skyostil@chromium.org - -# COMPONENT: UI>GFX
diff --git a/ui/gfx/animation/DIR_METADATA b/ui/gfx/animation/DIR_METADATA new file mode 100644 index 0000000..087c8bf --- /dev/null +++ b/ui/gfx/animation/DIR_METADATA
@@ -0,0 +1,12 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Internals>Compositing>Animation" +} +team_email: "threaded-rendering-dev@chromium.org" \ No newline at end of file
diff --git a/ui/gfx/animation/OWNERS b/ui/gfx/animation/OWNERS index 03d2109..a56274e 100644 --- a/ui/gfx/animation/OWNERS +++ b/ui/gfx/animation/OWNERS
@@ -1,5 +1,2 @@ flackr@chromium.org vollick@chromium.org - -# TEAM: threaded-rendering-dev@chromium.org -# COMPONENT: Internals>Compositing>Animation
diff --git a/ui/gfx/codec/OWNERS b/ui/gfx/codec/OWNERS index 3bcf86b..254c0ec 100644 --- a/ui/gfx/codec/OWNERS +++ b/ui/gfx/codec/OWNERS
@@ -1,4 +1,2 @@ dcheng@chromium.org scroggo@google.com - -# COMPONENT: UI>GFX
diff --git a/ui/gfx/image/OWNERS b/ui/gfx/image/OWNERS index 8e89a42a..23dbb5a 100644 --- a/ui/gfx/image/OWNERS +++ b/ui/gfx/image/OWNERS
@@ -2,5 +2,3 @@ # ImageSkia related classes except for _mac/_ios stuff per-file image_skia*=oshima@chromium.org - -# COMPONENT: UI>GFX
diff --git a/ui/gfx/mask_filter_info.cc b/ui/gfx/mask_filter_info.cc new file mode 100644 index 0000000..fd06a24 --- /dev/null +++ b/ui/gfx/mask_filter_info.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 "ui/gfx/mask_filter_info.h" + +#include <sstream> + +#include "ui/gfx/transform.h" + +namespace gfx { + +MaskFilterInfo::MaskFilterInfo(const RectF& bounds, + const RoundedCornersF& radii, + bool is_fast_rounded_corner) + : rounded_corner_bounds_(bounds, radii), + is_fast_rounded_corner_(is_fast_rounded_corner) {} + +bool MaskFilterInfo::Transform(const gfx::Transform& transform) { + return transform.TransformRRectF(&rounded_corner_bounds_); +} + +std::string MaskFilterInfo::ToString() const { + return "MaskFilterInfo{" + rounded_corner_bounds_.ToString() + + ", fast_rounded_corner=" + + (is_fast_rounded_corner_ ? "true" : "false") + "}"; +} + +} // namespace gfx
diff --git a/ui/gfx/mask_filter_info.h b/ui/gfx/mask_filter_info.h new file mode 100644 index 0000000..ef2e14a --- /dev/null +++ b/ui/gfx/mask_filter_info.h
@@ -0,0 +1,72 @@ +// 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 UI_GFX_MASK_FILTER_INFO_H_ +#define UI_GFX_MASK_FILTER_INFO_H_ + +#include "ui/gfx/geometry/rect_f.h" +#include "ui/gfx/geometry_skia_export.h" +#include "ui/gfx/rrect_f.h" + +namespace gfx { + +class Transform; + +class GEOMETRY_SKIA_EXPORT MaskFilterInfo { + public: + MaskFilterInfo() = default; + MaskFilterInfo(const RRectF& rrect, bool is_fast_rounded_corner) + : rounded_corner_bounds_(rrect), + is_fast_rounded_corner_(is_fast_rounded_corner) {} + MaskFilterInfo(const RectF& bounds, + const RoundedCornersF& radii, + bool is_fast_rounded_corner); + MaskFilterInfo(const MaskFilterInfo& copy) = default; + ~MaskFilterInfo() = default; + + // The bounds the filter will be applied to. + RectF bounds() const { return rounded_corner_bounds_.rect(); } + + // Defines the rounded corner bounds to clip. + const RRectF& rounded_corner_bounds() const { return rounded_corner_bounds_; } + + // If true, it makes the filter not trigger a render surface when the rounded + // corners is defined if possible. + bool is_fast_rounded_corner() const { return is_fast_rounded_corner_; } + + // True if this contains a rounded corner mask. + bool HasRoundedCorners() const { + return !IsEmpty() && + rounded_corner_bounds_.GetType() != RRectF::Type::kRect; + } + + // True if this contains no effective mask information. + bool IsEmpty() const { return rounded_corner_bounds_.IsEmpty(); } + + // Transform the mask information. Returns false if the transform + // cannot be applied. + bool Transform(const Transform& transform); + + std::string ToString() const; + + private: + // The rounded corner bounds. This also defines the bounds that the mask + // filter will be applied to. + RRectF rounded_corner_bounds_; + + bool is_fast_rounded_corner_ = false; +}; + +inline bool operator==(const MaskFilterInfo& lhs, const MaskFilterInfo& rhs) { + return lhs.rounded_corner_bounds() == rhs.rounded_corner_bounds() && + lhs.is_fast_rounded_corner() == rhs.is_fast_rounded_corner(); +} + +inline bool operator!=(const MaskFilterInfo& lhs, const MaskFilterInfo& rhs) { + return !(lhs == rhs); +} + +} // namespace gfx + +#endif // UI_GFX_MASK_FILTER_INFO_H_
diff --git a/ui/gfx/mojom/BUILD.gn b/ui/gfx/mojom/BUILD.gn index 5faeacec..6e2665c5 100644 --- a/ui/gfx/mojom/BUILD.gn +++ b/ui/gfx/mojom/BUILD.gn
@@ -14,6 +14,7 @@ "display_color_spaces.mojom", "font_render_params.mojom", "gpu_fence_handle.mojom", + "mask_filter_info.mojom", "overlay_transform.mojom", "presentation_feedback.mojom", "rrect_f.mojom", @@ -206,6 +207,17 @@ traits_headers = [ "swap_result_mojom_traits.h" ] traits_public_deps = [ "//ui/gfx" ] }, + { + types = [ + { + mojom = "gfx.mojom.MaskFilterInfo" + cpp = "::gfx::MaskFilterInfo" + }, + ] + traits_sources = [ "mask_filter_info_mojom_traits.cc" ] + traits_headers = [ "mask_filter_info_mojom_traits.h" ] + traits_public_deps = [ "//ui/gfx" ] + }, ] cpp_typemaps += shared_cpp_typemaps
diff --git a/ui/gfx/mojom/mask_filter_info.mojom b/ui/gfx/mojom/mask_filter_info.mojom new file mode 100644 index 0000000..47b5bd73 --- /dev/null +++ b/ui/gfx/mojom/mask_filter_info.mojom
@@ -0,0 +1,13 @@ +// 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. + +module gfx.mojom; + +import "ui/gfx/mojom/rrect_f.mojom"; + +// See ui/gfx/mask_filter_info.h. +struct MaskFilterInfo { + gfx.mojom.RRectF rounded_corner_bounds; + bool is_fast_rounded_corner; +};
diff --git a/ui/gfx/mojom/mask_filter_info_mojom_traits.cc b/ui/gfx/mojom/mask_filter_info_mojom_traits.cc new file mode 100644 index 0000000..23bccb1b --- /dev/null +++ b/ui/gfx/mojom/mask_filter_info_mojom_traits.cc
@@ -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. + +#include "ui/gfx/mojom/mask_filter_info_mojom_traits.h" + +namespace mojo { + +// static +bool StructTraits<gfx::mojom::MaskFilterInfoDataView, gfx::MaskFilterInfo>:: + Read(gfx::mojom::MaskFilterInfoDataView data, gfx::MaskFilterInfo* out) { + gfx::RRectF bounds; + if (!data.ReadRoundedCornerBounds(&bounds)) + return false; + *out = gfx::MaskFilterInfo(bounds, data.is_fast_rounded_corner()); + + return true; +} + +} // namespace mojo
diff --git a/ui/gfx/mojom/mask_filter_info_mojom_traits.h b/ui/gfx/mojom/mask_filter_info_mojom_traits.h new file mode 100644 index 0000000..ca9b0bbf --- /dev/null +++ b/ui/gfx/mojom/mask_filter_info_mojom_traits.h
@@ -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. + +#ifndef UI_GFX_MOJOM_MASK_FILTER_INFO_MOJOM_TRAITS_H_ +#define UI_GFX_MOJOM_MASK_FILTER_INFO_MOJOM_TRAITS_H_ + +#include "ui/gfx/mask_filter_info.h" +#include "ui/gfx/mojom/mask_filter_info.mojom-shared.h" +#include "ui/gfx/mojom/rrect_f_mojom_traits.h" + +namespace mojo { +template <> +struct StructTraits<gfx::mojom::MaskFilterInfoDataView, gfx::MaskFilterInfo> { + static const gfx::RRectF& rounded_corner_bounds( + const gfx::MaskFilterInfo& info) { + return info.rounded_corner_bounds(); + } + + static bool is_fast_rounded_corner(const gfx::MaskFilterInfo& info) { + return info.is_fast_rounded_corner(); + } + + static bool Read(gfx::mojom::MaskFilterInfoDataView data, + gfx::MaskFilterInfo* out); +}; + +} // namespace mojo +#endif // UI_GFX_MOJOM_LINEAR_GRADIENT_MOJOM_TRAITS_H_
diff --git a/ui/gfx/range/OWNERS b/ui/gfx/range/OWNERS index c93ccf46..14fce2ae 100644 --- a/ui/gfx/range/OWNERS +++ b/ui/gfx/range/OWNERS
@@ -1,3 +1 @@ rsesek@chromium.org - -# COMPONENT: UI>GFX
diff --git a/ui/gfx/x/OWNERS b/ui/gfx/x/OWNERS index 079174d..c5442ff 100644 --- a/ui/gfx/x/OWNERS +++ b/ui/gfx/x/OWNERS
@@ -2,5 +2,3 @@ # Adding new atoms is allowed without OWNERS review. per-file x11_atom_cache.cc=* - -# COMPONENT: UI>GFX
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn index b8e1f99..0b2f985 100644 --- a/ui/views/BUILD.gn +++ b/ui/views/BUILD.gn
@@ -1342,6 +1342,10 @@ if (use_ozone) { deps += [ "//ui/ozone" ] } + + if (is_linux || is_chromeos) { + sources += [ "color_chooser/color_chooser_unittest.cc" ] + } } # This target is added as a dependency of browser interactive_ui_tests. It must
diff --git a/ui/views/color_chooser/color_chooser_unittest.cc b/ui/views/color_chooser/color_chooser_unittest.cc new file mode 100644 index 0000000..e20ed34 --- /dev/null +++ b/ui/views/color_chooser/color_chooser_unittest.cc
@@ -0,0 +1,163 @@ +// 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. +// +// Very quick HSV primer for those unfamiliar with it: +// It helps to think of HSV like this: +// h is in (0,360) and draws a circle of colors, with r = 0, b = 120, g = 240 +// s is in (0,1) and is the distance from the center of that circle - higher +// values are more intense, with s = 0 being white, s = 1 being full color +// and then HSV is the 3d space caused by projecting that circle into a +// cylinder, with v in (0,1) being how far along the cylinder you are; v = 0 is +// black, v = 1 is full color intensity + +#include <tuple> + +#include "base/strings/string_number_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/events/test/event_generator.h" +#include "ui/views/background.h" +#include "ui/views/color_chooser/color_chooser_listener.h" +#include "ui/views/color_chooser/color_chooser_view.h" +#include "ui/views/controls/textfield/textfield.h" +#include "ui/views/test/views_test_base.h" +#include "ui/views/widget/widget_utils.h" + +namespace { + +class TestChooserListener : public views::ColorChooserListener { + public: + void OnColorChosen(SkColor color) override { color_ = color; } + void OnColorChooserDialogClosed() override { closed_ = true; } + + private: + SkColor color_ = SK_ColorTRANSPARENT; + bool closed_ = false; +}; + +class ColorChooserTest : public views::ViewsTestBase { + public: + ~ColorChooserTest() override = default; + + void SetUp() override { + ViewsTestBase::SetUp(); + chooser_ = + std::make_unique<views::ColorChooserView>(&listener_, SK_ColorGREEN); + chooser_->SetBounds(0, 0, 400, 300); + widget_ = CreateTestWidget(views::Widget::InitParams::TYPE_WINDOW); + widget_->GetContentsView()->AddChildView(chooser()); + generator_ = std::make_unique<ui::test::EventGenerator>( + views::GetRootWindow(widget_.get()), widget_->GetNativeWindow()); + generator_->set_assume_window_at_origin(false); + } + + void TearDown() override { + generator_.reset(); + widget_.reset(); + ViewsTestBase::TearDown(); + } + + views::ColorChooserView* chooser() { return chooser_.get(); } + ui::test::EventGenerator* generator() { return generator_.get(); } + + void ExpectExactHSV(float h, float s, float v) const { + EXPECT_EQ(h, chooser_->hue()); + EXPECT_EQ(s, chooser_->saturation()); + EXPECT_EQ(v, chooser_->value()); + } + + void ExpectApproximateHSV(float h, float s, float v) const { + // At the usual size of the hue chooser it's possible to hit within + // roughly 5 points of hue in either direction. + EXPECT_NEAR(chooser_->hue(), h, 10.0); + EXPECT_NEAR(chooser_->saturation(), s, 0.1); + EXPECT_NEAR(chooser_->value(), v, 0.1); + } + + SkColor GetShownColor() const { + return chooser_->selected_color_patch_for_testing() + ->background() + ->get_color(); + } + + SkColor GetTextualColor() const { + base::string16 text = chooser_->textfield_for_testing()->GetText(); + if (text.empty() || text[0] != '#') + return SK_ColorTRANSPARENT; + + uint32_t color; + return base::HexStringToUInt(base::UTF16ToUTF8(text.substr(1)), &color) + ? SkColorSetA(color, SK_AlphaOPAQUE) + : SK_ColorTRANSPARENT; + } + + void TypeColor(const std::string& color) { + chooser_->textfield_for_testing()->SetText(base::UTF8ToUTF16(color)); + // Synthesize ContentsChanged, since Textfield normally doesn't deliver it + // for SetText, only for user-typed text. + chooser_->ContentsChanged(chooser_->textfield_for_testing(), + chooser_->textfield_for_testing()->GetText()); + } + + void PressMouseAt(views::View* view, const gfx::Point& p) { +#if 0 + // TODO(ellyjones): Why doesn't this work? + const gfx::Point po = view->GetBoundsInScreen().origin(); + generator_->MoveMouseTo(po + p.OffsetFromOrigin()); + generator_->ClickLeftButton(); +#endif + ui::MouseEvent press(ui::ET_MOUSE_PRESSED, + gfx::Point(view->x() + p.x(), view->y() + p.y()), + gfx::Point(0, 0), base::TimeTicks::Now(), 0, 0); + view->OnMousePressed(press); + } + + private: + TestChooserListener listener_; + std::unique_ptr<views::ColorChooserView> chooser_; + std::unique_ptr<views::Widget> widget_; + std::unique_ptr<ui::test::EventGenerator> generator_; +}; + +TEST_F(ColorChooserTest, ShowsInitialColor) { + ExpectExactHSV(120, 1, 1); + EXPECT_EQ(GetShownColor(), SK_ColorGREEN); + EXPECT_EQ(GetTextualColor(), SK_ColorGREEN); +} + +TEST_F(ColorChooserTest, AdjustingTextAdjustsShown) { + TypeColor("#ff0000"); + ExpectExactHSV(0, 1, 1); + EXPECT_EQ(GetShownColor(), SK_ColorRED); + + TypeColor("0000ff"); + ExpectExactHSV(240, 1, 1); + EXPECT_EQ(GetShownColor(), SK_ColorBLUE); +} + +TEST_F(ColorChooserTest, HueSliderChangesHue) { + ExpectExactHSV(120, 1, 1); + + views::View* hv = chooser()->hue_view_for_testing(); + + PressMouseAt(hv, gfx::Point(1, hv->height())); + ExpectApproximateHSV(0, 1, 1); + + PressMouseAt(hv, gfx::Point(1, (hv->height() * 3) / 4)); + ExpectApproximateHSV(90, 1, 1); + + PressMouseAt(hv, gfx::Point(1, hv->height() / 2)); + ExpectApproximateHSV(180, 1, 1); + + PressMouseAt(hv, gfx::Point(1, hv->height() / 4)); + ExpectApproximateHSV(270, 1, 1); +} + +// Missing tests, TODO: +// TEST_F(ColorChooserTest, SatValueChooserChangesSatValue) +// TEST_F(ColorChooserTest, UpdateFromWebUpdatesShownValues) +// TEST_F(ColorChooserTest, AdjustingTextAffectsHue) +// TEST_F(ColorChooserTest, AdjustingTextAffectsSatValue) + +} // namespace
diff --git a/ui/views/color_chooser/color_chooser_view.cc b/ui/views/color_chooser/color_chooser_view.cc index b8053d0..8470a67 100644 --- a/ui/views/color_chooser/color_chooser_view.cc +++ b/ui/views/color_chooser/color_chooser_view.cc
@@ -434,17 +434,20 @@ textfield_->SetText(GetColorText(color)); } -bool ColorChooserView::CanMinimize() const { - return false; +View* ColorChooserView::hue_view_for_testing() { + return hue_; } -View* ColorChooserView::GetInitiallyFocusedView() { +View* ColorChooserView::saturation_value_view_for_testing() { + return saturation_value_; +} + +Textfield* ColorChooserView::textfield_for_testing() { return textfield_; } -void ColorChooserView::WindowClosing() { - if (listener_) - listener_->OnColorChooserDialogClosed(); +View* ColorChooserView::selected_color_patch_for_testing() { + return selected_color_patch_; } void ColorChooserView::ContentsChanged(Textfield* sender, @@ -472,4 +475,17 @@ return true; } +bool ColorChooserView::CanMinimize() const { + return false; +} + +View* ColorChooserView::GetInitiallyFocusedView() { + return textfield_; +} + +void ColorChooserView::WindowClosing() { + if (listener_) + listener_->OnColorChooserDialogClosed(); +} + } // namespace views
diff --git a/ui/views/color_chooser/color_chooser_view.h b/ui/views/color_chooser/color_chooser_view.h index c28c245..60bf2ac 100644 --- a/ui/views/color_chooser/color_chooser_view.h +++ b/ui/views/color_chooser/color_chooser_view.h
@@ -42,6 +42,17 @@ float value() const { return hsv_[2]; } void set_listener(ColorChooserListener* listener) { listener_ = listener; } + View* hue_view_for_testing(); + View* saturation_value_view_for_testing(); + Textfield* textfield_for_testing(); + View* selected_color_patch_for_testing(); + + // TextfieldController overrides: + void ContentsChanged(Textfield* sender, + const base::string16& new_contents) override; + bool HandleKeyEvent(Textfield* sender, + const ui::KeyEvent& key_event) override; + private: class HueView; class SaturationValueView; @@ -52,12 +63,6 @@ View* GetInitiallyFocusedView() override; void WindowClosing() override; - // TextfieldController overrides: - void ContentsChanged(Textfield* sender, - const base::string16& new_contents) override; - bool HandleKeyEvent(Textfield* sender, - const ui::KeyEvent& key_event) override; - // The current color in HSV coordinate. SkScalar hsv_[3];
diff --git a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/BrowserControlsHelper.java b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/BrowserControlsHelper.java index 6c57322..dfff4d4 100644 --- a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/BrowserControlsHelper.java +++ b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/BrowserControlsHelper.java
@@ -32,7 +32,7 @@ // Blocks until browser controls are fully initialized. Should only be created in a test's // setUp() method; see BrowserControlsHelper#createInSetUp(). - private BrowserControlsHelper(InstrumentationActivity activity) throws Throwable { + private BrowserControlsHelper(InstrumentationActivity activity) throws Exception { Assert.assertTrue(CommandLine.isInitialized()); Assert.assertTrue(CommandLine.getInstance().hasSwitch("enable-features")); String enabledFeatures = CommandLine.getInstance().getSwitchValue("enable-features"); @@ -73,7 +73,7 @@ } // Ensures that browser controls are fully initialized and ready for scrolls to be processed. - private void waitForBrowserControlsInitialization() throws Throwable { + private void waitForBrowserControlsInitialization() throws Exception { // Poll until the top view becomes visible. waitForBrowserControlsViewToBeVisible(mActivity.getTopContentsContainer()); TestThreadUtils.runOnUiThreadBlocking(() -> { @@ -88,7 +88,7 @@ // Creates a BrowserControlsHelper instance and blocks until browser controls are fully // initialized. Should be called from a test's setUp() method. static BrowserControlsHelper createAndBlockUntilBrowserControlsInitializedInSetUp( - InstrumentationActivity activity) throws Throwable { + InstrumentationActivity activity) throws Exception { return new BrowserControlsHelper(activity); }
diff --git a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/BrowserControlsTest.java b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/BrowserControlsTest.java index af749fc..40527d6 100644 --- a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/BrowserControlsTest.java +++ b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/BrowserControlsTest.java
@@ -10,6 +10,7 @@ import static androidx.test.espresso.matcher.ViewMatchers.withText; import android.os.Build; +import android.os.Bundle; import android.os.RemoteException; import android.view.View; import android.view.ViewGroup; @@ -20,16 +21,17 @@ import org.hamcrest.Matchers; import org.junit.Assert; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.MinAndroidSdkLevel; 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.TestThreadUtils; +import org.chromium.weblayer.BrowserControlsOffsetCallback; import org.chromium.weblayer.Tab; import org.chromium.weblayer.TestWebLayer; import org.chromium.weblayer.shell.InstrumentationActivity; @@ -88,8 +90,7 @@ }); } - @Before - public void setUp() throws Throwable { + private void createActivityWithTopView() throws Exception { final String url = mActivityTestRule.getTestDataURL("tall_page.html"); InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl(url); @@ -106,6 +107,7 @@ @Test @SmallTest public void testTopAndBottom() throws Exception { + createActivityWithTopView(); InstrumentationActivity activity = mActivityTestRule.getActivity(); View bottomView = TestThreadUtils.runOnUiThreadBlocking(() -> { TextView view = new TextView(activity); @@ -164,6 +166,7 @@ @Test @SmallTest public void testBottomOnly() throws Exception { + createActivityWithTopView(); InstrumentationActivity activity = mActivityTestRule.getActivity(); // Remove the top-view. TestThreadUtils.runOnUiThreadBlocking(() -> { activity.getBrowser().setTopView(null); }); @@ -219,6 +222,7 @@ @Test @SmallTest public void testTopOnly() throws Exception { + createActivityWithTopView(); InstrumentationActivity activity = mActivityTestRule.getActivity(); View topView = activity.getTopContentsContainer(); @@ -249,6 +253,7 @@ @Test @SmallTest public void testTopMinHeight() throws Exception { + createActivityWithTopView(); final int minHeight = 20; InstrumentationActivity activity = mActivityTestRule.getActivity(); View topContents = activity.getTopContentsContainer(); @@ -288,6 +293,7 @@ @Test @SmallTest public void testOnlyExpandTopControlsAtPageTop() throws Exception { + createActivityWithTopView(); InstrumentationActivity activity = mActivityTestRule.getActivity(); View topContents = activity.getTopContentsContainer(); TestThreadUtils.runOnUiThreadBlocking( @@ -333,6 +339,7 @@ @Test @SmallTest public void testAlertDoesntShowTopControlsIfOnlyExpandTopControlsAtPageTop() throws Exception { + createActivityWithTopView(); InstrumentationActivity activity = mActivityTestRule.getActivity(); View topContents = activity.getTopContentsContainer(); TestThreadUtils.runOnUiThreadBlocking( @@ -371,6 +378,7 @@ @Test @SmallTest public void testAlertShowsTopControls() throws Exception { + createActivityWithTopView(); InstrumentationActivity activity = mActivityTestRule.getActivity(); // Move by the size of the top-controls. @@ -400,6 +408,7 @@ @Test @SmallTest public void testAccessibility() throws Exception { + createActivityWithTopView(); InstrumentationActivity activity = mActivityTestRule.getActivity(); // Scroll such that top-controls are hidden. @@ -434,6 +443,7 @@ @Test @SmallTest public void testRemoveAllFromTopView() throws Exception { + createActivityWithTopView(); InstrumentationActivity activity = mActivityTestRule.getActivity(); // Install a different top-view. @@ -465,4 +475,64 @@ Criteria.checkThat(getVisiblePageHeight(), Matchers.not(mPageHeightWithTopView)); }); } + + private void registerBrowserControlsOffsetCallbackForOffset( + CallbackHelper helper, int targetOffset) { + InstrumentationActivity activity = mActivityTestRule.getActivity(); + TestThreadUtils.runOnUiThreadBlocking(() -> { + activity.getBrowser().registerBrowserControlsOffsetCallback( + new BrowserControlsOffsetCallback() { + @Override + public void onTopViewOffsetChanged(int offset) { + if (offset == targetOffset) { + activity.getBrowser().unregisterBrowserControlsOffsetCallback(this); + helper.notifyCalled(); + } + } + }); + }); + } + + @MinAndroidSdkLevel(Build.VERSION_CODES.M) + @Test + @SmallTest + public void testTopExpandedWhenOnlyExpandAtTop() throws Exception { + Bundle extras = new Bundle(); + extras.putBoolean(InstrumentationActivity.EXTRA_ONLY_EXPAND_CONTROLS_AT_TOP, true); + final String url = mActivityTestRule.getTestDataURL("tall_page.html"); + InstrumentationActivity activity = mActivityTestRule.launchShell(extras); + CallbackHelper helper = new CallbackHelper(); + registerBrowserControlsOffsetCallbackForOffset(helper, 0); + mActivityTestRule.navigateAndWait(url); + helper.waitForFirst(); + } + + @MinAndroidSdkLevel(Build.VERSION_CODES.M) + @Test + @SmallTest + public void testTopExpandedOnLoadWhenOnlyExpandAtTop() throws Exception { + Bundle extras = new Bundle(); + extras.putBoolean(InstrumentationActivity.EXTRA_ONLY_EXPAND_CONTROLS_AT_TOP, true); + InstrumentationActivity activity = mActivityTestRule.launchShell(extras); + CallbackHelper helper = new CallbackHelper(); + registerBrowserControlsOffsetCallbackForOffset(helper, 0); + mActivityTestRule.navigateAndWait(mActivityTestRule.getTestDataURL("tall_page.html")); + int callCount = 0; + helper.waitForCallback(callCount++); + + mTopViewHeight = TestThreadUtils.runOnUiThreadBlocking( + () -> { return activity.getTopContentsContainer().getHeight(); }); + Assert.assertNotEquals(mTopViewHeight, 0); + + // Scroll such that top-controls are hidden. + registerBrowserControlsOffsetCallbackForOffset(helper, -mTopViewHeight); + EventUtils.simulateDragFromCenterOfView( + activity.getWindow().getDecorView(), 0, -mTopViewHeight); + helper.waitForCallback(callCount++); + + // Load a new page. The top-controls should be shown again. + registerBrowserControlsOffsetCallbackForOffset(helper, 0); + mActivityTestRule.navigateAndWait(mActivityTestRule.getTestDataURL("simple_page.html")); + helper.waitForCallback(callCount++); + } }
diff --git a/weblayer/browser/controls_visibility_reason.h b/weblayer/browser/controls_visibility_reason.h index dd03668..097b3ac 100644 --- a/weblayer/browser/controls_visibility_reason.h +++ b/weblayer/browser/controls_visibility_reason.h
@@ -10,6 +10,10 @@ // This enum represents actions or UI conditions that affect the visibility of // top UI, and is used to track concurrent concerns and to allow native and Java // code to coordinate. +// +// WARNING: only a subset of these are used if OnlyExpandTopControlsAtPageTop +// is true. +// // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.weblayer_private // GENERATED_JAVA_CLASS_NAME_OVERRIDE: ImplControlsVisibilityReason enum class ControlsVisibilityReason {
diff --git a/weblayer/browser/tab_impl.cc b/weblayer/browser/tab_impl.cc index bbb893b..59bba86 100644 --- a/weblayer/browser/tab_impl.cc +++ b/weblayer/browser/tab_impl.cc
@@ -1194,6 +1194,30 @@ // bounce around. UpdateBrowserControlsState(content::BROWSER_CONTROLS_STATE_SHOWN, false); } else { + if (did_commit && current_browser_controls_visibility_constraint_ == + content::BROWSER_CONTROLS_STATE_BOTH) { + // If the current state is BROWSER_CONTROLS_STATE_BOTH, then + // TabImpl::UpdateBrowserControlsState() is going to call + // WebContents::UpdateBrowserControlsState() with both current and + // constraints set to BROWSER_CONTROLS_STATE_BOTH. cc does + // nothing in this case. During a navigation the top-view needs to be + // shown. To force the top-view to show, supply + // BROWSER_CONTROLS_STATE_SHOWN. This path is only hit if top-view + // is configured to only-expand-at-top, as in this case the top-view isn't + // forced shown during a page load. + // + // It's entirely possible the scroll offset is changed as part of the + // loading process (such as happens with back/forward navigation or + // links part way down a page). Trying to detect this and compensate + // here is likely to be racy, so the top-view is always shown. + const bool animate = + !base::FeatureList::IsEnabled(kImmediatelyHideBrowserControlsForTest); + web_contents_->GetMainFrame()->UpdateBrowserControlsState( + content::BROWSER_CONTROLS_STATE_BOTH, + content::BROWSER_CONTROLS_STATE_SHOWN, animate); + // This falls through to call UpdateBrowserControlsState() again to + // ensure the constraint is set back to BOTH. + } UpdateBrowserControlsState( content::BROWSER_CONTROLS_STATE_BOTH, current_browser_controls_visibility_constraint_ !=
diff --git a/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/InstrumentationActivity.java b/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/InstrumentationActivity.java index eee82bc..09ca890b 100644 --- a/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/InstrumentationActivity.java +++ b/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/InstrumentationActivity.java
@@ -43,6 +43,8 @@ /** * Activity for running instrumentation tests. */ +// This isn't part of Chrome, so using explicit colors/sizes is ok. +@SuppressWarnings("checkstyle:SetTextColorAndSetTextSizeCheck") public class InstrumentationActivity extends FragmentActivity { private static final String TAG = "WLInstrumentation"; private static final String KEY_MAIN_VIEW_ID = "mainViewId"; @@ -55,6 +57,10 @@ // True by default. If set to false, the test should call loadWebLayerSync. public static final String EXTRA_CREATE_WEBLAYER = "EXTRA_CREATE_WEBLAYER"; + public static final String EXTRA_TOP_VIEW_MIN_HEIGHT = "EXTRA_TOP_VIEW_MIN_HEIGHT"; + public static final String EXTRA_ONLY_EXPAND_CONTROLS_AT_TOP = + "EXTRA_ONLY_EXPAND_CONTROLS_AT_TOP"; + // Used in tests to specify whether WebLayer URL bar should set default click listeners // that show Page Info UI on its TextView. public static final String EXTRA_URLBAR_TEXT_CLICKABLE = "EXTRA_URLBAR_TEXT_CLICKABLE"; @@ -266,7 +272,18 @@ mBrowser = Browser.fromFragment(mFragment); mProfile = mBrowser.getProfile(); - mBrowser.setTopView(mTopContentsContainer); + final boolean onlyExpandControlsAtTop = + getIntent().getBooleanExtra(EXTRA_ONLY_EXPAND_CONTROLS_AT_TOP, false); + final int minTopViewHeight = getIntent().getIntExtra(EXTRA_TOP_VIEW_MIN_HEIGHT, -1); + + if (onlyExpandControlsAtTop || minTopViewHeight != -1) { + // This was added in 86. + mBrowser.setTopView(mTopContentsContainer, Math.max(0, minTopViewHeight), + onlyExpandControlsAtTop, + /* animate */ false); + } else { + mBrowser.setTopView(mTopContentsContainer); + } mRendererCrashListener = new TabCallback() { @Override