diff --git a/DEPS b/DEPS index c96d90d..56c4cf97 100644 --- a/DEPS +++ b/DEPS
@@ -179,7 +179,7 @@ # 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': '56ff573a6c1416dad552ed26b1724a30a632f4d3', + 'v8_revision': 'e18618490c3aeddf96e36c11b4bffcb5c7f12320', # 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. @@ -187,7 +187,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '9e9493f29dbf3afcd962c56f66cb752efe3c7ee8', + 'angle_revision': '3f283eb209adf9405721a05e8323bd80069912ad', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -246,7 +246,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': 'f92fd4849f47c9ad4a26c1864138f73418d60ddf', + 'devtools_frontend_revision': '07fd18460d096895e12a7f8b228cf9d2fbf117d6', # 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. @@ -286,7 +286,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'spv_tools_revision': 'e1688b60caf77e7efd9e440e57cca429ca7c5a1e', + 'spv_tools_revision': 'a6d3a2dd41d4efcafaefb4821ad491262be6b8d3', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -302,7 +302,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '9b5ecdf536e0da8740eba61fc925f172d51d3c12', + 'dawn_revision': '35645a601a73c26e40e9ddf20f2f685acacf7bde', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -532,7 +532,7 @@ }, 'src/ios/third_party/material_components_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '844112ed66147768bb88c48ad5af1179ab3ed7c8', + 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '8a6d4f9ab70a581253c8c2fb89ba6e076b71431a', 'condition': 'checkout_ios', }, @@ -944,7 +944,7 @@ Var('chromium_git') + '/codecs/libgav1.git' + '@' + 'fa1c3c4e673cf12ffa22b8fbe4a7c79314571f1b', 'src/third_party/glslang/src': - Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + '8985fc91089f3117d338f0ebd683596a197b2d92', + Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + 'c6a4c6d3d8b5b85b93308336534adf9c1ef0ae66', 'src/third_party/google_toolbox_for_mac/src': { 'url': Var('chromium_git') + '/external/github.com/google/google-toolbox-for-mac.git' + '@' + Var('google_toolbox_for_mac_revision'), @@ -1239,7 +1239,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '024aa887785036dd7f1012cc97ce131ed40304b4', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '0fd4f5cda74d29ee13a8942f973c827ec73d7b0d', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1440,7 +1440,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'ec18cc3262922e7dcdbe70243c6f40606f979144', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '80636981052754dcdaaf90a5d83a1cd9eb786dfb', + Var('webrtc_git') + '/src.git' + '@' + '4518a20e14ecb3415c52aecf132d9bc83edaa9c4', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1515,7 +1515,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@2fdaf67e552951e7d4c1d0fa1b688942caf25baa', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@3ac359c9ea04878a029df2e976aa4bcf11a273fc', 'condition': 'checkout_src_internal', },
diff --git a/ash/autotest_private_api_utils.cc b/ash/autotest_private_api_utils.cc index 141b681..245a48f 100644 --- a/ash/autotest_private_api_utils.cc +++ b/ash/autotest_private_api_utils.cc
@@ -81,8 +81,7 @@ std::vector<aura::Window*> GetAppWindowList() { ScopedSkipUserSessionBlockedCheck skip_session_blocked; - return Shell::Get()->mru_window_tracker()->BuildWindowForCycleWithPipList( - kAllDesks); + return Shell::Get()->mru_window_tracker()->BuildAppWindowList(kAllDesks); } bool WaitForLauncherState(AppListViewState target_state,
diff --git a/ash/wm/mru_window_tracker.cc b/ash/wm/mru_window_tracker.cc index fb5f785a..645d4a0 100644 --- a/ash/wm/mru_window_tracker.cc +++ b/ash/wm/mru_window_tracker.cc
@@ -6,6 +6,7 @@ #include <algorithm> +#include "ash/public/cpp/app_types.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/window_properties.h" #include "ash/session/session_controller_impl.h" @@ -208,6 +209,15 @@ window->RemoveObserver(this); } +MruWindowTracker::WindowList MruWindowTracker::BuildAppWindowList( + DesksMruType desks_mru_type) const { + return BuildWindowListInternal( + &mru_windows_, desks_mru_type, [](aura::Window* w) { + return w->GetProperty(aura::client::kAppType) != + static_cast<int>(ash::AppType::NON_APP); + }); +} + MruWindowTracker::WindowList MruWindowTracker::BuildMruWindowList( DesksMruType desks_mru_type) const { return BuildWindowListInternal(&mru_windows_, desks_mru_type,
diff --git a/ash/wm/mru_window_tracker.h b/ash/wm/mru_window_tracker.h index 81e1ab7b..65e6f2a 100644 --- a/ash/wm/mru_window_tracker.h +++ b/ash/wm/mru_window_tracker.h
@@ -49,6 +49,14 @@ MruWindowTracker(); ~MruWindowTracker() override; + // Returns the set windows in the mru list regardless of whether they can be + // included in the cycler or not. + // |desks_mru_type| determines whether to include or exclude windows from the + // inactive desks. + // TODO(oshima|afakhry): Investigate if we can consolidate BuildXXXList + // methods with parameters. + WindowList BuildAppWindowList(DesksMruType desks_mru_type) const; + // Returns the set of windows which can be cycled through using the tracked // list of most recently used windows. // |desks_mru_type| determines whether to include or exclude windows from the
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index 146f433..e084b3f 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -383,7 +383,6 @@ "//cc/base", "//cc/paint", "//components/viz/common", - "//services/tracing/public/cpp:cpp", "//skia", ] deps = [ @@ -399,6 +398,7 @@ "//mojo/public/cpp/bindings:struct_traits", "//services/metrics/public/cpp:ukm_builders", "//services/metrics/public/mojom", + "//services/tracing/public/cpp:cpp", "//ui/events:events_base", "//ui/gfx", "//ui/gfx/geometry",
diff --git a/cc/trees/latency_info_swap_promise.cc b/cc/trees/latency_info_swap_promise.cc index 3f96946..2edc793 100644 --- a/cc/trees/latency_info_swap_promise.cc +++ b/cc/trees/latency_info_swap_promise.cc
@@ -8,6 +8,8 @@ #include "base/logging.h" #include "base/trace_event/trace_event.h" +#include "services/tracing/public/cpp/perfetto/flow_event_utils.h" +#include "services/tracing/public/cpp/perfetto/macros.h" namespace cc { @@ -38,10 +40,19 @@ // Trace the original LatencyInfo of a LatencyInfoSwapPromise void LatencyInfoSwapPromise::OnCommit() { - TRACE_EVENT_WITH_FLOW1("input,benchmark", "LatencyInfo.Flow", - TRACE_ID_GLOBAL(TraceId()), - TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, - "step", "HandleInputEventMainCommit"); + using perfetto::protos::pbzero::ChromeLatencyInfo; + using perfetto::protos::pbzero::TrackEvent; + + TRACE_EVENT("input,benchmark", "LatencyInfo.Flow", + [this](perfetto::EventContext ctx) { + ChromeLatencyInfo* latency_info = + ctx.event()->set_chrome_latency_info(); + latency_info->set_trace_id(TraceId()); + latency_info->set_step( + ChromeLatencyInfo::STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT); + tracing::FillFlowEvent(ctx, TrackEvent::LegacyEvent::FLOW_INOUT, + TraceId()); + }); } } // namespace cc
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 13573155..584aff4 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -61,6 +61,8 @@ #include "cc/trees/tree_synchronizer.h" #include "cc/trees/ukm_manager.h" #include "services/metrics/public/cpp/ukm_recorder.h" +#include "services/tracing/public/cpp/perfetto/flow_event_utils.h" +#include "services/tracing/public/cpp/perfetto/macros.h" #include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/geometry/vector2d_conversions.h" #include "ui/gfx/presentation_feedback.h" @@ -943,11 +945,20 @@ void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet* info) { DCHECK(info); TRACE_EVENT0("cc", "LayerTreeHost::ApplyScrollAndScale"); + + using perfetto::protos::pbzero::ChromeLatencyInfo; + using perfetto::protos::pbzero::TrackEvent; + for (auto& swap_promise : info->swap_promises) { - TRACE_EVENT_WITH_FLOW1("input,benchmark", "LatencyInfo.Flow", - TRACE_ID_GLOBAL(swap_promise->TraceId()), - TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, - "step", "Main thread scroll update"); + TRACE_EVENT( + "input,benchmark", "LatencyInfo.Flow", + [&swap_promise](perfetto::EventContext ctx) { + ChromeLatencyInfo* info = ctx.event()->set_chrome_latency_info(); + info->set_trace_id(swap_promise->TraceId()); + info->set_step(ChromeLatencyInfo::STEP_MAIN_THREAD_SCROLL_UPDATE); + tracing::FillFlowEvent(ctx, TrackEvent::LegacyEvent::FLOW_INOUT, + swap_promise->TraceId()); + }); swap_promise_manager_.QueueSwapPromise(std::move(swap_promise)); }
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 35a18b6..5f1693c 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -112,6 +112,7 @@ #include "gpu/command_buffer/client/shared_image_interface.h" #include "gpu/command_buffer/common/shared_image_usage.h" #include "services/metrics/public/cpp/ukm_recorder.h" +#include "third_party/perfetto/protos/perfetto/trace/track_event/chrome_latency_info.pbzero.h" #include "third_party/skia/include/gpu/GrContext.h" #include "ui/gfx/display_color_spaces.h" #include "ui/gfx/geometry/point_conversions.h" @@ -2471,8 +2472,9 @@ ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, draw_time); } } - ui::LatencyInfo::TraceIntermediateFlowEvents(metadata.latency_info, - "SwapBuffers"); + ui::LatencyInfo::TraceIntermediateFlowEvents( + metadata.latency_info, + perfetto::protos::pbzero::ChromeLatencyInfo::STEP_SWAP_BUFFERS); // Collect all resource ids in the render passes into a single array. std::vector<viz::ResourceId> resources;
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index 3194c7c..123f2a6c 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -1395,6 +1395,7 @@ "//chrome/browser/resources:component_extension_resources", "//chrome/browser/resources:dev_ui_paks", "//chrome/browser/resources:downloads_resources", + "//chrome/browser/resources:gaia_auth_host_resources", "//chrome/browser/resources:history_resources", "//chrome/browser/resources:local_ntp_resources", "//chrome/browser/resources:new_tab_page_resources",
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayCoordinator.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayCoordinator.java index d01f873..eace6bd2 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayCoordinator.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayCoordinator.java
@@ -86,8 +86,10 @@ // TODO(b/143517837) Merge autofill assistant image fetcher UMA names. mImageFetcher.fetchImage(image.mImageUrl, ImageFetcher.ASSISTANT_DETAILS_UMA_CLIENT_NAME, result -> { - image.mImageBitmap = Bitmap.createScaledBitmap(result, - image.mImageSizeInPixels, image.mImageSizeInPixels, true); + image.mImageBitmap = result != null ? Bitmap.createScaledBitmap( + result, image.mImageSizeInPixels, + image.mImageSizeInPixels, true) + : null; mDrawable.setFullOverlayImage(image); }); } else {
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantBottomsheetTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantBottomsheetTest.java index f0e2ce5..e422eb0b 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantBottomsheetTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantBottomsheetTest.java
@@ -551,7 +551,7 @@ float y = GeneralLocation.TOP_CENTER.calculateCoordinates( mTestRule.getActivity().findViewById( R.id.autofill_assistant_bottom_sheet_toolbar))[1]; - Rect el = getAbsoluteBoundingRect(elementId, mTestRule); + Rect el = getAbsoluteBoundingRect(mTestRule, elementId); return el.bottom > y == shouldBeCovered; } catch (Exception e) { throw new RuntimeException(e);
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataIntegrationTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataIntegrationTest.java index 45cbb2c..6b79139 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataIntegrationTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataIntegrationTest.java
@@ -181,11 +181,11 @@ onView(withId(R.id.card_unmask_input)).perform(typeText("123")); onView(withId(R.id.positive_button)).perform(click()); waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); - assertThat(getElementValue("name", getWebContents()), is("John Doe")); - assertThat(getElementValue("card_number", getWebContents()), is("4111111111111111")); - assertThat(getElementValue("cv2_number", getWebContents()), is("123")); - assertThat(getElementValue("exp_month", getWebContents()), is("12")); - assertThat(getElementValue("exp_year", getWebContents()), is("2050")); + assertThat(getElementValue(getWebContents(), "name"), is("John Doe")); + assertThat(getElementValue(getWebContents(), "card_number"), is("4111111111111111")); + assertThat(getElementValue(getWebContents(), "cv2_number"), is("123")); + assertThat(getElementValue(getWebContents(), "exp_month"), is("12")); + assertThat(getElementValue(getWebContents(), "exp_year"), is("2050")); } /** @@ -236,8 +236,8 @@ startAutofillAssistant(mTestRule.getActivity(), testService); waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); - String password = getElementValue("password", getWebContents()); - String confirmation_password = getElementValue("password-conf", getWebContents()); + String password = getElementValue(getWebContents(), "password"); + String confirmation_password = getElementValue(getWebContents(), "password-conf"); assertThat(password.length(), greaterThan(0)); assertThat(password, is(confirmation_password)); } @@ -307,12 +307,12 @@ startAutofillAssistant(mTestRule.getActivity(), testService); waitUntilViewMatchesCondition(withText("Continue"), isDisplayed()); - tapElement("button", mTestRule); + tapElement(mTestRule, "button"); onView(withText("Continue")).perform(click()); waitUntilViewMatchesCondition(withText("Toggle"), isDisplayed()); // Verify that in the next step the touchable window is not present anymore. - tapElement("button", mTestRule); + tapElement(mTestRule, "button"); onView(withText("Toggle")).check(matches(isDisplayed())); }
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFormActionTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFormActionTest.java index 25ec7dc..7f23b2ad 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFormActionTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFormActionTest.java
@@ -6,6 +6,7 @@ import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.action.ViewActions.scrollTo; import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist; import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.intent.Intents.intended; @@ -176,44 +177,45 @@ waitUntilViewMatchesCondition(withText("Continue"), isCompletelyDisplayed()); // TODO(b/144690738) Remove the isDisplayed() condition. - onView(allOf(isDisplayed(), withId(R.id.value), + onView(allOf(withId(R.id.value), withEffectiveVisibility(VISIBLE), hasSibling(hasDescendant(withText("Counter 1"))))) .check(matches(hasTextColor(R.color.modern_grey_800_alpha_38))); - onView(allOf(isDisplayed(), withId(R.id.increase_button), + onView(allOf(withId(R.id.increase_button), withEffectiveVisibility(VISIBLE), hasSibling(hasDescendant(withText("Counter 1"))))) .check(matches(hasTintColor(R.color.modern_blue_600))); - onView(allOf(isDisplayed(), withId(R.id.decrease_button), + onView(allOf(withId(R.id.decrease_button), withEffectiveVisibility(VISIBLE), hasSibling(hasDescendant(withText("Counter 1"))))) .check(matches(hasTintColor(R.color.modern_grey_800_alpha_38))); // Click on Counter 1 +, increase from 0 to 1. - onView(allOf(isDisplayed(), withId(R.id.increase_button), + onView(allOf(withId(R.id.increase_button), withEffectiveVisibility(VISIBLE), hasSibling(hasDescendant(withText("Counter 1"))))) - .perform(click()); - onView(allOf(isDisplayed(), withId(R.id.value), + .perform(scrollTo(), click()); + onView(allOf(withId(R.id.value), withEffectiveVisibility(VISIBLE), hasSibling(hasDescendant(withText("Counter 1"))))) .check(matches(hasTextColor(R.color.modern_blue_600))); - onView(allOf(isDisplayed(), withId(R.id.increase_button), + onView(allOf(withId(R.id.increase_button), withEffectiveVisibility(VISIBLE), hasSibling(hasDescendant(withText("Counter 1"))))) .check(matches(hasTintColor(R.color.modern_grey_800_alpha_38))); // Decrease button is still disabled due to the minCountersSum requirement. // Click expand label to make Counter 2 visible. - onView(allOf(isDisplayed(), withId(R.id.expand_label))).perform(click()); + onView(allOf(withId(R.id.expand_label), withEffectiveVisibility(VISIBLE))) + .perform(scrollTo(), click()); // Click on Counter 3 +, increase from 0 to 1. - onView(allOf(isDisplayed(), withId(R.id.increase_button), + onView(allOf(withId(R.id.increase_button), withEffectiveVisibility(VISIBLE), hasSibling(hasDescendant(withText("Counter 3"))))) - .perform(click()); + .perform(scrollTo(), click()); // Click on Choice 1, then Choice 2, then back to Choice 1. onView(allOf(withClassName(is(RadioButton.class.getName())), withParentIndex(0), withEffectiveVisibility(VISIBLE))) - .perform(click()); + .perform(scrollTo(), click()); onView(allOf(withClassName(is(RadioButton.class.getName())), withParentIndex(3), withEffectiveVisibility(VISIBLE))) - .perform(click()); + .perform(scrollTo(), click()); onView(allOf(withClassName(is(RadioButton.class.getName())), withParentIndex(0), withEffectiveVisibility(VISIBLE))) - .perform(click()); + .perform(scrollTo(), click()); // Check that choice 1 is visually selected and choice 2 is de-selected. onView(allOf(withClassName(is(RadioButton.class.getName())), withParentIndex(0), @@ -224,9 +226,9 @@ .check(matches(not(isChecked()))); // Click on Counter 2 +, increase from 0 to 1. - onView(allOf(isDisplayed(), withId(R.id.increase_button), + onView(allOf(withId(R.id.increase_button), withEffectiveVisibility(VISIBLE), hasSibling(hasDescendant(withText("Counter 2"))))) - .perform(click()); + .perform(scrollTo(), click()); // Finish form action, wait for response and prepare next set of actions. List<ActionProto> nextActions = new ArrayList<>();
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 5ba558b5c..e334ce326 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
@@ -103,12 +103,12 @@ waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); // Tapping on the element should remove it from the DOM. - assertThat(checkElementExists("touch_area_one", mTestRule.getWebContents()), is(true)); - tapElement("touch_area_one", mTestRule); - assertThat(checkElementExists("touch_area_one", mTestRule.getWebContents()), is(false)); + assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_one"), is(true)); + tapElement(mTestRule, "touch_area_one"); + assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_one"), is(false)); // Tapping on the element should be blocked by the overlay. - tapElement("touch_area_four", mTestRule); - assertThat(checkElementExists("touch_area_four", mTestRule.getWebContents()), is(true)); + tapElement(mTestRule, "touch_area_four"); + assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_four"), is(true)); } /** @@ -149,15 +149,112 @@ // Tapping on the element should remove it from the DOM. The element should be after a // big element forcing the page to scroll. - assertThat(checkElementExists("touch_area_five", mTestRule.getWebContents()), is(true)); - tapElement("touch_area_five", mTestRule); - assertThat(checkElementExists("touch_area_five", mTestRule.getWebContents()), is(false)); + assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_five"), is(true)); + tapElement(mTestRule, "touch_area_five"); + assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_five"), is(false)); // Tapping on the element should be blocked by the overlay. - tapElement("touch_area_six", mTestRule); - assertThat(checkElementExists("touch_area_six", mTestRule.getWebContents()), is(true)); + tapElement(mTestRule, "touch_area_six"); + assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_six"), is(true)); } - // TODO(b/143942385): Write a test for an element within an iFrame. + /** + * Tests that clicking on an iFrame element works with a showcast. + */ + @Test + @MediumTest + public void testShowCastOnIFrameElement() throws Exception { + ElementReferenceProto element = (ElementReferenceProto) ElementReferenceProto.newBuilder() + .addSelectors("#iframe") + .addSelectors("#touch_area_1") + .build(); + + ArrayList<ActionProto> list = new ArrayList<>(); + list.add( + (ActionProto) ActionProto.newBuilder() + .setFocusElement(FocusElementProto.newBuilder() + .setElement(element) + .setTouchableElementArea( + ElementAreaProto.newBuilder().addTouchable( + Rectangle.newBuilder().addElements( + element)))) + .build()); + list.add((ActionProto) ActionProto.newBuilder() + .setPrompt(PromptProto.newBuilder().setMessage("Prompt").addChoices( + PromptProto.Choice.newBuilder())) + .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(), + list); + runScript(script); + + waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); + + // Tapping on the element should remove it from the DOM. + assertThat( + checkElementExists(mTestRule.getWebContents(), "iframe", "touch_area_1"), is(true)); + tapElement(mTestRule, "iframe", "touch_area_1"); + assertThat(checkElementExists(mTestRule.getWebContents(), "iframe", "touch_area_1"), + is(false)); + // Tapping on the element should be blocked by the overlay. + tapElement(mTestRule, "iframe", "touch_area_2"); + assertThat( + checkElementExists(mTestRule.getWebContents(), "iframe", "touch_area_2"), is(true)); + } + + /** + * Tests that clicking on an iFrame element works with a showcast in a scrolled iFrame. + */ + @Test + @MediumTest + public void testShowCastOnIFrameElementInScrollIFrame() throws Exception { + ElementReferenceProto element = (ElementReferenceProto) ElementReferenceProto.newBuilder() + .addSelectors("#iframe") + .addSelectors("#touch_area_3") + .build(); + + ArrayList<ActionProto> list = new ArrayList<>(); + list.add( + (ActionProto) ActionProto.newBuilder() + .setFocusElement(FocusElementProto.newBuilder() + .setElement(element) + .setTouchableElementArea( + ElementAreaProto.newBuilder().addTouchable( + Rectangle.newBuilder().addElements( + element)))) + .build()); + list.add((ActionProto) ActionProto.newBuilder() + .setPrompt(PromptProto.newBuilder().setMessage("Prompt").addChoices( + PromptProto.Choice.newBuilder())) + .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(), + list); + runScript(script); + + waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); + + // Tapping on the element should remove it from the DOM. The element should be after a + // big element forcing the page to scroll. + assertThat( + checkElementExists(mTestRule.getWebContents(), "iframe", "touch_area_3"), is(true)); + tapElement(mTestRule, "iframe", "touch_area_3"); + assertThat(checkElementExists(mTestRule.getWebContents(), "iframe", "touch_area_3"), + is(false)); + // Tapping on the element should be blocked by the overlay. + tapElement(mTestRule, "iframe", "touch_area_4"); + assertThat( + checkElementExists(mTestRule.getWebContents(), "iframe", "touch_area_4"), is(true)); + } private void runScript(AutofillAssistantTestScript script) { AutofillAssistantTestService testService =
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java index 733c9c0..a30a5ba 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java
@@ -12,6 +12,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.checkElementExists; import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.getBoundingRectForElement; @@ -23,6 +24,7 @@ import android.graphics.Color; import android.graphics.Rect; import android.graphics.RectF; +import android.support.annotation.Nullable; import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; @@ -71,16 +73,22 @@ return mTestRule.getWebContents(); } - /** Creates a coordinator for use in UI tests. */ + /** Creates a coordinator for use in UI tests with a default, non-null overlay image. */ private AssistantOverlayCoordinator createCoordinator(AssistantOverlayModel model) throws ExecutionException { - Bitmap testImage = BitmapFactory.decodeResource(mTestRule.getActivity().getResources(), - org.chromium.chrome.autofill_assistant.R.drawable.btn_close); + return createCoordinator(model, + BitmapFactory.decodeResource(mTestRule.getActivity().getResources(), + org.chromium.chrome.autofill_assistant.R.drawable.btn_close)); + } + /** Creates a coordinator for use in UI tests with a custom overlay image. */ + private AssistantOverlayCoordinator createCoordinator( + AssistantOverlayModel model, @Nullable Bitmap overlayImage) throws ExecutionException { return runOnUiThreadBlocking( () -> new AssistantOverlayCoordinator(mTestRule.getActivity(), model, - new AutofillAssistantUiTestUtil.MockImageFetcher(testImage, null))); + new AutofillAssistantUiTestUtil.MockImageFetcher( + overlayImage, null))); } /** Tests assumptions about the initial state of the infobox. */ @@ -92,7 +100,7 @@ assertScrimDisplayed(false); tapElement("touch_area_one"); - assertThat(checkElementExists("touch_area_one", getWebContents()), is(false)); + assertThat(checkElementExists(getWebContents(), "touch_area_one"), is(false)); } /** Tests assumptions about the full overlay. */ @@ -106,13 +114,13 @@ () -> model.set(AssistantOverlayModel.STATE, AssistantOverlayState.FULL)); assertScrimDisplayed(true); tapElement("touch_area_one"); - assertThat(checkElementExists("touch_area_one", getWebContents()), is(true)); + assertThat(checkElementExists(getWebContents(), "touch_area_one"), is(true)); runOnUiThreadBlocking( () -> model.set(AssistantOverlayModel.STATE, AssistantOverlayState.HIDDEN)); assertScrimDisplayed(false); tapElement("touch_area_one"); - assertThat(checkElementExists("touch_area_one", getWebContents()), is(false)); + assertThat(checkElementExists(getWebContents(), "touch_area_one"), is(false)); } /** Tests assumptions about the full overlay. */ @@ -144,16 +152,16 @@ () -> model.set(AssistantOverlayModel.STATE, AssistantOverlayState.PARTIAL)); assertScrimDisplayed(true); tapElement("touch_area_one"); - assertThat(checkElementExists("touch_area_one", getWebContents()), is(true)); + assertThat(checkElementExists(getWebContents(), "touch_area_one"), is(true)); - Rect rect = getBoundingRectForElement("touch_area_one", getWebContents()); + Rect rect = getBoundingRectForElement(getWebContents(), "touch_area_one"); runOnUiThreadBlocking(() -> model.set(AssistantOverlayModel.TOUCHABLE_AREA, Collections.singletonList(new RectF(rect)))); // Touchable area set, but no viewport given: equivalent to full overlay. tapElement("touch_area_one"); - assertThat(checkElementExists("touch_area_one", getWebContents()), is(true)); + assertThat(checkElementExists(getWebContents(), "touch_area_one"), is(true)); // Set viewport. Rect viewport = getViewport(getWebContents()); @@ -162,12 +170,12 @@ // Now the partial overlay allows tapping the highlighted touch area. tapElement("touch_area_one"); - assertThat(checkElementExists("touch_area_one", getWebContents()), is(false)); + assertThat(checkElementExists(getWebContents(), "touch_area_one"), is(false)); runOnUiThreadBlocking( () -> model.set(AssistantOverlayModel.TOUCHABLE_AREA, Collections.emptyList())); tapElement("touch_area_three"); - assertThat(checkElementExists("touch_area_three", getWebContents()), is(true)); + assertThat(checkElementExists(getWebContents(), "touch_area_three"), is(true)); } /** Scrolls a touchable area into view and then taps it. */ @@ -177,7 +185,7 @@ AssistantOverlayModel model = new AssistantOverlayModel(); AssistantOverlayCoordinator coordinator = createCoordinator(model); - Rect rect = getBoundingRectForElement("touch_area_two", getWebContents()); + Rect rect = getBoundingRectForElement(getWebContents(), "touch_area_two"); Rect viewport = getViewport(getWebContents()); runOnUiThreadBlocking(() -> { model.set(AssistantOverlayModel.STATE, AssistantOverlayState.PARTIAL); @@ -190,7 +198,49 @@ runOnUiThreadBlocking( () -> model.set(AssistantOverlayModel.VISUAL_VIEWPORT, new RectF(newViewport))); tapElement("touch_area_two"); - assertThat(checkElementExists("touch_area_two", getWebContents()), is(false)); + assertThat(checkElementExists(getWebContents(), "touch_area_two"), is(false)); + } + + /** + * Regular overlay image test. Since there is no easy way to test whether the image is actually + * rendered, this is simply checking that nothing crashes. + */ + @Test + @MediumTest + public void testOverlayImageDoesNotCrashIfValid() throws Exception { + AssistantOverlayModel model = new AssistantOverlayModel(); + Bitmap bitmap = BitmapFactory.decodeResource(mTestRule.getActivity().getResources(), + org.chromium.chrome.autofill_assistant.R.drawable.btn_close); + assertThat(bitmap, notNullValue()); + AssistantOverlayCoordinator coordinator = + createCoordinator(model, /* overlayImage = */ bitmap); + + runOnUiThreadBlocking(() -> { + model.set(AssistantOverlayModel.STATE, AssistantOverlayState.FULL); + model.set(AssistantOverlayModel.OVERLAY_IMAGE, + new AssistantOverlayImage("https://www.example.com/example.png", 32, 32, 12, + "Text", Color.RED, 20)); + }); + + assertScrimDisplayed(true); + } + + /** Simulates what would happen if the overlay image fetcher returned null. */ + @Test + @MediumTest + public void testOverlayDoesNotCrashIfImageFailsToLoad() throws Exception { + AssistantOverlayModel model = new AssistantOverlayModel(); + AssistantOverlayCoordinator coordinator = + createCoordinator(model, /* overlayImage = */ null); + + runOnUiThreadBlocking(() -> { + model.set(AssistantOverlayModel.STATE, AssistantOverlayState.FULL); + model.set(AssistantOverlayModel.OVERLAY_IMAGE, + new AssistantOverlayImage("https://www.example.com/example.png", 32, 32, 12, + "Text", Color.RED, 20)); + }); + + assertScrimDisplayed(true); } private void assertScrimDisplayed(boolean expected) throws Exception { @@ -214,7 +264,7 @@ } void tapElement(String elementId) throws Exception { - AutofillAssistantUiTestUtil.tapElement(elementId, mTestRule); + AutofillAssistantUiTestUtil.tapElement(mTestRule, elementId); } /**
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPersonalDataManagerTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPersonalDataManagerTest.java index d4aab0c..744354f3 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPersonalDataManagerTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPersonalDataManagerTest.java
@@ -165,8 +165,8 @@ .check(matches(allOf(withText("johndoe@google.com"), isDisplayed()))); onView(withText("Continue")).perform(click()); waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); - assertThat(getElementValue("profile_name", getWebContents()), is("John Doe")); - assertThat(getElementValue("email", getWebContents()), is("johndoe@google.com")); + assertThat(getElementValue(getWebContents(), "profile_name"), is("John Doe")); + assertThat(getElementValue(getWebContents(), "email"), is("johndoe@google.com")); } /** @@ -217,8 +217,8 @@ waitUntilViewMatchesCondition(withContentDescription("Continue"), isEnabled()); onView(withContentDescription("Continue")).perform(click()); waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); - assertThat(getElementValue("profile_name", getWebContents()), is("John Doe")); - assertThat(getElementValue("email", getWebContents()), is("johndoe@google.com")); + assertThat(getElementValue(getWebContents(), "profile_name"), is("John Doe")); + assertThat(getElementValue(getWebContents(), "email"), is("johndoe@google.com")); } /** @@ -276,8 +276,8 @@ onView(withText("Continue")).perform(click()); waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); // Make sure it's not Adam West that was selected. - assertThat(getElementValue("profile_name", getWebContents()), is("John Doe")); - assertThat(getElementValue("email", getWebContents()), is("johndoe@google.com")); + assertThat(getElementValue(getWebContents(), "profile_name"), is("John Doe")); + assertThat(getElementValue(getWebContents(), "email"), is("johndoe@google.com")); } /** @@ -395,8 +395,8 @@ onView(withText("Continue")).perform(click()); waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); // Make sure it's now Jane Doe. - assertThat(getElementValue("profile_name", getWebContents()), is("Jane Doe")); - assertThat(getElementValue("email", getWebContents()), is("janedoe@google.com")); + assertThat(getElementValue(getWebContents(), "profile_name"), is("Jane Doe")); + assertThat(getElementValue(getWebContents(), "email"), is("janedoe@google.com")); } /** @@ -477,11 +477,11 @@ onView(withId(R.id.card_unmask_input)).perform(typeText("123")); onView(withId(R.id.positive_button)).perform(click()); waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); - assertThat(getElementValue("name", getWebContents()), is("John Doe")); - assertThat(getElementValue("card_number", getWebContents()), is("4111111111111111")); - assertThat(getElementValue("cv2_number", getWebContents()), is("123")); - assertThat(getElementValue("exp_month", getWebContents()), is("01")); - assertThat(getElementValue("exp_year", getWebContents()), is(String.valueOf(year + 2))); + assertThat(getElementValue(getWebContents(), "name"), is("John Doe")); + assertThat(getElementValue(getWebContents(), "card_number"), is("4111111111111111")); + assertThat(getElementValue(getWebContents(), "cv2_number"), is("123")); + assertThat(getElementValue(getWebContents(), "exp_month"), is("01")); + assertThat(getElementValue(getWebContents(), "exp_year"), is(String.valueOf(year + 2))); } /**
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 2fdcb2b..a4a51d6 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
@@ -65,6 +65,7 @@ import org.chromium.content_public.browser.test.util.TestTouchUtils; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import jp.tomorrowkey.android.gifplayer.BaseGifImage; @@ -429,27 +430,28 @@ } /** Performs a single tap on the center of the specified element. */ - public static void tapElement(String elementId, CustomTabActivityTestRule testRule) + public static void tapElement(CustomTabActivityTestRule testRule, String... elementIds) throws Exception { - Rect coords = getAbsoluteBoundingRect(elementId, testRule); + Rect coords = getAbsoluteBoundingRect(testRule, elementIds); float x = coords.left + 0.5f * (coords.right - coords.left); float y = coords.top + 0.5f * (coords.bottom - coords.top); // Sanity check, can only click on coordinates on screen. DisplayMetrics displayMetrics = testRule.getActivity().getResources().getDisplayMetrics(); if (x < 0 || x > displayMetrics.widthPixels || y < 0 || y > displayMetrics.heightPixels) { - throw new IllegalArgumentException(elementId + " not on screen: tried to tap x=" + x - + ", y=" + y + ", which is outside of display with w=" - + displayMetrics.widthPixels + ", h=" + displayMetrics.heightPixels); + throw new IllegalArgumentException(Arrays.toString(elementIds) + + " not on screen: tried to tap x=" + x + ", y=" + y + + ", which is outside of display with w=" + displayMetrics.widthPixels + + ", h=" + displayMetrics.heightPixels); } TestTouchUtils.singleClick(InstrumentationRegistry.getInstrumentation(), x, y); } /** Computes the bounding rectangle of the specified DOM element in absolute screen space. */ - public static Rect getAbsoluteBoundingRect(String elementId, CustomTabActivityTestRule testRule) - throws Exception { + public static Rect getAbsoluteBoundingRect( + CustomTabActivityTestRule testRule, String... elementIds) throws Exception { // Get bounding rectangle in viewport space. - Rect elementRect = getBoundingRectForElement(elementId, testRule.getWebContents()); + Rect elementRect = getBoundingRectForElement(testRule.getWebContents(), elementIds); /* * Conversion from viewport space to screen space is done in two steps: @@ -475,34 +477,45 @@ * Retrieves the bounding rectangle for the specified element in the DOM tree in CSS pixel * coordinates. */ - public static Rect getBoundingRectForElement(String elementId, WebContents webContents) + public static Rect getBoundingRectForElement(WebContents webContents, String... elementIds) throws Exception { - if (!checkElementExists(elementId, webContents)) { - throw new IllegalArgumentException(elementId + " does not exist"); + if (!checkElementExists(webContents, elementIds)) { + throw new IllegalArgumentException(Arrays.toString(elementIds) + " does not exist"); } TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper javascriptHelper = new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper(); - javascriptHelper.evaluateJavaScriptForTests(webContents, - "(function() {" - + " rect = document.getElementById('" + elementId - + "').getBoundingClientRect();" - + " return [window.scrollX + rect.left, window.scrollY + rect.top, " - + " window.scrollX + rect.right, window.scrollY + rect.bottom];" - + "})()"); - javascriptHelper.waitUntilHasValue(); - JSONArray rectJson = new JSONArray(javascriptHelper.getJsonResultAndClear()); - return new Rect( - rectJson.getInt(0), rectJson.getInt(1), rectJson.getInt(2), rectJson.getInt(3)); + Rect rect = new Rect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE); + for (int i = 0; i < elementIds.length; ++i) { + String offsetX = i == 0 ? "window.scrollX" : "0"; + String offsetY = i == 0 ? "window.scrollY" : "0"; + String elementSelector = + getElementSelectorString(Arrays.copyOfRange(elementIds, 0, i + 1)); + javascriptHelper.evaluateJavaScriptForTests(webContents, + "(function() {" + + " rect = " + elementSelector + ".getBoundingClientRect();" + + " return [" + offsetX + " + rect.left, " + offsetY + " + rect.top, " + + " " + offsetX + " + rect.right, " + offsetY + + " + rect.bottom];" + + "})()"); + javascriptHelper.waitUntilHasValue(); + JSONArray rectJson = new JSONArray(javascriptHelper.getJsonResultAndClear()); + + rect = new Rect(Math.min(rect.right, rect.left + rectJson.getInt(0)), + Math.min(rect.bottom, rect.top + rectJson.getInt(1)), + Math.min(rect.right, rect.left + rectJson.getInt(2)), + Math.min(rect.bottom, rect.top + rectJson.getInt(3))); + } + return rect; } /** Checks whether the specified element exists in the DOM tree. */ - public static boolean checkElementExists(String elementId, WebContents webContents) + public static boolean checkElementExists(WebContents webContents, String... elementIds) throws Exception { TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper javascriptHelper = new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper(); javascriptHelper.evaluateJavaScriptForTests(webContents, "(function() {" - + " return [document.getElementById('" + elementId + "') != null]; " + + " return [" + getElementSelectorString(elementIds) + " != null]; " + "})()"); javascriptHelper.waitUntilHasValue(); JSONArray result = new JSONArray(javascriptHelper.getJsonResultAndClear()); @@ -510,14 +523,14 @@ } /** Checks whether the specified element is displayed in the DOM tree. */ - public static boolean checkElementIsDisplayed(String elementId, WebContents webContents) + public static boolean checkElementIsDisplayed(WebContents webContents, String... elementIds) throws Exception { TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper javascriptHelper = new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper(); javascriptHelper.evaluateJavaScriptForTests(webContents, "(function() {" - + " return [document.getElementById('" + elementId - + "').style.display != \"none\"]; " + + " return [" + getElementSelectorString(elementIds) + + ".style.display != \"none\"]; " + "})()"); javascriptHelper.waitUntilHasValue(); JSONArray result = new JSONArray(javascriptHelper.getJsonResultAndClear()); @@ -543,19 +556,37 @@ /** * Retrieves the value of the specified element. */ - public static String getElementValue(String elementId, WebContents webContents) + public static String getElementValue(WebContents webContents, String... elementIds) throws Exception { - if (!checkElementExists(elementId, webContents)) { - throw new IllegalArgumentException(elementId + " does not exist"); + if (!checkElementExists(webContents, elementIds)) { + throw new IllegalArgumentException(Arrays.toString(elementIds) + " does not exist"); } TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper javascriptHelper = new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper(); javascriptHelper.evaluateJavaScriptForTests(webContents, "(function() {" - + " return [document.getElementById('" + elementId + "').value]" + + " return [" + getElementSelectorString(elementIds) + ".value]" + "})()"); javascriptHelper.waitUntilHasValue(); JSONArray result = new JSONArray(javascriptHelper.getJsonResultAndClear()); return result.getString(0); } + + private static String getElementSelectorString(String[] elementIds) { + StringBuilder builder = new StringBuilder(); + builder.append("document"); + + for (int i = 0; i < elementIds.length; ++i) { + builder.append(".getElementById('"); + builder.append(elementIds[i]); + builder.append("')"); + if (i != elementIds.length - 1) { + // Get the iFrame document. This only works for local iFrames, OutOfProcess iFrames + // may respond with an error. + builder.append(".contentWindow.document"); + } + } + + return builder.toString(); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunUtils.java index eadb9e83..aeadbdb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunUtils.java
@@ -90,7 +90,7 @@ @VisibleForTesting static boolean hasGoogleAccounts() { - return AccountManagerFacade.get().hasGoogleAccounts(); + return !AccountManagerFacade.get().tryGetGoogleAccounts().isEmpty(); } @SuppressLint("InlinedApi")
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java index d2a4913..193e3d7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java
@@ -46,10 +46,11 @@ import org.chromium.chrome.browser.payments.ui.PaymentRequestSection.LineItemBreakdownSection; import org.chromium.chrome.browser.payments.ui.PaymentRequestSection.OptionSection; import org.chromium.chrome.browser.payments.ui.PaymentRequestSection.SectionSeparator; +import org.chromium.chrome.browser.signin.IdentityServicesProvider; import org.chromium.components.browser_ui.widget.FadingEdgeScrollView; import org.chromium.components.browser_ui.widget.animation.FocusAnimator; import org.chromium.components.browser_ui.widget.animation.Interpolators; -import org.chromium.components.signin.ChromeSigninController; +import org.chromium.components.signin.base.CoreAccountInfo; import org.chromium.ui.text.NoUnderlineClickableSpan; import org.chromium.ui.text.SpanApplier; import org.chromium.ui.text.SpanApplier.SpanInfo; @@ -1106,11 +1107,16 @@ String message; if (!mShowDataSource) { message = mContext.getString(R.string.payments_card_and_address_settings); - } else if (ChromeSigninController.get().isSignedIn()) { - message = mContext.getString(R.string.payments_card_and_address_settings_signed_in, - ChromeSigninController.get().getSignedInAccountName()); } else { - message = mContext.getString(R.string.payments_card_and_address_settings_signed_out); + CoreAccountInfo coreAccountInfo = + IdentityServicesProvider.get().getIdentityManager().getPrimaryAccountInfo(); + if (coreAccountInfo != null) { + message = mContext.getString(R.string.payments_card_and_address_settings_signed_in, + coreAccountInfo.getEmail()); + } else { + message = + mContext.getString(R.string.payments_card_and_address_settings_signed_out); + } } NoUnderlineClickableSpan settingsSpan = new NoUnderlineClickableSpan(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/settings/OWNERS index de5743e..ed50038 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/settings/OWNERS +++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/OWNERS
@@ -6,5 +6,6 @@ # Site settings: finnur@chromium.org hkamila@chromium.org +andypaicu@chromium.org # COMPONENT: UI>Browser>Mobile>Settings
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmManagedSyncDataDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmManagedSyncDataDialog.java index e040255..9d371014 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmManagedSyncDataDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmManagedSyncDataDialog.java
@@ -55,13 +55,13 @@ } private void setListener(Listener listener) { - assert mListener == null; + assert listener != null; mListener = listener; } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - if (savedInstanceState != null) { + if (mListener == null) { dismiss(); } String title = getString(R.string.sign_in_managed_account);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncController.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncController.java index 3003c0b..fc0d674d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncController.java
@@ -135,7 +135,7 @@ if (isSyncEnabled) { mProfileSyncService.requestStart(); } else { - if (Profile.getLastUsedProfile().isChild()) { + if (Profile.getLastUsedRegularProfile().isChild()) { // For child accounts, Sync needs to stay enabled, so we reenable it in settings. // TODO(bauerb): Remove the dependency on child account code and instead go through // prefs (here and in the Sync customization UI).
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseCreationDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseCreationDialogFragment.java index 9fb1589..00a3950c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseCreationDialogFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseCreationDialogFragment.java
@@ -78,7 +78,7 @@ public void onClick(View view) { HelpAndFeedback.getInstance().show(activity, activity.getString(R.string.help_context_change_sync_passphrase), - Profile.getLastUsedProfile(), null); + Profile.getLastUsedRegularProfile(), null); } })); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java index 596bb778..7291d82 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java
@@ -182,10 +182,6 @@ new SpanInfo("<learnmore>", "</learnmore>", new ClickableSpan() { @Override public void onClick(View view) { - // TODO(https://crbug.com/1048632): It works correctly now, but unsafe - // if sync runs in incognito mode ever. Use the current profile (i.e., - // regular profile or incognito profile) instead of always using regular - // profile. HelpAndFeedback.getInstance().show(getActivity(), helpContext, Profile.getLastUsedRegularProfile(), null); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java index 3a48354..c2a5056 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -1307,6 +1307,7 @@ @Test @SmallTest @Feature({"ContextualSearch"}) + @DisabledTest(message = "crbug.com/1058297") public void testTapCausesOneLowPriorityRequest() throws TimeoutException { mFakeServer.reset(); clickWordNode("states"); @@ -3010,6 +3011,7 @@ @Test @SmallTest @Feature({"ContextualSearch"}) + @DisabledTest(message = "crbug.com/1058297") public void testAllInternalStatesVisitedResolvingTap() throws InterruptedException, TimeoutException { // Set up a tracking version of the Internal State Controller.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunUtilsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunUtilsTest.java index 5474585..38646df 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunUtilsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunUtilsTest.java
@@ -46,7 +46,7 @@ private static class FakeAuthenticationAccountManager extends FakeAccountManagerDelegate { private final String mAccountType; - public FakeAuthenticationAccountManager(String accountType) { + FakeAuthenticationAccountManager(String accountType) { super(FakeAccountManagerDelegate.DISABLE_PROFILE_DATA_SOURCE); mAccountType = accountType; } @@ -70,11 +70,6 @@ AccountHolder.builder(mTestAccount).alwaysAccept(true).build()); } - // This test previously flaked on the try bot: http://crbug.com/543160. - // Re-enabling this test since there has been related cleanup/refactoring - // during the time the test was disabled. If the test starts flaking again, - // re-open the bug. - // TODO(nyquist): Remove this if the test is not flaky anymore. @Test @SmallTest @Feature({"GoogleAccounts"}) @@ -85,20 +80,10 @@ addTestAccount(); ContextUtils.initApplicationContextForTests(mAccountTestingContext); - boolean hasAccounts = FirstRunUtils.hasGoogleAccounts(); - - Assert.assertTrue(hasAccounts); - - boolean hasAuthenticator = FirstRunUtils.hasGoogleAccountAuthenticator(); - - Assert.assertTrue(hasAuthenticator); + Assert.assertTrue(FirstRunUtils.hasGoogleAccounts()); + Assert.assertTrue(FirstRunUtils.hasGoogleAccountAuthenticator()); } - // This test previously flaked on the try bot: http://crbug.com/543160. - // Re-enabling this test since there has been related cleanup/refactoring - // during the time the test was disabled. If the test starts flaking again, - // re-open the bug. - // TODO(nyquist): Remove this if the test is not flaky anymore. @Test @SmallTest @Feature({"GoogleAccounts"}) @@ -108,12 +93,7 @@ setUpAccountManager("Not A Google Account"); ContextUtils.initApplicationContextForTests(mAccountTestingContext); - boolean hasAccounts = FirstRunUtils.hasGoogleAccounts(); - - Assert.assertFalse(hasAccounts); - - boolean hasAuthenticator = FirstRunUtils.hasGoogleAccountAuthenticator(); - - Assert.assertFalse(hasAuthenticator); + Assert.assertFalse(FirstRunUtils.hasGoogleAccounts()); + Assert.assertFalse(FirstRunUtils.hasGoogleAccountAuthenticator()); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/ConfirmManagedSyncDataDialogIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/ConfirmManagedSyncDataDialogIntegrationTest.java index 68ce23c..300baed 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/ConfirmManagedSyncDataDialogIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/ConfirmManagedSyncDataDialogIntegrationTest.java
@@ -17,7 +17,6 @@ import org.mockito.Mock; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisabledTest; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.content_public.browser.test.util.TestThreadUtils; @@ -42,7 +41,6 @@ @Test @LargeTest - @DisabledTest(message = "Flaky crbug.com/1054855") public void testDialogIsDismissedWhenRecreated() { ConfirmManagedSyncDataDialog dialog = ConfirmManagedSyncDataDialog.create(mListenerMock, TEST_DOMAIN);
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index 9e914e2..888fd51e 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-82.0.4072.0_rc-r1-merged.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-82.0.4075.0_rc-r1-merged.afdo.bz2 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index f4b77ca..d5240107 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -633,11 +633,14 @@ Select timezone </message> <message name="IDS_OOBE_EULA_SECTION_TITLE" desc="Title of Terms of Service screen"> - Google Chrome OS Terms + Google universal Terms of Service (uToS) </message> <message name="IDS_OOBE_EULA_IFRAME_LABEL" desc="Accessibility label on an iframe with full Chrome OS Terms text"> Google Chrome OS Terms contents </message> + <message name="IDS_OOBE_EULA_ADDITIONAL_TERMS" desc="Text of the Link to Google Chrome and Chrome OS additional terms"> + Google Chrome and Chrome OS Additional Terms + </message> <message name="IDS_OOBE_EULA_ACCEPT_AND_CONTINUE_BUTTON_TEXT" desc="Label on a button on the Title of Terms of Service OOBE screen to accept EULA and continue."> Accept and continue </message>
diff --git a/chrome/app/chromeos_strings_grdp/IDS_OOBE_EULA_ADDITIONAL_TERMS.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_OOBE_EULA_ADDITIONAL_TERMS.png.sha1 new file mode 100644 index 0000000..1136b235 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_OOBE_EULA_ADDITIONAL_TERMS.png.sha1
@@ -0,0 +1 @@ +21d717ee171285a99bad56f5c920f11d4ea75df0 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_OOBE_EULA_SECTION_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_OOBE_EULA_SECTION_TITLE.png.sha1 new file mode 100644 index 0000000..1136b235 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_OOBE_EULA_SECTION_TITLE.png.sha1
@@ -0,0 +1 @@ +21d717ee171285a99bad56f5c920f11d4ea75df0 \ No newline at end of file
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 19ee0b4..ba4710a3 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -1527,9 +1527,6 @@ <message name="IDS_SETTINGS_SAFETY_CHECK_UPDATES_PRIMARY_LABEL" desc="'Updates' is an element in safety check that shows the update status of Chrome."> Updates </message> - <message name="IDS_SETTINGS_SAFETY_CHECK_PASSWORDS_PRIMARY_LABEL" desc="'Passwords' is an element in safety check that allows users to check for their passwords being compromised."> - Passwords - </message> <message name="IDS_SAFETY_CHECK_PASSWORDS_SUB_LABEL_SAFE" desc="This text points out that the safety check password check has not found any compromised passwords."> No compromised passwords found </message> @@ -1545,6 +1542,21 @@ <message name="IDS_SAFETY_CHECK_PASSWORDS_BUTTON_ERROR" desc="This button allows users to try the password check again."> Try again </message> + <message name="IDS_SETTINGS_SAFETY_CHECK_SAFE_BROWSING_SUB_LABEL_ENABLED" desc="This text points out that Safe Browsing is enabled and that the user is protected."> + Safe Browsing is up to date and protecting you from harmful sites and downloads + </message> + <message name="IDS_SETTINGS_SAFETY_CHECK_SAFE_BROWSING_SUB_LABEL_DISABLED" desc="This text points out that Safe Browsing is disabled and that the user is not protected."> + Safe Browsing is off. To stay safe on the web, turn it on. + </message> + <message name="IDS_SETTINGS_SAFETY_CHECK_SAFE_BROWSING_SUB_LABEL_DISABLED_BY_ADMIN" desc="This text points out that Safe Browsing is disabled by an administrator."> + Your administrator has turned off Safe Browsing + </message> + <message name="IDS_SETTINGS_SAFETY_CHECK_SAFE_BROWSING_SUB_LABEL_DISABLED_BY_EXTENSION" desc="This text points out that Safe Browsing is disabled by an extension."> + An extension has turned off Safe Browsing + </message> + <message name="IDS_SETTINGS_SAFETY_CHECK_SAFE_BROWSING_BUTTON" desc="This is the text for the button that allows users to manage their Safe Browsing settings."> + Manage + </message> <message name="IDS_SETTINGS_SAFETY_CHECK_EXTENSIONS_PRIMARY_LABEL" desc="'Extensions' is an element in safety check that shows the safety check status of installed extensions."> Extensions </message>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 3451aa00..0fd1c87 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -5564,6 +5564,7 @@ if (is_win || is_mac || is_desktop_linux || is_chromeos) { deps += [ "//chrome/browser/resources/discards:discards_resources_gen", + "//chrome/browser/resources/gaia_auth_host:modulize", "//chrome/browser/resources/management:polymer3_elements", "//chrome/browser/resources/signin:polymer3_elements", "//chrome/browser/ui/webui/discards:mojo_bindings_js",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 2220cd1..e527043d 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -4881,6 +4881,14 @@ FEATURE_VALUE_TYPE(features::kUserDataSnapshot)}, #endif +#if defined(OS_WIN) + {"run-video-capture-service-in-browser", + flag_descriptions::kRunVideoCaptureServiceInBrowserProcessName, + flag_descriptions::kRunVideoCaptureServiceInBrowserProcessDescription, + kOsWin, + FEATURE_VALUE_TYPE(features::kRunVideoCaptureServiceInBrowserProcess)}, +#endif // defined(OS_WIN) + {"legacy-tls-enforced", flag_descriptions::kLegacyTLSEnforcedName, flag_descriptions::kLegacyTLSEnforcedDescription, kOsDesktop | kOsAndroid, FEATURE_VALUE_TYPE(net::features::kLegacyTLSEnforced)},
diff --git a/chrome/browser/autofill/mock_autofill_popup_controller.cc b/chrome/browser/autofill/mock_autofill_popup_controller.cc index 06dc6e4c..fe41477b 100644 --- a/chrome/browser/autofill/mock_autofill_popup_controller.cc +++ b/chrome/browser/autofill/mock_autofill_popup_controller.cc
@@ -9,7 +9,7 @@ MockAutofillPopupController::MockAutofillPopupController() { gfx::FontList::SetDefaultFontDescription("Arial, Times New Roman, 15px"); layout_model_ = std::make_unique<autofill::AutofillPopupLayoutModel>( - this, false /* is_credit_card_field */); + false /* is_credit_card_field */); } MockAutofillPopupController::~MockAutofillPopupController() = default;
diff --git a/chrome/browser/autofill/mock_autofill_popup_controller.h b/chrome/browser/autofill/mock_autofill_popup_controller.h index e5212fc..7e1ab6a 100644 --- a/chrome/browser/autofill/mock_autofill_popup_controller.h +++ b/chrome/browser/autofill/mock_autofill_popup_controller.h
@@ -40,17 +40,13 @@ return *bounds; } MOCK_CONST_METHOD0(IsRTL, bool()); - const std::vector<autofill::Suggestion> GetSuggestions() override { - return suggestions_; - } -#if !defined(OS_ANDROID) - MOCK_METHOD1(GetElidedValueWidthForRow, int(int row)); - MOCK_METHOD1(GetElidedLabelWidthForRow, int(int row)); -#endif // AutofillPopupController MOCK_METHOD0(OnSuggestionsChanged, void()); MOCK_METHOD1(AcceptSuggestion, void(int index)); + const std::vector<autofill::Suggestion> GetSuggestions() override { + return suggestions_; + } int GetLineCount() const override { return suggestions_.size(); }
diff --git a/chrome/browser/bluetooth/bluetooth_chooser_context.cc b/chrome/browser/bluetooth/bluetooth_chooser_context.cc index 04a5b08..bc579e6 100644 --- a/chrome/browser/bluetooth/bluetooth_chooser_context.cc +++ b/chrome/browser/bluetooth/bluetooth_chooser_context.cc
@@ -291,13 +291,6 @@ return *object.FindStringKey(kDeviceNameKey); } -// static -WebBluetoothDeviceId BluetoothChooserContext::GetObjectDeviceId( - const base::Value& object) { - std::string device_id_str = *object.FindStringKey(kWebBluetoothDeviceIdKey); - return WebBluetoothDeviceId(device_id_str); -} - bool BluetoothChooserContext::IsValidObject(const base::Value& object) { return object.FindStringKey(kDeviceAddressKey) && object.FindStringKey(kDeviceNameKey) &&
diff --git a/chrome/browser/bluetooth/bluetooth_chooser_context.h b/chrome/browser/bluetooth/bluetooth_chooser_context.h index b29083bf..37581114 100644 --- a/chrome/browser/bluetooth/bluetooth_chooser_context.h +++ b/chrome/browser/bluetooth/bluetooth_chooser_context.h
@@ -79,8 +79,6 @@ // Returns the human readable string representing the given object. static std::string GetObjectName(const base::Value& object); - static blink::WebBluetoothDeviceId GetObjectDeviceId( - const base::Value& object); protected: // ChooserContextBase implementation;
diff --git a/chrome/browser/chromeos/login/saml/in_session_password_change_manager.cc b/chrome/browser/chromeos/login/saml/in_session_password_change_manager.cc index 8ae43ec..4a74e69 100644 --- a/chrome/browser/chromeos/login/saml/in_session_password_change_manager.cc +++ b/chrome/browser/chromeos/login/saml/in_session_password_change_manager.cc
@@ -204,7 +204,7 @@ // Remove |this| as a SessionActivationObserver. auto* session_controller = ash::SessionController::Get(); if (session_controller) { - session_controller->AddSessionActivationObserverForAccountId( + session_controller->RemoveSessionActivationObserverForAccountId( primary_user_->GetAccountId(), this); } }
diff --git a/chrome/browser/chromeos/login/screens/sync_consent_browsertest.cc b/chrome/browser/chromeos/login/screens/sync_consent_browsertest.cc index d8ddf6e..d3c4881 100644 --- a/chrome/browser/chromeos/login/screens/sync_consent_browsertest.cc +++ b/chrome/browser/chromeos/login/screens/sync_consent_browsertest.cc
@@ -290,14 +290,15 @@ SyncConsentPolicyDisabledTest, testing::Bool()); -// Tests of the consent dialog with the SplitSettingsSync flag enabled. -class SyncConsentSplitSettingsSyncTest : public SyncConsentTest { +// Tests of the consent dialog with the SplitSyncConsent flag enabled. +class SyncConsentSplitSyncConsentTest : public SyncConsentTest { public: - SyncConsentSplitSettingsSyncTest() { - sync_feature_list_.InitAndEnableFeature( - chromeos::features::kSplitSettingsSync); + SyncConsentSplitSyncConsentTest() { + sync_feature_list_.InitWithFeatures({chromeos::features::kSplitSettingsSync, + chromeos::features::kSplitSyncConsent}, + {}); } - ~SyncConsentSplitSettingsSyncTest() override = default; + ~SyncConsentSplitSyncConsentTest() override = default; private: base::test::ScopedFeatureList sync_feature_list_; @@ -309,7 +310,7 @@ #else #define MAYBE_DefaultFlow DefaultFlow #endif -IN_PROC_BROWSER_TEST_F(SyncConsentSplitSettingsSyncTest, MAYBE_DefaultFlow) { +IN_PROC_BROWSER_TEST_F(SyncConsentSplitSyncConsentTest, MAYBE_DefaultFlow) { LoginToSyncConsentScreen(); // OS sync is disabled by default. @@ -364,7 +365,7 @@ #else #define MAYBE_UserCanDisable UserCanDisable #endif -IN_PROC_BROWSER_TEST_F(SyncConsentSplitSettingsSyncTest, MAYBE_UserCanDisable) { +IN_PROC_BROWSER_TEST_F(SyncConsentSplitSyncConsentTest, MAYBE_UserCanDisable) { LoginToSyncConsentScreen(); // Wait for content to load.
diff --git a/chrome/browser/chromeos/login/screens/sync_consent_screen.cc b/chrome/browser/chromeos/login/screens/sync_consent_screen.cc index fc6543d..6171258 100644 --- a/chrome/browser/chromeos/login/screens/sync_consent_screen.cc +++ b/chrome/browser/chromeos/login/screens/sync_consent_screen.cc
@@ -127,7 +127,7 @@ const std::vector<int>& consent_description, int consent_confirmation, bool enable_os_sync) { - DCHECK(chromeos::features::IsSplitSettingsSyncEnabled()); + DCHECK(chromeos::features::IsSplitSyncConsentEnabled()); // The user only consented to the feature if they left the toggle on. RecordConsent(enable_os_sync ? CONSENT_GIVEN : CONSENT_NOT_GIVEN, consent_description, consent_confirmation);
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc index 1e68513..246ad20c 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.cc +++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -1353,7 +1353,7 @@ ->FindExtendedAccountInfoForAccountWithRefreshTokenByGaiaId( gaia_id); DCHECK(account_info.has_value()); - if (features::IsSplitSettingsSyncEnabled()) { + if (features::IsSplitSyncConsentEnabled()) { if (is_new_profile) { if (!identity_manager->HasPrimaryAccount(ConsentLevel::kSync)) { // Set the account without recording browser sync consent. @@ -1368,7 +1368,7 @@ gaia_id); } else { // Set a primary account here because the profile might have been - // created with the feature SplitSettingsSync enabled. Then the + // created with the feature SplitSyncConsent enabled. Then the // profile might only have an unconsented primary account. identity_manager->GetPrimaryAccountMutator()->SetPrimaryAccount( account_info->account_id); @@ -1677,7 +1677,7 @@ // If needed, create browser observer to display first run OOBE Goodies page. first_run::GoodiesDisplayer::Init(); - if (chromeos::features::IsSplitSettingsSyncEnabled() && + if (chromeos::features::IsSplitSyncConsentEnabled() && ProfileSyncServiceFactory::IsSyncAllowed(profile)) { turn_sync_on_helper_ = std::make_unique<TurnSyncOnHelper>(profile); }
diff --git a/chrome/browser/chromeos/sync/turn_sync_on_helper.cc b/chrome/browser/chromeos/sync/turn_sync_on_helper.cc index 4988a78..b9aa2c9 100644 --- a/chrome/browser/chromeos/sync/turn_sync_on_helper.cc +++ b/chrome/browser/chromeos/sync/turn_sync_on_helper.cc
@@ -86,7 +86,7 @@ delegate_(std::move(delegate)) { DCHECK(profile_); DCHECK(identity_manager_); - DCHECK(chromeos::features::IsSplitSettingsSyncEnabled()); + DCHECK(chromeos::features::IsSplitSyncConsentEnabled()); Init(); }
diff --git a/chrome/browser/chromeos/sync/turn_sync_on_helper_unittest.cc b/chrome/browser/chromeos/sync/turn_sync_on_helper_unittest.cc index 83e77d9..447bb2d 100644 --- a/chrome/browser/chromeos/sync/turn_sync_on_helper_unittest.cc +++ b/chrome/browser/chromeos/sync/turn_sync_on_helper_unittest.cc
@@ -49,7 +49,9 @@ class TurnSyncOnHelperTest : public BrowserWithTestWindowTest { public: TurnSyncOnHelperTest() { - feature_list_.InitAndEnableFeature(chromeos::features::kSplitSettingsSync); + feature_list_.InitWithFeatures({chromeos::features::kSplitSettingsSync, + chromeos::features::kSplitSyncConsent}, + {}); } ~TurnSyncOnHelperTest() override = default;
diff --git a/chrome/browser/content_settings/tab_specific_content_settings.cc b/chrome/browser/content_settings/tab_specific_content_settings.cc index df87f900..bad544c 100644 --- a/chrome/browser/content_settings/tab_specific_content_settings.cc +++ b/chrome/browser/content_settings/tab_specific_content_settings.cc
@@ -753,10 +753,6 @@ } ClearNavigationRelatedContentSettings(); - ClearGeolocationContentSettings(); - ClearMidiContentSettings(); - ClearPendingProtocolHandler(); - ClearContentSettingsChangedViaPageInfo(); } void TabSpecificContentSettings::ReadyToCommitNavigation( @@ -794,10 +790,11 @@ return; } - // Clear "blocked" flags. ClearContentSettingsExceptForNavigationRelatedSettings(); GeolocationDidNavigate(navigation_handle); MidiDidNavigate(navigation_handle); + ClearPendingProtocolHandler(); + ClearContentSettingsChangedViaPageInfo(); if (web_contents()->GetVisibleURL().SchemeIsHTTPOrHTTPS()) { content_settings::RecordPluginsAction( @@ -833,26 +830,20 @@ observer.OnSiteDataAccessed(); } -void TabSpecificContentSettings::ClearGeolocationContentSettings() { - geolocation_usages_state_.ClearStateMap(); -} - -void TabSpecificContentSettings::ClearMidiContentSettings() { - midi_usages_state_.ClearStateMap(); -} - void TabSpecificContentSettings::ClearContentSettingsChangedViaPageInfo() { content_settings_changed_via_page_info_.clear(); } void TabSpecificContentSettings::GeolocationDidNavigate( content::NavigationHandle* navigation_handle) { + geolocation_usages_state_.ClearStateMap(); geolocation_usages_state_.DidNavigate(navigation_handle->GetURL(), navigation_handle->GetPreviousURL()); } void TabSpecificContentSettings::MidiDidNavigate( content::NavigationHandle* navigation_handle) { + midi_usages_state_.ClearStateMap(); midi_usages_state_.DidNavigate(navigation_handle->GetURL(), navigation_handle->GetPreviousURL()); }
diff --git a/chrome/browser/content_settings/tab_specific_content_settings.h b/chrome/browser/content_settings/tab_specific_content_settings.h index 7f62118..5b20cd89 100644 --- a/chrome/browser/content_settings/tab_specific_content_settings.h +++ b/chrome/browser/content_settings/tab_specific_content_settings.h
@@ -381,12 +381,6 @@ // Notifies all registered |SiteDataObserver|s. void NotifySiteDataObservers(); - // Clears the Geolocation settings. - void ClearGeolocationContentSettings(); - - // Clears the MIDI settings. - void ClearMidiContentSettings(); - // Clears settings changed by the user via PageInfo since the last navigation. void ClearContentSettingsChangedViaPageInfo();
diff --git a/chrome/browser/enterprise_reporting/browser_report_generator.cc b/chrome/browser/enterprise_reporting/browser_report_generator.cc index 063221f1..551d25b 100644 --- a/chrome/browser/enterprise_reporting/browser_report_generator.cc +++ b/chrome/browser/enterprise_reporting/browser_report_generator.cc
@@ -10,11 +10,13 @@ #include "base/files/file_path.h" #include "base/path_service.h" #include "base/strings/utf_string_conversions.h" +#include "base/version.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile_attributes_entry.h" #include "chrome/browser/profiles/profile_attributes_storage.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/upgrade_detector/build_state.h" #include "chrome/common/channel_info.h" #include "components/policy/core/common/cloud/cloud_policy_util.h" #include "components/version_info/channel.h" @@ -60,6 +62,12 @@ #if !defined(OS_CHROMEOS) report->set_browser_version(version_info::GetVersionNumber()); report->set_channel(policy::ConvertToProtoChannel(chrome::GetChannel())); + const auto* const build_state = g_browser_process->GetBuildState(); + if (build_state->update_type() != BuildState::UpdateType::kNone) { + const auto& installed_version = build_state->installed_version(); + if (installed_version) + report->set_installed_browser_version(installed_version->GetString()); + } #endif report->set_executable_path(GetExecutablePath());
diff --git a/chrome/browser/enterprise_reporting/browser_report_generator_unittest.cc b/chrome/browser/enterprise_reporting/browser_report_generator_unittest.cc index d459a070..29777f6 100644 --- a/chrome/browser/enterprise_reporting/browser_report_generator_unittest.cc +++ b/chrome/browser/enterprise_reporting/browser_report_generator_unittest.cc
@@ -10,8 +10,11 @@ #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" #include "base/test/bind_test_util.h" +#include "base/version.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/enterprise_reporting/profile_report_generator.h" #include "chrome/browser/profiles/profile_attributes_storage.h" +#include "chrome/browser/upgrade_detector/build_state.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile_manager.h" #include "components/account_id/account_id.h" @@ -52,6 +55,12 @@ content::PluginService::GetInstance()->Init(); } + void InitializeUpdate() { + auto* build_state = g_browser_process->GetBuildState(); + build_state->SetUpdate(BuildState::UpdateType::kNormalUpdate, + base::Version("1.2.3.4"), base::nullopt); + } + void InitializeProfile() { profile_manager_.profile_attributes_storage()->AddProfile( profile_manager()->profiles_dir().AppendASCII(kProfileId), @@ -93,9 +102,18 @@ #if defined(OS_CHROMEOS) EXPECT_FALSE(report->has_browser_version()); EXPECT_FALSE(report->has_channel()); + EXPECT_FALSE(report->has_installed_browser_version()); #else EXPECT_NE(std::string(), report->browser_version()); EXPECT_TRUE(report->has_channel()); + const auto* build_state = g_browser_process->GetBuildState(); + if (build_state->update_type() == BuildState::UpdateType::kNone || + !build_state->installed_version()) { + EXPECT_FALSE(report->has_installed_browser_version()); + } else { + EXPECT_EQ(report->installed_browser_version(), + build_state->installed_version()->GetString()); + } #endif EXPECT_NE(std::string(), report->executable_path()); @@ -139,4 +157,14 @@ GenerateAndVerify(); } +#if !defined(OS_CHROMEOS) +TEST_F(BrowserReportGeneratorTest, GenerateBasicReportWithUpdate) { + InitializeUpdate(); + InitializeProfile(); + InitializeIrregularProfiles(); + InitializePlugin(); + GenerateAndVerify(); +} +#endif + } // namespace enterprise_reporting
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 25df656c..2d88cb1 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -3145,6 +3145,11 @@ "expiry_milestone": 75 }, { + "name": "run-video-capture-service-in-browser", + "owners": [ "armax", "guidou" ], + "expiry_milestone": 90 + }, + { "name": "safety-tips", "owners": [ "jdeblasio", "estark", "meacer" ], "expiry_milestone": 82
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 954ae61d..b5fe8feb 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3759,6 +3759,15 @@ #endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS) +#if defined(OS_WIN) + +const char kRunVideoCaptureServiceInBrowserProcessName[] = + "Run video capture service in browser"; +const char kRunVideoCaptureServiceInBrowserProcessDescription[] = + "Run the video capture service in the browser process."; + +#endif // defined(OS_WIN) + // ============================================================================ // Don't just add flags to the end, put them in the right section in // alphabetical order just like the header file.
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 2d778875..81635cd 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -2218,6 +2218,13 @@ #endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS) +#if defined(OS_WIN) + +extern const char kRunVideoCaptureServiceInBrowserProcessName[]; +extern const char kRunVideoCaptureServiceInBrowserProcessDescription[]; + +#endif // defined(OS_WIN) + // ============================================================================ // Don't just add flags to the end, put them in the right section in // alphabetical order. See top instructions for more.
diff --git a/chrome/browser/push_messaging/push_messaging_service_impl.cc b/chrome/browser/push_messaging/push_messaging_service_impl.cc index ee390b8..2e6049ec 100644 --- a/chrome/browser/push_messaging/push_messaging_service_impl.cc +++ b/chrome/browser/push_messaging/push_messaging_service_impl.cc
@@ -559,6 +559,15 @@ content::RenderFrameHost* render_frame_host = content::RenderFrameHost::FromID(render_process_id, render_frame_id); + if (!render_frame_host) { + // It is possible for `render_frame_host` to be nullptr here due to a race + // (crbug.com/1057981). + SubscribeEndWithError( + std::move(callback), + blink::mojom::PushRegistrationStatus::RENDERER_SHUTDOWN); + return; + } + if (!options->user_visible_only) { content::RenderFrameHost* main_frame = GetMainFrameForRenderFrameHost(render_frame_host);
diff --git a/chrome/browser/resources/BUILD.gn b/chrome/browser/resources/BUILD.gn index 53f15559..24e11e9 100644 --- a/chrome/browser/resources/BUILD.gn +++ b/chrome/browser/resources/BUILD.gn
@@ -26,6 +26,7 @@ "discards:closure_compile", "download_internals:closure_compile", "downloads:closure_compile", + "gaia_auth_host:closure_compile", "history:closure_compile", "local_ntp:closure_compile", "local_state:closure_compile", @@ -138,6 +139,27 @@ output_dir = "$root_gen_dir/chrome" } + grit("gaia_auth_host_resources") { + # The .grd contains references to generated files. + source_is_generated = true + grit_flags = [ + "-E", + "root_gen_dir=" + rebase_path(root_gen_dir, root_build_dir), + ] + + source = "gaia_auth_host/gaia_auth_host_resources.grd" + deps = [ "//chrome/browser/resources/gaia_auth_host:modulize" ] + + defines = chrome_grit_defines + outputs = [ + "grit/gaia_auth_host_resources.h", + "grit/gaia_auth_host_resources_map.cc", + "grit/gaia_auth_host_resources_map.h", + "gaia_auth_host_resources.pak", + ] + output_dir = "$root_gen_dir/chrome" + } + grit("history_resources") { # The .grd contains references to generated files. source_is_generated = true
diff --git a/chrome/browser/resources/chromeos/login/oobe_dialog_host.css b/chrome/browser/resources/chromeos/login/oobe_dialog_host.css index baf49be..4358c9d 100644 --- a/chrome/browser/resources/chromeos/login/oobe_dialog_host.css +++ b/chrome/browser/resources/chromeos/login/oobe_dialog_host.css
@@ -30,7 +30,7 @@ } .oobe-tos-webview { - border: 0.5px solid rgb(218, 220, 224); /* #DADCE0 */ + border: 1px solid rgb(218, 220, 224); /* #DADCE0 */ border-radius: 4px; box-shadow: inset 0 0 4px 4px rgba(241, 243, 244, 0.5); /* #F1F3F4 */ }
diff --git a/chrome/browser/resources/chromeos/login/oobe_eula.css b/chrome/browser/resources/chromeos/login/oobe_eula.css index d28d03e..ddc0995 100644 --- a/chrome/browser/resources/chromeos/login/oobe_eula.css +++ b/chrome/browser/resources/chromeos/login/oobe_eula.css
@@ -9,7 +9,8 @@ } #crosEulaFrame { - min-height: 200px; + /* minimal height which allows popup dialogs looks fine. */ + min-height: 300px; } #installationSettings, @@ -18,15 +19,18 @@ min-height: unset; } -#installationSettings { - margin-inline-start: 16px; +#footer-more { + padding-inline-start: 16px; +} + +#additionalTerms, +#installationSettings, +#logging { margin-top: 16px; } #logging { color: rgba(0, 0, 0, 0.54); - margin-inline-start: 16px; - margin-top: 16px; } cr-toggle {
diff --git a/chrome/browser/resources/chromeos/login/oobe_eula.html b/chrome/browser/resources/chromeos/login/oobe_eula.html index f8ba3f6..69af9c8 100644 --- a/chrome/browser/resources/chromeos/login/oobe_eula.html +++ b/chrome/browser/resources/chromeos/login/oobe_eula.html
@@ -33,22 +33,27 @@ i18n-values="aria-label:oobeEulaIframeLabel" on-contentload="onFrameLoad_"> </webview> - <a id="installationSettings" href="#" - on-tap="onInstallationSettingsClicked_"> - [[i18nDynamic(locale, 'eulaSystemInstallationSettings')]] - </a> - <div id="logging" class="layout horizontal"> - <cr-toggle id="usageStats" checked="{{usageStatsChecked}}" - on-change="onUsageChanged_" aria-labelledby="usageStatsLabel"> - </cr-toggle> - <div id="usageStatsLabelContainer"> - <span id="usageStatsLabel" on-tap="usageStatsLabelClicked_"> - [[i18nDynamic(locale, 'checkboxLogging')]] - </span> - <a id="learn-more" href="#" on-tap="onUsageStatsHelpLinkClicked_" - class="oobe-local-link"> - [[i18nDynamic(locale, 'learnMore')]] - </a> + <div id="footer-more" class="layout vertical"> + <a href="#" id="additionalTerms" on-tap="onAdditionalTermsClicked_"> + [[i18nDynamic(locale, 'oobeEulaAditionalTerms')]] + </a> + <a id="installationSettings" href="#" + on-tap="onInstallationSettingsClicked_"> + [[i18nDynamic(locale, 'eulaSystemInstallationSettings')]] + </a> + <div id="logging" class="layout horizontal"> + <cr-toggle id="usageStats" checked="{{usageStatsChecked}}" + on-change="onUsageChanged_" aria-labelledby="usageStatsLabel"> + </cr-toggle> + <div id="usageStatsLabelContainer"> + <span id="usageStatsLabel" on-tap="usageStatsLabelClicked_"> + [[i18nDynamic(locale, 'checkboxLogging')]] + </span> + <a id="learn-more" href="#" on-tap="onUsageStatsHelpLinkClicked_" + class="oobe-local-link"> + [[i18nDynamic(locale, 'learnMore')]] + </a> + </div> </div> </div> </div> @@ -104,5 +109,10 @@ on-tap="onInstallationSettingsCloseClicked_"></oobe-text-button> </div> </oobe-dialog> + <oobe-help-dialog id="additional-tos"> + <webview slot="content" role="document" class="flex oobe-tos-webview" + id="additionalChromeToS"> + </webview> + </oobe-help-dialog> </template> </dom-module>
diff --git a/chrome/browser/resources/chromeos/login/oobe_eula.js b/chrome/browser/resources/chromeos/login/oobe_eula.js index b9b9e2405..b1eaff4 100644 --- a/chrome/browser/resources/chromeos/login/oobe_eula.js +++ b/chrome/browser/resources/chromeos/login/oobe_eula.js
@@ -48,7 +48,7 @@ /** * Reference to OOBE screen object. * @type {!{ - * loadEulaToWebview_: function(Element), + * loadEulaToWebview_: function(Element, string, boolean), * onUsageStatsClicked_: function(boolean), * }} */ @@ -121,7 +121,15 @@ */ updateLocalizedContent(event) { // This forces frame to reload. - this.screen.loadEulaToWebview_(this.$.crosEulaFrame); + const onlineEulaUrl = loadTimeData.getString('eulaOnlineUrl'); + + this.screen.loadEulaToWebview_( + this.$.crosEulaFrame, onlineEulaUrl, false /* clear_anchors */); + + const additionalToSUrl = + loadTimeData.getString('eulaAdditionalToSOnlineUrl'); + this.screen.loadEulaToWebview_( + this.$.additionalChromeToS, additionalToSUrl, true /* clear_anchors */); this.i18nUpdateLocale(); }, @@ -143,6 +151,10 @@ this.screen.onUsageStatsClicked_(this.$.usageStats.checked); }, + onAdditionalTermsClicked_() { + this.$['additional-tos'].showDialog(); + }, + /** * On-tap event handler for installationSettings. *
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_eula.js b/chrome/browser/resources/chromeos/login/oobe_screen_eula.js index 3a49c755..773866c1 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_eula.js +++ b/chrome/browser/resources/chromeos/login/oobe_screen_eula.js
@@ -12,7 +12,9 @@ 'for(var i = 0; i < A.length; ++i) {' + ' const el = A[i];' + ' let e = document.createElement("span");' + - ' e.textContent=el.textContent;' + + ' if (el.textContent.trim().length > 0) {' + + ' e.textContent=el.textContent + "(" + el.href + ")";' + + ' }' + ' el.parentNode.replaceChild(e,el);' + '}' }; @@ -26,12 +28,12 @@ // the current requests fail. This prevents webview-loadAbort events from // being fired and unnecessary reloads. class EulaLoader { - constructor(webview, timeout, load_offline_callback) { + constructor(webview, timeout, load_offline_callback, clear_anchors) { assert(webview.tagName === 'WEBVIEW'); // Do not create multiple loaders. - if (EulaLoader.instance_) { - return EulaLoader.instance_; + if (EulaLoader.instances[webview.id]) { + return EulaLoader.instances[webview.id]; } this.webview_ = webview; @@ -41,16 +43,18 @@ this.loadOfflineCallback_ = load_offline_callback; this.loadTimer_ = 0; - // Add the CLEAR_ANCHORS_CONTENT_SCRIPT that will clear <a><\a> (anchors) - // in order to prevent any navigation in the webview itself. - webview.addContentScripts([{ - name: 'clearAnchors', - matches: ['<all_urls>'], - js: CLEAR_ANCHORS_CONTENT_SCRIPT, - }]); - webview.addEventListener('contentload', () => { - webview.executeScript(CLEAR_ANCHORS_CONTENT_SCRIPT); - }); + if (clear_anchors) { + // Add the CLEAR_ANCHORS_CONTENT_SCRIPT that will clear <a><\a> + // (anchors) in order to prevent any navigation in the webview itself. + webview.addContentScripts([{ + name: 'clearAnchors', + matches: ['<all_urls>'], + js: CLEAR_ANCHORS_CONTENT_SCRIPT, + }]); + webview.addEventListener('contentload', () => { + webview.executeScript(CLEAR_ANCHORS_CONTENT_SCRIPT); + }); + } // Monitor webRequests API events this.webview_.request.onCompleted.addListener( @@ -61,7 +65,7 @@ {urls: ['<all_urls>'], types: ['main_frame']}); // The only instance of the EulaLoader. - EulaLoader.instance_ = this; + EulaLoader.instances[webview.id] = this; } // Clears the internal state of the EULA loader. Stops the timeout timer @@ -165,6 +169,7 @@ } } } + EulaLoader.instances = {}; return { /** @override */ @@ -230,8 +235,11 @@ * privileged webui bindings. * * @param {!WebView} webview Webview element to host the terms. + * @param {!string} onlineEulaUrl + * @param {boolean} clear_anchors if true the script will clear anchors + * from the loaded page. */ - loadEulaToWebview_(webview) { + loadEulaToWebview_(webview, onlineEulaUrl, clear_anchors) { assert(webview.tagName === 'WEBVIEW'); /** @@ -251,16 +259,11 @@ webview, TERMS_URL, WebViewHelper.ContentType.HTML); }; - var onlineEulaUrl = loadTimeData.getString('eulaOnlineUrl'); - if (!onlineEulaUrl) { - loadBundledEula(); - return; - } - // Load online Eula with a timeout to fallback to the offline version. // This won't construct multiple EulaLoaders. Single instance. var eulaLoader = new EulaLoader( - webview, ONLINE_EULA_LOAD_TIMEOUT_IN_MS, loadBundledEula); + webview, ONLINE_EULA_LOAD_TIMEOUT_IN_MS, loadBundledEula, + clear_anchors); eulaLoader.setUrl(onlineEulaUrl); },
diff --git a/chrome/browser/resources/chromeos/login/sync_consent.html b/chrome/browser/resources/chromeos/login/sync_consent.html index 3760c05..aa2a164 100644 --- a/chrome/browser/resources/chromeos/login/sync_consent.html +++ b/chrome/browser/resources/chromeos/login/sync_consent.html
@@ -69,7 +69,7 @@ </div> </oobe-dialog> - <!-- Dialog used with SplitSettingsSync. --> + <!-- Dialog used with the SplitSyncConsent feature. --> <oobe-dialog id="osSyncConsentDialog" role="dialog" has-buttons aria-label$="[[i18nDynamic(locale, 'osSyncConsentTitle')]]" hidden>
diff --git a/chrome/browser/resources/chromeos/login/sync_consent.js b/chrome/browser/resources/chromeos/login/sync_consent.js index f4364d9f..a2a6c7bb 100644 --- a/chrome/browser/resources/chromeos/login/sync_consent.js +++ b/chrome/browser/resources/chromeos/login/sync_consent.js
@@ -65,8 +65,8 @@ * Reacts to changes in loadTimeData. */ updateLocalizedContent() { - if (loadTimeData.getBoolean('splitSettingsSync')) { - // SplitSettingsSync version. + if (loadTimeData.getBoolean('splitSyncConsent')) { + // SplitSyncConsent version. this.showScreen_('osSyncConsentDialog'); } else { // Regular version. @@ -96,7 +96,7 @@ * @private */ onOsSyncAcceptAndContinue_(event) { - assert(loadTimeData.getBoolean('splitSettingsSync')); + assert(loadTimeData.getBoolean('splitSyncConsent')); assert(event.path); let enableOsSync = !!this.$.enableOsSyncToggle.checked; chrome.send('login.SyncConsentScreen.osSyncAcceptAndContinue', [
diff --git a/chrome/browser/resources/gaia_auth_host/BUILD.gn b/chrome/browser/resources/gaia_auth_host/BUILD.gn index 05df31e..8f422cc1 100644 --- a/chrome/browser/resources/gaia_auth_host/BUILD.gn +++ b/chrome/browser/resources/gaia_auth_host/BUILD.gn
@@ -3,6 +3,8 @@ # found in the LICENSE file. import("//chrome/test/base/js2gtest.gni") +import("//third_party/closure_compiler/compile_js.gni") +import("//ui/webui/resources/tools/js_modulizer.gni") js2gtest("login_unitjs_tests") { # These could be unit tests, except they need a browser context in order @@ -24,3 +26,95 @@ testonly = true deps = [ ":login_unitjs_tests" ] } + +js_type_check("closure_compile") { + uses_js_modules = true + deps = [ + ":authenticator.m", + ":channel.m", + ":post_message_channel.m", + ":saml_handler.m", + ":saml_password_attributes.m", + ":saml_timestamps.m", + ":webview_event_manager.m", + ] +} + +js_library("channel.m") { + sources = + [ "$root_gen_dir/chrome/browser/resources/gaia_auth_host/channel.m.js" ] + extra_deps = [ ":modulize" ] +} + +js_library("webview_event_manager.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/gaia_auth_host/webview_event_manager.m.js" ] + extra_deps = [ ":modulize" ] +} + +js_library("post_message_channel.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/gaia_auth_host/post_message_channel.m.js" ] + deps = [ ":channel.m" ] + extra_deps = [ ":modulize" ] +} + +js_library("saml_password_attributes.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/gaia_auth_host/saml_password_attributes.m.js" ] + deps = [ ":saml_timestamps.m" ] + extra_deps = [ ":modulize" ] +} + +js_library("saml_timestamps.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/gaia_auth_host/saml_timestamps.m.js" ] + extra_deps = [ ":modulize" ] +} + +js_library("saml_handler.m") { + sources = [ + "$root_gen_dir/chrome/browser/resources/gaia_auth_host/saml_handler.m.js", + ] + deps = [ + ":channel.m", + ":post_message_channel.m", + ":webview_event_manager.m", + ] + extra_deps = [ ":modulize" ] +} + +js_library("authenticator.m") { + sources = [ + "$root_gen_dir/chrome/browser/resources/gaia_auth_host/authenticator.m.js", + ] + deps = [ + ":saml_handler.m", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:cr.m", + "//ui/webui/resources/js:util.m", + "//ui/webui/resources/js/cr:event_target.m", + ] + externs_list = [ + "$externs_path/chrome_extensions.js", + "$externs_path/webview_tag.js", + ] + extra_deps = [ ":modulize" ] +} + +js_modulizer("modulize") { + input_files = [ + "authenticator.js", + "channel.js", + "post_message_channel.js", + "saml_handler.js", + "saml_password_attributes.js", + "saml_timestamps.js", + "webview_event_manager.js", + ] + namespace_rewrites = [ + "DOMWindow|Object", + "cr.EventTarget|EventTarget", + "cr.login.SamlHandler|SamlHandler", + "samlPasswordAttributes.PasswordAttributes|PasswordAttributes", + "samlPasswordAttributes.readPasswordAttributes|readPasswordAttributes", + "samlTimestamps.decodeTimestamp|decodeTimestamp", + "XMLDocument|Object", + ] +}
diff --git a/chrome/browser/resources/gaia_auth_host/authenticator.js b/chrome/browser/resources/gaia_auth_host/authenticator.js index 627c6bbc..31ae361 100644 --- a/chrome/browser/resources/gaia_auth_host/authenticator.js +++ b/chrome/browser/resources/gaia_auth_host/authenticator.js
@@ -5,6 +5,16 @@ // <include src="saml_handler.js"> // Note: webview_event_manager.js is already included by saml_handler.js. +// clang-format off +// #import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js' +// #import {assert} from 'chrome://resources/js/assert.m.js'; +// #import {$, appendParam} from 'chrome://resources/js/util.m.js'; +// #import {sendWithPromise} from 'chrome://resources/js/cr.m.js'; + +// #import {SamlHandler, OnHeadersReceivedDetails} from './saml_handler.m.js'; +// #import {WebviewEventManager} from './webview_event_manager.m.js'; +// clang-format on + /** * @fileoverview An UI component to authenticate to Chrome. The component hosts * IdP web pages in a webview. A client who is interested in monitoring @@ -15,7 +25,33 @@ */ cr.define('cr.login', function() { - 'use strict'; + /* #ignore */ 'use strict'; + + /** + * Parameters for the authorization flow. + * @typedef {{ + * hl: string, + * gaiaUrl: string, + * authMode: Number, + * isLoginPrimaryAccount: boolean, + * email: string, + * constrained: string, + * readOnlyEmail: boolean, + * service: string, + * dontResizeNonEmbeddedPages: boolean, + * clientId: string, + * gaiaPath: string, + * emailDomain: string, + * showTos: string, + * extractSamlPasswordAttributes: boolean, + * flow: string, + * ignoreCrOSIdpSetting: boolean, + * enableGaiaActionButtons: boolean, + * enterpriseEnrollmentDomain: string, + * samlAclUrl: string + * }} + */ + /* #export */ let AuthParams; // TODO(rogerta): should use gaia URL from GaiaUrls::gaia_url() instead // of hardcoding the prod URL here. As is, this does not work with staging @@ -32,20 +68,20 @@ /** * The source URL parameter for the constrained signin flow. */ - const CONSTRAINED_FLOW_SOURCE = 'chrome'; + /* #export */ const CONSTRAINED_FLOW_SOURCE = 'chrome'; /** * Enum for the authorization mode, must match AuthMode defined in * chrome/browser/ui/webui/inline_login_ui.cc. * @enum {number} */ - const AuthMode = {DEFAULT: 0, OFFLINE: 1, DESKTOP: 2}; + /* #export */ const AuthMode = {DEFAULT: 0, OFFLINE: 1, DESKTOP: 2}; /** * Enum for the authorization type. * @enum {number} */ - const AuthFlow = {DEFAULT: 0, SAML: 1}; + /* #export */ const AuthFlow = {DEFAULT: 0, SAML: 1}; /** * Supported Authenticator params. @@ -215,7 +251,7 @@ /** * Initializes the authenticator component. */ - class Authenticator extends cr.EventTarget { + /* #export */ class Authenticator extends cr.EventTarget { /** * @param {!WebView|string} webview The webview element or its ID to host * IdP web pages. @@ -230,6 +266,10 @@ this.chooseWhatToSync_ = false; this.skipForNow_ = false; this.authFlow = AuthFlow.DEFAULT; + /** @type {AuthMode} */ + this.authMode = AuthMode.DEFAULT; + this.dontResizeNonEmbeddedPages = false; + this.authDomain = ''; /** * @type {!cr.login.SamlHandler|undefined} @@ -243,7 +283,12 @@ this.trusted_ = true; this.readyFired_ = false; this.authCompletedFired_ = false; - this.webview_ = typeof webview == 'string' ? $(webview) : webview; + /** + * @private {WebView|undefined} + */ + this.webview_ = typeof webview == 'string' ? + /** @type {WebView} */ ($(webview)) : + webview; assert(this.webview_); this.enableGaiaActionButtons_ = false; this.webviewEventManager_ = WebviewEventManager.create(); @@ -260,7 +305,7 @@ * Callback allowing to request whether the specified user which * authenticates via SAML is a user without a password (neither a manually * entered one nor one provided via Credentials Passing API). - * @type {function(string, string, function(boolean))} Arguments are the + * @type {?function(string, string, function(boolean))} Arguments are the * e-mail, the GAIA ID, and the response callback. */ this.getIsSamlUserPasswordlessCallback = null; @@ -273,6 +318,8 @@ * @private */ this.isSamlUserPasswordless_ = null; + /** @private {boolean} */ + this.isConstrainedWindow_ = false; this.samlAclUrl_ = null; window.addEventListener( @@ -398,7 +445,8 @@ /** * Re-binds to another webview. - * @param {Object} webview the new webview to be used by this Authenticator. + * @param {WebView} webview the new webview to be used by this + * Authenticator. * @private */ rebindWebview_(webview) { @@ -455,14 +503,14 @@ webivewParent.replaceChild(newWebview, this.webview_); - this.rebindWebview_(newWebview); + this.rebindWebview_(/** @type {WebView} */ (newWebview)); } } /** * Loads the authenticator component with the given parameters. * @param {AuthMode} authMode Authorization mode. - * @param {Object} data Parameters for the authorization flow. + * @param {AuthParams} data Parameters for the authorization flow. */ load(authMode, data) { this.authMode = authMode; @@ -576,7 +624,7 @@ } if (data.isFirstUser) { - url = appendParam(url, 'is_first_user', true); + url = appendParam(url, 'is_first_user', 'true'); if (data.lsbReleaseBoard) { url = appendParam(url, 'chromeos_board', data.lsbReleaseBoard); @@ -615,7 +663,7 @@ url = appendParam(url, 'ignoreCrOSIdpSetting', 'true'); } if (data.enableGaiaActionButtons) { - url = appendParam(url, 'use_native_navigation', 1); + url = appendParam(url, 'use_native_navigation', '1'); } return url; } @@ -684,10 +732,9 @@ /** * Invoked when the sign-in page takes focus. - * @param {object} e The focus event being triggered. * @private */ - onFocus_(e) { + onFocus_() { if (this.authMode == AuthMode.DESKTOP && document.activeElement == document.body) { this.webview_.focus(); @@ -696,7 +743,7 @@ /** * Invoked when the history state is changed. - * @param {object} e The popstate event being triggered. + * @param {!Event} e The popstate event being triggered. * @private */ onPopState_(e) { @@ -710,7 +757,7 @@ * Invoked when headers are received in the main frame of the webview. It * 1) reads the authenticated user info from a signin header, * 2) signals the start of a saml flow upon receiving a saml header. - * @return {!Object} Modified request headers. + * @param {OnHeadersReceivedDetails} details * @private */ onHeadersReceived_(details) { @@ -745,6 +792,7 @@ } else if (headerName == LOCATION_HEADER) { // If the "choose what to sync" checkbox was clicked, then the // continue URL will contain a source=3 field. + assert(header.value); const location = decodeURIComponent(header.value); this.chooseWhatToSync_ = !!location.match(/(\?|&)source=3($|&)/); } @@ -753,7 +801,7 @@ /** * Returns true if given HTML5 message is received from the webview element. - * @param {object} e Payload of the received HTML5 message. + * @param {Object} e Payload of the received HTML5 message. */ isGaiaMessage(e) { if (!this.isWebviewEvent_(e)) { @@ -775,7 +823,7 @@ /** * Invoked when an HTML5 message is received from the webview element. - * @param {object} e Payload of the received HTML5 message. + * @param {Object} e Payload of the received HTML5 message. * @private */ onMessageFromWebview_(e) { @@ -796,7 +844,7 @@ /** * Invoked to send a HTML5 message to the webview element. - * @param {object} e Payload of the HTML5 message. + * @param {Object} payload Payload of the HTML5 message. */ sendMessageToWebview(payload) { const currentUrl = this.webview_.src; @@ -1196,6 +1244,7 @@ } } + // #cr_define_end /** * The current auth flow of the hosted auth page. * @type {AuthFlow}
diff --git a/chrome/browser/resources/gaia_auth_host/channel.js b/chrome/browser/resources/gaia_auth_host/channel.js index 5cffb5e..50fc5377 100644 --- a/chrome/browser/resources/gaia_auth_host/channel.js +++ b/chrome/browser/resources/gaia_auth_host/channel.js
@@ -4,8 +4,9 @@ /** * Channel to the background script. + * @constructor */ -function Channel() { +/* #export */ function Channel() { this.messageCallbacks_ = {}; this.internalRequestCallbacks_ = {}; }
diff --git a/chrome/browser/resources/gaia_auth_host/gaia_auth_host_resources.grd b/chrome/browser/resources/gaia_auth_host/gaia_auth_host_resources.grd new file mode 100644 index 0000000..52a9c5a --- /dev/null +++ b/chrome/browser/resources/gaia_auth_host/gaia_auth_host_resources.grd
@@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<grit latest_public_release="0" current_release="1" output_all_resource_defines="false"> + <outputs> + <output filename="grit/gaia_auth_host_resources.h" type="rc_header"> + <emit emit_type='prepend'></emit> + </output> + <output filename="grit/gaia_auth_host_resources_map.cc" + type="resource_file_map_source" /> + <output filename="grit/gaia_auth_host_resources_map.h" + type="resource_map_header" /> + <output filename="gaia_auth_host_resources.pak" type="data_package" /> + </outputs> + <release seq="1"> + <includes> + <include name="IDR_GAIA_AUTH_AUTHENTICATOR_M_JS" + file="${root_gen_dir}/chrome/browser/resources/gaia_auth_host/authenticator.m.js" + use_base_dir="false" + type ="BINDATA" + compress="gzip" /> + <include name="IDR_GAIA_AUTH_SAML_HANDLER_M_JS" + file="${root_gen_dir}/chrome/browser/resources/gaia_auth_host/saml_handler.m.js" + use_base_dir="false" + type ="BINDATA" + compress="gzip" /> + <include name="IDR_GAIA_AUTH_CHANNEL_M_JS" + file="${root_gen_dir}/chrome/browser/resources/gaia_auth_host/channel.m.js" + use_base_dir="false" + type ="BINDATA" + compress="gzip" /> + <include name="IDR_GAIA_AUTH_POST_MESSAGE_CHANNEL_M_JS" + file="${root_gen_dir}/chrome/browser/resources/gaia_auth_host/post_message_channel.m.js" + use_base_dir="false" + type ="BINDATA" + compress="gzip" /> + <include name="IDR_GAIA_AUTH_WEBVIEW_EVENT_MANAGER_M_JS" + file="${root_gen_dir}/chrome/browser/resources/gaia_auth_host/webview_event_manager.m.js" + use_base_dir="false" + type ="BINDATA" + compress="gzip" /> + <include name="IDR_GAIA_AUTH_SAML_PASSWORD_ATTRIBUTES_M_JS" + file="${root_gen_dir}/chrome/browser/resources/gaia_auth_host/saml_password_attributes.m.js" + use_base_dir="false" + type ="BINDATA" + compress="gzip" /> + <include name="IDR_GAIA_AUTH_SAML_TIMESTAMPS_M_JS" + file="${root_gen_dir}/chrome/browser/resources/gaia_auth_host/saml_timestamps.m.js" + use_base_dir="false" + type ="BINDATA" + compress="gzip" /> + </includes> + </release> +</grit>
diff --git a/chrome/browser/resources/gaia_auth_host/post_message_channel.js b/chrome/browser/resources/gaia_auth_host/post_message_channel.js index 49deaa2..0fab561d 100644 --- a/chrome/browser/resources/gaia_auth_host/post_message_channel.js +++ b/chrome/browser/resources/gaia_auth_host/post_message_channel.js
@@ -11,7 +11,11 @@ // <include src="channel.js"> -const PostMessageChannel = (function() { +// clang-format off +// #import {Channel} from './channel.m.js'; +// clang-format on + +/* #export */ const PostMessageChannel = (function() { /** * Allowed origins of the hosting page. * @type {Array<string>} @@ -37,6 +41,7 @@ /** * A simple event target. + * @constructor */ function EventTarget() { this.listeners_ = []; @@ -136,7 +141,8 @@ createPort(channelId, channelName, opt_targetWindow, opt_targetOrigin) { const port = new PostMessagePort(channelId, channelName); if (opt_targetWindow) { - port.setTarget(opt_targetWindow, opt_targetOrigin); + port.setTarget( + opt_targetWindow, /** @type {string} */ (opt_targetOrigin)); } this.channels_[channelId] = port; return port; @@ -169,13 +175,13 @@ /** * Creates a connecting port to the daemon and request connection. * @param {string} name - * @return {PostMessagePort} + * @return {?PostMessagePort} */ connectToDaemon(name) { if (this.isDaemon) { console.error( 'Error: Connecting from the daemon page is not supported.'); - return; + return null; } const port = this.createPort(this.createChannelId_(), name); @@ -270,6 +276,7 @@ /** * A HTML5 postMessage based port that provides the same port interface * as the messaging API port. + * @constructor * @param {number} channelId * @param {string} name */ @@ -362,7 +369,6 @@ return PostMessageChannel; })(); -/** @override */ Channel.create = function() { return new PostMessageChannel(); };
diff --git a/chrome/browser/resources/gaia_auth_host/saml_handler.js b/chrome/browser/resources/gaia_auth_host/saml_handler.js index 5d30eac..ee280a5 100644 --- a/chrome/browser/resources/gaia_auth_host/saml_handler.js +++ b/chrome/browser/resources/gaia_auth_host/saml_handler.js
@@ -6,12 +6,20 @@ // <include src="webview_event_manager.js"> // <include src="saml_password_attributes.js"> +// clang-format off +// #import {Channel} from './channel.m.js'; +// #import {PostMessageChannel} from './post_message_channel.m.js'; +// #import {WebviewEventManager} from './webview_event_manager.m.js'; +// #import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js' +// #import {PasswordAttributes, readPasswordAttributes} from './saml_password_attributes.m.js'; +// clang-format on + /** * @fileoverview Saml support for webview based auth. */ cr.define('cr.login', function() { - 'use strict'; + /* #ignore */ 'use strict'; /** * The lowest version of the credentials passing API supported. @@ -54,6 +62,47 @@ `; /** + * @typedef {{ + * method: string, + * requestedVersion: number, + * keyType: string, + * token: string, + * passwordBytes: string + * }} + */ + let ApiCallMessageCall; + + /** + * @typedef {{ + * name: string, + * call: ApiCallMessageCall + * }} + */ + let ApiCallMessage; + + /** + * Details about the request. + * @typedef {{ + * method: string, + * requestBody: Object, + * url: string + * }} + * @see https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/onBeforeRequest#details + */ + /* #export */ let OnBeforeRequestDetails; + + /** + * Details of the request. + * @typedef {{ + * responseHeaders: Array<HttpHeader>, + * statusCode: number, + * url: string, + * }} + * @see https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/onHeadersReceived#details + */ + /* #export */ let OnHeadersReceivedDetails; + + /** * Creates a new URL by striping all query parameters. * @param {string} url The original URL. * @return {string} The new URL with all query parameters stripped. @@ -77,9 +126,9 @@ * A handler to provide saml support for the given webview that hosts the * auth IdP pages. */ - class SamlHandler extends cr.EventTarget { + /* #export */ class SamlHandler extends cr.EventTarget { /** - * @param {webview} webview + * @param {!WebView} webview * @param {boolean} startsOnSamlPage - whether initial URL is already SAML * page * */ @@ -108,25 +157,26 @@ /** * The webview that serves IdP pages. - * @type {webview} + * @private {!WebView} */ this.webview_ = webview; /** * Whether a Saml page is in the webview from the start. + * @private {boolean} */ this.startsOnSamlPage_ = startsOnSamlPage; /** * Whether a Saml IdP page is display in the webview. - * @type {boolean} + * @private {boolean} */ this.isSamlPage_ = this.startsOnSamlPage_; /** * Pending Saml IdP page flag that is set when a SAML_HEADER is received * and is copied to |isSamlPage_| in loadcommit. - * @type {boolean} + * @private {boolean} */ this.pendingIsSamlPage_ = this.startsOnSamlPage_; @@ -134,7 +184,7 @@ * The last aborted top level url. It is recorded in loadabort event and * used to skip injection into Chrome's error page in the following * loadcommit event. - * @type {string} + * @private {?string} */ this.abortedTopLevelUrl_ = null; @@ -146,38 +196,38 @@ /** * Scraped password stored in an id to password field value map. - * @type {Object<string, string>} - * @private + * @private {!Object<string, string>} */ this.passwordStore_ = {}; /** * Whether Saml API is initialized. - * @type {boolean} + * @private {boolean} */ this.apiInitialized_ = false; /** * Saml API version to use. - * @type {number} + * @private {number} */ this.apiVersion_ = 0; /** * Saml API tokens received. - * @type {Object} + * @private {!Object} */ this.apiTokenStore_ = {}; /** * Saml API confirmation token. Set by last 'confirm' call. + * @private {?string} */ this.confirmToken_ = null; /** * Saml API password bytes set by last 'add' call. Needed to not break * existing behavior. - * @type {string} + * @private {?string} */ this.lastApiPasswordBytes_ = null; @@ -197,29 +247,26 @@ /** * Current stage of device attestation flow. - * @type {DeviceAttestationStage} - * @private + * @private {!SamlHandler.DeviceAttestationStage} */ this.deviceAttestationStage_ = SamlHandler.DeviceAttestationStage.NONE; /** * Challenge from IdP to perform device attestation. - * @type {?string} - * @private + * @private {?string} */ this.verifiedAccessChallenge_ = null; /** * Response for a device attestation challenge. - * @type {?string} - * @private + * @private {?string} */ this.verifiedAccessChallengeResponse_ = null; /** * The password-attributes that were extracted from the SAMLResponse, if * any. (Doesn't contain the password itself). - * @type {PasswordAttributes} + * @private {!PasswordAttributes} */ this.passwordAttributes_ = samlPasswordAttributes.PasswordAttributes.EMPTY; @@ -289,7 +336,7 @@ /** * Returns the Saml API password bytes. - * @return {string} + * @return {?string} */ get apiPasswordBytes() { if (this.confirmToken_ != null && @@ -350,7 +397,7 @@ /** * Gets the password attributes extracted from SAML Response. - * @return {PasswordAttributes} + * @return {Object} */ get passwordAttributes() { return this.passwordAttributes_; @@ -483,18 +530,24 @@ * Handler for webRequest.onBeforeRequest that looks for the Base64 * encoded SAMLResponse in the POST-ed formdata sent from the SAML page. * Non-blocking. - * @param {Object} details The web-request details. + * @param {OnBeforeRequestDetails} details The web-request details. */ onMainFrameWebRequest(details) { - if (!this.extractSamlPasswordAttributes) return; - if (!this.isSamlPage_ || details.method != 'POST') return; + if (!this.extractSamlPasswordAttributes) { + return; + } + if (!this.isSamlPage_ || details.method != 'POST') { + return; + } const formData = details.requestBody.formData; let samlResponse = (formData && formData.SAMLResponse); if (!samlResponse) { samlResponse = new URL(details.url).searchParams.get('SAMLResponse'); } - if (!samlResponse) return; + if (!samlResponse) { + return; + } try { // atob means asciiToBinary, which actually means base64Decode: @@ -705,7 +758,7 @@ /** * Handlers for channel messages. * @param {Channel} channel A channel to send back response. - * @param {Object} msg Received message. + * @param {ApiCallMessage} msg Received message. * @private */ onAPICall_(channel, msg) { @@ -736,7 +789,7 @@ this.dispatchEvent(new CustomEvent('apiPasswordAdded')); } else if (call.method == 'confirm') { - if (!call.token in this.apiTokenStore_) { + if (!(call.token in this.apiTokenStore_)) { console.error('SamlHandler.onAPICall_: token mismatch'); } else { this.confirmToken_ = call.token; @@ -777,5 +830,6 @@ } } + // #cr_define_end return {SamlHandler: SamlHandler}; });
diff --git a/chrome/browser/resources/gaia_auth_host/saml_password_attributes.js b/chrome/browser/resources/gaia_auth_host/saml_password_attributes.js index f697475..4fecfd13 100644 --- a/chrome/browser/resources/gaia_auth_host/saml_password_attributes.js +++ b/chrome/browser/resources/gaia_auth_host/saml_password_attributes.js
@@ -4,6 +4,10 @@ // <include src="saml_timestamps.js"> +// clang-format off; +// #import {decodeTimestamp} from './saml_timestamps.m.js'; +// clang-format on + /** * @fileoverview A utility for extracting password information from SAML * authorization response. This requires that the SAML IDP administrator @@ -11,7 +15,7 @@ */ cr.define('samlPasswordAttributes', function() { - 'use strict'; + /* #ignore */ 'use strict'; /** @const @private {number} The shortest XML string that could be useful. */ const MIN_SANE_XML_LENGTH = 100; @@ -63,7 +67,7 @@ * could be extracted, formatted as strings. Some or all of the strings can * be empty if some or all of the attributes could not be extracted. */ - function readPasswordAttributes(xmlStr) { + /* #export */ function readPasswordAttributes(xmlStr) { // Don't throw any exception that could cause login to fail - extracting // these attributes can fail, but login should not be interrupted. try { @@ -135,7 +139,7 @@ * saml_password_attributes.cc must also be changed. * @export @final */ - class PasswordAttributes { + /* #export */ class PasswordAttributes { constructor(modifiedTime, expirationTime, passwordChangeUrl) { /** @type {string} Password last-modified timestamp. */ this.modifiedTime = modifiedTime; @@ -153,7 +157,7 @@ /** An immutable and empty PasswordAttributes struct. */ PasswordAttributes.EMPTY = new PasswordAttributes('', '', ''); - // Public functions: + // #cr_define_end return { readPasswordAttributes: readPasswordAttributes, PasswordAttributes: PasswordAttributes,
diff --git a/chrome/browser/resources/gaia_auth_host/saml_timestamps.js b/chrome/browser/resources/gaia_auth_host/saml_timestamps.js index e9e5d4a..a15a7101 100644 --- a/chrome/browser/resources/gaia_auth_host/saml_timestamps.js +++ b/chrome/browser/resources/gaia_auth_host/saml_timestamps.js
@@ -44,14 +44,14 @@ * @param {string} str A timestamp formatted as a string. * @return {?Date} A valid decoded timestamp, or null. */ - function decodeTimestamp(str) { + /* #export */ function decodeTimestamp(str) { str = str.trim(); if (str.length == 0 || str.length > MAX_SANE_LENGTH) { return null; } if (INTEGER_PATTERN.test(str)) { - return decodeIntegerTimestamp(parseInt(str)); + return decodeIntegerTimestamp(parseInt(str, 10)); } else if (ISO_8601_PATTERN.test(str)) { return decodeIso8601(str); } @@ -134,6 +134,7 @@ return isNaN(date) ? null : date; } + // #cr_define_end // Public functions: return {decodeTimestamp: decodeTimestamp}; });
diff --git a/chrome/browser/resources/gaia_auth_host/webview_event_manager.js b/chrome/browser/resources/gaia_auth_host/webview_event_manager.js index 6e1cb26b..0aa53b3 100644 --- a/chrome/browser/resources/gaia_auth_host/webview_event_manager.js +++ b/chrome/browser/resources/gaia_auth_host/webview_event_manager.js
@@ -11,8 +11,9 @@ /** * Creates a new WebviewEventManager. + * @constructor */ -function WebviewEventManager() { +/* #export */ function WebviewEventManager() { this.unbindWebviewCleanupFunctions_ = []; } @@ -20,10 +21,9 @@ /** * Adds a EventListener to |eventTarget| and adds a clean-up function so we * can remove the listener in unbindFromWebview. - * @param {Object} webview the object to add the listener to + * @param {Object} eventTarget the object to add the listener to * @param {string} type the event type * @param {Function} listener the event listener - * @private */ addEventListener(eventTarget, type, listener) { eventTarget.addEventListener(type, listener); @@ -34,10 +34,12 @@ /** * Adds a listener to |webRequestEvent| and adds a clean-up function so we can * remove the listener in unbindFromWebview. - * @param {Object} webRequestEvent the object to add the listener to - * @param {string} type the event type + * @param {Object} webRequestEvent the object to add the listener to. * @param {Function} listener the event listener - * @private + * @param {RequestFilter} filter the object describing filters to apply to + * webRequest events. + * @param {?Object} extraInfoSpec the object to pass additional event-specific + * instructions. */ addWebRequestEventListener(webRequestEvent, listener, filter, extraInfoSpec) { webRequestEvent.addListener(listener, filter, extraInfoSpec); @@ -47,7 +49,6 @@ /** * Unbinds this Authenticator from the currently bound webview. - * @private */ removeAllListeners() { for (let i = 0; i < this.unbindWebviewCleanupFunctions_.length; i++) {
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html b/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html index a2ac5fd..e7b6332 100644 --- a/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html +++ b/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.html
@@ -137,9 +137,9 @@ </cr-button> </div> - <div id="outer" class="layout vertical nowrap"> + <div id="outer" class="layout vertical nowrap" role="list"> <template is="dom-repeat" id="account-list" items="[[accounts_]]"> - <div class="settings-box account-list-item"> + <div class="settings-box account-list-item" role="listitem"> <div class="profile-icon" style="background-image: [[getIconImageSet_(item.pic)]]"> @@ -152,7 +152,8 @@ <div class="flex text-elide"> <!-- If account is signed in, display the full name --> <template is="dom-if" if="[[item.isSignedIn]]"> - <span>[[item.fullName]]</span> + <span id="fullName-[[index]]" + aria-hidden="true">[[item.fullName]]</span> </template> <!-- Else, display a re-authentication message --> <template is="dom-if" if="[[!item.isSignedIn]]"> @@ -161,26 +162,31 @@ </span> </template> - <div class="secondary">[[item.email]]</div> + <div class="secondary" id="email-[[index]]" + aria-hidden="true">[[item.email]]</div> </div> </div> <template is="dom-if" if="[[shouldShowReauthenticationButton_(item)]]"> <cr-button title="[[getAccountManagerSignedOutTitle_(item)]]" - class="reauth-button" on-click="onReauthenticationTap_"> + class="reauth-button" on-click="onReauthenticationTap_" + aria-labelledby$="fullName-[[index]] email-[[index]]"> [[getAccountManagerSignedOutLabel_(item.unmigrated)]] </cr-button> </template> <!-- If this is the Device Account, display the management status --> <template is="dom-if" if="[[item.isDeviceAccount]]"> - <cr-tooltip-icon icon-class="cr:info-outline" + <cr-tooltip-icon id="primaryAccountTooltip" aria-hidden="true" + icon-class="cr:info-outline" class="tooltip-primary-account" tooltip-text="$i18n{accountManagerPrimaryAccountTooltip}" icon-aria-label="$i18n{accountManagerPrimaryAccountTooltip}"> </cr-tooltip-icon> - <span class="management-status"> + <span class="management-status" + aria-labelledby$="fullName-[[index]] email-[[index]]" + aria-describedby="primaryAccountTooltip"> [[getManagementLabel_(item)]] </span> </template> @@ -188,6 +194,8 @@ <template is="dom-if" if="[[!item.isDeviceAccount]]"> <cr-icon-button class="icon-more-vert" title="[[getMoreActionsTitle_(item)]]" + aria-label="[[getMoreActionsTitle_(item)]]" + aria-describedby$="fullName-[[index]]" on-click="onAccountActionsMenuButtonTap_"> </cr-icon-button> </template>
diff --git a/chrome/browser/resources/settings/people_page/people_page.js b/chrome/browser/resources/settings/people_page/people_page.js index ce1c77d..1f8410c1 100644 --- a/chrome/browser/resources/settings/people_page/people_page.js +++ b/chrome/browser/resources/settings/people_page/people_page.js
@@ -360,7 +360,7 @@ return false; } // <if expr="chromeos"> - if (!loadTimeData.getBoolean('splitSettingsSyncEnabled')) { + if (!loadTimeData.getBoolean('splitSyncConsent')) { return false; } // </if>
diff --git a/chrome/browser/resources/settings/people_page/sync_page.js b/chrome/browser/resources/settings/people_page/sync_page.js index b088cf7..30fdf3e 100644 --- a/chrome/browser/resources/settings/people_page/sync_page.js +++ b/chrome/browser/resources/settings/people_page/sync_page.js
@@ -709,7 +709,7 @@ */ shouldShowSyncAccountControl_() { // <if expr="chromeos"> - if (!loadTimeData.getBoolean('splitSettingsSyncEnabled')) { + if (!loadTimeData.getBoolean('splitSyncConsent')) { return false; } // </if>
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_page.html b/chrome/browser/resources/settings/safety_check_page/safety_check_page.html index 9ded6ed..6cdbbdc 100644 --- a/chrome/browser/resources/settings/safety_check_page/safety_check_page.html +++ b/chrome/browser/resources/settings/safety_check_page/safety_check_page.html
@@ -49,7 +49,7 @@ <template is="dom-if" if="[[shouldShowParentButton_(parentStatus_)]]" restamp> <div class="separator"></div> - <cr-button id="safetyCheckParentButton" + <cr-button id="safetyCheckParentButton" class="action-button" on-click="onRunSafetyCheckClick_" no-search> $i18n{safetyCheckParentButton} </cr-button> @@ -79,7 +79,7 @@ <template is="dom-if" if="[[shouldShowUpdatesButton_(updatesStatus_)]]" restamp> <div class="separator"></div> - <cr-button id="safetyCheckUpdatesButton" + <cr-button id="safetyCheckUpdatesButton" class="action-button" on-click="onSafetyCheckUpdatesButtonClicked_" no-search> $i18n{aboutRelaunch} </cr-button> @@ -97,7 +97,7 @@ class$="[[getPasswordsIconClass_(passwordsStatus_)]]"> </iron-icon> <div class="start settings-box-text"> - <div>$i18n{safetyCheckPasswordsPrimaryLabel}</div> + <div>$i18n{passwords}</div> <div class="secondary" no-search> [[getPasswordsSubLabelText_(passwordsStatus_)]] </div> @@ -106,12 +106,39 @@ if="[[shouldShowPasswordsButton_(passwordsStatus_)]]" restamp> <div class="separator"></div> <cr-button id="safetyCheckPasswordsButton" + class$="[[getPasswordsButtonClass_(passwordsStatus_)]]" on-click="onPasswordsButtonClick_" no-search> [[getPasswordsButtonText_(passwordsStatus_)]] </cr-button> </template> </div> <div class="settings-box two-line"> + <iron-icon icon="[[getSafeBrowsingIcon_(safeBrowsingStatus_)]]" + src="[[getSafeBrowsingIconSrc_(safeBrowsingStatus_)]]" + class$="[[getSafeBrowsingIconClass_(safeBrowsingStatus_)]]"> + </iron-icon> + <div class="start settings-box-text"> + <div>$i18n{safeBrowsingSectionLabel}</div> + <div class="secondary" no-search> + [[getSafeBrowsingSubLabelText_(safeBrowsingStatus_)]] + </div> + </div> + <template is="dom-if" + if="[[shouldShowSafeBrowsingButton_(safeBrowsingStatus_)]]" restamp> + <div class="separator"></div> + <cr-button id="safetyCheckSafeBrowsingButton" class="action-button" + on-click="onSafeBrowsingButtonClick_" no-search> + $i18n{safetyCheckSafeBrowsingButton} + </cr-button> + </template> + <template is="dom-if" + if="[[shouldShowSafeBrowsingManagedIcon_(safeBrowsingStatus_)]]" + restamp> + <iron-icon id="safetyCheckSafeBrowsingManagedIcon" icon="cr20:domain"> + </iron-icon> + </template> + </div> + <div class="settings-box two-line"> <iron-icon icon="[[getExtensionsIcon_(extensionsStatus_)]]" src="[[getExtensionsIconSrc_(extensionsStatus_)]]" class$="[[getExtensionsIconClass_(extensionsStatus_)]]"> @@ -126,6 +153,7 @@ if="[[shouldShowExtensionsButton_(extensionsStatus_)]]" restamp> <div class="separator"></div> <cr-button id="safetyCheckExtensionsButton" + class$="[[getExtensionsButtonClass_(extensionsStatus_)]]" on-click="onSafetyCheckExtensionsButtonClicked_" no-search> $i18n{safetyCheckExtensionsButton} </cr-button>
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_page.js b/chrome/browser/resources/settings/safety_check_page/safety_check_page.js index b1f0828d..57b35c2c 100644 --- a/chrome/browser/resources/settings/safety_check_page/safety_check_page.js +++ b/chrome/browser/resources/settings/safety_check_page/safety_check_page.js
@@ -503,6 +503,19 @@ } }, + /** + * @private + * @return {string} + */ + getPasswordsButtonClass_: function() { + switch (this.passwordsStatus_) { + case settings.SafetyCheckPasswordsStatus.COMPROMISED: + return 'action-button'; + default: + return ''; + } + }, + /** @private */ onPasswordsButtonClick_: function() { switch (this.passwordsStatus_) { @@ -521,6 +534,105 @@ * @private * @return {boolean} */ + shouldShowSafeBrowsingButton_: function() { + switch (this.safeBrowsingStatus_) { + case settings.SafetyCheckSafeBrowsingStatus.DISABLED: + return true; + default: + return false; + } + }, + + /** + * @private + * @return {boolean} + */ + shouldShowSafeBrowsingManagedIcon_: function() { + switch (this.safeBrowsingStatus_) { + case settings.SafetyCheckSafeBrowsingStatus.DISABLED_BY_ADMIN: + case settings.SafetyCheckSafeBrowsingStatus.DISABLED_BY_EXTENSION: + return true; + default: + return false; + } + }, + + /** + * @private + * @return {string} + */ + getSafeBrowsingSubLabelText_: function() { + switch (this.safeBrowsingStatus_) { + case settings.SafetyCheckSafeBrowsingStatus.CHECKING: + return ''; + case settings.SafetyCheckSafeBrowsingStatus.ENABLED: + return this.i18n('safetyCheckSafeBrowsingSubLabelEnabled'); + case settings.SafetyCheckSafeBrowsingStatus.DISABLED: + return this.i18n('safetyCheckSafeBrowsingSubLabelDisabled'); + case settings.SafetyCheckSafeBrowsingStatus.DISABLED_BY_ADMIN: + return this.i18n('safetyCheckSafeBrowsingSubLabelDisabledByAdmin'); + case settings.SafetyCheckSafeBrowsingStatus.DISABLED_BY_EXTENSION: + return this.i18n('safetyCheckSafeBrowsingSubLabelDisabledByExtension'); + default: + assertNotReached(); + } + }, + + /** + * @private + * @return {?string} + */ + getSafeBrowsingIcon_: function() { + switch (this.safeBrowsingStatus_) { + case settings.SafetyCheckSafeBrowsingStatus.CHECKING: + return null; + case settings.SafetyCheckSafeBrowsingStatus.ENABLED: + return 'cr:check'; + case settings.SafetyCheckSafeBrowsingStatus.DISABLED: + case settings.SafetyCheckSafeBrowsingStatus.DISABLED_BY_ADMIN: + case settings.SafetyCheckSafeBrowsingStatus.DISABLED_BY_EXTENSION: + return 'cr:info'; + default: + assertNotReached(); + } + }, + + /** + * @private + * @return {?string} + */ + getSafeBrowsingIconSrc_: function() { + switch (this.safeBrowsingStatus_) { + case settings.SafetyCheckSafeBrowsingStatus.CHECKING: + return 'chrome://resources/images/throbber_small.svg'; + default: + return null; + } + }, + + /** + * @private + * @return {string} + */ + getSafeBrowsingIconClass_: function() { + switch (this.safeBrowsingStatus_) { + case settings.SafetyCheckSafeBrowsingStatus.CHECKING: + case settings.SafetyCheckSafeBrowsingStatus.ENABLED: + return 'icon-blue'; + default: + return ''; + } + }, + + /** @private */ + onSafeBrowsingButtonClick_: function() { + // TODO(crbug.com/1010001): Implement once behavior has been agreed on. + }, + + /** + * @private + * @return {boolean} + */ shouldShowExtensionsButton_: function() { switch (this.extensionsStatus_) { case settings.SafetyCheckExtensionsStatus.BAD_EXTENSIONS_ON: @@ -636,5 +748,18 @@ assertNotReached(); } }, + + /** + * @private + * @return {string} + */ + getExtensionsButtonClass_: function() { + switch (this.extensionsStatus_) { + case settings.SafetyCheckExtensionsStatus.BAD_EXTENSIONS_ON: + return 'action-button'; + default: + return ''; + } + }, }); })();
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/OWNERS b/chrome/browser/safe_browsing/cloud_content_scanning/OWNERS index 0046b2a..351867e 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/OWNERS +++ b/chrome/browser/safe_browsing/cloud_content_scanning/OWNERS
@@ -1,7 +1,12 @@ per-file deep_scanning_dialog_delegate*=rogerta@chromium.org +per-file deep_scanning_dialog_delegate*=domfc@chromium.org per-file fake_deep_scanning_dialog_delegate*=rogerta@chromium.org +per-file fake_deep_scanning_dialog_delegate*=domfc@chromium.org per-file deep_scanning_dialog_views*=rogerta@chromium.org +per-file deep_scanning_dialog_views*=domfc@chromium.org per-file deep_scanning_browsertest_base*=rogerta@chromium.org +per-file deep_scanning_browsertest_base*=domfc@chromium.org per-file deep_scanning_utils*=rogerta@chromium.org +per-file deep_scanning_utils*=domfc@chromium.org drubery@chromium.org
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/ShareImageFileUtilsTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/ShareImageFileUtilsTest.java index 4c6702a..d26f155d 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/ShareImageFileUtilsTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/ShareImageFileUtilsTest.java
@@ -9,6 +9,7 @@ import android.graphics.Canvas; import android.graphics.Paint; import android.net.Uri; +import android.os.Build; import android.os.Environment; import android.support.test.filters.SmallTest; import android.support.v4.content.FileProvider; @@ -26,6 +27,7 @@ import org.chromium.base.task.AsyncTask; 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.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeSwitches; @@ -201,6 +203,7 @@ @Test @SmallTest + @DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.LOLLIPOP, message = "crbug.com/1056059") public void testSaveBitmap() throws IOException { String fileName = "chrome-test-bitmap"; ShareImageFileUtils.OnImageSaveListener listener =
diff --git a/chrome/browser/sync/profile_sync_service_factory.cc b/chrome/browser/sync/profile_sync_service_factory.cc index dca006d..b250bbb 100644 --- a/chrome/browser/sync/profile_sync_service_factory.cc +++ b/chrome/browser/sync/profile_sync_service_factory.cc
@@ -260,7 +260,7 @@ // those two cases. Bug 88109. bool is_auto_start = browser_defaults::kSyncAutoStarts; #if defined(OS_CHROMEOS) - if (chromeos::features::IsSplitSettingsSyncEnabled()) + if (chromeos::features::IsSplitSyncConsentEnabled()) is_auto_start = false; #endif init_params.start_behavior = is_auto_start
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 0310e13..7e421b1 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1365,7 +1365,6 @@ "webui/settings/reset_settings_handler.h", "webui/settings/safety_check_handler.cc", "webui/settings/safety_check_handler.h", - "webui/settings/safety_check_handler_observer.h", "webui/settings/search_engines_handler.cc", "webui/settings/search_engines_handler.h", "webui/settings/settings_clear_browsing_data_handler.cc",
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller.h b/chrome/browser/ui/autofill/autofill_popup_controller.h index 6357f91..e6c9b3be 100644 --- a/chrome/browser/ui/autofill/autofill_popup_controller.h +++ b/chrome/browser/ui/autofill/autofill_popup_controller.h
@@ -35,6 +35,9 @@ // Returns the number of lines of data that there are. virtual int GetLineCount() const = 0; + // Returns the full set of autofill suggestions, if applicable. + virtual const std::vector<autofill::Suggestion> GetSuggestions() = 0; + // Returns the suggestion or pre-elided string at the given row index. virtual const autofill::Suggestion& GetSuggestionAt(int row) const = 0; virtual const base::string16& GetElidedValueAt(int row) const = 0;
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc index 9384626..9896064 100644 --- a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc +++ b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
@@ -79,22 +79,20 @@ base::i18n::TextDirection text_direction) : controller_common_(element_bounds, text_direction, container_view), web_contents_(web_contents), - layout_model_(this, delegate->GetPopupType() == PopupType::kCreditCards), + layout_model_(delegate->GetPopupType() == PopupType::kCreditCards), delegate_(delegate) { ClearState(); delegate->RegisterDeletionCallback(base::BindOnce( &AutofillPopupControllerImpl::HideViewAndDie, GetWeakPtr())); } -AutofillPopupControllerImpl::~AutofillPopupControllerImpl() {} +AutofillPopupControllerImpl::~AutofillPopupControllerImpl() = default; void AutofillPopupControllerImpl::Show( const std::vector<Suggestion>& suggestions, bool autoselect_first_suggestion, PopupType popup_type) { SetValues(suggestions); - DCHECK_EQ(suggestions_.size(), elided_values_.size()); - DCHECK_EQ(suggestions_.size(), elided_labels_.size()); bool just_created = false; if (!view_) { @@ -110,20 +108,6 @@ just_created = true; } -#if !defined(OS_ANDROID) - // Android displays the long text with ellipsis using the view attributes. - - layout_model_.UpdatePopupBounds(); - - // Elide the name and label strings so that the popup fits in the available - // space. - for (int i = 0; i < GetLineCount(); ++i) { - bool has_label = !suggestions_[i].label.empty(); - ElideValueAndLabelForRow( - i, layout_model_.GetAvailableWidthForRow(i, has_label)); - } -#endif - if (just_created) { #if defined(OS_ANDROID) ManualFillingController::GetOrCreate(web_contents_) @@ -149,17 +133,13 @@ ->RegisterKeyPressHandler( base::Bind(&AutofillPopupControllerImpl::HandleKeyPressEvent, base::Unretained(this))); + pinned_until_update_ = false; delegate_->OnPopupShown(); - - DCHECK_EQ(suggestions_.size(), elided_values_.size()); - DCHECK_EQ(suggestions_.size(), elided_labels_.size()); } void AutofillPopupControllerImpl::UpdateDataListValues( const std::vector<base::string16>& values, const std::vector<base::string16>& labels) { - DCHECK_EQ(suggestions_.size(), elided_values_.size()); - DCHECK_EQ(suggestions_.size(), elided_labels_.size()); selected_line_.reset(); // Remove all the old data list values, which should always be at the top of @@ -167,8 +147,6 @@ while (!suggestions_.empty() && suggestions_[0].frontend_id == POPUP_ITEM_ID_DATALIST_ENTRY) { suggestions_.erase(suggestions_.begin()); - elided_values_.erase(elided_values_.begin()); - elided_labels_.erase(elided_labels_.begin()); } // If there are no new data list values, exit (clearing the separator if there @@ -177,8 +155,6 @@ if (!suggestions_.empty() && suggestions_[0].frontend_id == POPUP_ITEM_ID_SEPARATOR) { suggestions_.erase(suggestions_.begin()); - elided_values_.erase(elided_values_.begin()); - elided_labels_.erase(elided_labels_.begin()); } // The popup contents have changed, so either update the bounds or hide it. @@ -195,29 +171,17 @@ suggestions_[0].frontend_id != POPUP_ITEM_ID_SEPARATOR) { suggestions_.insert(suggestions_.begin(), Suggestion()); suggestions_[0].frontend_id = POPUP_ITEM_ID_SEPARATOR; - elided_values_.insert(elided_values_.begin(), base::string16()); - elided_labels_.insert(elided_labels_.begin(), base::string16()); } // Prepend the parameters to the suggestions we already have. suggestions_.insert(suggestions_.begin(), values.size(), Suggestion()); - elided_values_.insert(elided_values_.begin(), values.size(), - base::string16()); - elided_labels_.insert(elided_labels_.begin(), values.size(), - base::string16()); for (size_t i = 0; i < values.size(); i++) { suggestions_[i].value = values[i]; suggestions_[i].label = labels[i]; suggestions_[i].frontend_id = POPUP_ITEM_ID_DATALIST_ENTRY; - - // TODO(brettw) it looks like these should be elided. - elided_values_[i] = values[i]; - elided_labels_[i] = labels[i]; } OnSuggestionsChanged(); - DCHECK_EQ(suggestions_.size(), elided_values_.size()); - DCHECK_EQ(suggestions_.size(), elided_labels_.size()); } void AutofillPopupControllerImpl::PinViewUntilUpdate() { @@ -231,9 +195,10 @@ void AutofillPopupControllerImpl::Hide(PopupHidingReason reason) { // If the reason for hiding is only stale data or a user interacting with - // native Chrome UI (kFocusChanged), the popup might be kept open. + // native Chrome UI (kFocusChanged/kEndEditing), the popup might be kept open. if (pinned_until_update_ && (reason == PopupHidingReason::kStaleData || - reason == PopupHidingReason::kFocusChanged)) { + reason == PopupHidingReason::kFocusChanged || + reason == PopupHidingReason::kEndEditing)) { return; // Don't close the popup while waiting for an update. } if (delegate_) { @@ -292,13 +257,7 @@ } void AutofillPopupControllerImpl::OnSuggestionsChanged() { -#if !defined(OS_ANDROID) - // TODO(csharp): Since UpdatePopupBounds can change the position of the popup, - // the popup could end up jumping from above the element to below it. - // It is unclear if it is better to keep the popup where it was, or if it - // should try and move to its desired position. - layout_model_.UpdatePopupBounds(); -#else +#if defined(OS_ANDROID) // Assume that suggestions are (still) available. If this is wrong, the method // |HideViewAndDie| will be called soon after and will hide all suggestions. ManualFillingController::GetOrCreate(web_contents_) @@ -349,18 +308,6 @@ return suggestions_; } -#if !defined(OS_ANDROID) -int AutofillPopupControllerImpl::GetElidedValueWidthForRow(int row) { - return gfx::GetStringWidth(GetElidedValueAt(row), - layout_model_.GetValueFontListForRow(row)); -} - -int AutofillPopupControllerImpl::GetElidedLabelWidthForRow(int row) { - return gfx::GetStringWidth(GetElidedLabelAt(row), - layout_model_.GetLabelFontListForRow(row)); -} -#endif - int AutofillPopupControllerImpl::GetLineCount() const { return suggestions_.size(); } @@ -371,12 +318,12 @@ const base::string16& AutofillPopupControllerImpl::GetElidedValueAt( int row) const { - return elided_values_[row]; + return suggestions_[row].value; } const base::string16& AutofillPopupControllerImpl::GetElidedLabelAt( int row) const { - return elided_labels_[row]; + return suggestions_[row].label; } bool AutofillPopupControllerImpl::GetRemovalConfirmationText( @@ -396,8 +343,6 @@ // Remove the deleted element. suggestions_.erase(suggestions_.begin() + list_index); - elided_values_.erase(elided_values_.begin() + list_index); - elided_labels_.erase(elided_labels_.begin() + list_index); selected_line_.reset(); @@ -501,46 +446,12 @@ void AutofillPopupControllerImpl::SetValues( const std::vector<Suggestion>& suggestions) { suggestions_ = suggestions; - elided_values_.resize(suggestions.size()); - elided_labels_.resize(suggestions.size()); - for (size_t i = 0; i < suggestions.size(); i++) { - elided_values_[i] = suggestions[i].value; - elided_labels_[i] = suggestions[i].label; - } } WeakPtr<AutofillPopupControllerImpl> AutofillPopupControllerImpl::GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } -#if !defined(OS_ANDROID) -void AutofillPopupControllerImpl::ElideValueAndLabelForRow( - int row, - int available_width) { - int value_width = gfx::GetStringWidth( - suggestions_[row].value, layout_model_.GetValueFontListForRow(row)); - int label_width = gfx::GetStringWidth( - suggestions_[row].label, layout_model_.GetLabelFontListForRow(row)); - int total_text_length = value_width + label_width; - - // The line can have no strings if it represents a UI element, such as - // a separator line. - if (total_text_length == 0) - return; - - // Each field receives space in proportion to its length. - int value_size = available_width * value_width / total_text_length; - elided_values_[row] = gfx::ElideText( - suggestions_[row].value, layout_model_.GetValueFontListForRow(row), - value_size, gfx::ELIDE_TAIL); - - int label_size = available_width * label_width / total_text_length; - elided_labels_[row] = gfx::ElideText( - suggestions_[row].label, layout_model_.GetLabelFontListForRow(row), - label_size, gfx::ELIDE_TAIL); -} -#endif - bool AutofillPopupControllerImpl::AcceptSelectedLine() { if (!selected_line_) return false; @@ -558,8 +469,6 @@ // Don't clear view_, because otherwise the popup will have to get regenerated // and this will cause flickering. suggestions_.clear(); - elided_values_.clear(); - elided_labels_.clear(); selected_line_.reset(); }
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_impl.h b/chrome/browser/ui/autofill/autofill_popup_controller_impl.h index 2f331f9f..3f9fb34 100644 --- a/chrome/browser/ui/autofill/autofill_popup_controller_impl.h +++ b/chrome/browser/ui/autofill/autofill_popup_controller_impl.h
@@ -96,10 +96,6 @@ void SetElementBounds(const gfx::RectF& bounds); bool IsRTL() const override; const std::vector<Suggestion> GetSuggestions() override; -#if !defined(OS_ANDROID) - int GetElidedValueWidthForRow(int row) override; - int GetElidedLabelWidthForRow(int row) override; -#endif // AutofillPopupController implementation. void OnSuggestionsChanged() override; @@ -151,14 +147,6 @@ virtual ui::AXPlatformNode* GetRootAXPlatformNodeForWebContents(); private: -#if !defined(OS_ANDROID) - FRIEND_TEST_ALL_PREFIXES(AutofillPopupControllerUnitTest, ElideText); - // Helper method which elides the value and label for the suggestion at |row| - // given the |available_width|. Puts the results in |elided_values_| and - // |elided_labels_|. - void ElideValueAndLabelForRow(int row, int available_width); -#endif - // The user has accepted the currently selected line. Returns whether there // was a selection to accept. bool AcceptSelectedLine(); @@ -187,11 +175,6 @@ // The current Autofill query values. std::vector<Suggestion> suggestions_; - // Elided values and labels corresponding to the suggestions_ vector to - // ensure that it fits on the screen. - std::vector<base::string16> elided_values_; - std::vector<base::string16> elided_labels_; - // The line that is currently selected by the user, null indicates that no // line is currently selected. base::Optional<int> selected_line_;
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc b/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc index de052a0..4a4b237 100644 --- a/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc +++ b/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc
@@ -701,55 +701,15 @@ EXPECT_CALL(*autofill_popup_view(), Hide).Times(0); autofill_popup_controller_->PinViewUntilUpdate(); - // Hide() will not work for stale data. + // Hide() will not work for stale data or when focusing native UI. autofill_popup_controller_->DoHide(PopupHidingReason::kStaleData); + autofill_popup_controller_->DoHide(PopupHidingReason::kEndEditing); // Check the expectations now since TearDown will perform a successful hide. Mock::VerifyAndClearExpectations(delegate()); Mock::VerifyAndClearExpectations(autofill_popup_view()); } -#if !defined(OS_ANDROID) -TEST_F(AutofillPopupControllerUnitTest, ElideText) { - std::vector<Suggestion> suggestions; - suggestions.push_back( - Suggestion("Text that will need to be trimmed", - "Label that will be trimmed", "genericCC", 0)); - suggestions.push_back( - Suggestion("untrimmed", "Untrimmed", "genericCC", 0)); - - autofill_popup_controller_->SetValues(suggestions); - - // Ensure the popup will be too small to display all of the first row. - int popup_max_width = - gfx::GetStringWidth( - suggestions[0].value, - autofill_popup_controller_->layout_model().GetValueFontListForRow( - 0)) + - gfx::GetStringWidth( - suggestions[0].label, - autofill_popup_controller_->layout_model().GetLabelFontListForRow( - 0)) - - 25; - - autofill_popup_controller_->ElideValueAndLabelForRow(0, popup_max_width); - - // The first element was long so it should have been trimmed. - EXPECT_NE(autofill_popup_controller_->GetSuggestionAt(0).value, - autofill_popup_controller_->GetElidedValueAt(0)); - EXPECT_NE(autofill_popup_controller_->GetSuggestionAt(0).label, - autofill_popup_controller_->GetElidedLabelAt(0)); - - autofill_popup_controller_->ElideValueAndLabelForRow(1, popup_max_width); - - // The second element was shorter so it should be unchanged. - EXPECT_EQ(autofill_popup_controller_->GetSuggestionAt(1).value, - autofill_popup_controller_->GetElidedValueAt(1)); - EXPECT_EQ(autofill_popup_controller_->GetSuggestionAt(1).label, - autofill_popup_controller_->GetElidedLabelAt(1)); -} -#endif - #if !defined(OS_CHROMEOS) TEST_F(AutofillPopupControllerAccessibilityUnitTest, FireControlsChangedEvent) { StrictMock<MockAxPlatformNodeDelegate> mock_ax_platform_node_delegate;
diff --git a/chrome/browser/ui/autofill/autofill_popup_layout_model.cc b/chrome/browser/ui/autofill/autofill_popup_layout_model.cc index ea6c8a59..f7a6748 100644 --- a/chrome/browser/ui/autofill/autofill_popup_layout_model.cc +++ b/chrome/browser/ui/autofill/autofill_popup_layout_model.cc
@@ -5,6 +5,9 @@ #include "chrome/browser/ui/autofill/autofill_popup_layout_model.h" #include <algorithm> +#include <memory> +#include <utility> +#include <vector> #include "base/macros.h" #include "base/stl_util.h" @@ -16,17 +19,12 @@ #include "chrome/browser/ui/autofill/popup_constants.h" #include "components/autofill/core/browser/data_model/credit_card.h" #include "components/autofill/core/browser/ui/popup_item_ids.h" -#include "components/autofill/core/browser/ui/suggestion.h" #include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_util.h" #include "components/grit/components_scaled_resources.h" #include "components/strings/grit/components_strings.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/color_palette.h" -#include "ui/gfx/color_utils.h" -#include "ui/gfx/font_list.h" -#include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/paint_vector_icon.h" @@ -39,16 +37,7 @@ namespace { -// The vertical height of each row in pixels. -const size_t kRowHeight = 24; - -// The vertical height of a separator in pixels. -const size_t kSeparatorHeight = 1; - #if !defined(OS_ANDROID) -// Size difference between the normal font and the smaller font, in pixels. -const int kSmallerFontSizeDelta = -1; - // Default sice for icons in the autofill popup. constexpr int kIconSize = 16; #endif @@ -91,174 +80,33 @@ #endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) }; -int GetRowHeightFromId(int identifier) { - if (identifier == POPUP_ITEM_ID_SEPARATOR) - return kSeparatorHeight; - - return kRowHeight; -} - } // namespace -AutofillPopupLayoutModel::AutofillPopupLayoutModel( - AutofillPopupViewDelegate* delegate, - bool is_credit_card_popup) - : delegate_(delegate), is_credit_card_popup_(is_credit_card_popup) { -#if !defined(OS_ANDROID) - smaller_font_list_ = - normal_font_list_.DeriveWithSizeDelta(kSmallerFontSizeDelta); - bold_font_list_ = normal_font_list_.DeriveWithWeight(gfx::Font::Weight::BOLD); - view_common_ = std::make_unique<PopupViewCommon>(); -#endif -} +AutofillPopupLayoutModel::AutofillPopupLayoutModel(bool is_credit_card_popup) + : is_credit_card_popup_(is_credit_card_popup) {} -AutofillPopupLayoutModel::~AutofillPopupLayoutModel() {} +AutofillPopupLayoutModel::~AutofillPopupLayoutModel() = default; #if !defined(OS_ANDROID) -int AutofillPopupLayoutModel::GetDesiredPopupHeight() const { - std::vector<autofill::Suggestion> suggestions = delegate_->GetSuggestions(); - int popup_height = 2 * kPopupBorderThickness; +// static +gfx::ImageSkia AutofillPopupLayoutModel::GetIconImage( + const autofill::Suggestion& suggestion) { + if (!suggestion.custom_icon.IsEmpty()) + return suggestion.custom_icon.AsImageSkia(); - for (size_t i = 0; i < suggestions.size(); ++i) { - popup_height += GetRowHeightFromId(suggestions[i].frontend_id); - } - - return popup_height; + return GetIconImageByName(suggestion.icon); } -int AutofillPopupLayoutModel::GetDesiredPopupWidth() const { - std::vector<autofill::Suggestion> suggestions = delegate_->GetSuggestions(); - - int popup_width = RoundedElementBounds().width(); - - for (size_t i = 0; i < suggestions.size(); ++i) { - int label_size = delegate_->GetElidedLabelWidthForRow(i); - int row_size = delegate_->GetElidedValueWidthForRow(i) + label_size + - RowWidthWithoutText(i, /* has_subtext= */ label_size > 0); - - popup_width = std::max(popup_width, row_size); - } - - return popup_width; -} - -int AutofillPopupLayoutModel::RowWidthWithoutText(int row, - bool has_subtext) const { - std::vector<autofill::Suggestion> suggestions = delegate_->GetSuggestions(); - int row_size = 2 * (kEndPadding + kPopupBorderThickness); - if (has_subtext) - row_size += kNamePadding; - - // Add the Autofill icon size, if required. - const std::string& icon = suggestions[row].icon; - if (!icon.empty()) { - row_size += GetIconImage(row).width() + kIconPadding; - } - return row_size; -} - -int AutofillPopupLayoutModel::GetAvailableWidthForRow(int row, - bool has_subtext) const { - return popup_bounds_.width() - RowWidthWithoutText(row, has_subtext); -} - -void AutofillPopupLayoutModel::UpdatePopupBounds() { - int popup_width = GetDesiredPopupWidth(); - int popup_height = GetDesiredPopupHeight(); - - popup_bounds_ = view_common_->CalculatePopupBounds( - popup_width, popup_height, RoundedElementBounds(), - delegate_->container_view(), delegate_->IsRTL()); -} - -const gfx::FontList& AutofillPopupLayoutModel::GetValueFontListForRow( - size_t index) const { - std::vector<autofill::Suggestion> suggestions = delegate_->GetSuggestions(); - - // Autofill values have positive |frontend_id|. - if (suggestions[index].frontend_id > 0) - return bold_font_list_; - - // All other message types are defined here. - PopupItemId id = static_cast<PopupItemId>(suggestions[index].frontend_id); - switch (id) { - case POPUP_ITEM_ID_INSECURE_CONTEXT_PAYMENT_DISABLED_MESSAGE: - case POPUP_ITEM_ID_CLEAR_FORM: - case POPUP_ITEM_ID_CREDIT_CARD_SIGNIN_PROMO: - case POPUP_ITEM_ID_AUTOFILL_OPTIONS: - case POPUP_ITEM_ID_CREATE_HINT: - case POPUP_ITEM_ID_SCAN_CREDIT_CARD: - case POPUP_ITEM_ID_SEPARATOR: - case POPUP_ITEM_ID_LOADING_SPINNER: - case POPUP_ITEM_ID_TITLE: - case POPUP_ITEM_ID_PASSWORD_ENTRY: - case POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY: - case POPUP_ITEM_ID_HIDE_AUTOFILL_SUGGESTIONS: - case POPUP_ITEM_ID_GENERATE_PASSWORD_ENTRY: - case POPUP_ITEM_ID_SHOW_ACCOUNT_CARDS: - case POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPTIN: - case POPUP_ITEM_ID_USE_VIRTUAL_CARD: - case POPUP_ITEM_ID_ONE_TIME_CODE: - return normal_font_list_; - case POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY: - case POPUP_ITEM_ID_DATALIST_ENTRY: - case POPUP_ITEM_ID_USERNAME_ENTRY: - return bold_font_list_; - } - NOTREACHED(); - return normal_font_list_; -} - -const gfx::FontList& AutofillPopupLayoutModel::GetLabelFontListForRow( - size_t index) const { - return smaller_font_list_; -} - -gfx::ImageSkia AutofillPopupLayoutModel::GetIconImage(size_t index) const { - std::vector<autofill::Suggestion> suggestions = delegate_->GetSuggestions(); - if (!suggestions[index].custom_icon.IsEmpty()) - return suggestions[index].custom_icon.AsImageSkia(); - - return GetIconImageByName(suggestions[index].icon); -} - +// static gfx::ImageSkia AutofillPopupLayoutModel::GetStoreIndicatorIconImage( - size_t index) const { - return GetIconImageByName( - delegate_->GetSuggestions()[index].store_indicator_icon); + const autofill::Suggestion& suggestion) { + return GetIconImageByName(suggestion.store_indicator_icon); } #endif // !defined(OS_ANDROID) -int AutofillPopupLayoutModel::LineFromY(int y) const { - std::vector<autofill::Suggestion> suggestions = delegate_->GetSuggestions(); - int current_height = kPopupBorderThickness; - - for (size_t i = 0; i < suggestions.size(); ++i) { - current_height += GetRowHeightFromId(suggestions[i].frontend_id); - - if (y <= current_height) - return i; - } - - // The y value goes beyond the popup so stop the selection at the last line. - return suggestions.size() - 1; -} - -gfx::Rect AutofillPopupLayoutModel::GetRowBounds(size_t index) const { - std::vector<autofill::Suggestion> suggestions = delegate_->GetSuggestions(); - - int top = kPopupBorderThickness; - for (size_t i = 0; i < index; ++i) { - top += GetRowHeightFromId(suggestions[i].frontend_id); - } - - return gfx::Rect(kPopupBorderThickness, top, - popup_bounds_.width() - 2 * kPopupBorderThickness, - GetRowHeightFromId(suggestions[index].frontend_id)); -} - +// static int AutofillPopupLayoutModel::GetIconResourceID( - const std::string& resource_name) const { + const std::string& resource_name) { #if !BUILDFLAG(GOOGLE_CHROME_BRANDING) if (resource_name == "googlePay" || resource_name == "googlePayDark") { return 0; @@ -280,13 +128,10 @@ view_common_ = std::move(view_common); } -gfx::Rect AutofillPopupLayoutModel::RoundedElementBounds() const { - return gfx::ToEnclosingRect(delegate_->element_bounds()); -} - #if !defined(OS_ANDROID) +// static gfx::ImageSkia AutofillPopupLayoutModel::GetIconImageByName( - const std::string& icon_str) const { + const std::string& icon_str) { if (icon_str.empty()) return gfx::ImageSkia();
diff --git a/chrome/browser/ui/autofill/autofill_popup_layout_model.h b/chrome/browser/ui/autofill/autofill_popup_layout_model.h index 02fe284..ef4c03e7 100644 --- a/chrome/browser/ui/autofill/autofill_popup_layout_model.h +++ b/chrome/browser/ui/autofill/autofill_popup_layout_model.h
@@ -7,10 +7,11 @@ #include <stddef.h> +#include <memory> #include <string> -#include "chrome/browser/ui/autofill/autofill_popup_view_delegate.h" #include "chrome/browser/ui/autofill/popup_view_common.h" +#include "components/autofill/core/browser/ui/suggestion.h" #include "ui/gfx/font_list.h" #include "ui/gfx/geometry/rect.h" @@ -24,100 +25,36 @@ // TODO(mathp): investigate moving ownership of this class to the view. class AutofillPopupLayoutModel { public: - AutofillPopupLayoutModel(AutofillPopupViewDelegate* delegate, - bool is_credit_card_popup); + explicit AutofillPopupLayoutModel(bool is_credit_card_popup); ~AutofillPopupLayoutModel(); - // The minimum amount of padding between the Autofill name and subtext, - // in dip. - static const int kNamePadding = 15; - - // The amount of padding around icons in dip. - static const int kIconPadding = 5; - - // The amount of horizontal padding around icons in dip for the case, when - // icon is located on the left side. - static const int kPaddingAfterLeadingIcon = 8; - - // The amount of padding at the end of the popup in dip. - static const int kEndPadding = 8; - #if !defined(OS_ANDROID) - // Calculates the desired height of the popup based on its contents. - int GetDesiredPopupHeight() const; + // Returns the icon image of the given |suggestion|. + static gfx::ImageSkia GetIconImage(const autofill::Suggestion& suggestion); - // Calculates the desired width of the popup based on its contents. - int GetDesiredPopupWidth() const; - - // Calculate the width of the row, excluding all the text. This provides - // the size of the row that won't be reducible (since all the text can be - // elided if there isn't enough space). |with_label| indicates whether a label - // is expected to be present. - int RowWidthWithoutText(int row, bool with_label) const; - - // Get the available space for the total text width. |with_label| indicates - // whether a label is expected to be present. - int GetAvailableWidthForRow(int row, bool with_label) const; - - // Calculates and sets the bounds of the popup, including placing it properly - // to prevent it from going off the screen. - void UpdatePopupBounds(); - - // The same font can vary based on the type of data it is showing at the row - // |index|. - const gfx::FontList& GetValueFontListForRow(size_t index) const; - const gfx::FontList& GetLabelFontListForRow(size_t index) const; - - // Returns the icon image of the item at |index| in the popup. - gfx::ImageSkia GetIconImage(size_t index) const; - - // Returns the store indicator icon image of the item at |index| in the popup. - gfx::ImageSkia GetStoreIndicatorIconImage(size_t index) const; + // Returns the store indicator icon image of the given |suggestion|. + static gfx::ImageSkia GetStoreIndicatorIconImage( + const autofill::Suggestion& suggestion); #endif - // Convert a y-coordinate to the closest line. - int LineFromY(int y) const; - - const gfx::Rect popup_bounds() const { return popup_bounds_; } - - // Returns the bounds of the item at |index| in the popup, relative to - // the top left of the popup. - gfx::Rect GetRowBounds(size_t index) const; + bool is_credit_card_popup() const { return is_credit_card_popup_; } // Gets the resource value for the given resource, returning 0 if the // resource isn't recognized. - int GetIconResourceID(const std::string& resource_name) const; - - bool is_credit_card_popup() const { return is_credit_card_popup_; } + static int GetIconResourceID(const std::string& resource_name); // Allows the provision of another implementation of view_common, for use in // unit tests where using the real thing could cause crashes. void SetUpForTesting(std::unique_ptr<PopupViewCommon> view_common); private: - // Returns the enclosing rectangle for the element_bounds. - gfx::Rect RoundedElementBounds() const; - #if !defined(OS_ANDROID) - gfx::ImageSkia GetIconImageByName(const std::string& icon_str) const; - - // The fonts for the popup text. - // Normal font (readable size, non bold). - gfx::FontList normal_font_list_; - // Slightly smaller than the normal font. - gfx::FontList smaller_font_list_; - // Bold version of the normal font. - gfx::FontList bold_font_list_; + static gfx::ImageSkia GetIconImageByName(const std::string& icon_str); #endif - // The bounds of the Autofill popup. - gfx::Rect popup_bounds_; - std::unique_ptr<PopupViewCommon> view_common_; - AutofillPopupViewDelegate* delegate_; // Weak reference. - const bool is_credit_card_popup_; DISALLOW_COPY_AND_ASSIGN(AutofillPopupLayoutModel);
diff --git a/chrome/browser/ui/autofill/autofill_popup_layout_model_unittest.cc b/chrome/browser/ui/autofill/autofill_popup_layout_model_unittest.cc index 35b1a58..1c44dd9a 100644 --- a/chrome/browser/ui/autofill/autofill_popup_layout_model_unittest.cc +++ b/chrome/browser/ui/autofill/autofill_popup_layout_model_unittest.cc
@@ -9,101 +9,25 @@ #include <memory> #include <vector> -#include "chrome/browser/ui/autofill/autofill_popup_view.h" -#include "chrome/browser/ui/autofill/autofill_popup_view_delegate.h" -#include "chrome/browser/ui/autofill/popup_constants.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" -#include "components/autofill/core/browser/ui/popup_item_ids.h" -#include "components/autofill/core/browser/ui/suggestion.h" -#include "components/grit/components_scaled_resources.h" -#include "content/public/browser/web_contents.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/geometry/point.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/gfx/geometry/rect_f.h" -#include "ui/gfx/image/image_skia.h" -#include "ui/gfx/native_widget_types.h" namespace autofill { namespace { -class TestAutofillPopupViewDelegate : public AutofillPopupViewDelegate { - public: - explicit TestAutofillPopupViewDelegate(content::WebContents* web_contents) - : element_bounds_(0.0, 0.0, 100.0, 100.0), - container_view_(web_contents->GetNativeView()) {} - - void Hide(PopupHidingReason reason) override {} - void ViewDestroyed() override {} - void SelectionCleared() override {} - gfx::NativeView container_view() const override { return container_view_; } - const gfx::RectF& element_bounds() const override { return element_bounds_; } - bool IsRTL() const override { return false; } - - const std::vector<autofill::Suggestion> GetSuggestions() override { - // Give elements 1 and 3 subtexts and elements 2 and 3 icons, to ensure - // all combinations of subtexts and icons. - std::vector<Suggestion> suggestions; - suggestions.push_back(Suggestion("", "", "", 0)); - suggestions.push_back(Suggestion("", "x", "", 0)); - suggestions.push_back(Suggestion("", "", "americanExpressCC", 0)); - suggestions.push_back(Suggestion("", "x", "genericCC", 0)); - return suggestions; - } -#if !defined(OS_ANDROID) - int GetElidedValueWidthForRow(int row) override { return 0; } - int GetElidedLabelWidthForRow(int row) override { return 0; } -#endif - - private: - gfx::RectF element_bounds_; - gfx::NativeView container_view_; -}; - class AutofillPopupLayoutModelTest : public ChromeRenderViewHostTestHarness { public: void SetUp() override { ChromeRenderViewHostTestHarness::SetUp(); - - delegate_ = std::make_unique<TestAutofillPopupViewDelegate>(web_contents()); - layout_model_ = std::make_unique<AutofillPopupLayoutModel>( - delegate_.get(), false /* is_credit_card_field */); + layout_model_ = std::make_unique<AutofillPopupLayoutModel>(false); } AutofillPopupLayoutModel* layout_model() { return layout_model_.get(); } private: - std::unique_ptr<TestAutofillPopupViewDelegate> delegate_; std::unique_ptr<AutofillPopupLayoutModel> layout_model_; }; } // namespace -#if !defined(OS_ANDROID) -TEST_F(AutofillPopupLayoutModelTest, RowWidthWithoutText) { - int base_size = - AutofillPopupLayoutModel::kEndPadding * 2 + kPopupBorderThickness * 2; - int subtext_increase = AutofillPopupLayoutModel::kNamePadding; - - // Refer to GetSuggestions() in TestAutofillPopupViewDelegate. - EXPECT_EQ(base_size, - layout_model()->RowWidthWithoutText(0, /* has_substext= */ false)); - EXPECT_EQ(base_size + subtext_increase, - layout_model()->RowWidthWithoutText(1, /* has_substext= */ true)); - EXPECT_EQ(base_size + AutofillPopupLayoutModel::kIconPadding + - ui::ResourceBundle::GetSharedInstance() - .GetImageNamed(IDR_AUTOFILL_CC_AMEX) - .Width(), - layout_model()->RowWidthWithoutText(2, /* has_substext= */ false)); - EXPECT_EQ(base_size + subtext_increase + - AutofillPopupLayoutModel::kIconPadding + - ui::ResourceBundle::GetSharedInstance() - .GetImageNamed(IDR_AUTOFILL_CC_GENERIC) - .Width(), - layout_model()->RowWidthWithoutText(3, /* has_substext= */ true)); -} -#endif - } // namespace autofill
diff --git a/chrome/browser/ui/autofill/autofill_popup_view_delegate.h b/chrome/browser/ui/autofill/autofill_popup_view_delegate.h index f03d35a4..1f6e2b5 100644 --- a/chrome/browser/ui/autofill/autofill_popup_view_delegate.h +++ b/chrome/browser/ui/autofill/autofill_popup_view_delegate.h
@@ -20,8 +20,6 @@ namespace autofill { -struct Suggestion; - // Base class for Controllers of Autofill-style popups. This interface is // used by the relevant views to communicate with the controller. class AutofillPopupViewDelegate { @@ -47,15 +45,6 @@ // If the current popup should be displayed in RTL mode. virtual bool IsRTL() const = 0; - // Returns the full set of autofill suggestions, if applicable. - virtual const std::vector<autofill::Suggestion> GetSuggestions() = 0; - -#if !defined(OS_ANDROID) - // Returns elided values and labels for the given |row|. - virtual int GetElidedValueWidthForRow(int row) = 0; - virtual int GetElidedLabelWidthForRow(int row) = 0; -#endif - protected: virtual ~AutofillPopupViewDelegate() {} };
diff --git a/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller_unittest.mm b/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller_unittest.mm index b16b417a..829aa37 100644 --- a/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller_unittest.mm
@@ -30,8 +30,7 @@ public: MockAutofillPopupController() { gfx::FontList::SetDefaultFontDescription("Arial, Times New Roman, 15px"); - layout_model_ = - std::make_unique<autofill::AutofillPopupLayoutModel>(this, false); + layout_model_ = std::make_unique<autofill::AutofillPopupLayoutModel>(false); suggestions_.push_back( autofill::Suggestion("bufflehead", "canvasback", "goldeneye", 1)); suggestions_.push_back( @@ -88,7 +87,7 @@ void SetIsCreditCardField(bool is_credit_card_field) { layout_model_.reset( - new autofill::AutofillPopupLayoutModel(this, is_credit_card_field)); + new autofill::AutofillPopupLayoutModel(is_credit_card_field)); } void set_line_count(int line_count) {
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc index a7da3621..64a3e3e 100644 --- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc +++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
@@ -13,6 +13,7 @@ #include "build/build_config.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/browsing_data/browsing_data_helper.h" +#include "chrome/browser/password_manager/account_storage/account_password_store_factory.h" #include "chrome/browser/password_manager/chrome_password_manager_client.h" #include "chrome/browser/password_manager/password_store_factory.h" #include "chrome/browser/signin/signin_ui_util.h" @@ -56,7 +57,7 @@ namespace { -password_manager::PasswordStore* GetPasswordStore( +password_manager::PasswordStore* GetProfilePasswordStore( content::WebContents* web_contents) { return PasswordStoreFactory::GetForProfile( Profile::FromBrowserContext(web_contents->GetBrowserContext()), @@ -64,6 +65,14 @@ .get(); } +password_manager::PasswordStore* GetAccountPasswordStore( + content::WebContents* web_contents) { + return AccountPasswordStoreFactory::GetForProfile( + Profile::FromBrowserContext(web_contents->GetBrowserContext()), + ServiceAccessType::EXPLICIT_ACCESS) + .get(); +} + std::vector<std::unique_ptr<autofill::PasswordForm>> CopyFormVector( const std::vector<std::unique_ptr<autofill::PasswordForm>>& forms) { std::vector<std::unique_ptr<autofill::PasswordForm>> result(forms.size()); @@ -90,13 +99,17 @@ are_passwords_revealed_when_next_bubble_is_opened_(false) { passwords_data_.set_client( ChromePasswordManagerClient::FromWebContents(web_contents)); - password_manager::PasswordStore* password_store = - GetPasswordStore(web_contents); - if (password_store) - password_store->AddObserver(this); + password_manager::PasswordStore* profile_password_store = + GetProfilePasswordStore(web_contents); + if (profile_password_store) + profile_password_store->AddObserver(this); + password_manager::PasswordStore* account_password_store = + GetAccountPasswordStore(web_contents); + if (account_password_store) + account_password_store->AddObserver(this); } -ManagePasswordsUIController::~ManagePasswordsUIController() {} +ManagePasswordsUIController::~ManagePasswordsUIController() = default; void ManagePasswordsUIController::OnPasswordSubmitted( std::unique_ptr<PasswordFormManagerForUI> form_manager) { @@ -623,10 +636,14 @@ } void ManagePasswordsUIController::WebContentsDestroyed() { - password_manager::PasswordStore* password_store = - GetPasswordStore(web_contents()); - if (password_store) - password_store->RemoveObserver(this); + password_manager::PasswordStore* profile_password_store = + GetProfilePasswordStore(web_contents()); + if (profile_password_store) + profile_password_store->RemoveObserver(this); + password_manager::PasswordStore* account_password_store = + GetAccountPasswordStore(web_contents()); + if (account_password_store) + account_password_store->RemoveObserver(this); HidePasswordBubble(); }
diff --git a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc index 41b16fd..b388a1c 100644 --- a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc +++ b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc
@@ -319,21 +319,6 @@ return base::i18n::IsRTL(); } -const std::vector<autofill::Suggestion> -PasswordGenerationPopupControllerImpl::GetSuggestions() { - return std::vector<autofill::Suggestion>(); -} - -#if !defined(OS_ANDROID) -int PasswordGenerationPopupControllerImpl::GetElidedValueWidthForRow(int row) { - return 0; -} - -int PasswordGenerationPopupControllerImpl::GetElidedLabelWidthForRow(int row) { - return 0; -} -#endif - PasswordGenerationPopupController::GenerationUIState PasswordGenerationPopupControllerImpl::state() const { return state_;
diff --git a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.h b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.h index 75ff28b..c77f3f77 100644 --- a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.h +++ b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.h
@@ -40,7 +40,6 @@ namespace autofill { struct FormData; -struct Suggestion; namespace password_generation { struct PasswordGenerationUIData; } // namespace password_generation @@ -137,11 +136,6 @@ gfx::NativeView container_view() const override; const gfx::RectF& element_bounds() const override; bool IsRTL() const override; - const std::vector<autofill::Suggestion> GetSuggestions() override; -#if !defined(OS_ANDROID) - int GetElidedValueWidthForRow(int row) override; - int GetElidedLabelWidthForRow(int row) override; -#endif GenerationUIState state() const override; bool password_selected() const override;
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_base_view_browsertest.cc b/chrome/browser/ui/views/autofill/autofill_popup_base_view_browsertest.cc index 8ae813c..7ece012 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_base_view_browsertest.cc +++ b/chrome/browser/ui/views/autofill/autofill_popup_base_view_browsertest.cc
@@ -41,11 +41,6 @@ MOCK_CONST_METHOD0(container_view, gfx::NativeView()); MOCK_CONST_METHOD0(element_bounds, gfx::RectF&()); MOCK_CONST_METHOD0(IsRTL, bool()); - MOCK_METHOD0(GetSuggestions, const std::vector<autofill::Suggestion>()); -#if !defined(OS_ANDROID) - MOCK_METHOD1(GetElidedValueWidthForRow, int(int)); - MOCK_METHOD1(GetElidedLabelWidthForRow, int(int)); -#endif }; } // namespace
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc index d86cc08e..6b70805 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc +++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
@@ -447,8 +447,10 @@ layout_manager->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kCenter); + std::vector<autofill::Suggestion> suggestions = controller->GetSuggestions(); + const gfx::ImageSkia icon = - controller->layout_model().GetIconImage(line_number()); + controller->layout_model().GetIconImage(suggestions[line_number()]); if (!icon.isNull()) { AddIcon(icon); @@ -489,7 +491,8 @@ AddChildView(std::move(all_labels)); const gfx::ImageSkia store_indicator_icon = - controller->layout_model().GetStoreIndicatorIconImage(line_number()); + controller->layout_model().GetStoreIndicatorIconImage( + suggestions[line_number()]); if (!store_indicator_icon.isNull()) { AddSpacerWithSize(GetHorizontalMargin(), /*resize=*/true, layout_manager); @@ -719,8 +722,8 @@ layout_manager->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStretch); - const gfx::ImageSkia icon = - controller->layout_model().GetIconImage(line_number()); + const gfx::ImageSkia icon = controller->layout_model().GetIconImage( + controller->GetSuggestions()[line_number()]); // A FooterView shows an icon, if any, on the trailing (right in LTR) side, // but the Show Account Cards context is an anomaly. Its icon is on the
diff --git a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc index 7660ca0..abe19d4 100644 --- a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc +++ b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc
@@ -1278,7 +1278,9 @@ CheckBrowserLayout(browser_view(), TopChromeShownState::kFullyShown); } -IN_PROC_BROWSER_TEST_F(TopControlsSlideControllerTest, TestPermissionBubble) { +// Disabled due to flakiness: https://crbug.com/1033651 +IN_PROC_BROWSER_TEST_F(TopControlsSlideControllerTest, + DISABLED_TestPermissionBubble) { ToggleTabletMode(); ASSERT_TRUE(GetTabletModeEnabled()); EXPECT_TRUE(top_controls_slide_controller()->IsEnabled());
diff --git a/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc index 1a2a0cd..aa87c7a 100644 --- a/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc
@@ -75,6 +75,11 @@ g_browser_process->GetApplicationLocale().c_str()); } +std::string EulaScreenHandler::GetAdditionalToSUrl() { + return base::StringPrintf(chrome::kAdditionalToSOnlineURLPath, + g_browser_process->GetApplicationLocale().c_str()); +} + void EulaScreenHandler::DeclareLocalizedValues( ::login::LocalizedValuesBuilder* builder) { builder->Add("eulaScreenAccessibleTitle", IDS_EULA_SCREEN_ACCESSIBLE_TITLE); @@ -107,9 +112,11 @@ // Online URL to use. May be overridden by tests. builder->Add("eulaOnlineUrl", GetEulaOnlineUrl()); + builder->Add("eulaAdditionalToSOnlineUrl", GetAdditionalToSUrl()); /* MD-OOBE */ builder->Add("oobeEulaSectionTitle", IDS_OOBE_EULA_SECTION_TITLE); + builder->Add("oobeEulaAditionalTerms", IDS_OOBE_EULA_ADDITIONAL_TERMS); builder->Add("oobeEulaIframeLabel", IDS_OOBE_EULA_IFRAME_LABEL); builder->Add("oobeEulaAcceptAndContinueButtonText", IDS_OOBE_EULA_ACCEPT_AND_CONTINUE_BUTTON_TEXT);
diff --git a/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.h index 848c494..bb724d1f 100644 --- a/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.h
@@ -74,6 +74,7 @@ // Determines the online URL to use. std::string GetEulaOnlineUrl(); static const char* eula_url_for_testing_; + std::string GetAdditionalToSUrl(); void UpdateLocalizedValues(::login::SecureModuleUsed secure_module_used);
diff --git a/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.cc index ca64a2c2..8b92640 100644 --- a/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.cc
@@ -110,7 +110,7 @@ IDS_LOGIN_SYNC_CONSENT_SCREEN_ACCEPT_AND_CONTINUE, builder); - // SplitSettingsSync strings. The version of the dialog to show is chosen + // SplitSyncConsent strings. The version of the dialog to show is chosen // after the WebUI is loaded, so always supply both sets of strings. RememberLocalizedValue("osSyncConsentTitle", IDS_LOGIN_OS_SYNC_CONSENT_TITLE, builder); @@ -152,15 +152,15 @@ void SyncConsentScreenHandler::GetAdditionalParameters( base::DictionaryValue* parameters) { - parameters->SetBoolean("splitSettingsSync", - chromeos::features::IsSplitSettingsSyncEnabled()); + parameters->SetBoolean("splitSyncConsent", + chromeos::features::IsSplitSyncConsentEnabled()); BaseScreenHandler::GetAdditionalParameters(parameters); } void SyncConsentScreenHandler::HandleContinueAndReview( const login::StringList& consent_description, const std::string& consent_confirmation) { - DCHECK(!chromeos::features::IsSplitSettingsSyncEnabled()); + DCHECK(!chromeos::features::IsSplitSyncConsentEnabled()); std::vector<int> consent_description_ids; int consent_confirmation_id; GetConsentIDs(known_string_ids_, consent_description, consent_confirmation, @@ -179,7 +179,7 @@ void SyncConsentScreenHandler::HandleContinueWithDefaults( const login::StringList& consent_description, const std::string& consent_confirmation) { - DCHECK(!chromeos::features::IsSplitSettingsSyncEnabled()); + DCHECK(!chromeos::features::IsSplitSyncConsentEnabled()); std::vector<int> consent_description_ids; int consent_confirmation_id; GetConsentIDs(known_string_ids_, consent_description, consent_confirmation, @@ -199,7 +199,7 @@ const login::StringList& consent_description, const std::string& consent_confirmation, bool enable_os_sync) { - DCHECK(chromeos::features::IsSplitSettingsSyncEnabled()); + DCHECK(chromeos::features::IsSplitSyncConsentEnabled()); std::vector<int> consent_description_ids; int consent_confirmation_id; GetConsentIDs(known_string_ids_, consent_description, consent_confirmation,
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.cc index 60ec95a5..b26d934 100644 --- a/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.cc
@@ -2002,7 +2002,7 @@ html_source->AddBoolean("isAccountManagerEnabled", chromeos::IsAccountManagerAvailable(profile)); - if (chromeos::features::IsSplitSettingsSyncEnabled()) { + if (chromeos::features::IsSplitSyncConsentEnabled()) { static constexpr webui::LocalizedString kTurnOffStrings[] = { {"syncDisconnect", IDS_SETTINGS_PEOPLE_SYNC_TURN_OFF}, {"syncDisconnectTitle",
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc b/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc index e01c22d..ae0407a 100644 --- a/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc
@@ -169,6 +169,8 @@ ::features::kAppManagement)); html_source->AddBoolean("splitSettingsSyncEnabled", chromeos::features::IsSplitSettingsSyncEnabled()); + html_source->AddBoolean("splitSyncConsent", + chromeos::features::IsSplitSyncConsentEnabled()); html_source->AddBoolean( "isSupportedArcVersion",
diff --git a/chrome/browser/ui/webui/settings/safety_check_handler.cc b/chrome/browser/ui/webui/settings/safety_check_handler.cc index 6da98bb..3bde7f6 100644 --- a/chrome/browser/ui/webui/settings/safety_check_handler.cc +++ b/chrome/browser/ui/webui/settings/safety_check_handler.cc
@@ -5,18 +5,19 @@ #include "chrome/browser/ui/webui/settings/safety_check_handler.h" #include "base/bind.h" +#include "chrome/browser/password_manager/bulk_leak_check_service_factory.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/webui/settings/safety_check_handler_observer.h" #include "components/prefs/pref_service.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" namespace { // Constants for communication with JS. -static constexpr char kStatusChanged[] = "safety-check-status-changed"; -static constexpr char kPerformSafetyCheck[] = "performSafetyCheck"; -static constexpr char kSafetyCheckComponent[] = "safetyCheckComponent"; -static constexpr char kNewState[] = "newState"; +constexpr char kStatusChanged[] = "safety-check-status-changed"; +constexpr char kPerformSafetyCheck[] = "performSafetyCheck"; +constexpr char kSafetyCheckComponent[] = "safetyCheckComponent"; +constexpr char kNewState[] = "newState"; +constexpr char kPasswordsCompromised[] = "passwordsCompromised"; // Converts the VersionUpdater::Status to the UpdateStatus enum to be passed // to the safety check frontend. Note: if the VersionUpdater::Status gets @@ -47,8 +48,7 @@ } } // namespace -SafetyCheckHandler::SafetyCheckHandler() - : SafetyCheckHandler(nullptr, nullptr) {} +SafetyCheckHandler::SafetyCheckHandler() = default; SafetyCheckHandler::~SafetyCheckHandler() = default; @@ -59,12 +59,19 @@ } CheckUpdates(); CheckSafeBrowsing(); + if (!leak_service_) { + leak_service_ = BulkLeakCheckServiceFactory::GetForProfile( + Profile::FromWebUI(web_ui())); + } + DCHECK(leak_service_); + CheckPasswords(); } SafetyCheckHandler::SafetyCheckHandler( std::unique_ptr<VersionUpdater> version_updater, - SafetyCheckHandlerObserver* observer) - : version_updater_(std::move(version_updater)), observer_(observer) {} + password_manager::BulkLeakCheckService* leak_service) + : version_updater_(std::move(version_updater)), + leak_service_(leak_service) {} void SafetyCheckHandler::HandlePerformSafetyCheck( const base::ListValue* /*args*/) { @@ -72,9 +79,6 @@ } void SafetyCheckHandler::CheckUpdates() { - if (observer_) { - observer_->OnUpdateCheckStart(); - } version_updater_->CheckForUpdate( base::Bind(&SafetyCheckHandler::OnUpdateCheckResult, base::Unretained(this)), @@ -82,9 +86,6 @@ } void SafetyCheckHandler::CheckSafeBrowsing() { - if (observer_) { - observer_->OnSafeBrowsingCheckStart(); - } PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs(); const PrefService::Preference* pref = pref_service->FindPreference(prefs::kSafeBrowsingEnabled); @@ -101,39 +102,100 @@ OnSafeBrowsingCheckResult(status); } -void SafetyCheckHandler::OnUpdateCheckResult( - VersionUpdater::Status status, - int /*progress*/, - bool /*rollback*/, - const std::string& /*version*/, - int64_t /*update_size*/, - const base::string16& /*message*/) { +void SafetyCheckHandler::CheckPasswords() { + // Remove |this| as an existing observer for BulkLeakCheck if it is + // registered. This takes care of an edge case when safety check starts twice + // on the same page. Normally this should not happen, but if it does, the + // browser should not crash. + observed_leak_check_.RemoveAll(); + observed_leak_check_.Add(leak_service_); + // TODO(crbug.com/1015841): Implement starting a leak check if one is not + // running already once the API for it becomes available (see + // crrev.com/c/2072742 and follow up CLs). +} + +void SafetyCheckHandler::OnUpdateCheckResult(VersionUpdater::Status status, + int progress, + bool rollback, + const std::string& version, + int64_t update_size, + const base::string16& message) { UpdateStatus update_status = ConvertToUpdateStatus(status); - if (observer_) { - observer_->OnUpdateCheckResult(update_status); - } - auto event = std::make_unique<base::DictionaryValue>(); - event->SetInteger(kSafetyCheckComponent, - static_cast<int>(SafetyCheckComponent::kUpdates)); - event->SetInteger(kNewState, static_cast<int>(update_status)); - FireWebUIListener(kStatusChanged, *event); + base::DictionaryValue event; + event.SetIntKey(kSafetyCheckComponent, + static_cast<int>(SafetyCheckComponent::kUpdates)); + event.SetIntKey(kNewState, static_cast<int>(update_status)); + FireWebUIListener(kStatusChanged, event); } void SafetyCheckHandler::OnSafeBrowsingCheckResult( SafetyCheckHandler::SafeBrowsingStatus status) { - if (observer_) { - observer_->OnSafeBrowsingCheckResult(status); + base::DictionaryValue event; + event.SetIntKey(kSafetyCheckComponent, + static_cast<int>(SafetyCheckComponent::kSafeBrowsing)); + event.SetIntKey(kNewState, static_cast<int>(status)); + FireWebUIListener(kStatusChanged, event); +} + +void SafetyCheckHandler::OnPasswordsCheckResult(PasswordsStatus status, + int num_compromised) { + base::DictionaryValue event; + event.SetIntKey(kSafetyCheckComponent, + static_cast<int>(SafetyCheckComponent::kPasswords)); + event.SetIntKey(kNewState, static_cast<int>(status)); + if (status == PasswordsStatus::kCompromisedExist) { + event.SetIntKey(kPasswordsCompromised, num_compromised); } - auto event = std::make_unique<base::DictionaryValue>(); - event->SetInteger(kSafetyCheckComponent, - static_cast<int>(SafetyCheckComponent::kSafeBrowsing)); - event->SetInteger(kNewState, static_cast<int>(status)); - FireWebUIListener(kStatusChanged, *event); + FireWebUIListener(kStatusChanged, event); +} + +void SafetyCheckHandler::OnStateChanged( + password_manager::BulkLeakCheckService::State state, + size_t pending_credentials) { + using password_manager::BulkLeakCheckService; + switch (state) { + case BulkLeakCheckService::State::kIdle: + // TODO(crbug.com/1015841): Implement retrieving the number + // of leaked passwords (if any) once PasswordsPrivateDelegate provides an + // API for that (see crrev.com/c/2072742). + break; + case BulkLeakCheckService::State::kRunning: + OnPasswordsCheckResult(PasswordsStatus::kChecking, 0); + return; + case BulkLeakCheckService::State::kSignedOut: + OnPasswordsCheckResult(PasswordsStatus::kSignedOut, 0); + break; + case BulkLeakCheckService::State::kNetworkError: + OnPasswordsCheckResult(PasswordsStatus::kOffline, 0); + break; + case BulkLeakCheckService::State::kTokenRequestFailure: + case BulkLeakCheckService::State::kHashingFailure: + case BulkLeakCheckService::State::kServiceError: + OnPasswordsCheckResult(PasswordsStatus::kError, 0); + break; + } + // TODO(crbug.com/1015841): implement detecting the following states if it is + // possible: kNoPasswords, kQuotaLimit, and kTooManyPasswords. + + // Stop observing the leak service in all terminal states. + observed_leak_check_.Remove(leak_service_); +} + +void SafetyCheckHandler::OnLeakFound( + const password_manager::LeakCheckCredential& credential) { + // Do nothing because we only want to know the total number of compromised + // credentials at the end of the bulk leak check. } void SafetyCheckHandler::OnJavascriptAllowed() {} -void SafetyCheckHandler::OnJavascriptDisallowed() {} +void SafetyCheckHandler::OnJavascriptDisallowed() { + // Remove |this| as an observer for BulkLeakCheck. This takes care of an edge + // case when the page is reloaded while the password check is in progress and + // another safety check is started. Otherwise |observed_leak_check_| + // automatically calls RemoveAll() on destruction. + observed_leak_check_.RemoveAll(); +} void SafetyCheckHandler::RegisterMessages() { web_ui()->RegisterMessageCallback(
diff --git a/chrome/browser/ui/webui/settings/safety_check_handler.h b/chrome/browser/ui/webui/settings/safety_check_handler.h index 7721fd5..4a20d23 100644 --- a/chrome/browser/ui/webui/settings/safety_check_handler.h +++ b/chrome/browser/ui/webui/settings/safety_check_handler.h
@@ -13,15 +13,17 @@ #include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/scoped_observer.h" #include "chrome/browser/ui/webui/help/version_updater.h" #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" - -class SafetyCheckHandlerObserver; +#include "components/password_manager/core/browser/bulk_leak_check_service.h" // Settings page UI handler that checks four areas of browser safety: // browser updates, password leaks, malicious extensions, and unwanted // software. -class SafetyCheckHandler : public settings::SettingsPageUIHandler { +class SafetyCheckHandler + : public settings::SettingsPageUIHandler, + public password_manager::BulkLeakCheckService::Observer { public: // Used in communication with the frontend to indicate which component the // communicated status update applies to. @@ -31,6 +33,9 @@ kSafeBrowsing, kExtensions, }; + // The following enums represent the state of each component of the safety + // check and should be kept in sync with the JS frontend + // (safety_check_browser_proxy.js). enum class UpdateStatus { kChecking, kUpdated, @@ -47,6 +52,17 @@ kDisabledByAdmin, kDisabledByExtension, }; + enum class PasswordsStatus { + kChecking, + kSafe, + kCompromisedExist, + kOffline, + kNoPasswords, + kSignedOut, + kQuotaLimit, + kTooManyPasswords, + kError, + }; SafetyCheckHandler(); ~SafetyCheckHandler() override; @@ -58,14 +74,14 @@ protected: SafetyCheckHandler(std::unique_ptr<VersionUpdater> version_updater, - SafetyCheckHandlerObserver* observer); + password_manager::BulkLeakCheckService* leak_service); private: // Handles triggering the safety check from the frontend (by user pressing a // button). void HandlePerformSafetyCheck(const base::ListValue* args); - // Triggers an update check and invokes the provided callback once results + // Triggers an update check and invokes OnUpdateCheckResult once results // are available. void CheckUpdates(); @@ -73,6 +89,10 @@ // OnSafeBrowsingCheckResult with results. void CheckSafeBrowsing(); + // Triggers a bulk password leak check and invokes OnPasswordsCheckResult once + // results are available. + void CheckPasswords(); + // Callbacks that get triggered when each check completes. void OnUpdateCheckResult(VersionUpdater::Status status, int progress, @@ -83,6 +103,14 @@ void OnSafeBrowsingCheckResult(SafeBrowsingStatus status); + void OnPasswordsCheckResult(PasswordsStatus status, int num_compromised); + + // BulkLeakCheckService::Observer implementation. + void OnStateChanged(password_manager::BulkLeakCheckService::State state, + size_t pending_credentials) override; + void OnLeakFound( + const password_manager::LeakCheckCredential& credential) override; + // SettingsPageUIHandler implementation. void OnJavascriptAllowed() override; void OnJavascriptDisallowed() override; @@ -91,7 +119,10 @@ void RegisterMessages() override; std::unique_ptr<VersionUpdater> version_updater_; - SafetyCheckHandlerObserver* const observer_; + password_manager::BulkLeakCheckService* leak_service_ = nullptr; + ScopedObserver<password_manager::BulkLeakCheckService, + password_manager::BulkLeakCheckService::Observer> + observed_leak_check_{this}; }; #endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_SAFETY_CHECK_HANDLER_H_
diff --git a/chrome/browser/ui/webui/settings/safety_check_handler_observer.h b/chrome/browser/ui/webui/settings/safety_check_handler_observer.h deleted file mode 100644 index b1fe68c..0000000 --- a/chrome/browser/ui/webui/settings/safety_check_handler_observer.h +++ /dev/null
@@ -1,27 +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 CHROME_BROWSER_UI_WEBUI_SETTINGS_SAFETY_CHECK_HANDLER_OBSERVER_H_ -#define CHROME_BROWSER_UI_WEBUI_SETTINGS_SAFETY_CHECK_HANDLER_OBSERVER_H_ - -#include "chrome/browser/ui/webui/help/version_updater.h" -#include "chrome/browser/ui/webui/settings/safety_check_handler.h" - -// Observer for SafetyCheckHandler events. Currently only used for testing. -class SafetyCheckHandlerObserver { - public: - SafetyCheckHandlerObserver() = default; - SafetyCheckHandlerObserver(const SafetyCheckHandlerObserver&) = delete; - SafetyCheckHandlerObserver& operator=(const SafetyCheckHandlerObserver&) = - delete; - virtual ~SafetyCheckHandlerObserver() = default; - - virtual void OnUpdateCheckStart() = 0; - virtual void OnUpdateCheckResult(SafetyCheckHandler::UpdateStatus status) = 0; - virtual void OnSafeBrowsingCheckStart() = 0; - virtual void OnSafeBrowsingCheckResult( - SafetyCheckHandler::SafeBrowsingStatus status) = 0; -}; - -#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_SAFETY_CHECK_HANDLER_OBSERVER_H_
diff --git a/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc b/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc index e1a9d18..c817164 100644 --- a/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc
@@ -7,46 +7,25 @@ #include "base/bind.h" #include "base/optional.h" #include "chrome/browser/ui/webui/help/test_version_updater.h" -#include "chrome/browser/ui/webui/settings/safety_check_handler_observer.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" +#include "components/password_manager/core/browser/bulk_leak_check_service.h" #include "components/prefs/pref_service.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "content/public/test/test_web_ui.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" #include "testing/gtest/include/gtest/gtest.h" -class TestSafetyCheckObserver : public SafetyCheckHandlerObserver { - public: - void OnUpdateCheckStart() override { update_check_started_ = true; } - - void OnUpdateCheckResult(SafetyCheckHandler::UpdateStatus status) override { - update_check_status_ = status; - } - - void OnSafeBrowsingCheckStart() override { - safe_browsing_check_started_ = true; - } - - void OnSafeBrowsingCheckResult( - SafetyCheckHandler::SafeBrowsingStatus status) override { - safe_browsing_check_status_ = status; - } - - bool update_check_started_ = false; - base::Optional<SafetyCheckHandler::UpdateStatus> update_check_status_; - bool safe_browsing_check_started_ = false; - base::Optional<SafetyCheckHandler::SafeBrowsingStatus> - safe_browsing_check_status_; -}; - class TestingSafetyCheckHandler : public SafetyCheckHandler { public: using SafetyCheckHandler::AllowJavascript; + using SafetyCheckHandler::DisallowJavascript; using SafetyCheckHandler::set_web_ui; - TestingSafetyCheckHandler(std::unique_ptr<VersionUpdater> version_updater, - SafetyCheckHandlerObserver* observer) - : SafetyCheckHandler(std::move(version_updater), observer) {} + TestingSafetyCheckHandler( + std::unique_ptr<VersionUpdater> version_updater, + password_manager::BulkLeakCheckService* leak_service) + : SafetyCheckHandler(std::move(version_updater), leak_service) {} }; class SafetyCheckHandlerTest : public ChromeRenderViewHostTestHarness { @@ -59,7 +38,7 @@ protected: TestVersionUpdater* version_updater_ = nullptr; - TestSafetyCheckObserver observer_; + std::unique_ptr<password_manager::BulkLeakCheckService> test_leak_service_; content::TestWebUI test_web_ui_; std::unique_ptr<TestingSafetyCheckHandler> safety_check_; }; @@ -71,10 +50,12 @@ // SafetyCheckHandler, but a raw pointer is retained here to change its // state. auto version_updater = std::make_unique<TestVersionUpdater>(); + test_leak_service_ = std::make_unique<password_manager::BulkLeakCheckService>( + nullptr, nullptr); version_updater_ = version_updater.get(); test_web_ui_.set_web_contents(web_contents()); safety_check_ = std::make_unique<TestingSafetyCheckHandler>( - std::move(version_updater), &observer_); + std::move(version_updater), test_leak_service_.get()); test_web_ui_.ClearTrackedCalls(); safety_check_->set_web_ui(&test_web_ui_); safety_check_->AllowJavascript(); @@ -108,18 +89,9 @@ return false; } -TEST_F(SafetyCheckHandlerTest, PerformSafetyCheck_AllChecksInvoked) { - safety_check_->PerformSafetyCheck(); - EXPECT_TRUE(observer_.update_check_started_); - EXPECT_TRUE(observer_.safe_browsing_check_started_); -} - TEST_F(SafetyCheckHandlerTest, CheckUpdates_Updated) { version_updater_->SetReturnedStatus(VersionUpdater::Status::UPDATED); safety_check_->PerformSafetyCheck(); - ASSERT_TRUE(observer_.update_check_status_.has_value()); - EXPECT_EQ(SafetyCheckHandler::UpdateStatus::kUpdated, - observer_.update_check_status_); EXPECT_TRUE(HasSafetyCheckStatusChangedWithData( static_cast<int>(SafetyCheckHandler::SafetyCheckComponent::kUpdates), static_cast<int>(SafetyCheckHandler::UpdateStatus::kUpdated))); @@ -129,9 +101,6 @@ version_updater_->SetReturnedStatus( VersionUpdater::Status::DISABLED_BY_ADMIN); safety_check_->PerformSafetyCheck(); - ASSERT_TRUE(observer_.update_check_status_.has_value()); - EXPECT_EQ(SafetyCheckHandler::UpdateStatus::kDisabledByAdmin, - observer_.update_check_status_); EXPECT_TRUE(HasSafetyCheckStatusChangedWithData( static_cast<int>(SafetyCheckHandler::SafetyCheckComponent::kUpdates), static_cast<int>(SafetyCheckHandler::UpdateStatus::kDisabledByAdmin))); @@ -142,9 +111,6 @@ ->GetPrefs() ->SetBoolean(prefs::kSafeBrowsingEnabled, true); safety_check_->PerformSafetyCheck(); - ASSERT_TRUE(observer_.safe_browsing_check_status_.has_value()); - EXPECT_EQ(SafetyCheckHandler::SafeBrowsingStatus::kEnabled, - observer_.safe_browsing_check_status_); EXPECT_TRUE(HasSafetyCheckStatusChangedWithData( static_cast<int>(SafetyCheckHandler::SafetyCheckComponent::kSafeBrowsing), static_cast<int>(SafetyCheckHandler::SafeBrowsingStatus::kEnabled))); @@ -155,9 +121,6 @@ ->GetPrefs() ->SetBoolean(prefs::kSafeBrowsingEnabled, false); safety_check_->PerformSafetyCheck(); - ASSERT_TRUE(observer_.safe_browsing_check_status_.has_value()); - EXPECT_EQ(SafetyCheckHandler::SafeBrowsingStatus::kDisabled, - observer_.safe_browsing_check_status_); EXPECT_TRUE(HasSafetyCheckStatusChangedWithData( static_cast<int>(SafetyCheckHandler::SafetyCheckComponent::kSafeBrowsing), static_cast<int>(SafetyCheckHandler::SafeBrowsingStatus::kDisabled))); @@ -170,9 +133,6 @@ ->SetManagedPref(prefs::kSafeBrowsingEnabled, std::make_unique<base::Value>(false)); safety_check_->PerformSafetyCheck(); - ASSERT_TRUE(observer_.safe_browsing_check_status_.has_value()); - EXPECT_EQ(SafetyCheckHandler::SafeBrowsingStatus::kDisabledByAdmin, - observer_.safe_browsing_check_status_); EXPECT_TRUE(HasSafetyCheckStatusChangedWithData( static_cast<int>(SafetyCheckHandler::SafetyCheckComponent::kSafeBrowsing), static_cast<int>( @@ -186,11 +146,73 @@ ->SetExtensionPref(prefs::kSafeBrowsingEnabled, std::make_unique<base::Value>(false)); safety_check_->PerformSafetyCheck(); - ASSERT_TRUE(observer_.safe_browsing_check_status_.has_value()); - EXPECT_EQ(SafetyCheckHandler::SafeBrowsingStatus::kDisabledByExtension, - observer_.safe_browsing_check_status_); EXPECT_TRUE(HasSafetyCheckStatusChangedWithData( static_cast<int>(SafetyCheckHandler::SafetyCheckComponent::kSafeBrowsing), static_cast<int>( SafetyCheckHandler::SafeBrowsingStatus::kDisabledByExtension))); } + +TEST_F(SafetyCheckHandlerTest, CheckPasswords_ObserverRemovedAfterError) { + safety_check_->PerformSafetyCheck(); + // First, a "running" change of state. + test_leak_service_->set_state_and_notify( + password_manager::BulkLeakCheckService::State::kRunning); + EXPECT_TRUE(HasSafetyCheckStatusChangedWithData( + static_cast<int>(SafetyCheckHandler::SafetyCheckComponent::kPasswords), + static_cast<int>(SafetyCheckHandler::PasswordsStatus::kChecking))); + // Second, an "offline" state. + test_leak_service_->set_state_and_notify( + password_manager::BulkLeakCheckService::State::kNetworkError); + EXPECT_TRUE(HasSafetyCheckStatusChangedWithData( + static_cast<int>(SafetyCheckHandler::SafetyCheckComponent::kPasswords), + static_cast<int>(SafetyCheckHandler::PasswordsStatus::kOffline))); + // Another error, but since the previous state is terminal, the handler should + // no longer be observing the BulkLeakCheckService state. + test_leak_service_->set_state_and_notify( + password_manager::BulkLeakCheckService::State::kServiceError); + EXPECT_TRUE(HasSafetyCheckStatusChangedWithData( + static_cast<int>(SafetyCheckHandler::SafetyCheckComponent::kPasswords), + static_cast<int>(SafetyCheckHandler::PasswordsStatus::kOffline))); +} + +TEST_F(SafetyCheckHandlerTest, CheckPasswords_InterruptedAndRefreshed) { + safety_check_->PerformSafetyCheck(); + // Password check running. + test_leak_service_->set_state_and_notify( + password_manager::BulkLeakCheckService::State::kRunning); + EXPECT_TRUE(HasSafetyCheckStatusChangedWithData( + static_cast<int>(SafetyCheckHandler::SafetyCheckComponent::kPasswords), + static_cast<int>(SafetyCheckHandler::PasswordsStatus::kChecking))); + // The check gets interrupted and the page is refreshed. + safety_check_->DisallowJavascript(); + safety_check_->AllowJavascript(); + // Another run of the safety check. + safety_check_->PerformSafetyCheck(); + test_leak_service_->set_state_and_notify( + password_manager::BulkLeakCheckService::State::kRunning); + EXPECT_TRUE(HasSafetyCheckStatusChangedWithData( + static_cast<int>(SafetyCheckHandler::SafetyCheckComponent::kPasswords), + static_cast<int>(SafetyCheckHandler::PasswordsStatus::kChecking))); + test_leak_service_->set_state_and_notify( + password_manager::BulkLeakCheckService::State::kNetworkError); + EXPECT_TRUE(HasSafetyCheckStatusChangedWithData( + static_cast<int>(SafetyCheckHandler::SafetyCheckComponent::kPasswords), + static_cast<int>(SafetyCheckHandler::PasswordsStatus::kOffline))); +} + +TEST_F(SafetyCheckHandlerTest, CheckPasswords_StartedTwice) { + safety_check_->PerformSafetyCheck(); + safety_check_->PerformSafetyCheck(); + // First, a "running" change of state. + test_leak_service_->set_state_and_notify( + password_manager::BulkLeakCheckService::State::kRunning); + EXPECT_TRUE(HasSafetyCheckStatusChangedWithData( + static_cast<int>(SafetyCheckHandler::SafetyCheckComponent::kPasswords), + static_cast<int>(SafetyCheckHandler::PasswordsStatus::kChecking))); + // Second, an "offline" state. + test_leak_service_->set_state_and_notify( + password_manager::BulkLeakCheckService::State::kNetworkError); + EXPECT_TRUE(HasSafetyCheckStatusChangedWithData( + static_cast<int>(SafetyCheckHandler::SafetyCheckComponent::kPasswords), + static_cast<int>(SafetyCheckHandler::PasswordsStatus::kOffline))); +}
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index 2f2a4490..13e2f496 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -883,15 +883,15 @@ Profile* profile) { #if defined(OS_CHROMEOS) bool is_dice_enabled = false; - bool is_split_settings_sync_enabled = - chromeos::features::IsSplitSettingsSyncEnabled(); + bool is_split_sync_consent_enabled = + chromeos::features::IsSplitSyncConsentEnabled(); #else bool is_dice_enabled = AccountConsistencyModeManager::IsDiceEnabledForProfile(profile); - bool is_split_settings_sync_enabled = false; + bool is_split_sync_consent_enabled = false; #endif - if (is_split_settings_sync_enabled || is_dice_enabled) { + if (is_split_sync_consent_enabled || is_dice_enabled) { static constexpr webui::LocalizedString kTurnOffStrings[] = { {"syncDisconnect", IDS_SETTINGS_PEOPLE_SYNC_TURN_OFF}, {"syncDisconnectTitle", @@ -1126,8 +1126,6 @@ IDS_SETTINGS_SAFETY_CHECK_UPDATES_SUB_LABEL_FAILED_OFFLINE}, {"safetyCheckUpdatesSubLabelFailed", IDS_SETTINGS_SAFETY_CHECK_UPDATES_SUB_LABEL_FAILED}, - {"safetyCheckPasswordsPrimaryLabel", - IDS_SETTINGS_SAFETY_CHECK_PASSWORDS_PRIMARY_LABEL}, {"safetyCheckPasswordsSubLabelSafe", IDS_SAFETY_CHECK_PASSWORDS_SUB_LABEL_SAFE}, {"safetyCheckPasswordsSubLabelCompromisedSingular", @@ -1150,6 +1148,16 @@ IDS_SAFETY_CHECK_PASSWORDS_BUTTON_COMPROMISED}, {"safetyCheckPasswordsButtonError", IDS_SAFETY_CHECK_PASSWORDS_BUTTON_ERROR}, + {"safetyCheckSafeBrowsingSubLabelEnabled", + IDS_SETTINGS_SAFETY_CHECK_SAFE_BROWSING_SUB_LABEL_ENABLED}, + {"safetyCheckSafeBrowsingSubLabelDisabled", + IDS_SETTINGS_SAFETY_CHECK_SAFE_BROWSING_SUB_LABEL_DISABLED}, + {"safetyCheckSafeBrowsingSubLabelDisabledByAdmin", + IDS_SETTINGS_SAFETY_CHECK_SAFE_BROWSING_SUB_LABEL_DISABLED_BY_ADMIN}, + {"safetyCheckSafeBrowsingSubLabelDisabledByExtension", + IDS_SETTINGS_SAFETY_CHECK_SAFE_BROWSING_SUB_LABEL_DISABLED_BY_EXTENSION}, + {"safetyCheckSafeBrowsingButton", + IDS_SETTINGS_SAFETY_CHECK_SAFE_BROWSING_BUTTON}, {"safetyCheckExtensionsPrimaryLabel", IDS_SETTINGS_SAFETY_CHECK_EXTENSIONS_PRIMARY_LABEL}, {"safetyCheckExtensionsSubLabelError",
diff --git a/chrome/browser/ui/webui/settings/settings_ui.cc b/chrome/browser/ui/webui/settings/settings_ui.cc index da445d8..b6702e7 100644 --- a/chrome/browser/ui/webui/settings/settings_ui.cc +++ b/chrome/browser/ui/webui/settings/settings_ui.cc
@@ -280,6 +280,8 @@ #if defined(OS_CHROMEOS) html_source->AddBoolean("splitSettingsSyncEnabled", chromeos::features::IsSplitSettingsSyncEnabled()); + html_source->AddBoolean("splitSyncConsent", + chromeos::features::IsSplitSyncConsentEnabled()); html_source->AddBoolean( "userCannotManuallyEnterPassword",
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni index 5121fa7..4bddb4a2 100644 --- a/chrome/chrome_paks.gni +++ b/chrome/chrome_paks.gni
@@ -128,6 +128,7 @@ "$root_gen_dir/chrome/component_extension_resources.pak", "$root_gen_dir/chrome/dev_ui_resources.pak", "$root_gen_dir/chrome/downloads_resources.pak", + "$root_gen_dir/chrome/gaia_auth_host_resources.pak", "$root_gen_dir/chrome/history_resources.pak", "$root_gen_dir/chrome/local_ntp_resources.pak", "$root_gen_dir/chrome/new_tab_page_resources.pak", @@ -140,6 +141,7 @@ "//chrome/browser/resources:component_extension_resources", "//chrome/browser/resources:dev_ui_paks", "//chrome/browser/resources:downloads_resources", + "//chrome/browser/resources:gaia_auth_host_resources", "//chrome/browser/resources:history_resources", "//chrome/browser/resources:local_ntp_resources", "//chrome/browser/resources:new_tab_page_resources",
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc index 6e32f3d..1640e0c 100644 --- a/chrome/common/url_constants.cc +++ b/chrome/common/url_constants.cc
@@ -359,7 +359,10 @@ const char kOemEulaURLPath[] = "oem"; const char kOnlineEulaURLPath[] = - "https://www.google.com/intl/%s/chrome/eula_text.html"; + "https://policies.google.com/terms/embedded?hl=%s"; + +const char kAdditionalToSOnlineURLPath[] = + "https://www.google.com/intl/%s/chrome/terms/"; const char kOsSettingsSearchHelpURL[] = "https://support.google.com/chromebook/?p=settings_search_help";
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h index de5ef3c4..93ad5152 100644 --- a/chrome/common/url_constants.h +++ b/chrome/common/url_constants.h
@@ -320,6 +320,8 @@ extern const char kOnlineEulaURLPath[]; +extern const char kAdditionalToSOnlineURLPath[]; + // The URL for the "learn more" link for TPM firmware update. extern const char kTPMFirmwareUpdateLearnMoreURL[];
diff --git a/chrome/installer/util/install_service_work_item_unittest.cc b/chrome/installer/util/install_service_work_item_unittest.cc index b0727a53..5021569e 100644 --- a/chrome/installer/util/install_service_work_item_unittest.cc +++ b/chrome/installer/util/install_service_work_item_unittest.cc
@@ -154,7 +154,7 @@ EXPECT_EQ(0UL, GetImpl(item.get())->GetCurrentServiceName().find(kServiceName)); - EXPECT_EQ(ERROR_SUCCESS, key.DeleteKey(L"")); + EXPECT_EQ(ERROR_SUCCESS, key.DeleteValue(kServiceName)); } } // namespace installer
diff --git a/chrome/renderer/autofill/autofill_renderer_browsertest.cc b/chrome/renderer/autofill/autofill_renderer_browsertest.cc index d960f0d..f83951e 100644 --- a/chrome/renderer/autofill/autofill_renderer_browsertest.cc +++ b/chrome/renderer/autofill/autofill_renderer_browsertest.cc
@@ -117,6 +117,8 @@ void DidPreviewAutofillFormData() override {} + void DidEndTextFieldEditing() override {} + void SetDataList(const std::vector<base::string16>& values, const std::vector<base::string16>& labels) override {}
diff --git a/chrome/renderer/autofill/form_autocomplete_browsertest.cc b/chrome/renderer/autofill/form_autocomplete_browsertest.cc index c90ffc5..96bea1d 100644 --- a/chrome/renderer/autofill/form_autocomplete_browsertest.cc +++ b/chrome/renderer/autofill/form_autocomplete_browsertest.cc
@@ -105,6 +105,8 @@ void DidPreviewAutofillFormData() override {} + void DidEndTextFieldEditing() override {} + void SetDataList(const std::vector<base::string16>& values, const std::vector<base::string16>& labels) override {}
diff --git a/chrome/renderer/sync_encryption_keys_extension.cc b/chrome/renderer/sync_encryption_keys_extension.cc index edde01c3..a21eb18 100644 --- a/chrome/renderer/sync_encryption_keys_extension.cc +++ b/chrome/renderer/sync_encryption_keys_extension.cc
@@ -157,9 +157,8 @@ int last_key_version = 0; if (!args->GetNext(&last_key_version)) { DLOG(ERROR) << "No version provided"; - // TODO(crbug.com/1032485): Be more strict here and issue an error if the - // version is not provided. - last_key_version = static_cast<int>(encryption_keys.size()) - 1; + args->ThrowError(); + return; } auto global_callback =
diff --git a/chrome/test/data/webui/settings/people_page_test.js b/chrome/test/data/webui/settings/people_page_test.js index da13be0b..ebcd807 100644 --- a/chrome/test/data/webui/settings/people_page_test.js +++ b/chrome/test/data/webui/settings/people_page_test.js
@@ -646,10 +646,11 @@ }); }); - suite('Chrome OS with SplitSettingsSync', function() { + suite('Chrome OS with SplitSyncConsent', function() { suiteSetup(function() { loadTimeData.overrideValues({ splitSettingsSyncEnabled: true, + splitSyncConsent: true, }); });
diff --git a/chrome/test/data/webui/settings/safety_check_page_test.js b/chrome/test/data/webui/settings/safety_check_page_test.js index 28d85de..ee5fc75 100644 --- a/chrome/test/data/webui/settings/safety_check_page_test.js +++ b/chrome/test/data/webui/settings/safety_check_page_test.js
@@ -163,6 +163,56 @@ } }); + test('safeBrowsingCheckingUiTest', function() { + cr.webUIListenerCallback('safety-check-status-changed', { + safetyCheckComponent: settings.SafetyCheckComponent.SAFE_BROWSING, + newState: settings.SafetyCheckSafeBrowsingStatus.CHECKING, + }); + Polymer.dom.flush(); + assertFalse(!!page.$$('#safetyCheckSafeBrowsingButton')); + assertFalse(!!page.$$('#safetyCheckSafeBrowsingManagedIcon')); + }); + + test('safeBrowsingCheckingUiTest', function() { + cr.webUIListenerCallback('safety-check-status-changed', { + safetyCheckComponent: settings.SafetyCheckComponent.SAFE_BROWSING, + newState: settings.SafetyCheckSafeBrowsingStatus.ENABLED, + }); + Polymer.dom.flush(); + assertFalse(!!page.$$('#safetyCheckSafeBrowsingButton')); + assertFalse(!!page.$$('#safetyCheckSafeBrowsingManagedIcon')); + }); + + test('safeBrowsingCheckingUiTest', function() { + cr.webUIListenerCallback('safety-check-status-changed', { + safetyCheckComponent: settings.SafetyCheckComponent.SAFE_BROWSING, + newState: settings.SafetyCheckSafeBrowsingStatus.DISABLED, + }); + Polymer.dom.flush(); + assertTrue(!!page.$$('#safetyCheckSafeBrowsingButton')); + assertFalse(!!page.$$('#safetyCheckSafeBrowsingManagedIcon')); + }); + + test('safeBrowsingCheckingUiTest', function() { + cr.webUIListenerCallback('safety-check-status-changed', { + safetyCheckComponent: settings.SafetyCheckComponent.SAFE_BROWSING, + newState: settings.SafetyCheckSafeBrowsingStatus.DISABLED_BY_ADMIN, + }); + Polymer.dom.flush(); + assertFalse(!!page.$$('#safetyCheckSafeBrowsingButton')); + assertTrue(!!page.$$('#safetyCheckSafeBrowsingManagedIcon')); + }); + + test('safeBrowsingCheckingUiTest', function() { + cr.webUIListenerCallback('safety-check-status-changed', { + safetyCheckComponent: settings.SafetyCheckComponent.SAFE_BROWSING, + newState: settings.SafetyCheckSafeBrowsingStatus.DISABLED_BY_EXTENSION, + }); + Polymer.dom.flush(); + assertFalse(!!page.$$('#safetyCheckSafeBrowsingButton')); + assertTrue(!!page.$$('#safetyCheckSafeBrowsingManagedIcon')); + }); + test('extensionsCheckingUiTest', function() { cr.webUIListenerCallback('safety-check-status-changed', { safetyCheckComponent: settings.SafetyCheckComponent.EXTENSIONS,
diff --git a/chromecast/browser/cast_web_contents.h b/chromecast/browser/cast_web_contents.h index fc44ff5b..7376fa73 100644 --- a/chromecast/browser/cast_web_contents.h +++ b/chromecast/browser/cast_web_contents.h
@@ -16,6 +16,7 @@ #include "base/strings/string16.h" #include "base/strings/string_piece_forward.h" #include "chromecast/common/mojom/feature_manager.mojom.h" +#include "content/public/common/media_playback_renderer_type.mojom.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/common/messaging/web_message_port.h" @@ -204,7 +205,8 @@ // debugging interfaces. bool enabled_for_dev = false; // Chooses a media renderer for the WebContents. - bool use_cma_renderer = false; + content::mojom::RendererType renderer_type = + content::mojom::RendererType::DEFAULT_RENDERER; // Whether the WebContents is a root native window, or if it is embedded in // another WebContents (see Delegate::InnerContentsCreated()). bool is_root_window = false;
diff --git a/chromecast/browser/cast_web_contents_impl.cc b/chromecast/browser/cast_web_contents_impl.cc index 21d3c2f..d7160be 100644 --- a/chromecast/browser/cast_web_contents_impl.cc +++ b/chromecast/browser/cast_web_contents_impl.cc
@@ -137,7 +137,7 @@ page_state_(PageState::IDLE), last_state_(PageState::IDLE), enabled_for_dev_(init_params.enabled_for_dev), - use_cma_renderer_(init_params.use_cma_renderer), + renderer_type_(init_params.renderer_type), handle_inner_contents_(init_params.handle_inner_contents), view_background_color_(init_params.background_color), remote_debugging_server_( @@ -175,8 +175,9 @@ } // TODO(yucliu): Change the flag name to kDisableCmaRenderer in a latter diff. - if (GetSwitchValueBoolean(switches::kDisableMojoRenderer, false)) { - use_cma_renderer_ = false; + if (GetSwitchValueBoolean(switches::kDisableMojoRenderer, false) && + renderer_type_ == content::mojom::RendererType::MOJO_RENDERER) { + renderer_type_ = content::mojom::RendererType::DEFAULT_RENDERER; } // Provides QueryableDataHostCast if the new QueryableData bindings is not @@ -482,7 +483,7 @@ media_playback_options; render_frame_host->GetRemoteAssociatedInterfaces()->GetInterface( &media_playback_options); - media_playback_options->SetUseCmaRenderer(use_cma_renderer_); + media_playback_options->SetRendererType(renderer_type_); // Send queryable values mojo::Remote<chromecast::shell::mojom::QueryableDataStore>
diff --git a/chromecast/browser/cast_web_contents_impl.h b/chromecast/browser/cast_web_contents_impl.h index 53664ad..63b59c3 100644 --- a/chromecast/browser/cast_web_contents_impl.h +++ b/chromecast/browser/cast_web_contents_impl.h
@@ -26,6 +26,7 @@ #include "content/public/browser/render_process_host_observer.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" +#include "content/public/common/media_playback_renderer_type.mojom.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/mojom/favicon/favicon_url.mojom-forward.h" @@ -165,7 +166,7 @@ PageState page_state_; PageState last_state_; const bool enabled_for_dev_; - bool use_cma_renderer_; + content::mojom::RendererType renderer_type_; const bool handle_inner_contents_; BackgroundColor view_background_color_; shell::RemoteDebuggingServer* const remote_debugging_server_;
diff --git a/chromecast/browser/test/cast_browser_test.cc b/chromecast/browser/test/cast_browser_test.cc index 5f9300e4..6cbad71 100644 --- a/chromecast/browser/test/cast_browser_test.cc +++ b/chromecast/browser/test/cast_browser_test.cc
@@ -18,6 +18,7 @@ #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_switches.h" +#include "content/public/common/media_playback_renderer_type.mojom.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_navigation_observer.h" @@ -60,7 +61,9 @@ CastWebView::CreateParams params; params.delegate = weak_factory_.GetWeakPtr(); params.web_contents_params.delegate = weak_factory_.GetWeakPtr(); - params.web_contents_params.use_cma_renderer = true; + // MOJO_RENDERER is CMA renderer on Chromecast + params.web_contents_params.renderer_type = + content::mojom::RendererType::MOJO_RENDERER; params.web_contents_params.enabled_for_dev = true; params.window_params.delegate = weak_factory_.GetWeakPtr(); cast_web_view_ =
diff --git a/chromecast/common/mojom/BUILD.gn b/chromecast/common/mojom/BUILD.gn index dbce21a0..f2a4e10 100644 --- a/chromecast/common/mojom/BUILD.gn +++ b/chromecast/common/mojom/BUILD.gn
@@ -20,5 +20,8 @@ "service_connector.mojom", ] - public_deps = [ "//mojo/public/mojom/base" ] + public_deps = [ + "//content/public/common:renderer_type", + "//mojo/public/mojom/base", + ] }
diff --git a/chromecast/common/mojom/media_playback_options.mojom b/chromecast/common/mojom/media_playback_options.mojom index 3de812017..8f94e2d 100644 --- a/chromecast/common/mojom/media_playback_options.mojom +++ b/chromecast/common/mojom/media_playback_options.mojom
@@ -4,17 +4,18 @@ module chromecast.shell.mojom; +import "content/public/common/media_playback_renderer_type.mojom"; + // Receives messages from browser process to control media playback options // (block loading, background playback) for a specific RenderFrame. // Implemented by a RenderFrameObserver. interface MediaPlaybackOptions { + // Set true to enable background suspend SetMediaLoadingBlocked(bool blocked); + // Set true to allow video playback to be played in the background SetBackgroundVideoPlaybackEnabled(bool enabled); - // Enable CMA (MojoRenderer) for media playback. - // Otherwise, media playback uses RendererImpl, which is the same as other - // platforms. For video codec supported by v4l2 (e.g. h264), it's still - // accelerated by hardware. Video will be rendererd on graphics plane. - SetUseCmaRenderer(bool enabled); + // Set the renderer type that will be used in WebMediaPlayerImpl + SetRendererType(content.mojom.RendererType type); };
diff --git a/chromecast/renderer/cast_media_playback_options.cc b/chromecast/renderer/cast_media_playback_options.cc index 83b4c68..ca30ebd3 100644 --- a/chromecast/renderer/cast_media_playback_options.cc +++ b/chromecast/renderer/cast_media_playback_options.cc
@@ -78,8 +78,9 @@ renderer_media_playback_options_); } -void CastMediaPlaybackOptions::SetUseCmaRenderer(bool enable) { - renderer_media_playback_options_.is_mojo_renderer_enabled = enable; +void CastMediaPlaybackOptions::SetRendererType( + content::mojom::RendererType type) { + renderer_media_playback_options_.renderer_type = type; render_frame()->SetRenderFrameMediaPlaybackOptions( renderer_media_playback_options_); }
diff --git a/chromecast/renderer/cast_media_playback_options.h b/chromecast/renderer/cast_media_playback_options.h index 1531494..9d26773 100644 --- a/chromecast/renderer/cast_media_playback_options.h +++ b/chromecast/renderer/cast_media_playback_options.h
@@ -11,6 +11,7 @@ #include "base/callback_forward.h" #include "base/sequence_checker.h" #include "chromecast/common/mojom/media_playback_options.mojom.h" +#include "content/public/common/media_playback_renderer_type.mojom.h" #include "content/public/renderer/render_frame_media_playback_options.h" #include "content/public/renderer/render_frame_observer.h" #include "content/public/renderer/render_frame_observer_tracker.h" @@ -49,7 +50,7 @@ // MediaPlaybackOptions implementation void SetMediaLoadingBlocked(bool blocked) override; void SetBackgroundVideoPlaybackEnabled(bool enabled) override; - void SetUseCmaRenderer(bool enable) override; + void SetRendererType(content::mojom::RendererType type) override; void OnMediaPlaybackOptionsAssociatedReceiver( mojo::PendingAssociatedReceiver<
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc index 4397488..ebaa8cf0 100644 --- a/chromeos/constants/chromeos_features.cc +++ b/chromeos/constants/chromeos_features.cc
@@ -288,6 +288,14 @@ const base::Feature kSplitSettingsSync{"SplitSettingsSync", base::FEATURE_DISABLED_BY_DEFAULT}; +// Introduces a new OOBE dialog for the OS sync feature. Uses the same browser +// sync consent dialog as Windows/Mac/Linux. Allows the user to fully opt-out of +// browser sync, including marking the signin primary account as unconsented. +// Requires SplitSettingsSync. +// NOTE: Use IsSplitSyncConsentEnabled() to test the flag, see implementation. +const base::Feature kSplitSyncConsent{"SplitSyncConsent", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Enables unified media view in Files app to browse recently-modified media // files from local local, Google Drive, and Android. const base::Feature kUnifiedMediaView{"UnifiedMediaView", @@ -365,6 +373,12 @@ return base::FeatureList::IsEnabled(kSplitSettingsSync); } +bool IsSplitSyncConsentEnabled() { + // SplitSyncConsent requires SplitSettingsSync. + return base::FeatureList::IsEnabled(kSplitSettingsSync) && + base::FeatureList::IsEnabled(kSplitSyncConsent); +} + bool ShouldShowPlayStoreInDemoMode() { return base::FeatureList::IsEnabled(kShowPlayInDemoMode); }
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h index 9e0ac01..5d8ff98 100644 --- a/chromeos/constants/chromeos_features.h +++ b/chromeos/constants/chromeos_features.h
@@ -132,6 +132,9 @@ extern const base::Feature kSmartDimModelV3; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kSplitSettingsSync; +// Visible for testing. Use IsSplitSyncConsentEnabled() to check the flag. +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) +extern const base::Feature kSplitSyncConsent; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kUnifiedMediaView; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) @@ -163,6 +166,7 @@ COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsQuickAnswersEnabled(); COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsQuickAnswersRichUiEnabled(); COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsSplitSettingsSyncEnabled(); +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsSplitSyncConsentEnabled(); // TODO(michaelpg): Remove after M71 branch to re-enable Play Store by default. COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool ShouldShowPlayStoreInDemoMode();
diff --git a/components/autofill/content/browser/content_autofill_driver.cc b/components/autofill/content/browser/content_autofill_driver.cc index 1f9831a..df274c3 100644 --- a/components/autofill/content/browser/content_autofill_driver.cc +++ b/components/autofill/content/browser/content_autofill_driver.cc
@@ -285,6 +285,10 @@ autofill_handler_->OnDidPreviewAutofillFormData(); } +void ContentAutofillDriver::DidEndTextFieldEditing() { + autofill_handler_->OnDidEndTextFieldEditing(); +} + void ContentAutofillDriver::SetDataList( const std::vector<base::string16>& values, const std::vector<base::string16>& labels) {
diff --git a/components/autofill/content/browser/content_autofill_driver.h b/components/autofill/content/browser/content_autofill_driver.h index d62b3c40..9597492 100644 --- a/components/autofill/content/browser/content_autofill_driver.h +++ b/components/autofill/content/browser/content_autofill_driver.h
@@ -116,6 +116,7 @@ void DidFillAutofillFormData(const FormData& form, base::TimeTicks timestamp) override; void DidPreviewAutofillFormData() override; + void DidEndTextFieldEditing() override; void SetDataList(const std::vector<base::string16>& values, const std::vector<base::string16>& labels) override; void SelectFieldOptionsDidChange(const FormData& form) override;
diff --git a/components/autofill/content/common/mojom/autofill_driver.mojom b/components/autofill/content/common/mojom/autofill_driver.mojom index 23844f9..3aa538b 100644 --- a/components/autofill/content/common/mojom/autofill_driver.mojom +++ b/components/autofill/content/common/mojom/autofill_driver.mojom
@@ -69,6 +69,9 @@ // Sent when a form is previewed with Autofill suggestions. DidPreviewAutofillFormData(); + // Sent when a text field is done editing. + DidEndTextFieldEditing(); + // Informs browser of data list values for the current field. SetDataList(array<mojo_base.mojom.String16> values, array<mojo_base.mojom.String16> labels);
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc index 3c6fa39..9f8a720 100644 --- a/components/autofill/content/renderer/autofill_agent.cc +++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -319,6 +319,7 @@ password_generation_agent_->ShouldIgnoreBlur()) { return; } + GetAutofillDriver()->DidEndTextFieldEditing(); password_autofill_agent_->DidEndTextFieldEditing(); if (password_generation_agent_) password_generation_agent_->DidEndTextFieldEditing(element);
diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc index 82575f6..411034a 100644 --- a/components/autofill/core/browser/autofill_external_delegate.cc +++ b/components/autofill/core/browser/autofill_external_delegate.cc
@@ -311,6 +311,10 @@ return false; } +void AutofillExternalDelegate::DidEndTextFieldEditing() { + manager_->client()->HideAutofillPopup(PopupHidingReason::kEndEditing); +} + void AutofillExternalDelegate::ClearPreviewedForm() { driver_->RendererShouldClearPreviewedForm(); }
diff --git a/components/autofill/core/browser/autofill_external_delegate.h b/components/autofill/core/browser/autofill_external_delegate.h index cf68744..b54e4e7 100644 --- a/components/autofill/core/browser/autofill_external_delegate.h +++ b/components/autofill/core/browser/autofill_external_delegate.h
@@ -94,6 +94,10 @@ const std::vector<base::string16>& data_list_values, const std::vector<base::string16>& data_list_labels); + // Inform the delegate that the text field editing has ended. This is + // used to help record the metrics of when a new popup is shown. + void DidEndTextFieldEditing(); + // Returns the delegate to its starting state by removing any page specific // values or settings. void Reset();
diff --git a/components/autofill/core/browser/autofill_external_delegate_unittest.cc b/components/autofill/core/browser/autofill_external_delegate_unittest.cc index c5e4b79..7adcb7a5 100644 --- a/components/autofill/core/browser/autofill_external_delegate_unittest.cc +++ b/components/autofill/core/browser/autofill_external_delegate_unittest.cc
@@ -572,6 +572,17 @@ POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY); } +// Test that the popup is hidden once we are done editing the autofill field. +TEST_F(AutofillExternalDelegateUnitTest, + ExternalDelegateHidePopupAfterEditing) { + EXPECT_CALL(autofill_client_, ShowAutofillPopup); + test::GenerateTestAutofillPopup(external_delegate_.get()); + + EXPECT_CALL(autofill_client_, + HideAutofillPopup(autofill::PopupHidingReason::kEndEditing)); + external_delegate_->DidEndTextFieldEditing(); +} + // Test that the driver is directed to accept the data list after being notified // that the user accepted the data list suggestion. TEST_F(AutofillExternalDelegateUnitTest,
diff --git a/components/autofill/core/browser/autofill_handler.h b/components/autofill/core/browser/autofill_handler.h index bc4c95f..32dc40af 100644 --- a/components/autofill/core/browser/autofill_handler.h +++ b/components/autofill/core/browser/autofill_handler.h
@@ -102,6 +102,9 @@ // Invoked when preview autofill value has been shown. virtual void OnDidPreviewAutofillFormData() = 0; + // Invoked when textfeild editing ended + virtual void OnDidEndTextFieldEditing() = 0; + // Invoked when popup window should be hidden. virtual void OnHidePopup() = 0;
diff --git a/components/autofill/core/browser/autofill_handler_proxy.cc b/components/autofill/core/browser/autofill_handler_proxy.cc index 5b2fe15..8a9fcaf4 100644 --- a/components/autofill/core/browser/autofill_handler_proxy.cc +++ b/components/autofill/core/browser/autofill_handler_proxy.cc
@@ -86,6 +86,8 @@ void AutofillHandlerProxy::OnDidPreviewAutofillFormData() {} +void AutofillHandlerProxy::OnDidEndTextFieldEditing() {} + void AutofillHandlerProxy::OnHidePopup() {} void AutofillHandlerProxy::OnSetDataList(
diff --git a/components/autofill/core/browser/autofill_handler_proxy.h b/components/autofill/core/browser/autofill_handler_proxy.h index cf3b247..152292c 100644 --- a/components/autofill/core/browser/autofill_handler_proxy.h +++ b/components/autofill/core/browser/autofill_handler_proxy.h
@@ -26,6 +26,7 @@ const base::TimeTicks timestamp) override; void OnDidPreviewAutofillFormData() override; + void OnDidEndTextFieldEditing() override; void OnHidePopup() override; void OnSetDataList(const std::vector<base::string16>& values, const std::vector<base::string16>& labels) override;
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index 4b23493..cc33f645 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc
@@ -1416,6 +1416,10 @@ credit_card_field_, *credit_card, cvc); } +void AutofillManager::OnDidEndTextFieldEditing() { + external_delegate_->DidEndTextFieldEditing(); +} + bool AutofillManager::IsAutofillEnabled() const { return IsAutofillProfileEnabled() || IsAutofillCreditCardEnabled(); }
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h index 8690596..348bf3bf 100644 --- a/components/autofill/core/browser/autofill_manager.h +++ b/components/autofill/core/browser/autofill_manager.h
@@ -226,6 +226,7 @@ void OnDidFillAutofillFormData(const FormData& form, const base::TimeTicks timestamp) override; void OnDidPreviewAutofillFormData() override; + void OnDidEndTextFieldEditing() override; void OnHidePopup() override; void OnSetDataList(const std::vector<base::string16>& values, const std::vector<base::string16>& labels) override;
diff --git a/components/autofill/core/browser/ui/popup_types.h b/components/autofill/core/browser/ui/popup_types.h index 5942255..1656116 100644 --- a/components/autofill/core/browser/ui/popup_types.h +++ b/components/autofill/core/browser/ui/popup_types.h
@@ -23,7 +23,8 @@ enum class PopupHidingReason { kAcceptSuggestion, // A suggestion was accepted. kAttachInterstitialPage, // An interstitial page displaces the popup. - kFocusChanged, // Focus removed from field. + kEndEditing, // A field isn't edited anymore but remains focused for now. + kFocusChanged, // Focus removed from field. Follows kEndEditing. kContentAreaMoved, // Scrolling or zooming into the page displaces popup. kNavigation, // A navigation on page or frame level. kNoSuggestions, // The popup is or would become empty.
diff --git a/components/autofill_assistant/browser/web/web_controller_browsertest.cc b/components/autofill_assistant/browser/web/web_controller_browsertest.cc index 8acebe3..131487c 100644 --- a/components/autofill_assistant/browser/web/web_controller_browsertest.cc +++ b/components/autofill_assistant/browser/web/web_controller_browsertest.cc
@@ -1483,9 +1483,10 @@ Selector document_element({"#full_height_section"}); EXPECT_TRUE(GetElementPosition(document_element, &document_element_rect)); - // This element must be after the full_height_section! + // The iFrame must be after the #full_height_section element to check that + // the resulting rect is global. RectF iframe_element_rect; - Selector iframe_element({"#iframe", "#touch_area"}); + Selector iframe_element({"#iframe", "#touch_area_1"}); EXPECT_TRUE(GetElementPosition(iframe_element, &iframe_element_rect)); EXPECT_GT(iframe_element_rect.top, document_element_rect.bottom);
diff --git a/components/invalidation/impl/single_object_invalidation_set_unittest.cc b/components/invalidation/impl/single_object_invalidation_set_unittest.cc index 7643b6c..f343101 100644 --- a/components/invalidation/impl/single_object_invalidation_set_unittest.cc +++ b/components/invalidation/impl/single_object_invalidation_set_unittest.cc
@@ -74,39 +74,6 @@ EXPECT_FALSE(list.StartsWithUnknownVersion()); } -TEST_F(SingleObjectInvalidationSetTest, SerializeEmpty) { - SingleObjectInvalidationSet list; - - std::unique_ptr<base::ListValue> value = list.ToValue(); - ASSERT_TRUE(value.get()); - SingleObjectInvalidationSet deserialized; - deserialized.ResetFromValue(*value); - EXPECT_TRUE(list == deserialized); -} - -TEST_F(SingleObjectInvalidationSetTest, SerializeOne) { - SingleObjectInvalidationSet list; - list.Insert(Invalidation::Init(kId, 1, "one")); - - std::unique_ptr<base::ListValue> value = list.ToValue(); - ASSERT_TRUE(value.get()); - SingleObjectInvalidationSet deserialized; - deserialized.ResetFromValue(*value); - EXPECT_TRUE(list == deserialized); -} - -TEST_F(SingleObjectInvalidationSetTest, SerializeMany) { - SingleObjectInvalidationSet list; - list.Insert(Invalidation::Init(kId, 1, "one")); - list.Insert(Invalidation::InitUnknownVersion(kId)); - - std::unique_ptr<base::ListValue> value = list.ToValue(); - ASSERT_TRUE(value.get()); - SingleObjectInvalidationSet deserialized; - deserialized.ResetFromValue(*value); - EXPECT_TRUE(list == deserialized); -} - } // namespace } // namespace syncer
diff --git a/components/invalidation/public/invalidation.cc b/components/invalidation/public/invalidation.cc index e6ec0da..6ca9a9a 100644 --- a/components/invalidation/public/invalidation.cc +++ b/components/invalidation/public/invalidation.cc
@@ -59,42 +59,6 @@ dropped.id_, true, kInvalidVersion, std::string(), dropped.ack_handle_); } -// static -std::unique_ptr<Invalidation> Invalidation::InitFromValue( - const base::DictionaryValue& value) { - invalidation::ObjectId id; - - const base::DictionaryValue* object_id_dict; - if (!value.GetDictionary(kObjectIdKey, &object_id_dict) || - !ObjectIdFromValue(*object_id_dict, &id)) { - DLOG(WARNING) << "Failed to parse id"; - return nullptr; - } - bool is_unknown_version; - if (!value.GetBoolean(kIsUnknownVersionKey, &is_unknown_version)) { - DLOG(WARNING) << "Failed to parse is_unknown_version flag"; - return nullptr; - } - if (is_unknown_version) { - return base::WrapUnique(new Invalidation( - id, true, kInvalidVersion, std::string(), AckHandle::CreateUnique())); - } - int64_t version = 0; - std::string version_as_string; - if (!value.GetString(kVersionKey, &version_as_string) - || !base::StringToInt64(version_as_string, &version)) { - DLOG(WARNING) << "Failed to parse version"; - return nullptr; - } - std::string payload; - if (!value.GetString(kPayloadKey, &payload)) { - DLOG(WARNING) << "Failed to parse payload"; - return nullptr; - } - return base::WrapUnique( - new Invalidation(id, false, version, payload, AckHandle::CreateUnique())); -} - Invalidation::Invalidation(const Invalidation& other) = default; Invalidation::~Invalidation() = default;
diff --git a/components/invalidation/public/invalidation.h b/components/invalidation/public/invalidation.h index d458e85..01ffb3f 100644 --- a/components/invalidation/public/invalidation.h +++ b/components/invalidation/public/invalidation.h
@@ -42,8 +42,6 @@ static Invalidation InitUnknownVersion(const invalidation::ObjectId& id); static Invalidation InitUnknownVersion(const Topic& topic); static Invalidation InitFromDroppedInvalidation(const Invalidation& dropped); - static std::unique_ptr<Invalidation> InitFromValue( - const base::DictionaryValue& value); Invalidation(const Invalidation& other); ~Invalidation();
diff --git a/components/invalidation/public/single_object_invalidation_set.cc b/components/invalidation/public/single_object_invalidation_set.cc index 4986332..b3ea986 100644 --- a/components/invalidation/public/single_object_invalidation_set.cc +++ b/components/invalidation/public/single_object_invalidation_set.cc
@@ -96,23 +96,4 @@ return value; } -bool SingleObjectInvalidationSet::ResetFromValue( - const base::ListValue& list) { - for (size_t i = 0; i < list.GetSize(); ++i) { - const base::DictionaryValue* dict; - if (!list.GetDictionary(i, &dict)) { - DLOG(WARNING) << "Could not find invalidation at index " << i; - return false; - } - std::unique_ptr<Invalidation> invalidation = - Invalidation::InitFromValue(*dict); - if (!invalidation) { - DLOG(WARNING) << "Failed to parse invalidation at index " << i; - return false; - } - invalidations_.insert(*invalidation); - } - return true; -} - } // namespace syncer
diff --git a/components/invalidation/public/single_object_invalidation_set.h b/components/invalidation/public/single_object_invalidation_set.h index 34d2369..a83ef5d 100644 --- a/components/invalidation/public/single_object_invalidation_set.h +++ b/components/invalidation/public/single_object_invalidation_set.h
@@ -56,7 +56,6 @@ const Invalidation& back() const; std::unique_ptr<base::ListValue> ToValue() const; - bool ResetFromValue(const base::ListValue& list); private: InvalidationsSet invalidations_;
diff --git a/components/password_manager/OWNERS b/components/password_manager/OWNERS index 55e5a05..5b8680ef 100644 --- a/components/password_manager/OWNERS +++ b/components/password_manager/OWNERS
@@ -1,6 +1,7 @@ dvadym@chromium.org jdoerrie@chromium.org kolos@chromium.org +mamir@chromium.org vasilii@chromium.org # COMPONENT: UI>Browser>Passwords
diff --git a/components/password_manager/core/browser/bulk_leak_check_service.h b/components/password_manager/core/browser/bulk_leak_check_service.h index a7523f9..7007218 100644 --- a/components/password_manager/core/browser/bulk_leak_check_service.h +++ b/components/password_manager/core/browser/bulk_leak_check_service.h
@@ -92,6 +92,11 @@ void set_leak_factory(std::unique_ptr<LeakDetectionCheckFactory> factory) { leak_check_factory_ = std::move(factory); } + + void set_state_and_notify(State state) { + state_ = state; + NotifyStateChanged(); + } #endif // defined(UNIT_TEST) private:
diff --git a/components/password_manager/core/browser/login_database.cc b/components/password_manager/core/browser/login_database.cc index d3a8e4a..6e7d89f 100644 --- a/components/password_manager/core/browser/login_database.cc +++ b/components/password_manager/core/browser/login_database.cc
@@ -1165,11 +1165,6 @@ if (changes) { changes->clear(); } - if (form.is_public_suffix_match) { - // TODO(dvadym): Discuss whether we should allow to remove PSL matched - // credentials. - return false; - } #if defined(OS_IOS) DeleteEncryptedPassword(form); #endif
diff --git a/components/password_manager/core/browser/login_database_unittest.cc b/components/password_manager/core/browser/login_database_unittest.cc index 7af0924..ce98196f 100644 --- a/components/password_manager/core/browser/login_database_unittest.cc +++ b/components/password_manager/core/browser/login_database_unittest.cc
@@ -513,14 +513,6 @@ EXPECT_EQ(1U, result.size()); EXPECT_EQ("https://foo.com/", result[0]->signon_realm); EXPECT_TRUE(result[0]->is_public_suffix_match); - - // Try to remove PSL matched form - EXPECT_FALSE(db().RemoveLogin(*result[0], /*changes=*/nullptr)); - result.clear(); - // Ensure that the original form is still there - EXPECT_TRUE(db().GetLogins(PasswordStore::FormDigest(form), &result)); - EXPECT_EQ(1U, result.size()); - result.clear(); } TEST_F(LoginDatabaseTest, TestFederatedMatching) {
diff --git a/components/password_manager/core/browser/multi_store_password_save_manager.cc b/components/password_manager/core/browser/multi_store_password_save_manager.cc index 0c9d481..37fb430 100644 --- a/components/password_manager/core/browser/multi_store_password_save_manager.cc +++ b/components/password_manager/core/browser/multi_store_password_save_manager.cc
@@ -135,9 +135,7 @@ void MultiStorePasswordSaveManager::MoveCredentialsToAccountStore() { // TODO(crbug.com/1032992): There are other rare corner cases that should - // still be handled: 0. Moving PSL matched credentials doesn't work now - // because of - // https://cs.chromium.org/chromium/src/components/password_manager/core/browser/login_database.cc?l=1318&rcl=e32055d4843e9fc1fa920c5f1f83c1313607e28a + // still be handled: // 1. Credential exists only in the profile store but with an outdated // password. // 2. Credentials exist in both stores.
diff --git a/components/password_manager/core/browser/password_manager_util.cc b/components/password_manager/core/browser/password_manager_util.cc index 401347e..9c37ccd 100644 --- a/components/password_manager/core/browser/password_manager_util.cc +++ b/components/password_manager/core/browser/password_manager_util.cc
@@ -349,12 +349,14 @@ std::sort(non_federated_same_scheme->begin(), non_federated_same_scheme->end(), IsBetterMatch); - std::set<base::string16> usernames; + std::set<std::pair<PasswordForm::Store, base::string16>> store_usernames; for (const auto* match : *non_federated_same_scheme) { - const base::string16& username = match->username_value; - // The first match for |username| in the sorted array is best match. - if (!base::Contains(usernames, username)) { - usernames.insert(username); + auto store_username = + std::make_pair(match->in_store, match->username_value); + // The first match for |store_username| in the sorted array is best + // match. + if (!base::Contains(store_usernames, store_username)) { + store_usernames.insert(store_username); best_matches->push_back(match); } }
diff --git a/components/password_manager/core/browser/password_manager_util_unittest.cc b/components/password_manager/core/browser/password_manager_util_unittest.cc index 795dd2f..3928c582 100644 --- a/components/password_manager/core/browser/password_manager_util_unittest.cc +++ b/components/password_manager/core/browser/password_manager_util_unittest.cc
@@ -228,6 +228,59 @@ } } +TEST(PasswordManagerUtil, FindBestMatchesInProfileAndAccountStores) { + const base::string16 kUsername1 = base::ASCIIToUTF16("Username1"); + const base::string16 kPassword1 = base::ASCIIToUTF16("Password1"); + const base::string16 kUsername2 = base::ASCIIToUTF16("Username2"); + const base::string16 kPassword2 = base::ASCIIToUTF16("Password2"); + + PasswordForm form; + form.is_public_suffix_match = false; + form.date_last_used = base::Time::Now(); + + // Add the same credentials in account and profile stores. + PasswordForm account_form1(form); + account_form1.username_value = kUsername1; + account_form1.password_value = kPassword1; + account_form1.in_store = PasswordForm::Store::kAccountStore; + + PasswordForm profile_form1(account_form1); + profile_form1.in_store = PasswordForm::Store::kProfileStore; + + // Add the credentials for the same username in account and profile stores but + // with different passwords. + PasswordForm account_form2(form); + account_form2.username_value = kUsername2; + account_form2.password_value = kPassword1; + account_form2.in_store = PasswordForm::Store::kAccountStore; + + PasswordForm profile_form2(account_form2); + profile_form2.password_value = kPassword2; + profile_form2.in_store = PasswordForm::Store::kProfileStore; + + std::vector<const PasswordForm*> matches; + matches.push_back(&account_form1); + matches.push_back(&profile_form1); + matches.push_back(&account_form2); + matches.push_back(&profile_form2); + + std::vector<const PasswordForm*> best_matches; + const PasswordForm* preferred_match = nullptr; + std::vector<const PasswordForm*> same_scheme_matches; + FindBestMatches(matches, PasswordForm::Scheme::kHtml, &same_scheme_matches, + &best_matches, &preferred_match); + // All 4 matches should be returned in best matches. + EXPECT_EQ(best_matches.size(), 4U); + EXPECT_NE(std::find(best_matches.begin(), best_matches.end(), &account_form1), + best_matches.end()); + EXPECT_NE(std::find(best_matches.begin(), best_matches.end(), &account_form2), + best_matches.end()); + EXPECT_NE(std::find(best_matches.begin(), best_matches.end(), &profile_form1), + best_matches.end()); + EXPECT_NE(std::find(best_matches.begin(), best_matches.end(), &profile_form2), + best_matches.end()); +} + TEST(PasswordManagerUtil, GetMatchForUpdating_MatchUsername) { autofill::PasswordForm stored = GetTestCredential(); autofill::PasswordForm parsed = GetTestCredential();
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto index 53e23c9..f9b66cd4 100644 --- a/components/policy/proto/device_management_backend.proto +++ b/components/policy/proto/device_management_backend.proto
@@ -1550,6 +1550,12 @@ // A list of plugins installed in the browser. repeated Plugin plugins = 7; + + // The installed version of the browser if it differs from |browser_version|, + // or absent otherwise. When present, it indicates that an update (of a higher + // or lower version) has been installed and will be the active version + // following a browser restart. + optional string installed_browser_version = 8; } // Report Operating system related information.
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java index 8d622db..17e21dd1 100644 --- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java +++ b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java
@@ -262,14 +262,6 @@ * Asynchronous version of {@link #tryGetGoogleAccountNames()}. */ @MainThread - public void tryGetGoogleAccountNames(final Callback<List<String>> callback) { - runAfterCacheIsPopulated(() -> callback.onResult(tryGetGoogleAccountNames())); - } - - /** - * Asynchronous version of {@link #tryGetGoogleAccountNames()}. - */ - @MainThread public void getGoogleAccountNames( final Callback<AccountManagerResult<List<String>>> callback) { runAfterCacheIsPopulated(() -> { @@ -316,14 +308,6 @@ } /** - * Asynchronous version of {@link #getGoogleAccounts()}. - */ - @MainThread - public void getGoogleAccounts(Callback<AccountManagerResult<List<Account>>> callback) { - runAfterCacheIsPopulated(() -> callback.onResult(mFilteredAccounts.get())); - } - - /** * Retrieves all Google accounts on the device. * Returns an empty array if an error occurs while getting account list. */ @@ -344,23 +328,6 @@ runAfterCacheIsPopulated(() -> callback.onResult(tryGetGoogleAccounts())); } - /** - * Determine whether there are any Google accounts on the device. - * Returns false if an error occurs while getting account list. - */ - @AnyThread - public boolean hasGoogleAccounts() { - return !tryGetGoogleAccounts().isEmpty(); - } - - /** - * Asynchronous version of {@link #hasGoogleAccounts()}. - */ - @MainThread - public void hasGoogleAccounts(final Callback<Boolean> callback) { - runAfterCacheIsPopulated(() -> callback.onResult(hasGoogleAccounts())); - } - private String canonicalizeName(String name) { String[] parts = AT_SYMBOL.split(name); if (parts.length != 2) return name; @@ -391,14 +358,6 @@ } /** - * Asynchronous version of {@link #getAccountFromName(String)}. - */ - @MainThread - public void getAccountFromName(String accountName, final Callback<Account> callback) { - runAfterCacheIsPopulated(() -> callback.onResult(getAccountFromName(accountName))); - } - - /** * Returns whether an account exists with the given name. * Returns false if an error occurs while getting account list. */ @@ -408,16 +367,6 @@ } /** - * Asynchronous version of {@link #hasAccountForName(String)}. - */ - // TODO(maxbogue): Remove once this function is used outside of tests. - @VisibleForTesting - @MainThread - public void hasAccountForName(String accountName, final Callback<Boolean> callback) { - runAfterCacheIsPopulated(() -> callback.onResult(hasAccountForName(accountName))); - } - - /** * @return Whether or not there is an account authenticator for Google accounts. */ @AnyThread
diff --git a/components/signin/public/identity_manager/identity_manager.cc b/components/signin/public/identity_manager/identity_manager.cc index 82a17d1..47d0021 100644 --- a/components/signin/public/identity_manager/identity_manager.cc +++ b/components/signin/public/identity_manager/identity_manager.cc
@@ -539,7 +539,6 @@ void IdentityManager::GoogleSigninSucceeded( const CoreAccountInfo& account_info) { - UpdateUnconsentedPrimaryAccount(); for (auto& observer : observer_list_) { observer.OnPrimaryAccountSet(account_info); } @@ -562,6 +561,12 @@ void IdentityManager::GoogleSignedOut(const CoreAccountInfo& account_info) { DCHECK(!HasPrimaryAccount()); DCHECK(!account_info.IsEmpty()); + // This is needed for the case where the user chooses to start syncing + // with an account that is different then the unconsented primary account + // (not the first in cookies) but then cancel. In that case, the tokens stay + // the same. In all the other cases, either the token will be revoked which + // will trigger an update for the unconsented primary account or the + // primary account stays the same but the sync consent is revoked. UpdateUnconsentedPrimaryAccount(); for (auto& observer : observer_list_) { observer.OnPrimaryAccountCleared(account_info); @@ -688,7 +693,6 @@ const CoreAccountId primary_account_id = GetPrimaryAccountId(); if (primary_account_id == info.account_id) { primary_account_manager_->UpdateAuthenticatedAccountInfo(); - UpdateUnconsentedPrimaryAccount(); } } @@ -698,7 +702,6 @@ } void IdentityManager::OnAccountRemoved(const AccountInfo& info) { - UpdateUnconsentedPrimaryAccount(); for (auto& observer : observer_list_) observer.OnExtendedAccountInfoRemoved(info); }
diff --git a/components/sync/engine_impl/non_blocking_type_commit_contribution.cc b/components/sync/engine_impl/non_blocking_type_commit_contribution.cc index bc96b1b5..ccf939b 100644 --- a/components/sync/engine_impl/non_blocking_type_commit_contribution.cc +++ b/components/sync/engine_impl/non_blocking_type_commit_contribution.cc
@@ -274,6 +274,9 @@ encrypted_password.mutable_password() ->mutable_unencrypted_metadata() ->set_url(password_data.signon_realm()); + encrypted_password.mutable_password() + ->mutable_unencrypted_metadata() + ->set_blacklisted(password_data.blacklisted()); } bool result = cryptographer_->Encrypt(
diff --git a/components/sync/engine_impl/non_blocking_type_commit_contribution_unittest.cc b/components/sync/engine_impl/non_blocking_type_commit_contribution_unittest.cc index 7194529..e979ed4 100644 --- a/components/sync/engine_impl/non_blocking_type_commit_contribution_unittest.cc +++ b/components/sync/engine_impl/non_blocking_type_commit_contribution_unittest.cc
@@ -198,6 +198,10 @@ EXPECT_TRUE(entity.specifics().has_password()); EXPECT_EQ(kSignonRealm, entity.specifics().password().unencrypted_metadata().url()); + EXPECT_TRUE( + entity.specifics().password().unencrypted_metadata().has_blacklisted()); + EXPECT_FALSE( + entity.specifics().password().unencrypted_metadata().blacklisted()); EXPECT_FALSE(entity.specifics().password().encrypted().blob().empty()); EXPECT_TRUE(entity.parent_id_string().empty()); EXPECT_FALSE(entity.unique_position().has_custom_compressed_v1());
diff --git a/components/sync/protocol/password_specifics.proto b/components/sync/protocol/password_specifics.proto index 8dbee6bc..a12821d 100644 --- a/components/sync/protocol/password_specifics.proto +++ b/components/sync/protocol/password_specifics.proto
@@ -119,6 +119,10 @@ // Contains the password specifics metadata which simplifies its lookup. message PasswordSpecificsMetadata { optional string url = 1; + + // True, if user chose permanently not to save the credentials for the form. + // Introduced in M82. + optional bool blacklisted = 2; } // Properties of password sync objects.
diff --git a/components/test/data/autofill_assistant/html/autofill_assistant_target_website_iframe_one.html b/components/test/data/autofill_assistant/html/autofill_assistant_target_website_iframe_one.html index 2e7605506..050ee52 100644 --- a/components/test/data/autofill_assistant/html/autofill_assistant_target_website_iframe_one.html +++ b/components/test/data/autofill_assistant/html/autofill_assistant_target_website_iframe_one.html
@@ -30,8 +30,8 @@ button.parentNode.removeChild(button); } - var removeTouchArea = function() { - var touch_area = document.getElementById("touch_area"); + var removeTouchArea = function(id) { + var touch_area = document.getElementById(id); touch_area.parentNode.removeChild(touch_area); } @@ -91,7 +91,20 @@ </div> <div> - <p id="touch_area" ontouchend="removeTouchArea()">Touchable Area</p> + <p id="touch_area" ontouchend="removeTouchArea('touch_area')"> + Touchable Area</p> + <br> + </div> + + <div> + <p id="touch_area_1" ontouchend="removeTouchArea('touch_area_1')"> + Touchable Area 1 (iFrame)</p> + <br> + </div> + + <div> + <p id="touch_area_2" ontouchend="removeTouchArea('touch_area_2')"> + Touchable Area 2 (iFrame)</p> <br> </div> @@ -108,6 +121,18 @@ </div> <div id="focus">Hidden Text</div> + <div> + <p id="touch_area_3" ontouchend="removeTouchArea('touch_area_3')"> + Touchable Area 3 (iFrame)</p> + <br> + </div> + + <div> + <p id="touch_area_4" ontouchend="removeTouchArea('touch_area_4')"> + Touchable Area 4 (iFrame)</p> + <br> + </div> + <iframe id="iframe" width="100%" height="500" src= "autofill_assistant_target_website_iframe_two.html"></iframe> </body>
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn index 5cd92d7..6cd9edd 100644 --- a/components/viz/service/BUILD.gn +++ b/components/viz/service/BUILD.gn
@@ -196,6 +196,7 @@ "//media", "//media/capture:capture_lib", "//media/mojo/services", + "//services/tracing/public/cpp:cpp", "//services/viz/privileged/mojom", "//skia:skcms", "//ui/display/types",
diff --git a/components/viz/service/display/DEPS b/components/viz/service/display/DEPS index 23bfdee..96ec1f3e 100644 --- a/components/viz/service/display/DEPS +++ b/components/viz/service/display/DEPS
@@ -25,6 +25,7 @@ "+skia", "+third_party/khronos", "+third_party/skia", + "+third_party/perfetto/protos/perfetto/trace/track_event", "+ui/latency", "+ui/gfx/video_types.h", "+ui/gl/android/android_surface_control_compat.h",
diff --git a/components/viz/service/display/display.cc b/components/viz/service/display/display.cc index ced4a1d..3e81e49 100644 --- a/components/viz/service/display/display.cc +++ b/components/viz/service/display/display.cc
@@ -38,6 +38,7 @@ #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/ipc/scheduler_sequence.h" #include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom.h" +#include "third_party/perfetto/protos/perfetto/trace/track_event/chrome_latency_info.pbzero.h" #include "ui/gfx/buffer_types.h" #include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/overlay_transform_utils.h" @@ -688,8 +689,9 @@ swapped_trace_id_, "WaitForSwap"); swapped_since_resize_ = true; - ui::LatencyInfo::TraceIntermediateFlowEvents(frame.metadata.latency_info, - "Display::DrawAndSwap"); + ui::LatencyInfo::TraceIntermediateFlowEvents( + frame.metadata.latency_info, + perfetto::protos::pbzero::ChromeLatencyInfo::STEP_DRAW_AND_SWAP); cc::benchmark_instrumentation::IssueDisplayRenderingStatsEvent(); DirectRenderer::SwapFrameData swap_frame_data;
diff --git a/components/viz/service/display_embedder/skia_output_device_gl.cc b/components/viz/service/display_embedder/skia_output_device_gl.cc index badf412..11a5eaa7 100644 --- a/components/viz/service/display_embedder/skia_output_device_gl.cc +++ b/components/viz/service/display_embedder/skia_output_device_gl.cc
@@ -41,9 +41,8 @@ std::move(did_swap_buffer_complete_callback)), mailbox_manager_(mailbox_manager), context_state_(context_state), - gl_surface_(std::move(gl_surface)) { - // Only BufferQueue should support async swap. - DCHECK(!gl_surface_->SupportsAsyncSwap()); + gl_surface_(std::move(gl_surface)), + supports_async_swap_(gl_surface_->SupportsAsyncSwap()) { capabilities_.output_surface_origin = gl_surface_->GetOrigin(); capabilities_.supports_post_sub_buffer = gl_surface_->SupportsPostSubBuffer(); if (feature_info->workarounds() @@ -172,8 +171,15 @@ gfx::Size surface_size = gfx::Size(sk_surface_->width(), sk_surface_->height()); - FinishSwapBuffers(gl_surface_->SwapBuffers(std::move(feedback)), surface_size, - std::move(latency_info)); + if (supports_async_swap_) { + auto callback = base::BindOnce(&SkiaOutputDeviceGL::DoFinishSwapBuffers, + weak_ptr_factory_.GetWeakPtr(), surface_size, + std::move(latency_info)); + gl_surface_->SwapBuffersAsync(std::move(callback), std::move(feedback)); + } else { + FinishSwapBuffers(gl_surface_->SwapBuffers(std::move(feedback)), + surface_size, std::move(latency_info)); + } } void SkiaOutputDeviceGL::PostSubBuffer( @@ -185,10 +191,20 @@ gfx::Size surface_size = gfx::Size(sk_surface_->width(), sk_surface_->height()); - FinishSwapBuffers( - gl_surface_->PostSubBuffer(rect.x(), rect.y(), rect.width(), - rect.height(), std::move(feedback)), - surface_size, std::move(latency_info)); + if (supports_async_swap_) { + auto callback = base::BindOnce(&SkiaOutputDeviceGL::DoFinishSwapBuffers, + weak_ptr_factory_.GetWeakPtr(), surface_size, + std::move(latency_info)); + gl_surface_->PostSubBufferAsync(rect.x(), rect.y(), rect.width(), + rect.height(), std::move(callback), + std::move(feedback)); + + } else { + FinishSwapBuffers( + gl_surface_->PostSubBuffer(rect.x(), rect.y(), rect.width(), + rect.height(), std::move(feedback)), + surface_size, std::move(latency_info)); + } } void SkiaOutputDeviceGL::CommitOverlayPlanes( @@ -199,8 +215,25 @@ gfx::Size surface_size = gfx::Size(sk_surface_->width(), sk_surface_->height()); - FinishSwapBuffers(gl_surface_->CommitOverlayPlanes(std::move(feedback)), - surface_size, std::move(latency_info)); + if (supports_async_swap_) { + auto callback = base::BindOnce(&SkiaOutputDeviceGL::DoFinishSwapBuffers, + weak_ptr_factory_.GetWeakPtr(), surface_size, + std::move(latency_info)); + gl_surface_->CommitOverlayPlanesAsync(std::move(callback), + std::move(feedback)); + } else { + FinishSwapBuffers(gl_surface_->CommitOverlayPlanes(std::move(feedback)), + surface_size, std::move(latency_info)); + } +} + +void SkiaOutputDeviceGL::DoFinishSwapBuffers( + const gfx::Size& size, + std::vector<ui::LatencyInfo> latency_info, + gfx::SwapResult result, + std::unique_ptr<gfx::GpuFence> gpu_fence) { + DCHECK(!gpu_fence); + FinishSwapBuffers(result, size, latency_info); } void SkiaOutputDeviceGL::SetDrawRectangle(const gfx::Rect& draw_rectangle) {
diff --git a/components/viz/service/display_embedder/skia_output_device_gl.h b/components/viz/service/display_embedder/skia_output_device_gl.h index 77dd37e6..c9fea03 100644 --- a/components/viz/service/display_embedder/skia_output_device_gl.h +++ b/components/viz/service/display_embedder/skia_output_device_gl.h
@@ -20,6 +20,10 @@ class GLSurface; } // namespace gl +namespace gfx { +class GpuFence; +} // namespace gfx + namespace gpu { class MailboxManager; class SharedContextState; @@ -71,12 +75,20 @@ void EndPaint(const GrBackendSemaphore& semaphore) override; private: + // Used as callback for SwapBuffersAsync and PostSubBufferAsync to finish + // operation + void DoFinishSwapBuffers(const gfx::Size& size, + std::vector<ui::LatencyInfo> latency_info, + gfx::SwapResult result, + std::unique_ptr<gfx::GpuFence>); + scoped_refptr<gl::GLImage> GetGLImageForMailbox(const gpu::Mailbox& mailbox); gpu::MailboxManager* const mailbox_manager_; gpu::SharedContextState* const context_state_; scoped_refptr<gl::GLSurface> gl_surface_; + const bool supports_async_swap_; sk_sp<SkSurface> sk_surface_;
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index db36659..799ad94 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1787,12 +1787,12 @@ void RenderFrameHostImpl::AccessibilityFatalError() { browser_accessibility_manager_.reset(nullptr); - if (accessibility_reset_token_) + if (accessibility_reset_token_ || !render_accessibility_) return; accessibility_reset_count_++; if (accessibility_reset_count_ >= kMaxAccessibilityResets) { - Send(new AccessibilityMsg_FatalError(routing_id_)); + render_accessibility_->FatalError(); } else { accessibility_reset_token_ = g_next_accessibility_reset_token++; Send(new AccessibilityMsg_Reset(routing_id_, accessibility_reset_token_)); @@ -6192,10 +6192,19 @@ if (!IsRenderFrameCreated()) return; - if (!render_accessibility_) - GetRemoteAssociatedInterfaces()->GetInterface(&render_accessibility_); - ui::AXMode ax_mode = delegate_->GetAccessibilityMode(); + if (!ax_mode.has_mode(ui::AXMode::kWebContents)) { + // Resetting the Remote signals the renderer to shutdown accessibility + // in the renderer. + render_accessibility_.reset(); + return; + } + + if (!render_accessibility_) { + // Render accessibility is not enabled yet, so bind the interface first. + GetRemoteAssociatedInterfaces()->GetInterface(&render_accessibility_); + } + render_accessibility_->SetMode(ax_mode.mode()); }
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index 932d94ac..e6fb9a8 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -521,11 +521,16 @@ << host_->LayersAsString(); } +void CompositorImpl::BeginMainFrame(const viz::BeginFrameArgs& args) { + latest_frame_time_ = args.frame_time; +} + void CompositorImpl::UpdateLayerTreeHost() { + DCHECK(!latest_frame_time_.is_null()); client_->UpdateLayerTreeHost(); if (needs_animate_) { needs_animate_ = false; - root_window_->Animate(base::TimeTicks::Now()); + root_window_->Animate(latest_frame_time_); } }
diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h index 16517997..c9d7b2a2 100644 --- a/content/browser/renderer_host/compositor_impl_android.h +++ b/content/browser/renderer_host/compositor_impl_android.h
@@ -112,7 +112,7 @@ void DidBeginMainFrame() override {} void WillUpdateLayers() override {} void DidUpdateLayers() override; - void BeginMainFrame(const viz::BeginFrameArgs& args) override {} + void BeginMainFrame(const viz::BeginFrameArgs& args) override; void OnDeferMainFrameUpdatesChanged(bool) override {} void OnDeferCommitsChanged(bool) override {} void BeginMainFrameNotExpectedSoon() override {} @@ -268,6 +268,8 @@ size_t num_of_consecutive_surface_failures_ = 0u; + base::TimeTicks latest_frame_time_; + base::WeakPtrFactory<CompositorImpl> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(CompositorImpl);
diff --git a/content/browser/renderer_host/input/fling_controller.cc b/content/browser/renderer_host/input/fling_controller.cc index 631c3b0..ff74cc7 100644 --- a/content/browser/renderer_host/input/fling_controller.cc +++ b/content/browser/renderer_host/input/fling_controller.cc
@@ -186,7 +186,7 @@ // will be received when the user puts their finger down for a potential // boost. FlingBooster will process the event stream after the current fling // is ended and decide whether or not to boost any subsequent FlingStart. - EndCurrentFling(); + EndCurrentFling(gesture_event.event.TimeStamp()); } void FlingController::ProgressFling(base::TimeTicks current_time) { @@ -235,13 +235,13 @@ if (!fling_is_active && current_fling_parameters_.source_device != blink::WebGestureDevice::kSyntheticAutoscroll) { fling_booster_.Reset(); - EndCurrentFling(); + EndCurrentFling(current_time); return; } if (std::abs(delta_to_scroll.x()) > kMinInertialScrollDelta || std::abs(delta_to_scroll.y()) > kMinInertialScrollDelta) { - GenerateAndSendFlingProgressEvents(delta_to_scroll); + GenerateAndSendFlingProgressEvents(current_time, delta_to_scroll); last_progress_time_ = current_time; } @@ -253,15 +253,16 @@ void FlingController::StopFling() { fling_booster_.Reset(); if (fling_curve_) - EndCurrentFling(); + EndCurrentFling(clock_->NowTicks()); } void FlingController::GenerateAndSendWheelEvents( + base::TimeTicks current_time, const gfx::Vector2dF& delta, blink::WebMouseWheelEvent::Phase phase) { MouseWheelEventWithLatencyInfo synthetic_wheel( WebInputEvent::kMouseWheel, current_fling_parameters_.modifiers, - clock_->NowTicks(), ui::LatencyInfo(ui::SourceEventType::WHEEL)); + current_time, ui::LatencyInfo(ui::SourceEventType::WHEEL)); synthetic_wheel.event.delta_units = ui::ScrollGranularity::kScrollByPrecisePixel; synthetic_wheel.event.delta_x = delta.x(); @@ -278,10 +279,11 @@ } void FlingController::GenerateAndSendGestureScrollEvents( + base::TimeTicks current_time, WebInputEvent::Type type, const gfx::Vector2dF& delta /* = gfx::Vector2dF() */) { GestureEventWithLatencyInfo synthetic_gesture( - type, current_fling_parameters_.modifiers, clock_->NowTicks(), + type, current_fling_parameters_.modifiers, current_time, ui::LatencyInfo(ui::SourceEventType::INERTIAL)); synthetic_gesture.event.SetPositionInWidget(current_fling_parameters_.point); synthetic_gesture.event.SetPositionInScreen( @@ -306,19 +308,20 @@ } void FlingController::GenerateAndSendFlingProgressEvents( + base::TimeTicks current_time, const gfx::Vector2dF& delta) { switch (current_fling_parameters_.source_device) { case blink::WebGestureDevice::kTouchpad: { blink::WebMouseWheelEvent::Phase phase = first_fling_update_sent() ? blink::WebMouseWheelEvent::kPhaseChanged : blink::WebMouseWheelEvent::kPhaseBegan; - GenerateAndSendWheelEvents(delta, phase); + GenerateAndSendWheelEvents(current_time, delta, phase); break; } case blink::WebGestureDevice::kTouchscreen: case blink::WebGestureDevice::kSyntheticAutoscroll: - GenerateAndSendGestureScrollEvents(WebInputEvent::kGestureScrollUpdate, - delta); + GenerateAndSendGestureScrollEvents( + current_time, WebInputEvent::kGestureScrollUpdate, delta); break; case blink::WebGestureDevice::kUninitialized: case blink::WebGestureDevice::kScrollbar: @@ -329,15 +332,17 @@ fling_booster_.ObserveProgressFling(current_fling_parameters_.velocity); } -void FlingController::GenerateAndSendFlingEndEvents() { +void FlingController::GenerateAndSendFlingEndEvents( + base::TimeTicks current_time) { switch (current_fling_parameters_.source_device) { case blink::WebGestureDevice::kTouchpad: - GenerateAndSendWheelEvents(gfx::Vector2d(), + GenerateAndSendWheelEvents(current_time, gfx::Vector2d(), blink::WebMouseWheelEvent::kPhaseEnded); break; case blink::WebGestureDevice::kTouchscreen: case blink::WebGestureDevice::kSyntheticAutoscroll: - GenerateAndSendGestureScrollEvents(WebInputEvent::kGestureScrollEnd); + GenerateAndSendGestureScrollEvents(current_time, + WebInputEvent::kGestureScrollEnd); break; case blink::WebGestureDevice::kUninitialized: case blink::WebGestureDevice::kScrollbar: @@ -347,10 +352,10 @@ } } -void FlingController::EndCurrentFling() { +void FlingController::EndCurrentFling(base::TimeTicks current_time) { last_progress_time_ = base::TimeTicks(); - GenerateAndSendFlingEndEvents(); + GenerateAndSendFlingEndEvents(current_time); current_fling_parameters_ = ActiveFlingParameters(); if (fling_curve_) { @@ -387,7 +392,7 @@ if (velocity.IsZero() && fling_start_event.SourceDevice() != blink::WebGestureDevice::kSyntheticAutoscroll) { fling_booster_.Reset(); - EndCurrentFling(); + EndCurrentFling(fling_start_event.TimeStamp()); return false; } @@ -398,7 +403,7 @@ // state of fling_booster_ and return false. if (root_widget_viewport_size.IsEmpty()) { fling_booster_.Reset(); - EndCurrentFling(); + EndCurrentFling(last_seen_scroll_update_); return false; }
diff --git a/content/browser/renderer_host/input/fling_controller.h b/content/browser/renderer_host/input/fling_controller.h index c524d559..91e6308 100644 --- a/content/browser/renderer_host/input/fling_controller.h +++ b/content/browser/renderer_host/input/fling_controller.h
@@ -123,12 +123,14 @@ void ScheduleFlingProgress(); // Used to generate synthetic wheel events from touchpad fling and send them. - void GenerateAndSendWheelEvents(const gfx::Vector2dF& delta, + void GenerateAndSendWheelEvents(base::TimeTicks current_time, + const gfx::Vector2dF& delta, blink::WebMouseWheelEvent::Phase phase); // Used to generate synthetic gesture scroll events from touchscreen fling and // send them. void GenerateAndSendGestureScrollEvents( + base::TimeTicks current_time, blink::WebInputEvent::Type type, const gfx::Vector2dF& delta = gfx::Vector2dF()); @@ -138,11 +140,12 @@ // to progress flings with touchscreen and touchpad source respectively. // The reason for this difference is that during the touchpad fling we still // send wheel events to JS and generating GSU events directly is not enough. - void GenerateAndSendFlingProgressEvents(const gfx::Vector2dF& delta); + void GenerateAndSendFlingProgressEvents(base::TimeTicks current_time, + const gfx::Vector2dF& delta); - void GenerateAndSendFlingEndEvents(); + void GenerateAndSendFlingEndEvents(base::TimeTicks current_time); - void EndCurrentFling(); + void EndCurrentFling(base::TimeTicks current_time); // Used to update the fling_curve_ state based on the parameters of the fling // start event. Returns true if the fling curve was updated for a valid
diff --git a/content/browser/renderer_host/input/input_router_impl.cc b/content/browser/renderer_host/input/input_router_impl.cc index 3606a3b..4687453 100644 --- a/content/browser/renderer_host/input/input_router_impl.cc +++ b/content/browser/renderer_host/input/input_router_impl.cc
@@ -26,6 +26,7 @@ #include "content/public/common/content_switches.h" #include "content/public/common/input_event_ack_state.h" #include "ipc/ipc_sender.h" +#include "services/tracing/public/cpp/perfetto/flow_event_utils.h" #include "ui/events/blink/blink_event_util.h" #include "ui/events/blink/blink_features.h" #include "ui/events/blink/web_input_event_traits.h" @@ -40,6 +41,8 @@ using blink::WebMouseEvent; using blink::WebMouseWheelEvent; using blink::WebTouchEvent; +using perfetto::protos::pbzero::ChromeLatencyInfo; +using perfetto::protos::pbzero::TrackEvent; using ui::WebInputEventTraits; namespace { @@ -514,11 +517,20 @@ mojom::WidgetInputHandler::DispatchEventCallback callback) { TRACE_EVENT1("input", "InputRouterImpl::FilterAndSendWebInputEvent", "type", WebInputEvent::GetName(input_event.GetType())); - TRACE_EVENT_WITH_FLOW2( - "input,benchmark,devtools.timeline", "LatencyInfo.Flow", - TRACE_ID_GLOBAL(latency_info.trace_id()), - TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "step", - "SendInputEventUI", "frameTreeNodeId", frame_tree_node_id_); + TRACE_EVENT("input,benchmark,devtools.timeline", "LatencyInfo.Flow", + [&latency_info, this](perfetto::EventContext ctx) { + ChromeLatencyInfo* info = + ctx.event()->set_chrome_latency_info(); + info->set_trace_id(latency_info.trace_id()); + info->set_step(ChromeLatencyInfo::STEP_SEND_INPUT_EVENT_UI); + info->set_frame_tree_node_id(frame_tree_node_id_); + + tracing::FillFlowEvent( + ctx, + perfetto::protos::pbzero:: + TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT, + latency_info.trace_id()); + }); output_stream_validator_.Validate(input_event); InputEventAckState filtered_state =
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index dd6d4fb..1baaaea1 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -789,6 +789,13 @@ ->SetInitialFocus(reverse); } +void RenderViewHostImpl::AnimateDoubleTapZoom(const gfx::Point& point, + const gfx::Rect& rect) { + static_cast<RenderFrameHostImpl*>(GetMainFrame()) + ->GetAssociatedLocalMainFrame() + ->AnimateDoubleTapZoom(point, rect); +} + void RenderViewHostImpl::RenderWidgetDidFirstVisuallyNonEmptyPaint() { did_first_visually_non_empty_paint_ = true; delegate_->DidFirstVisuallyNonEmptyPaint(this);
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h index cb27619..5670a4e 100644 --- a/content/browser/renderer_host/render_view_host_impl.h +++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -166,6 +166,10 @@ // https://crbug.com/763548. void DispatchRenderViewCreated(); + // Tells the renderer process to request a page-scale animation based on the + // specified point/rect. + void AnimateDoubleTapZoom(const gfx::Point& point, const gfx::Rect& rect); + // Tells the renderer process to run the page's unload handler. // A completion callback is invoked by the renderer when the handler // execution completes.
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 173e4e0..0358c81 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -3126,8 +3126,7 @@ } auto* root_rvhi = RenderViewHostImpl::From(root_view->GetRenderWidgetHost()); - root_rvhi->Send(new ViewMsg_AnimateDoubleTapZoom( - root_rvhi->GetRoutingID(), transformed_point, transformed_rect_to_zoom)); + root_rvhi->AnimateDoubleTapZoom(transformed_point, transformed_rect_to_zoom); } void RenderWidgetHostImpl::OnZoomToFindInPageRectInMainFrame(
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc index f65f8aa8..9d33e7e0b 100644 --- a/content/browser/service_worker/service_worker_provider_host.cc +++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -89,12 +89,6 @@ container_host_.reset(); } -ServiceWorkerVersion* ServiceWorkerProviderHost::running_hosted_version() - const { - DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); - return running_hosted_version_; -} - void ServiceWorkerProviderHost::CompleteStartWorkerPreparation( int process_id, mojo::PendingReceiver<blink::mojom::BrowserInterfaceBroker>
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h index cd9866b..60e172d 100644 --- a/content/browser/service_worker/service_worker_provider_host.h +++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -57,10 +57,9 @@ int provider_id() const { return provider_id_; } int worker_process_id() const { return worker_process_id_; } - - // This is nullptr when the worker is still starting up (until - // CompleteStartWorkerPreparation() is called). - ServiceWorkerVersion* running_hosted_version() const; + ServiceWorkerVersion* running_hosted_version() const { + return running_hosted_version_; + } // Completes initialization of this provider host. It is called once a // renderer process has been found to host the worker.
diff --git a/content/browser/site_per_process_hit_test_browsertest.cc b/content/browser/site_per_process_hit_test_browsertest.cc index 6be234e..bdfcffa 100644 --- a/content/browser/site_per_process_hit_test_browsertest.cc +++ b/content/browser/site_per_process_hit_test_browsertest.cc
@@ -4494,11 +4494,17 @@ EXPECT_EQ(nullptr, router->wheel_target_); } +#if defined(OS_LINUX) +#define MAYBE_MouseWheelEventPositionChange \ + DISABLED_MouseWheelEventPositionChange +#else +#define MAYBE_MouseWheelEventPositionChange MouseWheelEventPositionChange +#endif // Ensure that the positions of mouse wheel events sent to cross-process // subframes account for any change in the position of the subframe during the // scroll sequence. IN_PROC_BROWSER_TEST_F(SitePerProcessMouseWheelHitTestBrowserTest, - MouseWheelEventPositionChange) { + MAYBE_MouseWheelEventPositionChange) { GURL main_url(embedded_test_server()->GetURL( "/frame_tree/page_with_tall_positioned_frame.html")); EXPECT_TRUE(NavigateToURL(shell(), main_url));
diff --git a/content/browser/tracing/background_tracing_active_scenario.cc b/content/browser/tracing/background_tracing_active_scenario.cc index 07ae2d2..2828e2c9 100644 --- a/content/browser/tracing/background_tracing_active_scenario.cc +++ b/content/browser/tracing/background_tracing_active_scenario.cc
@@ -21,7 +21,9 @@ #include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/system/data_pipe_drainer.h" #include "services/tracing/public/cpp/perfetto/perfetto_config.h" +#include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h" #include "services/tracing/public/cpp/perfetto/trace_event_data_source.h" +#include "services/tracing/public/cpp/trace_startup.h" #include "services/tracing/public/cpp/tracing_features.h" using base::trace_event::TraceConfig; @@ -65,6 +67,7 @@ base::OnceClosure on_failure) = 0; virtual void AbortScenario( const base::RepeatingClosure& on_abort_callback) = 0; + virtual bool did_setup_startup_tracing() const = 0; }; class PerfettoTracingSession @@ -81,8 +84,9 @@ // TODO(crbug.com/941318): Re-enable startup tracing for Android once all // Perfetto-related deadlocks are resolved. if (!TracingControllerImpl::GetInstance()->IsTracing()) { - tracing::TraceEventDataSource::GetInstance()->SetupStartupTracing( - /*privacy_filtering_enabled=*/true); + did_setup_startup_tracing_ = tracing::SetupStartupTracingForProcess( + /*privacy_filtering_enabled=*/true, + /*enable_sampler_profiler=*/false); } #endif @@ -125,6 +129,10 @@ on_abort_callback.Run(); } + bool did_setup_startup_tracing() const override { + return did_setup_startup_tracing_; + } + // mojo::DataPipeDrainer::Client implementation: void OnDataAvailable(const void* data, size_t num_bytes) override { raw_data_->append(reinterpret_cast<const char*>(data), num_bytes); @@ -180,6 +188,7 @@ std::unique_ptr<std::string> raw_data_; bool has_finished_read_buffers_ = false; bool has_finished_receiving_data_ = false; + bool did_setup_startup_tracing_ = false; }; class LegacyTracingSession @@ -192,8 +201,9 @@ // TODO(crbug.com/941318): Re-enable startup tracing for Android once all // Perfetto-related deadlocks are resolved. if (!TracingControllerImpl::GetInstance()->IsTracing()) { - tracing::TraceEventDataSource::GetInstance()->SetupStartupTracing( - /*privacy_filtering_enabled=*/false); + did_setup_startup_tracing_ = tracing::SetupStartupTracingForProcess( + /*privacy_filtering_enabled=*/false, + /*enable_sampler_profiler=*/false); } #endif @@ -257,8 +267,13 @@ } } + bool did_setup_startup_tracing() const override { + return did_setup_startup_tracing_; + } + private: BackgroundTracingActiveScenario* const parent_scenario_; + bool did_setup_startup_tracing_ = false; }; BackgroundTracingActiveScenario::BackgroundTracingActiveScenario( @@ -350,20 +365,6 @@ if (!chrome_config.event_filters().empty()) modes |= base::trace_event::TraceLog::FILTERING_MODE; -// TODO(crbug.com/941318): Re-enable startup tracing for Perfetto backend on -// Android once all Perfetto-related deadlocks are resolved. -#if !defined(OS_ANDROID) - TraceConfig chrome_config_for_trace_log(chrome_config); - // Perfetto backend configures buffer sizes when tracing is started in the - // service (see perfetto_config.cc). Zero them out here for TraceLog to avoid - // DCHECKs in TraceConfig::Merge. - chrome_config_for_trace_log.SetTraceBufferSizeInKb(0); - chrome_config_for_trace_log.SetTraceBufferSizeInEvents(0); - - base::trace_event::TraceLog::GetInstance()->SetEnabled( - chrome_config_for_trace_log, modes); -#endif // !defined(OS_ANDROID) - DCHECK(!tracing_session_); if (base::FeatureList::IsEnabled(features::kBackgroundTracingProtoOutput)) { tracing_session_ = std::make_unique<PerfettoTracingSession>( @@ -373,6 +374,22 @@ std::make_unique<LegacyTracingSession>(this, chrome_config); } +// TODO(crbug.com/941318): Re-enable startup tracing for Perfetto backend on +// Android once all Perfetto-related deadlocks are resolved. +#if !defined(OS_ANDROID) + if (tracing_session_->did_setup_startup_tracing()) { + TraceConfig chrome_config_for_trace_log(chrome_config); + // Perfetto backend configures buffer sizes when tracing is started in the + // service (see perfetto_config.cc). Zero them out here for TraceLog to + // avoid DCHECKs in TraceConfig::Merge. + chrome_config_for_trace_log.SetTraceBufferSizeInKb(0); + chrome_config_for_trace_log.SetTraceBufferSizeInEvents(0); + + base::trace_event::TraceLog::GetInstance()->SetEnabled( + chrome_config_for_trace_log, modes); + } +#endif // !defined(OS_ANDROID) + SetState(State::kTracing); BackgroundTracingManagerImpl::RecordMetric(Metrics::RECORDING_ENABLED); return true;
diff --git a/content/browser/tracing/startup_tracing_browsertest.cc b/content/browser/tracing/startup_tracing_browsertest.cc index b9931973..bb9d6d0 100644 --- a/content/browser/tracing/startup_tracing_browsertest.cc +++ b/content/browser/tracing/startup_tracing_browsertest.cc
@@ -132,8 +132,9 @@ // the SMB once the full tracing service starts up. This is to catch common // deadlocks. IN_PROC_BROWSER_TEST_F(StartupTracingInProcessTest, TestFilledStartupBuffer) { - tracing::TraceEventDataSource::GetInstance()->SetupStartupTracing( - /*privacy_filtering_enabled=*/false); + CHECK(tracing::SetupStartupTracingForProcess( + /*privacy_filtering_enabled=*/false, + /*enable_sampler_profiler=*/false)); auto config = tracing::TraceStartupConfig::GetInstance() ->GetDefaultBrowserStartupConfig();
diff --git a/content/browser/tracing/tracing_controller_browsertest.cc b/content/browser/tracing/tracing_controller_browsertest.cc index a7e7451..f07ab96 100644 --- a/content/browser/tracing/tracing_controller_browsertest.cc +++ b/content/browser/tracing/tracing_controller_browsertest.cc
@@ -349,6 +349,9 @@ DISABLED_EnableAndStopTracingWithFilePath #define MAYBE_EnableAndStopTracingWithCompression \ DISABLED_EnableAndStopTracingWithCompression +#define MAYBE_EnableAndStopTracingWithEmptyFile \ + DISABLED_EnableAndStopTracingWithEmptyFile +#define MAYBE_DoubleStopTracing DISABLED_DoubleStopTracing #define MAYBE_ProcessesPresentInTrace DISABLED_ProcessesPresentInTrace #else #define MAYBE_EnableAndStopTracing EnableAndStopTracing @@ -357,6 +360,9 @@ #define MAYBE_EnableAndStopTracingWithFilePath EnableAndStopTracingWithFilePath #define MAYBE_EnableAndStopTracingWithCompression \ EnableAndStopTracingWithCompression +#define MAYBE_EnableAndStopTracingWithEmptyFile \ + EnableAndStopTracingWithEmptyFile +#define MAYBE_DoubleStopTracing DoubleStopTracing #define MAYBE_ProcessesPresentInTrace ProcessesPresentInTrace #endif @@ -450,7 +456,7 @@ } IN_PROC_BROWSER_TEST_F(TracingControllerTest, - EnableAndStopTracingWithEmptyFile) { + MAYBE_EnableAndStopTracingWithEmptyFile) { Navigate(shell()); base::RunLoop run_loop; @@ -468,7 +474,7 @@ run_loop.Run(); } -IN_PROC_BROWSER_TEST_F(TracingControllerTest, DoubleStopTracing) { +IN_PROC_BROWSER_TEST_F(TracingControllerTest, MAYBE_DoubleStopTracing) { Navigate(shell()); base::RunLoop run_loop;
diff --git a/content/common/accessibility_messages.h b/content/common/accessibility_messages.h index e793c54..dd70f7a 100644 --- a/content/common/accessibility_messages.h +++ b/content/common/accessibility_messages.h
@@ -146,10 +146,6 @@ IPC_MESSAGE_ROUTED1(AccessibilityMsg_Reset, int /* reset token */) -// Kill the renderer because we got a fatal error in the accessibility tree -// and we've already reset too many times. -IPC_MESSAGE_ROUTED0(AccessibilityMsg_FatalError) - // Request a one-time snapshot of the accessibility tree without // enabling accessibility if it wasn't already enabled. The passed id // will be returned in the AccessibilityHostMsg_SnapshotResponse message.
diff --git a/content/common/render_accessibility.mojom b/content/common/render_accessibility.mojom index 3a0fa75..8ff041e 100644 --- a/content/common/render_accessibility.mojom +++ b/content/common/render_accessibility.mojom
@@ -18,4 +18,8 @@ // contain at least the ui::AXMode::kWebContents value to enable accessibility // support for web contents. See ui/accessibility/ax_mode.h for valid values. SetMode(uint32 ax_mode); + + // Kills the renderer. Sent when there is a fatal error in the accessibility + // tree and the maximum number of resets has been hit. + FatalError(); };
diff --git a/content/common/view_messages.h b/content/common/view_messages.h index 7aa8ff0..276bd5b 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h
@@ -127,12 +127,6 @@ bool /* result */) #endif -// Sent to the main-frame's view to request performing a page scale animation -// based on the point/rect provided. -IPC_MESSAGE_ROUTED2(ViewMsg_AnimateDoubleTapZoom, - gfx::Point /* tap point */, - gfx::Rect /* rect_to_zoom */) - // Sent to the main-frame's view to request performing a zoom-to-find-in-page // based on the rect provided. IPC_MESSAGE_ROUTED1(ViewMsg_ZoomToFindInPageRect, gfx::Rect /*rect_to_zoom */)
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h index 801826b5..865c1481 100644 --- a/content/public/browser/web_contents.h +++ b/content/public/browser/web_contents.h
@@ -905,16 +905,18 @@ // Returns the WakeLockContext accociated with this WebContents. virtual device::mojom::WakeLockContext* GetWakeLockContext() = 0; - using ImageDownloadCallback = base::OnceCallback<void( - int id, - int http_status_code, // Can be 0 e.g. for data: URLs. - const GURL& image_url, - const std::vector<SkBitmap>& bitmaps, - /* The sizes in pixel of the bitmaps before they were resized due to the - max bitmap size passed to DownloadImage(). Each entry in the bitmaps - vector corresponds to an entry in the sizes vector. If a bitmap was - resized, there should be a single returned bitmap. */ - const std::vector<gfx::Size>& sizes)>; + // |http_status_code| can be 0 e.g. for data: URLs. + // |bitmaps| will be empty on download failure. + // |sizes| are the sizes in pixels of the bitmaps before they were resized due + // to the max bitmap size passed to DownloadImage(). Each entry in the bitmaps + // vector corresponds to an entry in the sizes vector. If a bitmap was + // resized, there should be a single returned bitmap. + using ImageDownloadCallback = + base::OnceCallback<void(int id, + int http_status_code, + const GURL& image_url, + const std::vector<SkBitmap>& bitmaps, + const std::vector<gfx::Size>& sizes)>; // Sends a request to download the given image |url| and returns the unique // id of the download request. When the download is finished, |callback| will
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn index 4642d27..ba68284 100644 --- a/content/public/common/BUILD.gn +++ b/content/public/common/BUILD.gn
@@ -200,6 +200,7 @@ public_deps = [ ":interfaces", + ":renderer_type", ":service_names", "//content/common", "//ipc", @@ -327,6 +328,10 @@ export_header = "content/common/content_export.h" } +mojom("renderer_type") { + sources = [ "media_playback_renderer_type.mojom" ] +} + mojom("web_preferences_mojom") { sources = [ "web_preferences.mojom" ]
diff --git a/content/public/common/media_playback_renderer_type.mojom b/content/public/common/media_playback_renderer_type.mojom new file mode 100644 index 0000000..43d00a93 --- /dev/null +++ b/content/public/common/media_playback_renderer_type.mojom
@@ -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. + +module content.mojom; + +enum RendererType { + // Media playback uses RendererImpl, which is the same as other + // platforms. For video codec supported by v4l2 (e.g. h264), it's still + // accelerated by hardware. Video will be rendererd on graphics plane. + DEFAULT_RENDERER = 0, + + // Enables Mojo Renderer (MojoRenderer) for media playback. + // On Chromecast, CMA renderer is enabled here. + MOJO_RENDERER = 1, + + // Enables RemotingRenderer for playing remoting media in + // blink::WebMediaPlayer. + REMOTING_RENDERER = 2, +};
diff --git a/content/public/renderer/render_frame_media_playback_options.h b/content/public/renderer/render_frame_media_playback_options.h index 32b53942..2135fde 100644 --- a/content/public/renderer/render_frame_media_playback_options.h +++ b/content/public/renderer/render_frame_media_playback_options.h
@@ -6,6 +6,7 @@ #define CONTENT_PUBLIC_RENDERER_RENDER_FRAME_MEDIA_PLAYBACK_OPTIONS_H_ #include "build/build_config.h" +#include "content/public/common/media_playback_renderer_type.mojom.h" namespace content { @@ -29,8 +30,16 @@ // Whether background video optimization is supported on current platform. bool is_background_video_track_optimization_supported = true; - // Whether MojoRenderer should be used for given |render_frame|. - bool is_mojo_renderer_enabled = true; + // Which renderer should be used in this media playback. + mojom::RendererType renderer_type = mojom::RendererType::DEFAULT_RENDERER; + + bool is_mojo_renderer_enabled() const { + return renderer_type == mojom::RendererType::MOJO_RENDERER; + } + + bool is_remoting_renderer_enabled() const { + return renderer_type == mojom::RendererType::REMOTING_RENDERER; + } }; } // namespace content
diff --git a/content/renderer/accessibility/render_accessibility_impl.cc b/content/renderer/accessibility/render_accessibility_impl.cc index 1fe6796..86bfa4e 100644 --- a/content/renderer/accessibility/render_accessibility_impl.cc +++ b/content/renderer/accessibility/render_accessibility_impl.cc
@@ -298,7 +298,6 @@ IPC_MESSAGE_HANDLER(AccessibilityMsg_PerformAction, OnPerformAction) IPC_MESSAGE_HANDLER(AccessibilityMsg_EventBundle_ACK, OnEventsAck) IPC_MESSAGE_HANDLER(AccessibilityMsg_Reset, OnReset) - IPC_MESSAGE_HANDLER(AccessibilityMsg_FatalError, OnFatalError) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -865,10 +864,6 @@ SendPendingAccessibilityEvents(); } -void RenderAccessibilityImpl::OnFatalError() { - CHECK(false) << "Invalid accessibility tree."; -} - void RenderAccessibilityImpl::OnHitTest(const gfx::Point& point, ax::mojom::Event event_to_fire, int action_request_id) {
diff --git a/content/renderer/accessibility/render_accessibility_impl.h b/content/renderer/accessibility/render_accessibility_impl.h index ba986bcd..44e92760 100644 --- a/content/renderer/accessibility/render_accessibility_impl.h +++ b/content/renderer/accessibility/render_accessibility_impl.h
@@ -160,7 +160,6 @@ // Handlers for messages from the browser to the renderer. void OnPerformAction(const ui::AXActionData& data); void OnEventsAck(int ack_token); - void OnFatalError(); void OnReset(int reset_token); void OnHitTest(const gfx::Point& point,
diff --git a/content/renderer/accessibility/render_accessibility_manager.cc b/content/renderer/accessibility/render_accessibility_manager.cc index b3e5aa6..a32ef236 100644 --- a/content/renderer/accessibility/render_accessibility_manager.cc +++ b/content/renderer/accessibility/render_accessibility_manager.cc
@@ -22,6 +22,12 @@ mojo::PendingAssociatedReceiver<mojom::RenderAccessibility> receiver) { DCHECK(!receiver_.is_bound()); receiver_.Bind(std::move(receiver)); + receiver_.set_disconnect_handler(base::BindOnce( + [](RenderAccessibilityManager* impl) { + impl->receiver_.reset(); + impl->SetMode(0); + }, + base::Unretained(this))); } RenderAccessibilityImpl* @@ -58,4 +64,8 @@ render_frame_->NotifyAccessibilityModeChange(new_mode); } +void RenderAccessibilityManager::FatalError() { + CHECK(false) << "Invalid accessibility tree."; +} + } // namespace content
diff --git a/content/renderer/accessibility/render_accessibility_manager.h b/content/renderer/accessibility/render_accessibility_manager.h index 786ffa6..ba07276 100644 --- a/content/renderer/accessibility/render_accessibility_manager.h +++ b/content/renderer/accessibility/render_accessibility_manager.h
@@ -54,6 +54,7 @@ // mojom::RenderAccessibility implementation. void SetMode(uint32_t ax_mode) override; + void FatalError() override; private: // The RenderFrameImpl that owns us.
diff --git a/content/renderer/input/render_widget_input_handler.cc b/content/renderer/input/render_widget_input_handler.cc index dd0de3f..7db490c 100644 --- a/content/renderer/input/render_widget_input_handler.cc +++ b/content/renderer/input/render_widget_input_handler.cc
@@ -25,6 +25,8 @@ #include "content/renderer/render_frame_proxy.h" #include "content/renderer/render_thread_impl.h" #include "content/renderer/render_widget.h" +#include "services/tracing/public/cpp/perfetto/flow_event_utils.h" +#include "services/tracing/public/cpp/perfetto/macros.h" #include "third_party/blink/public/common/input/web_gesture_device.h" #include "third_party/blink/public/common/input/web_gesture_event.h" #include "third_party/blink/public/common/input/web_keyboard_event.h" @@ -56,6 +58,8 @@ using blink::WebPointerEvent; using blink::WebTouchEvent; using blink::WebTouchPoint; +using perfetto::protos::pbzero::ChromeLatencyInfo; +using perfetto::protos::pbzero::TrackEvent; using ui::DidOverscrollParams; namespace content { @@ -351,10 +355,15 @@ TRACE_EVENT1("renderer,benchmark,rail", "RenderWidgetInputHandler::OnHandleInputEvent", "event", WebInputEvent::GetName(input_event.GetType())); - TRACE_EVENT_WITH_FLOW1("input,benchmark", "LatencyInfo.Flow", - TRACE_ID_GLOBAL(latency_info.trace_id()), - TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, - "step", "HandleInputEventMain"); + TRACE_EVENT("input,benchmark", "LatencyInfo.Flow", + [&latency_info](perfetto::EventContext ctx) { + ChromeLatencyInfo* info = + ctx.event()->set_chrome_latency_info(); + info->set_trace_id(latency_info.trace_id()); + info->set_step(ChromeLatencyInfo::STEP_HANDLE_INPUT_EVENT_MAIN); + tracing::FillFlowEvent(ctx, TrackEvent::LegacyEvent::FLOW_INOUT, + latency_info.trace_id()); + }); // If we don't have a high res timer, these metrics won't be accurate enough // to be worth collecting. Note that this does introduce some sampling bias.
diff --git a/content/renderer/media/media_factory.cc b/content/renderer/media/media_factory.cc index 6823532..4eddb30 100644 --- a/content/renderer/media/media_factory.cc +++ b/content/renderer/media/media_factory.cc
@@ -349,7 +349,7 @@ auto factory_selector = CreateRendererFactorySelector( media_log.get(), use_media_player_renderer, render_frame_->GetRenderFrameMediaPlaybackOptions() - .is_mojo_renderer_enabled, + .is_mojo_renderer_enabled(), GetDecoderFactory(), std::make_unique<media::RemotePlaybackClientWrapperImpl>(client), &media_observer); @@ -432,6 +432,8 @@ .is_background_video_playback_enabled, render_frame_->GetRenderFrameMediaPlaybackOptions() .is_background_video_track_optimization_supported, + render_frame_->GetRenderFrameMediaPlaybackOptions() + .is_remoting_renderer_enabled(), std::move(power_status_helper))); std::unique_ptr<media::VideoFrameCompositor> vfc =
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index 9294830..9693972 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc
@@ -2352,6 +2352,26 @@ ASSERT_TRUE(GetRenderAccessibilityManager()->GetRenderAccessibilityImpl()); } +TEST_F(RenderViewImplTest, AccessibilityModeOnClosingConnection) { + // Force the RenderAccessibilityManager to bind a pending receiver so that we + // can test what happens after closing the remote endpoint. + mojo::AssociatedRemote<mojom::RenderAccessibility> remote; + GetRenderAccessibilityManager()->BindReceiver( + remote.BindNewEndpointAndPassReceiver()); + + GetRenderAccessibilityManager()->SetMode(ui::kAXModeWebContentsOnly.mode()); + ASSERT_TRUE(GetAccessibilityMode() == ui::kAXModeWebContentsOnly); + ASSERT_TRUE(GetRenderAccessibilityManager()->GetRenderAccessibilityImpl()); + + // Closing the remote endpoint of the mojo pipe gets accessibility disabled + // for the frame and the RenderAccessibility object deleted. + remote.reset(); + base::RunLoop().RunUntilIdle(); + ASSERT_TRUE(GetRenderAccessibilityManager()); + ASSERT_TRUE(GetAccessibilityMode().is_mode_off()); + ASSERT_FALSE(GetRenderAccessibilityManager()->GetRenderAccessibilityImpl()); +} + // Checks that when a navigation starts in the renderer, |navigation_start| is // recorded at an appropriate time and is passed in the corresponding message. TEST_F(RenderViewImplTest, RendererNavigationStartTransmittedToBrowser) {
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 8d235493..97d7026e 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -1174,8 +1174,6 @@ IPC_MESSAGE_HANDLER(ViewMsg_MoveOrResizeStarted, OnMoveOrResizeStarted) IPC_MESSAGE_HANDLER(ViewMsg_EnablePreferredSizeChangedMode, OnEnablePreferredSizeChangedMode) - IPC_MESSAGE_HANDLER(ViewMsg_AnimateDoubleTapZoom, - OnAnimateDoubleTapZoomInMainFrame) IPC_MESSAGE_HANDLER(ViewMsg_ZoomToFindInPageRect, OnZoomToFindInPageRect) IPC_MESSAGE_HANDLER(ViewMsg_SetBackgroundOpaque, OnSetBackgroundOpaque) @@ -1924,12 +1922,6 @@ } } -void RenderViewImpl::OnAnimateDoubleTapZoomInMainFrame( - const gfx::Point& point, - const blink::WebRect& bound) { - GetWebView()->AnimateDoubleTapZoom(point, bound); -} - void RenderViewImpl::OnZoomToFindInPageRect( const blink::WebRect& rect_to_zoom) { GetWebView()->ZoomToFindInPageRect(rect_to_zoom);
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index 7ac12ec..ddf098a 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h
@@ -405,8 +405,6 @@ void OnDisableScrollbarsForSmallWindows( const gfx::Size& disable_scrollbars_size_limit); void OnEnablePreferredSizeChangedMode(); - void OnAnimateDoubleTapZoomInMainFrame(const gfx::Point& point, - const blink::WebRect& rect_to_zoom); void OnZoomToFindInPageRect(const blink::WebRect& rect_to_zoom); void OnMoveOrResizeStarted(); void OnExitFullscreen();
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn index 92c49392..450b90d4 100644 --- a/content/shell/BUILD.gn +++ b/content/shell/BUILD.gn
@@ -158,8 +158,6 @@ "browser/web_test/fake_bluetooth_chooser.h", "browser/web_test/fake_bluetooth_chooser_factory.cc", "browser/web_test/fake_bluetooth_chooser_factory.h", - "browser/web_test/fake_bluetooth_delegate.cc", - "browser/web_test/fake_bluetooth_delegate.h", "browser/web_test/fake_bluetooth_scanning_prompt.cc", "browser/web_test/fake_bluetooth_scanning_prompt.h", "browser/web_test/leak_detector.cc",
diff --git a/content/shell/browser/web_test/blink_test_controller.cc b/content/shell/browser/web_test/blink_test_controller.cc index c898b1d1..eed2d06 100644 --- a/content/shell/browser/web_test/blink_test_controller.cc +++ b/content/shell/browser/web_test/blink_test_controller.cc
@@ -10,7 +10,6 @@ #include <algorithm> #include <iostream> #include <memory> -#include <queue> #include <set> #include <utility> #include <vector> @@ -576,7 +575,6 @@ WebTestContentBrowserClient::Get()->SetPopupBlockingEnabled(false); WebTestContentBrowserClient::Get()->ResetMockClipboardHost(); WebTestContentBrowserClient::Get()->SetScreenOrientationChanged(false); - WebTestContentBrowserClient::Get()->ResetFakeBluetoothDelegate(); navigation_history_dump_ = ""; pixel_dump_.reset(); actual_pixel_hash_ = "";
diff --git a/content/shell/browser/web_test/fake_bluetooth_delegate.cc b/content/shell/browser/web_test/fake_bluetooth_delegate.cc deleted file mode 100644 index 4f02cca..0000000 --- a/content/shell/browser/web_test/fake_bluetooth_delegate.cc +++ /dev/null
@@ -1,139 +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. - -#include "content/shell/browser/web_test/fake_bluetooth_delegate.h" - -#include "content/public/browser/web_contents.h" -#include "device/bluetooth/bluetooth_device.h" -#include "third_party/blink/public/common/bluetooth/web_bluetooth_device_id.h" -#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom.h" -#include "url/origin.h" - -using blink::WebBluetoothDeviceId; -using device::BluetoothDevice; -using device::BluetoothUUID; - -namespace content { - -// public -FakeBluetoothDelegate::FakeBluetoothDelegate() = default; -FakeBluetoothDelegate::~FakeBluetoothDelegate() = default; - -WebBluetoothDeviceId FakeBluetoothDelegate::GetWebBluetoothDeviceId( - RenderFrameHost* frame, - const std::string& device_address) { - auto& device_address_to_id_map = GetAddressToIdMapForOrigin(frame); - auto it = device_address_to_id_map.find(device_address); - if (it != device_address_to_id_map.end()) - return it->second; - return {}; -} - -std::string FakeBluetoothDelegate::GetDeviceAddress( - RenderFrameHost* frame, - const WebBluetoothDeviceId& device_id) { - auto& device_address_to_id_map = GetAddressToIdMapForOrigin(frame); - for (auto& entry : device_address_to_id_map) { - if (entry.second == device_id) - return entry.first; - } - return std::string(); -} - -blink::WebBluetoothDeviceId FakeBluetoothDelegate::AddScannedDevice( - RenderFrameHost* frame, - const std::string& device_address) { - return GetOrCreateDeviceIdForDeviceAddress(frame, device_address); -} - -WebBluetoothDeviceId FakeBluetoothDelegate::GrantServiceAccessPermission( - RenderFrameHost* frame, - const BluetoothDevice* device, - const blink::mojom::WebBluetoothRequestDeviceOptions* options) { - WebBluetoothDeviceId device_id = - GetOrCreateDeviceIdForDeviceAddress(frame, device->GetAddress()); - device_id_to_name_map_[device_id] = - device->GetName() ? *device->GetName() : std::string(); - GrantUnionOfServicesForDevice(device_id, options); - return device_id; -} - -bool FakeBluetoothDelegate::HasDevicePermission( - RenderFrameHost* frame, - const WebBluetoothDeviceId& device_id) { - return base::Contains(device_id_to_services_map_, device_id); -} - -bool FakeBluetoothDelegate::IsAllowedToAccessService( - RenderFrameHost* frame, - const WebBluetoothDeviceId& device_id, - const BluetoothUUID& service) { - auto id_to_services_it = device_id_to_services_map_.find(device_id); - if (id_to_services_it == device_id_to_services_map_.end()) - return false; - - return base::Contains(id_to_services_it->second, service); -} - -bool FakeBluetoothDelegate::IsAllowedToAccessAtLeastOneService( - RenderFrameHost* frame, - const WebBluetoothDeviceId& device_id) { - auto id_to_services_it = device_id_to_services_map_.find(device_id); - if (id_to_services_it == device_id_to_services_map_.end()) - return false; - - return !id_to_services_it->second.empty(); -} - -WebBluetoothDeviceId FakeBluetoothDelegate::GetOrCreateDeviceIdForDeviceAddress( - RenderFrameHost* frame, - const std::string& device_address) { - WebBluetoothDeviceId device_id; - auto& device_address_to_id_map = GetAddressToIdMapForOrigin(frame); - auto it = device_address_to_id_map.find(device_address); - if (it != device_address_to_id_map.end()) { - device_id = it->second; - } else { - device_id = WebBluetoothDeviceId::Create(); - device_address_to_id_map[device_address] = device_id; - } - return device_id; -} - -void FakeBluetoothDelegate::GrantUnionOfServicesForDevice( - const WebBluetoothDeviceId& device_id, - const blink::mojom::WebBluetoothRequestDeviceOptions* options) { - if (!options) - return; - - // Create an entry for |device_id| in |device_id_to_services_map_| to indicate - // that the site can attempt to GATT connect even if |options| does not - // contain any services. - base::flat_set<BluetoothUUID>& granted_services = - device_id_to_services_map_[device_id]; - if (options->filters) { - for (const blink::mojom::WebBluetoothLeScanFilterPtr& filter : - options->filters.value()) { - if (!filter->services) - continue; - - for (const BluetoothUUID& uuid : filter->services.value()) - granted_services.insert(uuid); - } - } - - for (const BluetoothUUID& uuid : options->optional_services) - granted_services.insert(uuid); -} - -FakeBluetoothDelegate::AddressToIdMap& -FakeBluetoothDelegate::GetAddressToIdMapForOrigin(RenderFrameHost* frame) { - auto* web_contents = WebContents::FromRenderFrameHost(frame); - auto origin_pair = - std::make_pair(frame->GetLastCommittedOrigin(), - web_contents->GetMainFrame()->GetLastCommittedOrigin()); - return device_address_to_id_map_for_origin_[origin_pair]; -} - -} // namespace content
diff --git a/content/shell/browser/web_test/fake_bluetooth_delegate.h b/content/shell/browser/web_test/fake_bluetooth_delegate.h deleted file mode 100644 index 1b80b79f..0000000 --- a/content/shell/browser/web_test/fake_bluetooth_delegate.h +++ /dev/null
@@ -1,103 +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 CONTENT_SHELL_BROWSER_WEB_TEST_FAKE_BLUETOOTH_DELEGATE_H_ -#define CONTENT_SHELL_BROWSER_WEB_TEST_FAKE_BLUETOOTH_DELEGATE_H_ - -#include <map> -#include <string> -#include <utility> -#include <vector> - -#include "base/containers/flat_set.h" -#include "content/public/browser/bluetooth_delegate.h" -#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-forward.h" - -namespace blink { -class WebBluetoothDeviceId; -} // namespace blink - -namespace device { -class BluetoothDevice; -class BluetoothUUID; -} // namespace device - -namespace url { -class Origin; -} // namespace url - -namespace content { - -class RenderFrameHost; - -// Fakes Web Bluetooth permissions for web tests by emulating Chrome's -// implementation. -class FakeBluetoothDelegate : public BluetoothDelegate { - public: - FakeBluetoothDelegate(); - ~FakeBluetoothDelegate() override; - - // Move-only class. - FakeBluetoothDelegate(const FakeBluetoothDelegate&) = delete; - FakeBluetoothDelegate& operator=(const FakeBluetoothDelegate&) = delete; - - // BluetoothDelegate implementation: - blink::WebBluetoothDeviceId GetWebBluetoothDeviceId( - RenderFrameHost* frame, - const std::string& device_address) override; - std::string GetDeviceAddress(RenderFrameHost* frame, - const blink::WebBluetoothDeviceId&) override; - blink::WebBluetoothDeviceId AddScannedDevice( - RenderFrameHost* frame, - const std::string& device_address) override; - blink::WebBluetoothDeviceId GrantServiceAccessPermission( - RenderFrameHost* frame, - const device::BluetoothDevice* device, - const blink::mojom::WebBluetoothRequestDeviceOptions* options) override; - bool HasDevicePermission( - RenderFrameHost* frame, - const blink::WebBluetoothDeviceId& device_id) override; - bool IsAllowedToAccessService(RenderFrameHost* frame, - const blink::WebBluetoothDeviceId& device_id, - const device::BluetoothUUID& service) override; - bool IsAllowedToAccessAtLeastOneService( - RenderFrameHost* frame, - const blink::WebBluetoothDeviceId& device_id) override; - - private: - using AddressToIdMap = std::map<std::string, blink::WebBluetoothDeviceId>; - using OriginPair = std::pair<url::Origin, url::Origin>; - using IdToServicesMap = std::map<blink::WebBluetoothDeviceId, - base::flat_set<device::BluetoothUUID>>; - using IdToNameMap = std::map<blink::WebBluetoothDeviceId, std::string>; - - // Finds an existing WebBluetoothDeviceId for |device_address| for |frame| or - // creates a new ID for the Bluetooth device on the current frame. - blink::WebBluetoothDeviceId GetOrCreateDeviceIdForDeviceAddress( - RenderFrameHost* frame, - const std::string& device_address); - - // Adds the union of |options->filters->services| and - // |options->optional_services| to the allowed services for |device_id|. - void GrantUnionOfServicesForDevice( - const blink::WebBluetoothDeviceId& device_id, - const blink::mojom::WebBluetoothRequestDeviceOptions* options); - AddressToIdMap& GetAddressToIdMapForOrigin(RenderFrameHost* frame); - - // Maps origins to their own maps of device address to device ID. - // If a given origin and device address does not have an associated device ID, - // then the origin does not have permission to access the device. - std::map<OriginPair, AddressToIdMap> device_address_to_id_map_for_origin_; - - // These map device IDs to their set of allowed services and device names. - // Since devices IDs are randomly generated, it is very unlikely that two - // unique devices will share the same ID. Therefore, these maps contain all of - // the service permissions and device names from all of the origins. - IdToServicesMap device_id_to_services_map_; - IdToNameMap device_id_to_name_map_; -}; - -} // namespace content - -#endif // CONTENT_SHELL_BROWSER_WEB_TEST_FAKE_BLUETOOTH_DELEGATE_H_
diff --git a/content/shell/browser/web_test/web_test_content_browser_client.cc b/content/shell/browser/web_test/web_test_content_browser_client.cc index 730790e..b899d61 100644 --- a/content/shell/browser/web_test/web_test_content_browser_client.cc +++ b/content/shell/browser/web_test/web_test_content_browser_client.cc
@@ -30,7 +30,6 @@ #include "content/shell/browser/web_test/blink_test_controller.h" #include "content/shell/browser/web_test/fake_bluetooth_chooser.h" #include "content/shell/browser/web_test/fake_bluetooth_chooser_factory.h" -#include "content/shell/browser/web_test/fake_bluetooth_delegate.h" #include "content/shell/browser/web_test/mojo_web_test_helper.h" #include "content/shell/browser/web_test/web_test_bluetooth_fake_adapter_setter_impl.h" #include "content/shell/browser/web_test/web_test_browser_context.h" @@ -356,16 +355,6 @@ switches::kRunWebTests); } -BluetoothDelegate* WebTestContentBrowserClient::GetBluetoothDelegate() { - if (!fake_bluetooth_delegate_) - fake_bluetooth_delegate_ = std::make_unique<FakeBluetoothDelegate>(); - return fake_bluetooth_delegate_.get(); -} - -void WebTestContentBrowserClient::ResetFakeBluetoothDelegate() { - fake_bluetooth_delegate_.reset(); -} - content::TtsControllerDelegate* WebTestContentBrowserClient::GetTtsControllerDelegate() { return WebTestTtsControllerDelegate::GetInstance();
diff --git a/content/shell/browser/web_test/web_test_content_browser_client.h b/content/shell/browser/web_test/web_test_content_browser_client.h index aaf3b8fe..0992408 100644 --- a/content/shell/browser/web_test/web_test_content_browser_client.h +++ b/content/shell/browser/web_test/web_test_content_browser_client.h
@@ -6,8 +6,6 @@ #define CONTENT_SHELL_BROWSER_WEB_TEST_WEB_TEST_CONTENT_BROWSER_CLIENT_H_ #include <memory> -#include <string> -#include <vector> #include "content/public/common/client_hints.mojom.h" #include "content/shell/browser/shell_content_browser_client.h" @@ -22,7 +20,6 @@ class FakeBluetoothChooser; class FakeBluetoothChooserFactory; -class FakeBluetoothDelegate; class MockClipboardHost; class MockPlatformNotificationService; class WebTestBrowserContext; @@ -42,7 +39,6 @@ // Retrieves the last created FakeBluetoothChooser instance. std::unique_ptr<FakeBluetoothChooser> GetNextFakeBluetoothChooser(); - void ResetFakeBluetoothDelegate(); // ContentBrowserClient overrides. void RenderProcessWillLaunch(RenderProcessHost* host) override; @@ -79,7 +75,7 @@ service_manager::BinderMapWithContext<content::RenderFrameHost*>* map) override; bool CanAcceptUntrustedExchangesIfNeeded() override; - BluetoothDelegate* GetBluetoothDelegate() override; + content::TtsControllerDelegate* GetTtsControllerDelegate() override; content::TtsPlatform* GetTtsPlatform() override; bool CanEnterFullscreenWithoutUserActivation() override; @@ -116,7 +112,6 @@ // Stores the FakeBluetoothChooserFactory that produces FakeBluetoothChoosers. std::unique_ptr<FakeBluetoothChooserFactory> fake_bluetooth_chooser_factory_; - std::unique_ptr<FakeBluetoothDelegate> fake_bluetooth_delegate_; std::unique_ptr<MockClipboardHost> mock_clipboard_host_; };
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index fe0ecaa..dd69d9f 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -127,7 +127,6 @@ #import "ios/chrome/browser/ui/promos/signin_promo_view_controller.h" #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" #include "ios/chrome/browser/ui/tab_grid/tab_grid_coordinator.h" -#import "ios/chrome/browser/ui/tab_grid/tab_switcher.h" #import "ios/chrome/browser/ui/tab_grid/view_controller_swapping.h" #import "ios/chrome/browser/ui/ui_feature_flags.h" #include "ios/chrome/browser/ui/util/ui_util.h" @@ -282,8 +281,6 @@ // The object that drives the Chrome startup/shutdown logic. std::unique_ptr<IOSChromeMain> _chromeMain; - // TabSwitcher object -- the tab grid. - id<TabSwitcher> _tabSwitcher; // True if the current session began from a cold start. False if the app has // entered the background at least once since start up. @@ -328,11 +325,6 @@ BOOL _animationDisabled; } -// Wrangler to handle BVC and tab model creation, access, and related logic. -// Implements faetures exposed from this object through the -// BrowserViewInformation protocol. -@property(nonatomic, strong) BrowserViewWrangler* browserViewWrangler; - // The ChromeBrowserState associated with the main (non-OTR) browsing mode. @property(nonatomic, assign) ChromeBrowserState* mainBrowserState; // Weak. @@ -386,8 +378,6 @@ - (void)scheduleDeleteTempPasswordsDirectory; // Returns whether or not the app can launch in incognito mode. - (BOOL)canLaunchInIncognito; -// Determines which UI should be shown on startup, and shows it. -- (void)createInitialUI:(ApplicationMode)launchMode; // Initializes the first run UI and presents it to the user. - (void)showFirstRunUI; // Schedules presentation of the first eligible promo found, if any. @@ -602,10 +592,10 @@ // This is per-window code. - DCHECK(!self.browserViewWrangler); + DCHECK(!self.sceneController.browserViewWrangler); DCHECK(self.sceneController.appURLLoadingService); - self.browserViewWrangler = [[BrowserViewWrangler alloc] + self.sceneController.browserViewWrangler = [[BrowserViewWrangler alloc] initWithBrowserState:self.mainBrowserState webStateListObserver:self.sceneController applicationCommandEndpoint:self.sceneController @@ -613,7 +603,7 @@ appURLLoadingService:self.sceneController.appURLLoadingService]; // Ensure the main tab model is created. This also creates the BVC. - [self.browserViewWrangler createMainBrowser]; + [self.sceneController.browserViewWrangler createMainBrowser]; // Only create the restoration helper if the browser state was backed up // successfully. @@ -641,16 +631,17 @@ if (postCrashLaunch || switchFromIncognito) { [self.sceneController clearIOSSpecificIncognitoData]; if (switchFromIncognito) - [self.browserViewWrangler + [self.sceneController.browserViewWrangler switchGlobalStateToMode:ApplicationMode::NORMAL]; } if (switchFromIncognito) startInIncognito = NO; - [self createInitialUI:(startInIncognito ? ApplicationMode::INCOGNITO - : ApplicationMode::NORMAL)]; + [self.sceneController + createInitialUI:(startInIncognito ? ApplicationMode::INCOGNITO + : ApplicationMode::NORMAL)]; - [self.browserViewWrangler updateDeviceSharingManager]; + [self.sceneController.browserViewWrangler updateDeviceSharingManager]; if (!self.startupParameters) { // The startup parameters may create new tabs or navigations. If the restore @@ -662,6 +653,8 @@ // End of per-window code. + CustomizeUIAppearance(); + [self scheduleStartupCleanupTasks]; [MetricsMediator logLaunchMetricsWithStartupInformation:self @@ -728,7 +721,7 @@ #pragma mark - Property implementation. - (id<BrowserInterfaceProvider>)interfaceProvider { - return self.browserViewWrangler; + return self.sceneController.browserViewWrangler; } - (TabGridCoordinator*)mainCoordinator { @@ -786,8 +779,8 @@ // Invariant: The UI is stopped before the model is shutdown. DCHECK(!_mainCoordinator); - [self.browserViewWrangler shutdown]; - self.browserViewWrangler = nil; + [self.sceneController.browserViewWrangler shutdown]; + self.sceneController.browserViewWrangler = nil; // End of per-window code. @@ -1178,71 +1171,6 @@ return ![self.otrTabModel isEmpty]; } -- (void)createInitialUI:(ApplicationMode)launchMode { - DCHECK(self.mainBrowserState); - - // In order to correctly set the mode switch icon, we need to know how many - // tabs are in the other tab model. That means loading both models. They - // may already be loaded. - // TODO(crbug.com/546203): Find a way to handle this that's closer to the - // point where it is necessary. - TabModel* mainTabModel = self.mainTabModel; - TabModel* otrTabModel = self.otrTabModel; - - // MainCoordinator shouldn't have been initialized yet. - DCHECK(!_mainCoordinator); - - // Enables UI initializations to query the keyWindow's size. - [self.window makeKeyAndVisible]; - - CustomizeUIAppearance(); - - // Lazy init of mainCoordinator. - [self.mainCoordinator start]; - - _tabSwitcher = self.mainCoordinator.tabSwitcher; - // Call -restoreInternalState so that the grid shows the correct panel. - [_tabSwitcher restoreInternalStateWithMainBrowser:self.mainBrowser - otrBrowser:self.otrBrowser - activeBrowser:self.currentBrowser]; - - // Decide if the First Run UI needs to run. - BOOL firstRun = (FirstRun::IsChromeFirstRun() || - experimental_flags::AlwaysDisplayFirstRun()) && - !tests_hook::DisableFirstRun(); - - [self.browserViewWrangler switchGlobalStateToMode:launchMode]; - - TabModel* tabModel; - if (launchMode == ApplicationMode::INCOGNITO) { - tabModel = otrTabModel; - [self.sceneController - setCurrentInterfaceForMode:ApplicationMode::INCOGNITO]; - } else { - tabModel = mainTabModel; - [self.sceneController setCurrentInterfaceForMode:ApplicationMode::NORMAL]; - } - if (self.tabSwitcherIsActive) { - DCHECK(!self.dismissingTabSwitcher); - [self.sceneController - beginDismissingTabSwitcherWithCurrentModel:self.mainTabModel - focusOmnibox:NO]; - [self.sceneController finishDismissingTabSwitcher]; - } - if (firstRun || - [self.sceneController shouldOpenNTPTabOnActivationOfTabModel:tabModel]) { - OpenNewTabCommand* command = [OpenNewTabCommand - commandWithIncognito:(self.currentBVC == self.otrBVC)]; - command.userInitiated = NO; - [self.currentBVC.dispatcher openURLInNewTab:command]; - } - - if (firstRun) { - [self showFirstRunUI]; - // Do not ever show the 'restore' infobar during first run. - self.restoreHelper = nil; - } -} - (void)showFirstRunUI { // Register for notification when First Run is completed. @@ -1517,11 +1445,6 @@ })); } -#pragma mark - MainControllerGuts - -- (id<TabSwitcher>)tabSwitcher { - return _tabSwitcher; -} @end @@ -1536,11 +1459,15 @@ } - (DeviceSharingManager*)deviceSharingManager { - return [self.browserViewWrangler deviceSharingManager]; + return [self.sceneController.browserViewWrangler deviceSharingManager]; } - (void)setTabSwitcher:(id<TabSwitcher>)switcher { - _tabSwitcher = switcher; + [self.sceneController setTabSwitcher:switcher]; +} + +- (id<TabSwitcher>)tabSwitcher { + return self.sceneController.tabSwitcher; } - (void)setTabSwitcherActive:(BOOL)active {
diff --git a/ios/chrome/app/main_controller_guts.h b/ios/chrome/app/main_controller_guts.h index 91c67f7..92dd1a03 100644 --- a/ios/chrome/app/main_controller_guts.h +++ b/ios/chrome/app/main_controller_guts.h
@@ -14,11 +14,9 @@ #import "ios/chrome/browser/crash_report/crash_restore_helper.h" @class BrowserViewController; -@class BrowserViewWrangler; class ChromeBrowserState; @class TabGridCoordinator; @protocol BrowserInterfaceProvider; -@protocol TabSwitcher; // TODO(crbug.com/1012697): Remove this protocol when SceneController is // operational. Move the private internals back into MainController, and pass @@ -39,8 +37,6 @@ // Keeps track of the restore state during startup. @property(nonatomic, strong) CrashRestoreHelper* restoreHelper; -- (BrowserViewWrangler*)browserViewWrangler; -- (id<TabSwitcher>)tabSwitcher; - (TabModel*)currentTabModel; - (ChromeBrowserState*)mainBrowserState; - (ChromeBrowserState*)currentBrowserState; @@ -49,12 +45,15 @@ - (BrowserViewController*)otrBVC; - (TabGridCoordinator*)mainCoordinator; - (id<BrowserInterfaceProvider>)interfaceProvider; +- (UIWindow*)window; - (void)removeBrowsingDataForBrowserState:(ChromeBrowserState*)browserState timePeriod:(browsing_data::TimePeriod)timePeriod removeMask:(BrowsingDataRemoveMask)removeMask completionBlock:(ProceduralBlock)completionBlock; +- (void)showFirstRunUI; + @end #endif // IOS_CHROME_APP_MAIN_CONTROLLER_GUTS_H_
diff --git a/ios/chrome/app/main_controller_private.h b/ios/chrome/app/main_controller_private.h index b8d95ef0..6b483862 100644 --- a/ios/chrome/app/main_controller_private.h +++ b/ios/chrome/app/main_controller_private.h
@@ -30,11 +30,12 @@ @interface MainController (TestingOnly) @property(nonatomic, readonly) DeviceSharingManager* deviceSharingManager; -@property(nonatomic, retain) id<TabSwitcher> tabSwitcher; // Tab switcher state. @property(nonatomic, getter=isTabSwitcherActive) BOOL tabSwitcherActive; +@property(nonatomic, strong) id<TabSwitcher> tabSwitcher; + // Sets the internal startup state to indicate that the launch was triggered // by an external app opening the given URL. - (void)setStartupParametersWithURL:(const GURL&)launchURL;
diff --git a/ios/chrome/browser/passwords/update_password_infobar_controller.mm b/ios/chrome/browser/passwords/update_password_infobar_controller.mm index 39d6dd58..8744ef55 100644 --- a/ios/chrome/browser/passwords/update_password_infobar_controller.mm +++ b/ios/chrome/browser/passwords/update_password_infobar_controller.mm
@@ -48,8 +48,10 @@ - (void)infobarLinkDidPress:(NSUInteger)tag { DCHECK(self.baseViewController); + // TODO(crbug.com/1058340): Provide a Browser for the coordinator. self.selectorCoordinator = [[SelectorCoordinator alloc] - initWithBaseViewController:self.baseViewController]; + initWithBaseViewController:self.baseViewController + browser:nullptr]; self.selectorCoordinator.delegate = self; self.selectorCoordinator.options = [NSOrderedSet orderedSetWithArray:_delegate->GetAccounts()];
diff --git a/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_view_controller.mm b/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_view_controller.mm index e1f9406b..a6f1da90 100644 --- a/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_view_controller.mm +++ b/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_view_controller.mm
@@ -133,7 +133,6 @@ [self addConfirmationButtonToView]; [self embedUserConsentView]; - [self addActivityIndicatorToView]; [self addSkipSigninButtonToView]; [self.view addSubview:self.gradientView];
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm index fbe077cc..307bcc6 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -753,10 +753,10 @@ // removal. if (!IsDownloadInfobarMessagesUIEnabled()) { _downloadManagerCoordinator = [[DownloadManagerCoordinator alloc] - initWithBaseViewController:_browserContainerViewController]; + initWithBaseViewController:_browserContainerViewController + browser:browser]; _downloadManagerCoordinator.presenter = [[VerticalAnimationContainer alloc] init]; - _downloadManagerCoordinator.dispatcher = self.dispatcher; } if (!base::FeatureList::IsEnabled(dialogs::kNonModalDialogs)) { @@ -2171,7 +2171,6 @@ if (!IsDownloadInfobarMessagesUIEnabled()) { // DownloadManagerCoordinator is already created. DCHECK(_downloadManagerCoordinator); - _downloadManagerCoordinator.webStateList = self.browser->GetWebStateList(); _downloadManagerCoordinator.bottomMarginHeightAnchor = [NamedGuide guideWithName:kSecondaryToolbarGuide view:self.contentArea] .heightAnchor;
diff --git a/ios/chrome/browser/ui/download/download_manager_coordinator.h b/ios/chrome/browser/ui/download/download_manager_coordinator.h index b4d389a9..6f5066b 100644 --- a/ios/chrome/browser/ui/download/download_manager_coordinator.h +++ b/ios/chrome/browser/ui/download/download_manager_coordinator.h
@@ -12,15 +12,20 @@ class DownloadTask; } // namespace web -@protocol BrowserCoordinatorCommands; -@class CommandDispatcher; @protocol ContainedPresenter; -class WebStateList; // Coordinates presentation of Download Manager UI. @interface DownloadManagerCoordinator : ChromeCoordinator<DownloadManagerTabHelperDelegate> +// Unavailable, use -initWithBaseViewController:browser:. +- (instancetype)initWithBaseViewController:(UIViewController*)viewController + NS_UNAVAILABLE; +// Unavailable, use -initWithBaseViewController:browser:. +- (instancetype)initWithBaseViewController:(UIViewController*)viewController + browserState:(ChromeBrowserState*)browserState + NS_UNAVAILABLE; + // Presents the receiver's view controller. @property(nonatomic) id<ContainedPresenter> presenter; @@ -31,17 +36,12 @@ // stop method is called. @property(nonatomic) web::DownloadTask* downloadTask; -// Needed to observe web state closing. Set to null when stop method is called. -@property(nonatomic) WebStateList* webStateList; - // Controls the height of the bottom margin. @property(nonatomic) NSLayoutDimension* bottomMarginHeightAnchor; // Underlying UIViewController presented by this coordinator. @property(nonatomic, readonly) UIViewController* viewController; -@property(nonatomic, weak) CommandDispatcher* dispatcher; - @end #endif // IOS_CHROME_BROWSER_UI_DOWNLOAD_DOWNLOAD_MANAGER_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/download/download_manager_coordinator.mm b/ios/chrome/browser/ui/download/download_manager_coordinator.mm index 3ec4ef14..1aeca3bd 100644 --- a/ios/chrome/browser/ui/download/download_manager_coordinator.mm +++ b/ios/chrome/browser/ui/download/download_manager_coordinator.mm
@@ -20,6 +20,7 @@ #import "ios/chrome/browser/download/download_manager_tab_helper.h" #import "ios/chrome/browser/download/google_drive_app_util.h" #import "ios/chrome/browser/installation_notifier.h" +#import "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/store_kit/store_kit_coordinator.h" #import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h" #import "ios/chrome/browser/ui/commands/browser_coordinator_commands.h" @@ -180,7 +181,6 @@ @synthesize presenter = _presenter; @synthesize animatesPresentation = _animatesPresentation; @synthesize downloadTask = _downloadTask; -@synthesize webStateList = _webStateList; @synthesize bottomMarginHeightAnchor = _bottomMarginHeightAnchor; - (void)dealloc { @@ -190,6 +190,7 @@ - (void)start { DCHECK(self.presenter); + DCHECK(self.browser); _viewController = [[DownloadManagerViewController alloc] init]; _viewController.delegate = self; @@ -201,6 +202,8 @@ self.presenter.presentedViewController = _viewController; self.presenter.delegate = self; + self.browser->GetWebStateList()->AddObserver(&_unopenedDownloads); + [self.presenter prepareForPresentation]; [self.presenter presentAnimated:self.animatesPresentation]; @@ -217,7 +220,9 @@ completion:nil]; _confirmationDialog = nil; _downloadTask = nullptr; - self.webStateList = nullptr; + + if (self.browser) + (self.browser->GetWebStateList())->RemoveObserver(&_unopenedDownloads); [_storeKitCoordinator stop]; _storeKitCoordinator = nil; @@ -225,19 +230,6 @@ _installDriveAlertCoordinator = nil; } -- (void)setWebStateList:(WebStateList*)webStateList { - if (_webStateList == webStateList) - return; - - if (_webStateList) - _webStateList->RemoveObserver(&_unopenedDownloads); - - _webStateList = webStateList; - - if (_webStateList) - _webStateList->AddObserver(&_unopenedDownloads); -} - - (UIViewController*)viewController { return _viewController; } @@ -368,8 +360,8 @@ if (base::FeatureList::IsEnabled(web::features::kEnablePersistentDownloads)) { OpenDownloadsFolderActivity* customActivity = [[OpenDownloadsFolderActivity alloc] init]; - customActivity.browserHandler = - HandlerForProtocol(self.dispatcher, BrowserCoordinatorCommands); + customActivity.browserHandler = HandlerForProtocol( + self.browser->GetCommandDispatcher(), BrowserCoordinatorCommands); activities = @[ customActivity ]; } _openInController =
diff --git a/ios/chrome/browser/ui/download/download_manager_coordinator_unittest.mm b/ios/chrome/browser/ui/download/download_manager_coordinator_unittest.mm index 8da8e2f6..412ec6b 100644 --- a/ios/chrome/browser/ui/download/download_manager_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/download/download_manager_coordinator_unittest.mm
@@ -19,6 +19,7 @@ #include "ios/chrome/browser/download/download_manager_metric_names.h" #import "ios/chrome/browser/download/download_manager_tab_helper.h" #import "ios/chrome/browser/download/google_drive_app_util.h" +#include "ios/chrome/browser/main/test_browser.h" #import "ios/chrome/browser/ui/download/download_manager_view_controller.h" #import "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" @@ -76,11 +77,13 @@ DownloadManagerCoordinatorTest() : presenter_([[FakeContainedPresenter alloc] init]), base_view_controller_([[UIViewController alloc] init]), + browser_(std::make_unique<TestBrowser>()), document_interaction_controller_class_( OCMClassMock([UIDocumentInteractionController class])), tab_helper_(&web_state_), coordinator_([[DownloadManagerCoordinator alloc] - initWithBaseViewController:base_view_controller_]) { + initWithBaseViewController:base_view_controller_ + browser:browser_.get()]) { [scoped_key_window_.Get() setRootViewController:base_view_controller_]; coordinator_.presenter = presenter_; } @@ -99,6 +102,7 @@ web::WebTaskEnvironment task_environment_; FakeContainedPresenter* presenter_; UIViewController* base_view_controller_; + std::unique_ptr<Browser> browser_; ScopedKeyWindow scoped_key_window_; web::TestWebState web_state_; id document_interaction_controller_class_; @@ -504,12 +508,9 @@ auto task = CreateTestTask(); coordinator_.downloadTask = task.get(); web::DownloadTask* task_ptr = task.get(); - FakeWebStateListDelegate web_state_list_delegate; - WebStateList web_state_list(&web_state_list_delegate); auto web_state = std::make_unique<web::TestWebState>(); - web_state_list.InsertWebState( + browser_->GetWebStateList()->InsertWebState( 0, std::move(web_state), WebStateList::INSERT_NO_FLAGS, WebStateOpener()); - coordinator_.webStateList = &web_state_list; [coordinator_ start]; EXPECT_EQ(1U, base_view_controller_.childViewControllers.count); @@ -532,7 +533,7 @@ })); // Web States are closed without user action only during app termination. - web_state_list.CloseAllWebStates(WebStateList::CLOSE_NO_FLAGS); + browser_->GetWebStateList()->CloseAllWebStates(WebStateList::CLOSE_NO_FLAGS); // Download task is destroyed before the download is complete. task = nullptr; @@ -548,7 +549,6 @@ static_cast<base::HistogramBase::Sample>(DownloadFileResult::Other), 1); histogram_tester_.ExpectTotalCount("Download.IOSDownloadFileUIGoogleDrive", 0); - coordinator_.webStateList = nullptr; } // Tests closing view controller while the download is in progress. Coordinator
diff --git a/ios/chrome/browser/ui/elements/selector_coordinator.h b/ios/chrome/browser/ui/elements/selector_coordinator.h index 7bdadec7..4ad0c852 100644 --- a/ios/chrome/browser/ui/elements/selector_coordinator.h +++ b/ios/chrome/browser/ui/elements/selector_coordinator.h
@@ -19,6 +19,16 @@ // Coordinator for displaying UI to allow the user to pick among options. @interface SelectorCoordinator : ChromeCoordinator +// Use -initWithBaseViewController:browser: +- (nonnull instancetype)initWithBaseViewController: + (nonnull UIViewController*)viewController NS_UNAVAILABLE; + +// Use -initWithBaseViewController:browser: +- (nonnull instancetype) + initWithBaseViewController:(nonnull UIViewController*)viewController + browserState:(nonnull ChromeBrowserState*)browserState + NS_UNAVAILABLE; + // Options to present to the user. @property(nonatomic, nullable, copy) NSOrderedSet<NSString*>* options;
diff --git a/ios/chrome/browser/ui/elements/selector_coordinator_unittest.mm b/ios/chrome/browser/ui/elements/selector_coordinator_unittest.mm index cd554be9..429c53f3c 100644 --- a/ios/chrome/browser/ui/elements/selector_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/elements/selector_coordinator_unittest.mm
@@ -5,6 +5,8 @@ #import "ios/chrome/browser/ui/elements/selector_coordinator.h" #import "base/test/ios/wait_util.h" +#import "base/test/task_environment.h" +#import "ios/chrome/browser/main/test_browser.h" #import "ios/chrome/browser/ui/elements/selector_picker_view_controller.h" #import "ios/chrome/browser/ui/elements/selector_view_controller_delegate.h" #include "testing/gtest/include/gtest/gtest.h" @@ -28,10 +30,14 @@ // Tests that invoking start on the coordinator presents the selector view, and // that invoking stop dismisses the view and invokes the delegate. TEST_F(SelectorCoordinatorTest, StartAndStop) { + base::test::TaskEnvironment task_environment_; + UIWindow* keyWindow = [[UIApplication sharedApplication] keyWindow]; UIViewController* rootViewController = keyWindow.rootViewController; - SelectorCoordinator* coordinator = [[SelectorCoordinator alloc] - initWithBaseViewController:rootViewController]; + std::unique_ptr<Browser> browser_ = std::make_unique<TestBrowser>(); + SelectorCoordinator* coordinator = + [[SelectorCoordinator alloc] initWithBaseViewController:rootViewController + browser:browser_.get()]; void (^testSteps)(void) = ^{ [coordinator start]; @@ -51,10 +57,14 @@ // Tests that calling the view controller delegate method invokes the // SelectorCoordinatorDelegate method and stops the coordinator. TEST_F(SelectorCoordinatorTest, Delegate) { + base::test::TaskEnvironment task_environment_; + UIWindow* keyWindow = [[UIApplication sharedApplication] keyWindow]; UIViewController* rootViewController = keyWindow.rootViewController; - SelectorCoordinator* coordinator = [[SelectorCoordinator alloc] - initWithBaseViewController:rootViewController]; + std::unique_ptr<Browser> browser_ = std::make_unique<TestBrowser>(); + SelectorCoordinator* coordinator = + [[SelectorCoordinator alloc] initWithBaseViewController:rootViewController + browser:browser_.get()]; id delegate = [OCMockObject mockForProtocol:@protocol(SelectorCoordinatorDelegate)]; coordinator.delegate = delegate;
diff --git a/ios/chrome/browser/ui/main/BUILD.gn b/ios/chrome/browser/ui/main/BUILD.gn index d7c6224..87539db8 100644 --- a/ios/chrome/browser/ui/main/BUILD.gn +++ b/ios/chrome/browser/ui/main/BUILD.gn
@@ -7,8 +7,10 @@ source_set("scene_guts") { sources = [ "scene_controller_guts.h" ] deps = [ + "//ios/chrome/app:mode", "//ios/chrome/app/application_delegate:application_delegate_internal", "//ios/chrome/browser:utils", + "//ios/chrome/browser/ui/tab_grid", "//ios/chrome/browser/url_loading", "//ios/chrome/browser/web_state_list", ] @@ -34,6 +36,7 @@ "//components/signin/public/identity_manager", "//components/url_formatter", "//ios/chrome/app:app", + "//ios/chrome/app:tests_hook", "//ios/chrome/app/application_delegate:application_delegate_internal", "//ios/chrome/browser", "//ios/chrome/browser:chrome_url_constants", @@ -43,11 +46,13 @@ "//ios/chrome/browser/crash_report:crash_report_internal", "//ios/chrome/browser/crash_report/breadcrumbs", "//ios/chrome/browser/crash_report/breadcrumbs:feature_flags", + "//ios/chrome/browser/first_run", "//ios/chrome/browser/main", "//ios/chrome/browser/ntp:features", "//ios/chrome/browser/signin", "//ios/chrome/browser/snapshots", "//ios/chrome/browser/tabs:tabs", + "//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui/authentication", "//ios/chrome/browser/ui/browser_view", "//ios/chrome/browser/ui/commands:commands",
diff --git a/ios/chrome/browser/ui/main/scene_controller.mm b/ios/chrome/browser/ui/main/scene_controller.mm index 9519759..0814a40d 100644 --- a/ios/chrome/browser/ui/main/scene_controller.mm +++ b/ios/chrome/browser/ui/main/scene_controller.mm
@@ -17,6 +17,7 @@ #import "ios/chrome/app/chrome_overlay_window.h" #import "ios/chrome/app/deferred_initialization_runner.h" #import "ios/chrome/app/main_controller_guts.h" +#import "ios/chrome/app/tests_hook.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/browsing_data/browsing_data_remove_mask.h" #include "ios/chrome/browser/browsing_data/browsing_data_remover.h" @@ -29,10 +30,12 @@ #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_report_helper.h" +#import "ios/chrome/browser/first_run/first_run.h" #include "ios/chrome/browser/main/browser.h" #include "ios/chrome/browser/ntp/features.h" #include "ios/chrome/browser/signin/identity_manager_factory.h" #import "ios/chrome/browser/snapshots/snapshot_tab_helper.h" +#include "ios/chrome/browser/system_flags.h" #import "ios/chrome/browser/tabs/tab_model.h" #import "ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.h" #import "ios/chrome/browser/ui/browser_view/browser_view_controller.h" @@ -47,6 +50,7 @@ #import "ios/chrome/browser/ui/signin_interaction/signin_interaction_coordinator.h" #include "ios/chrome/browser/ui/tab_grid/tab_grid_coordinator.h" #import "ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h" +#import "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/browser/ui/util/multi_window_support.h" #import "ios/chrome/browser/ui/util/top_view_controller.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" @@ -145,12 +149,17 @@ @property(nonatomic, readwrite) NTPTabOpeningPostOpeningAction NTPActionAfterTabSwitcherDismissal; +// TabSwitcher object -- the tab grid. +@property(nonatomic, strong) id<TabSwitcher> tabSwitcher; + @end @implementation SceneController @synthesize settingsNavigationController; //< From AppNavigation protocol. @synthesize appURLLoadingService = _appURLLoadingService; //< From SceneControllerGuts +@synthesize browserViewWrangler = + _browserViewWrangler; //< From SceneControllerGuts - (instancetype)initWithSceneState:(SceneState*)sceneState { self = [super init]; @@ -204,10 +213,76 @@ } } +#pragma mark - SceneControllerGuts +- (void)initializeUI { + if (self.hasInitializedUI) { + return; + } + + self.hasInitializedUI = YES; +} + #pragma mark - private -- (void)initializeUI { - self.hasInitializedUI = YES; +// Determines which UI should be shown on startup, and shows it. +- (void)createInitialUI:(ApplicationMode)launchMode { + DCHECK(self.mainController.mainBrowserState); + + // In order to correctly set the mode switch icon, we need to know how many + // tabs are in the other tab model. That means loading both models. They + // may already be loaded. + // TODO(crbug.com/546203): Find a way to handle this that's closer to the + // point where it is necessary. + TabModel* mainTabModel = self.mainInterface.tabModel; + TabModel* otrTabModel = self.incognitoInterface.tabModel; + + // Enables UI initializations to query the keyWindow's size. + [self.mainController.window makeKeyAndVisible]; + + // Lazy init of mainCoordinator. + [self.mainController.mainCoordinator start]; + + _tabSwitcher = self.mainController.mainCoordinator.tabSwitcher; + // Call -restoreInternalState so that the grid shows the correct panel. + [_tabSwitcher + restoreInternalStateWithMainBrowser:self.mainInterface.browser + otrBrowser:self.incognitoInterface.browser + activeBrowser:self.currentInterface.browser]; + + // Decide if the First Run UI needs to run. + BOOL firstRun = (FirstRun::IsChromeFirstRun() || + experimental_flags::AlwaysDisplayFirstRun()) && + !tests_hook::DisableFirstRun(); + + [self.browserViewWrangler switchGlobalStateToMode:launchMode]; + + TabModel* tabModel; + if (launchMode == ApplicationMode::INCOGNITO) { + tabModel = otrTabModel; + [self setCurrentInterfaceForMode:ApplicationMode::INCOGNITO]; + } else { + tabModel = mainTabModel; + [self setCurrentInterfaceForMode:ApplicationMode::NORMAL]; + } + if (self.mainController.tabSwitcherIsActive) { + DCHECK(!self.mainController.dismissingTabSwitcher); + [self beginDismissingTabSwitcherWithCurrentModel:self.mainInterface.tabModel + focusOmnibox:NO]; + [self finishDismissingTabSwitcher]; + } + if (firstRun || [self shouldOpenNTPTabOnActivationOfTabModel:tabModel]) { + OpenNewTabCommand* command = + [OpenNewTabCommand commandWithIncognito:(self.currentInterface.bvc == + self.incognitoInterface.bvc)]; + command.userInitiated = NO; + [self.currentInterface.bvc.dispatcher openURLInNewTab:command]; + } + + if (firstRun) { + [self.mainController showFirstRunUI]; + // Do not ever show the 'restore' infobar during first run. + self.mainController.restoreHelper = nil; + } } // This method completely destroys all of the UI. It should be called when the @@ -279,7 +354,7 @@ }); } [self.mainController.mainCoordinator - prepareToShowTabSwitcher:self.mainController.tabSwitcher]; + prepareToShowTabSwitcher:self.tabSwitcher]; } - (void)displayTabSwitcher { @@ -760,7 +835,7 @@ #pragma mark - TabSwitching - (BOOL)openNewTabFromTabSwitcher { - if (!self.mainController.tabSwitcher) + if (!self.tabSwitcher) return NO; UrlLoadParams urlLoadParams = @@ -769,10 +844,9 @@ Browser* mainBrowser = self.mainInterface.browser; WebStateList* webStateList = mainBrowser->GetWebStateList(); - [self.mainController.tabSwitcher - dismissWithNewTabAnimationToBrowser:mainBrowser - withUrlLoadParams:urlLoadParams - atIndex:webStateList->count()]; + [self.tabSwitcher dismissWithNewTabAnimationToBrowser:mainBrowser + withUrlLoadParams:urlLoadParams + atIndex:webStateList->count()]; return YES; } @@ -832,14 +906,13 @@ // If the tabSwitcher is contained, check if the parent container is // presenting another view controller. - if ([[self.mainController.tabSwitcher viewController] + if ([[self.tabSwitcher viewController] .parentViewController presentedViewController]) { return NO; } // Check if the tabSwitcher is directly presenting another view controller. - if ([self.mainController.tabSwitcher viewController] - .presentedViewController) { + if ([self.tabSwitcher viewController].presentedViewController) { return NO; } @@ -1024,7 +1097,7 @@ self.NTPActionAfterTabSwitcherDismissal = [self.mainController.startupParameters postOpeningAction]; [self.mainController setStartupParameters:nil]; - [self.mainController.tabSwitcher + [self.tabSwitcher dismissWithNewTabAnimationToBrowser:targetInterface.browser withUrlLoadParams:urlLoadParams atIndex:tabIndex]; @@ -1315,18 +1388,17 @@ } - (void)showTabSwitcher { - DCHECK(self.mainController.tabSwitcher); + DCHECK(self.tabSwitcher); // Tab switcher implementations may need to rebuild state before being // displayed. - [self.mainController.tabSwitcher + [self.tabSwitcher restoreInternalStateWithMainBrowser:self.mainInterface.browser otrBrowser:self.incognitoInterface.browser activeBrowser:self.currentInterface.browser]; self.mainController.tabSwitcherIsActive = YES; - [self.mainController.tabSwitcher setDelegate:self]; + [self.tabSwitcher setDelegate:self]; - [self.mainController.mainCoordinator - showTabSwitcher:self.mainController.tabSwitcher]; + [self.mainController.mainCoordinator showTabSwitcher:self.tabSwitcher]; } // Destroys and rebuilds the incognito browser state. @@ -1336,7 +1408,7 @@ // Clear the Incognito Browser and notify the _tabSwitcher that its otrBrowser // will be destroyed. - [self.mainController.tabSwitcher setOtrBrowser:nil]; + [self.tabSwitcher setOtrBrowser:nil]; if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) { BreadcrumbManagerBrowserAgent::FromBrowser(self.incognitoInterface.browser) @@ -1347,7 +1419,7 @@ self.incognitoInterface.browserState)); } - [self.mainController.browserViewWrangler destroyAndRebuildIncognitoBrowser]; + [self.browserViewWrangler destroyAndRebuildIncognitoBrowser]; if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) { breakpad::MonitorBreadcrumbManagerService( @@ -1361,8 +1433,7 @@ // Always set the new otr Browser for the tablet or grid switcher. // Notify the _tabSwitcher with the new Incognito Browser. - [self.mainController.tabSwitcher - setOtrBrowser:self.incognitoInterface.browser]; + [self.tabSwitcher setOtrBrowser:self.incognitoInterface.browser]; // This seems the best place to deem the destroying and rebuilding the // incognito browser state to be completed.
diff --git a/ios/chrome/browser/ui/main/scene_controller_guts.h b/ios/chrome/browser/ui/main/scene_controller_guts.h index f444b52..0fcc176 100644 --- a/ios/chrome/browser/ui/main/scene_controller_guts.h +++ b/ios/chrome/browser/ui/main/scene_controller_guts.h
@@ -9,20 +9,30 @@ #include "ios/chrome/app/application_delegate/startup_information.h" #import "ios/chrome/app/application_delegate/tab_opening.h" +#include "ios/chrome/app/application_mode.h" #import "ios/chrome/browser/procedural_block_types.h" +#import "ios/chrome/browser/ui/tab_grid/tab_switcher.h" #import "ios/chrome/browser/url_loading/app_url_loading_service.h" #import "ios/chrome/browser/url_loading/url_loading_params.h" #import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h" class ChromeBrowserState; +@class BrowserViewWrangler; @class TabModel; @protocol SceneControllerGuts <WebStateListObserving> +// Wrangler to handle BVC and tab model creation, access, and related logic. +// Implements faetures exposed from this object through the +// BrowserViewInformation protocol. +@property(nonatomic, strong) BrowserViewWrangler* browserViewWrangler; + // The scene level component for url loading. Is passed down to // browser state level UrlLoadingService instances. @property(nonatomic, assign) AppUrlLoadingService* appURLLoadingService; +- (void)createInitialUI:(ApplicationMode)launchMode; + - (void)dismissModalDialogsWithCompletion:(ProceduralBlock)completion dismissOmnibox:(BOOL)dismissOmnibox; @@ -55,6 +65,10 @@ // screen and showing the appropriate BVC. - (void)finishDismissingTabSwitcher; +// Testing only. +- (void)setTabSwitcher:(id<TabSwitcher>)switcher; +- (id<TabSwitcher>)tabSwitcher; + #pragma mark - AppNavigation helpers // Presents a SignedInAccountsViewController for |browserState| on the top view
diff --git a/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.h b/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.h index 3ceed59..b215650d 100644 --- a/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.h +++ b/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.h
@@ -7,6 +7,12 @@ #import <UIKit/UIKit.h> +// A11y Identifiers for testing. +extern NSString* const kConfirmationAlertMoreInfoAccessibilityIdentifier; +extern NSString* const kConfirmationAlertTitleAccessibilityIdentifier; +extern NSString* const kConfirmationAlertSubtitleAccessibilityIdentifier; +extern NSString* const kConfirmationAlertPrimaryActionAccessibilityIdentifier; + @protocol ConfirmationAlertActionHandler; // A view controller useful to show modal alerts and confirmations. The main
diff --git a/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.mm b/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.mm index c85c4de..2acd368 100644 --- a/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.mm +++ b/ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.mm
@@ -13,6 +13,15 @@ #error "This file requires ARC support." #endif +NSString* const kConfirmationAlertMoreInfoAccessibilityIdentifier = + @"kConfirmationAlertMoreInfoAccessibilityIdentifier"; +NSString* const kConfirmationAlertTitleAccessibilityIdentifier = + @"kConfirmationAlertTitleAccessibilityIdentifier"; +NSString* const kConfirmationAlertSubtitleAccessibilityIdentifier = + @"kConfirmationAlertSubtitleAccessibilityIdentifier"; +NSString* const kConfirmationAlertPrimaryActionAccessibilityIdentifier = + @"kConfirmationAlertPrimaryActionAccessibilityIdentifier"; + namespace { constexpr CGFloat kButtonVerticalInsets = 17; @@ -251,6 +260,8 @@ target:self action:@selector(didTapHelpButton)]; [items addObject:helpButton]; + helpButton.accessibilityIdentifier = + kConfirmationAlertMoreInfoAccessibilityIdentifier; // Set the help button as the left button item so it can be used as a // popover anchor. _helpButton = helpButton; @@ -297,6 +308,8 @@ title.textAlignment = NSTextAlignmentCenter; title.translatesAutoresizingMaskIntoConstraints = NO; title.adjustsFontForContentSizeCategory = YES; + title.accessibilityIdentifier = + kConfirmationAlertTitleAccessibilityIdentifier; return title; } @@ -310,6 +323,8 @@ subtitle.textAlignment = NSTextAlignmentCenter; subtitle.translatesAutoresizingMaskIntoConstraints = NO; subtitle.adjustsFontForContentSizeCategory = YES; + subtitle.accessibilityIdentifier = + kConfirmationAlertSubtitleAccessibilityIdentifier; return subtitle; } @@ -354,6 +369,8 @@ primaryActionButton.layer.cornerRadius = kPrimaryButtonCornerRadius; primaryActionButton.titleLabel.adjustsFontForContentSizeCategory = NO; primaryActionButton.translatesAutoresizingMaskIntoConstraints = NO; + primaryActionButton.accessibilityIdentifier = + kConfirmationAlertPrimaryActionAccessibilityIdentifier; return primaryActionButton; }
diff --git a/ios/chrome/credential_provider_extension/ui/resources/no_data_illustration.imageset/Contents.json b/ios/chrome/credential_provider_extension/ui/resources/empty_credentials_illustration.imageset/Contents.json similarity index 100% rename from ios/chrome/credential_provider_extension/ui/resources/no_data_illustration.imageset/Contents.json rename to ios/chrome/credential_provider_extension/ui/resources/empty_credentials_illustration.imageset/Contents.json
diff --git a/ios/chrome/credential_provider_extension/ui/resources/no_data_illustration.imageset/illustration_dark.png b/ios/chrome/credential_provider_extension/ui/resources/empty_credentials_illustration.imageset/illustration_dark.png similarity index 100% rename from ios/chrome/credential_provider_extension/ui/resources/no_data_illustration.imageset/illustration_dark.png rename to ios/chrome/credential_provider_extension/ui/resources/empty_credentials_illustration.imageset/illustration_dark.png Binary files differ
diff --git a/ios/chrome/credential_provider_extension/ui/resources/no_data_illustration.imageset/illustration_light.png b/ios/chrome/credential_provider_extension/ui/resources/empty_credentials_illustration.imageset/illustration_light.png similarity index 100% rename from ios/chrome/credential_provider_extension/ui/resources/no_data_illustration.imageset/illustration_light.png rename to ios/chrome/credential_provider_extension/ui/resources/empty_credentials_illustration.imageset/illustration_light.png Binary files differ
diff --git a/ios/showcase/BUILD.gn b/ios/showcase/BUILD.gn index 93ca944d..5649886 100644 --- a/ios/showcase/BUILD.gn +++ b/ios/showcase/BUILD.gn
@@ -26,6 +26,7 @@ "//ios/showcase/badges", "//ios/showcase/bubble", "//ios/showcase/content_suggestions", + "//ios/showcase/credential_provider", "//ios/showcase/infobars", "//ios/showcase/omnibox_popup", "//ios/showcase/recent_tabs", @@ -73,6 +74,7 @@ "//ios/showcase/bubble:eg2_tests", "//ios/showcase/content_suggestions:eg2_tests", "//ios/showcase/core:eg2_tests", + "//ios/showcase/credential_provider:eg2_tests", "//ios/showcase/infobars:eg2_tests", "//ios/showcase/text_badge_view:eg2_tests", ]
diff --git a/ios/showcase/core/showcase_model.mm b/ios/showcase/core/showcase_model.mm index dd2e768..7da05e9 100644 --- a/ios/showcase/core/showcase_model.mm +++ b/ios/showcase/core/showcase_model.mm
@@ -17,6 +17,21 @@ + (NSArray<showcase::ModelRow*>*)model { return @[ @{ + showcase::kClassForDisplayKey : @"ConsentViewController", + showcase::kClassForInstantiationKey : @"ConsentViewController", + showcase::kUseCaseKey : @"Credential Provider Consent UI", + }, + @{ + showcase::kClassForDisplayKey : @"EmptyCredentialsViewController", + showcase::kClassForInstantiationKey : @"EmptyCredentialsViewController", + showcase::kUseCaseKey : @"Credential Provider Empty Credentials UI", + }, + @{ + showcase::kClassForDisplayKey : @"StaleCredentialsViewController", + showcase::kClassForInstantiationKey : @"StaleCredentialsViewController", + showcase::kUseCaseKey : @"Credential Provider Stale Credentials UI", + }, + @{ showcase::kClassForDisplayKey : @"ContentSuggestionsViewController", showcase::kClassForInstantiationKey : @"SCContentSuggestionsCoordinator", showcase::kUseCaseKey : @"Content Suggestions UI",
diff --git a/ios/showcase/credential_provider/BUILD.gn b/ios/showcase/credential_provider/BUILD.gn new file mode 100644 index 0000000..1eac6607 --- /dev/null +++ b/ios/showcase/credential_provider/BUILD.gn
@@ -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. + +source_set("credential_provider") { + sources = [] + deps = [ "//ios/chrome/credential_provider_extension/ui" ] + libs = [ "UIKit.framework" ] + configs += [ "//build/config/compiler:enable_arc" ] +} + +source_set("eg2_tests") { + defines = [ "CHROME_EARL_GREY_2" ] + configs += [ + "//build/config/compiler:enable_arc", + "//build/config/ios:xctest_config", + ] + testonly = true + sources = [ "credential_provider_egtest.mm" ] + deps = [ + "//base", + "//ios/chrome/common/ui/confirmation_alert", + "//ios/showcase/test:eg2_test", + "//ios/testing/earl_grey:eg_test_support+eg2", + "//ios/third_party/earl_grey2:test_lib", + "//ui/base", + ] + libs = [ "UIKit.framework" ] +}
diff --git a/ios/showcase/credential_provider/OWNERS b/ios/showcase/credential_provider/OWNERS new file mode 100644 index 0000000..d3e76b7 --- /dev/null +++ b/ios/showcase/credential_provider/OWNERS
@@ -0,0 +1,4 @@ +javierrobles@chromium.org + +# TEAM: ios-directory-owners@chromium.org +# OS: iOS
diff --git a/ios/showcase/credential_provider/credential_provider_egtest.mm b/ios/showcase/credential_provider/credential_provider_egtest.mm new file mode 100644 index 0000000..215d8e93 --- /dev/null +++ b/ios/showcase/credential_provider/credential_provider_egtest.mm
@@ -0,0 +1,90 @@ +// 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/ios/ios_util.h" +#import "ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.h" +#import "ios/showcase/test/showcase_eg_utils.h" +#import "ios/showcase/test/showcase_test_case.h" +#import "ios/testing/earl_grey/earl_grey_test.h" +#include "ui/base/l10n/l10n_util_mac.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { + +id<GREYMatcher> TitleMatcher() { + return grey_accessibilityID(kConfirmationAlertTitleAccessibilityIdentifier); +} + +id<GREYMatcher> SubtitleMatcher() { + return grey_accessibilityID( + kConfirmationAlertSubtitleAccessibilityIdentifier); +} + +id<GREYMatcher> PrimaryActionButtonMatcher() { + return grey_accessibilityID( + kConfirmationAlertPrimaryActionAccessibilityIdentifier); +} + +id<GREYMatcher> MoreInfoButtonMatcher() { + return grey_accessibilityID( + kConfirmationAlertMoreInfoAccessibilityIdentifier); +} + +} // namespace + +// Tests for the suggestions view controller. +@interface SCCredentialProviderTestCase : ShowcaseTestCase +@end + +@implementation SCCredentialProviderTestCase + +// Tests ConsentViewController. +- (void)testConsentScreen { + showcase_utils::Open(@"ConsentViewController"); + [[EarlGrey selectElementWithMatcher:TitleMatcher()] + assertWithMatcher:grey_interactable()]; + [[EarlGrey selectElementWithMatcher:SubtitleMatcher()] + assertWithMatcher:grey_interactable()]; + [[EarlGrey selectElementWithMatcher:PrimaryActionButtonMatcher()] + assertWithMatcher:grey_interactable()]; + [[EarlGrey selectElementWithMatcher:MoreInfoButtonMatcher()] + assertWithMatcher:grey_interactable()]; + + showcase_utils::Close(); +} + +// Tests ConsentViewController. +- (void)testEmptyCredentialsScreen { + showcase_utils::Open(@"EmptyCredentialsViewController"); + [[EarlGrey selectElementWithMatcher:TitleMatcher()] + assertWithMatcher:grey_interactable()]; + [[EarlGrey selectElementWithMatcher:SubtitleMatcher()] + assertWithMatcher:grey_interactable()]; + [[EarlGrey selectElementWithMatcher:PrimaryActionButtonMatcher()] + assertWithMatcher:grey_nil()]; + [[EarlGrey selectElementWithMatcher:MoreInfoButtonMatcher()] + assertWithMatcher:grey_nil()]; + + showcase_utils::Close(); +} + +// Tests ConsentViewController. +- (void)testStaleCredentialsScreen { + showcase_utils::Open(@"StaleCredentialsViewController"); + [[EarlGrey selectElementWithMatcher:TitleMatcher()] + assertWithMatcher:grey_interactable()]; + [[EarlGrey selectElementWithMatcher:SubtitleMatcher()] + assertWithMatcher:grey_interactable()]; + [[EarlGrey selectElementWithMatcher:PrimaryActionButtonMatcher()] + assertWithMatcher:grey_nil()]; + [[EarlGrey selectElementWithMatcher:MoreInfoButtonMatcher()] + assertWithMatcher:grey_nil()]; + + showcase_utils::Close(); +} + +@end
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index 510845c0..246a7994 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -315,6 +315,7 @@ params->IsBackgroundVideoPlaybackEnabled()), is_background_video_track_optimization_supported_( params->IsBackgroundVideoTrackOptimizationSupported()), + is_remoting_renderer_enabled_(params->IsRemotingRendererEnabled()), reported_renderer_type_(RendererFactoryType::kDefault), simple_watch_timer_( base::BindRepeating(&WebMediaPlayerImpl::OnSimpleWatchTimerTick,
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h index 20fb66ab..c0718c90 100644 --- a/media/blink/webmediaplayer_impl.h +++ b/media/blink/webmediaplayer_impl.h
@@ -1018,6 +1018,15 @@ // Whether background video optimization is supported on current platform. bool is_background_video_track_optimization_supported_ = true; + // Whether the media in this frame is a remoting media. + // + // Remoting media is a special media that has the media streams are delivered + // to the browser directly from somewhere without any URL request + // (http, file, ...) + // When setting to true, a remoting renderer will be created as the remoting + // target in the client. + bool is_remoting_renderer_enabled_ = false; + base::CancelableOnceClosure have_enough_after_lazy_load_cb_; // State for simplified watch time reporting.
diff --git a/media/blink/webmediaplayer_impl_unittest.cc b/media/blink/webmediaplayer_impl_unittest.cc index 7c4ce9ea..3d48e62 100644 --- a/media/blink/webmediaplayer_impl_unittest.cc +++ b/media/blink/webmediaplayer_impl_unittest.cc
@@ -396,7 +396,7 @@ viz::TestContextProvider::Create(), blink::WebMediaPlayer::SurfaceLayerMode::kAlways, is_background_suspend_enabled_, is_background_video_playback_enabled_, - true, nullptr); + true, false, nullptr); auto compositor = std::make_unique<NiceMock<MockVideoFrameCompositor>>( params->video_frame_compositor_task_runner());
diff --git a/media/blink/webmediaplayer_params.cc b/media/blink/webmediaplayer_params.cc index 6cf17a6..41cd376 100644 --- a/media/blink/webmediaplayer_params.cc +++ b/media/blink/webmediaplayer_params.cc
@@ -32,6 +32,7 @@ bool is_background_suspend_enabled, bool is_background_video_playback_enabled, bool is_background_video_track_optimization_supported, + bool is_remoting_renderer_enabled, std::unique_ptr<PowerStatusHelper> power_status_helper) : defer_load_cb_(defer_load_cb), audio_renderer_sink_(audio_renderer_sink), @@ -55,6 +56,7 @@ is_background_video_playback_enabled), is_background_video_track_optimization_supported_( is_background_video_track_optimization_supported), + is_remoting_renderer_enabled_(is_remoting_renderer_enabled), power_status_helper_(std::move(power_status_helper)) {} WebMediaPlayerParams::~WebMediaPlayerParams() = default;
diff --git a/media/blink/webmediaplayer_params.h b/media/blink/webmediaplayer_params.h index 28958ec..dd732c0 100644 --- a/media/blink/webmediaplayer_params.h +++ b/media/blink/webmediaplayer_params.h
@@ -84,6 +84,7 @@ bool is_background_suspend_enabled, bool is_background_video_play_enabled, bool is_background_video_track_optimization_supported, + bool is_remoting_renderer_enabled, std::unique_ptr<PowerStatusHelper> power_status_helper); ~WebMediaPlayerParams(); @@ -167,6 +168,10 @@ return is_background_video_track_optimization_supported_; } + bool IsRemotingRendererEnabled() const { + return is_remoting_renderer_enabled_; + } + std::unique_ptr<PowerStatusHelper> TakePowerStatusHelper() { return std::move(power_status_helper_); } @@ -199,6 +204,8 @@ bool is_background_video_playback_enabled_ = true; // Whether background video optimization is supported on current platform. bool is_background_video_track_optimization_supported_ = true; + // Whether the media in this frame is a remoting media. + bool is_remoting_renderer_enabled_ = false; std::unique_ptr<PowerStatusHelper> power_status_helper_;
diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc index 965b7ed..2c790804 100644 --- a/media/filters/chunk_demuxer.cc +++ b/media/filters/chunk_demuxer.cc
@@ -10,6 +10,7 @@ #include <utility> #include "base/bind.h" +#include "base/bind_helpers.h" #include "base/callback_helpers.h" #include "base/location.h" #include "base/macros.h" @@ -655,12 +656,10 @@ std::unique_ptr<SourceBufferState> source_state = std::make_unique<SourceBufferState>( std::move(stream_parser), std::move(frame_processor), - base::Bind(&ChunkDemuxer::CreateDemuxerStream, base::Unretained(this), - id), + base::BindRepeating(&ChunkDemuxer::CreateDemuxerStream, + base::Unretained(this), id), media_log_); - SourceBufferState::NewTextTrackCB new_text_track_cb; - // TODO(wolenetz): Change these to DCHECKs or switch to returning // kReachedIdLimit once less verification in release build is needed. See // https://crbug.com/786975. @@ -673,7 +672,7 @@ source_state->Init(base::BindOnce(&ChunkDemuxer::OnSourceInitDone, base::Unretained(this), id), ExpectedCodecs(content_type, codecs), - encrypted_media_init_data_cb_, new_text_track_cb); + encrypted_media_init_data_cb_, base::NullCallback()); // TODO(wolenetz): Change to DCHECKs once less verification in release build // is needed. See https://crbug.com/786975.
diff --git a/media/filters/source_buffer_range.cc b/media/filters/source_buffer_range.cc index 08a33267..92da7cc 100644 --- a/media/filters/source_buffer_range.cc +++ b/media/filters/source_buffer_range.cc
@@ -17,15 +17,15 @@ GapPolicy gap_policy, const BufferQueue& new_buffers, base::TimeDelta range_start_pts, - const InterbufferDistanceCB& interbuffer_distance_cb) + InterbufferDistanceCB interbuffer_distance_cb) : gap_policy_(gap_policy), next_buffer_index_(-1), - interbuffer_distance_cb_(interbuffer_distance_cb), + interbuffer_distance_cb_(std::move(interbuffer_distance_cb)), size_in_bytes_(0), range_start_pts_(range_start_pts), keyframe_map_index_base_(0) { DVLOG(3) << __func__; - DCHECK(interbuffer_distance_cb); + DCHECK(interbuffer_distance_cb_); CHECK(!new_buffers.empty()); DCHECK(new_buffers.front()->is_key_frame()); AppendBuffersToEnd(new_buffers, range_start_pts_);
diff --git a/media/filters/source_buffer_range.h b/media/filters/source_buffer_range.h index ef44264..eb5b830 100644 --- a/media/filters/source_buffer_range.h +++ b/media/filters/source_buffer_range.h
@@ -28,7 +28,7 @@ // of which this range is a part. Used to estimate the duration of a buffer if // its duration is not known, and in GetFudgeRoom() for determining whether a // time or coded frame is close enough to be considered part of this range. - using InterbufferDistanceCB = base::Callback<base::TimeDelta()>; + using InterbufferDistanceCB = base::RepeatingCallback<base::TimeDelta()>; using BufferQueue = StreamParser::BufferQueue; @@ -48,7 +48,7 @@ SourceBufferRange(GapPolicy gap_policy, const BufferQueue& new_buffers, base::TimeDelta range_start_pts, - const InterbufferDistanceCB& interbuffer_distance_cb); + InterbufferDistanceCB interbuffer_distance_cb); ~SourceBufferRange();
diff --git a/media/filters/source_buffer_state.cc b/media/filters/source_buffer_state.cc index 6541a2a..9ce7a59 100644 --- a/media/filters/source_buffer_state.cc +++ b/media/filters/source_buffer_state.cc
@@ -129,13 +129,13 @@ SourceBufferState::SourceBufferState( std::unique_ptr<StreamParser> stream_parser, std::unique_ptr<FrameProcessor> frame_processor, - const CreateDemuxerStreamCB& create_demuxer_stream_cb, + CreateDemuxerStreamCB create_demuxer_stream_cb, MediaLog* media_log) - : timestamp_offset_during_append_(NULL), + : timestamp_offset_during_append_(nullptr), parsing_media_segment_(false), stream_parser_(stream_parser.release()), frame_processor_(frame_processor.release()), - create_demuxer_stream_cb_(create_demuxer_stream_cb), + create_demuxer_stream_cb_(std::move(create_demuxer_stream_cb)), media_log_(media_log), state_(UNINITIALIZED) { DCHECK(create_demuxer_stream_cb_); @@ -150,11 +150,11 @@ StreamParser::InitCB init_cb, const std::string& expected_codecs, const StreamParser::EncryptedMediaInitDataCB& encrypted_media_init_data_cb, - const NewTextTrackCB& new_text_track_cb) { + NewTextTrackCB new_text_track_cb) { DCHECK_EQ(state_, UNINITIALIZED); init_cb_ = std::move(init_cb); encrypted_media_init_data_cb_ = encrypted_media_init_data_cb; - new_text_track_cb_ = new_text_track_cb; + new_text_track_cb_ = std::move(new_text_track_cb); state_ = PENDING_PARSER_CONFIG; InitializeParser(expected_codecs); } @@ -224,7 +224,7 @@ << " append_window_end=" << append_window_end.InSecondsF(); } - timestamp_offset_during_append_ = NULL; + timestamp_offset_during_append_ = nullptr; append_in_progress_ = false; return result; } @@ -239,7 +239,7 @@ append_window_end_during_append_ = append_window_end; stream_parser_->Flush(); - timestamp_offset_during_append_ = NULL; + timestamp_offset_during_append_ = nullptr; frame_processor_->Reset(); parsing_media_segment_ = false;
diff --git a/media/filters/source_buffer_state.h b/media/filters/source_buffer_state.h index 38d3d55..ae4c76ab 100644 --- a/media/filters/source_buffer_state.h +++ b/media/filters/source_buffer_state.h
@@ -31,15 +31,15 @@ class MEDIA_EXPORT SourceBufferState { public: // Callback signature used to create ChunkDemuxerStreams. - typedef base::Callback<ChunkDemuxerStream*(DemuxerStream::Type)> - CreateDemuxerStreamCB; + using CreateDemuxerStreamCB = + base::RepeatingCallback<ChunkDemuxerStream*(DemuxerStream::Type)>; - typedef base::Callback<void(ChunkDemuxerStream*, const TextTrackConfig&)> - NewTextTrackCB; + using NewTextTrackCB = base::RepeatingCallback<void(ChunkDemuxerStream*, + const TextTrackConfig&)>; SourceBufferState(std::unique_ptr<StreamParser> stream_parser, std::unique_ptr<FrameProcessor> frame_processor, - const CreateDemuxerStreamCB& create_demuxer_stream_cb, + CreateDemuxerStreamCB create_demuxer_stream_cb, MediaLog* media_log); ~SourceBufferState(); @@ -48,7 +48,7 @@ const std::string& expected_codecs, const StreamParser::EncryptedMediaInitDataCB& encrypted_media_init_data_cb, - const NewTextTrackCB& new_text_track_cb); + NewTextTrackCB new_text_track_cb); // Reconfigures this source buffer to use |new_stream_parser|. Caller must // first ensure that ResetParserState() was done to flush any pending frames @@ -239,7 +239,7 @@ DemuxerStreamMap text_streams_; std::unique_ptr<FrameProcessor> frame_processor_; - CreateDemuxerStreamCB create_demuxer_stream_cb_; + const CreateDemuxerStreamCB create_demuxer_stream_cb_; MediaLog* media_log_; StreamParser::InitCB init_cb_;
diff --git a/media/filters/source_buffer_state_unittest.cc b/media/filters/source_buffer_state_unittest.cc index 1b4cd4f..d5eb381 100644 --- a/media/filters/source_buffer_state_unittest.cc +++ b/media/filters/source_buffer_state_unittest.cc
@@ -68,8 +68,8 @@ mock_stream_parser_ = new testing::StrictMock<MockStreamParser>(); return base::WrapUnique(new SourceBufferState( base::WrapUnique(mock_stream_parser_), std::move(frame_processor), - base::Bind(&SourceBufferStateTest::CreateDemuxerStream, - base::Unretained(this)), + base::BindRepeating(&SourceBufferStateTest::CreateDemuxerStream, + base::Unretained(this)), &media_log_)); }
diff --git a/media/formats/mp2t/es_adapter_video.cc b/media/formats/mp2t/es_adapter_video.cc index 70e7a59..15a3dd3 100644 --- a/media/formats/mp2t/es_adapter_video.cc +++ b/media/formats/mp2t/es_adapter_video.cc
@@ -26,9 +26,9 @@ static const size_t kHistorySize = 5; EsAdapterVideo::EsAdapterVideo(NewVideoConfigCB new_video_config_cb, - const EmitBufferCB& emit_buffer_cb) + EmitBufferCB emit_buffer_cb) : new_video_config_cb_(std::move(new_video_config_cb)), - emit_buffer_cb_(emit_buffer_cb), + emit_buffer_cb_(std::move(emit_buffer_cb)), has_valid_config_(false), has_valid_frame_(false), last_frame_duration_(
diff --git a/media/formats/mp2t/es_adapter_video.h b/media/formats/mp2t/es_adapter_video.h index 5c9b69b..60193351 100644 --- a/media/formats/mp2t/es_adapter_video.h +++ b/media/formats/mp2t/es_adapter_video.h
@@ -35,10 +35,11 @@ public: using NewVideoConfigCB = base::RepeatingCallback<void(const VideoDecoderConfig&)>; - typedef base::Callback<void(scoped_refptr<StreamParserBuffer>)> EmitBufferCB; + using EmitBufferCB = + base::RepeatingCallback<void(scoped_refptr<StreamParserBuffer>)>; EsAdapterVideo(NewVideoConfigCB new_video_config_cb, - const EmitBufferCB& emit_buffer_cb); + EmitBufferCB emit_buffer_cb); ~EsAdapterVideo(); // Force the emission of the pending video buffers.
diff --git a/media/formats/mp2t/es_parser.h b/media/formats/mp2t/es_parser.h index 3bcc38e8..2cca8db 100644 --- a/media/formats/mp2t/es_parser.h +++ b/media/formats/mp2t/es_parser.h
@@ -28,8 +28,9 @@ class MEDIA_EXPORT EsParser { public: - using EmitBufferCB = base::Callback<void(scoped_refptr<StreamParserBuffer>)>; - using GetDecryptConfigCB = base::Callback<const DecryptConfig*()>; + using EmitBufferCB = + base::RepeatingCallback<void(scoped_refptr<StreamParserBuffer>)>; + using GetDecryptConfigCB = base::RepeatingCallback<const DecryptConfig*()>; EsParser(); virtual ~EsParser();
diff --git a/media/formats/mp2t/es_parser_adts.cc b/media/formats/mp2t/es_parser_adts.cc index 7d682c2c..231578f9 100644 --- a/media/formats/mp2t/es_parser_adts.cc +++ b/media/formats/mp2t/es_parser_adts.cc
@@ -116,10 +116,10 @@ } EsParserAdts::EsParserAdts(const NewAudioConfigCB& new_audio_config_cb, - const EmitBufferCB& emit_buffer_cb, + EmitBufferCB emit_buffer_cb, bool sbr_in_mimetype) : new_audio_config_cb_(new_audio_config_cb), - emit_buffer_cb_(emit_buffer_cb), + emit_buffer_cb_(std::move(emit_buffer_cb)), #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) get_decrypt_config_cb_(), init_encryption_scheme_(EncryptionScheme::kUnencrypted), @@ -129,13 +129,13 @@ #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) EsParserAdts::EsParserAdts(const NewAudioConfigCB& new_audio_config_cb, - const EmitBufferCB& emit_buffer_cb, - const GetDecryptConfigCB& get_decrypt_config_cb, + EmitBufferCB emit_buffer_cb, + GetDecryptConfigCB get_decrypt_config_cb, EncryptionScheme init_encryption_scheme, bool sbr_in_mimetype) : new_audio_config_cb_(new_audio_config_cb), - emit_buffer_cb_(emit_buffer_cb), - get_decrypt_config_cb_(get_decrypt_config_cb), + emit_buffer_cb_(std::move(emit_buffer_cb)), + get_decrypt_config_cb_(std::move(get_decrypt_config_cb)), init_encryption_scheme_(init_encryption_scheme), sbr_in_mimetype_(sbr_in_mimetype) {} #endif
diff --git a/media/formats/mp2t/es_parser_adts.h b/media/formats/mp2t/es_parser_adts.h index c004469..7997788 100644 --- a/media/formats/mp2t/es_parser_adts.h +++ b/media/formats/mp2t/es_parser_adts.h
@@ -34,12 +34,12 @@ typedef base::Callback<void(const AudioDecoderConfig&)> NewAudioConfigCB; EsParserAdts(const NewAudioConfigCB& new_audio_config_cb, - const EmitBufferCB& emit_buffer_cb, + EmitBufferCB emit_buffer_cb, bool sbr_in_mimetype); #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) EsParserAdts(const NewAudioConfigCB& new_audio_config_cb, - const EmitBufferCB& emit_buffer_cb, - const GetDecryptConfigCB& get_decrypt_config_cb, + EmitBufferCB emit_buffer_cb, + GetDecryptConfigCB get_decrypt_config_cb, EncryptionScheme init_encryption_scheme, bool sbr_in_mimetype); #endif
diff --git a/media/formats/mp2t/es_parser_adts_fuzzer.cc b/media/formats/mp2t/es_parser_adts_fuzzer.cc index 756a2597..ccc2f328 100644 --- a/media/formats/mp2t/es_parser_adts_fuzzer.cc +++ b/media/formats/mp2t/es_parser_adts_fuzzer.cc
@@ -14,7 +14,7 @@ // Entry point for LibFuzzer. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { media::mp2t::EsParserAdts es_parser(base::Bind(&NewAudioConfig), - base::Bind(&EmitBuffer), true); + base::BindRepeating(&EmitBuffer), true); if (!es_parser.Parse(data, size, media::kNoTimestamp, media::kNoDecodeTimestamp())) { return 0;
diff --git a/media/formats/mp2t/es_parser_adts_unittest.cc b/media/formats/mp2t/es_parser_adts_unittest.cc index 1303e59..1f906f59 100644 --- a/media/formats/mp2t/es_parser_adts_unittest.cc +++ b/media/formats/mp2t/es_parser_adts_unittest.cc
@@ -40,7 +40,8 @@ bool sbr_in_mimetype) { EsParserAdts es_parser( base::Bind(&EsParserAdtsTest::NewAudioConfig, base::Unretained(this)), - base::Bind(&EsParserAdtsTest::EmitBuffer, base::Unretained(this)), + base::BindRepeating(&EsParserAdtsTest::EmitBuffer, + base::Unretained(this)), sbr_in_mimetype); return ProcessPesPackets(&es_parser, pes_packets, false /* force_timing */); } @@ -87,4 +88,3 @@ } } // namespace mp2t } // namespace media -
diff --git a/media/formats/mp2t/es_parser_h264.cc b/media/formats/mp2t/es_parser_h264.cc index 66e458c..2093e21d 100644 --- a/media/formats/mp2t/es_parser_h264.cc +++ b/media/formats/mp2t/es_parser_h264.cc
@@ -178,8 +178,8 @@ const int kMinAUDSize = 4; EsParserH264::EsParserH264(NewVideoConfigCB new_video_config_cb, - const EmitBufferCB& emit_buffer_cb) - : es_adapter_(std::move(new_video_config_cb), emit_buffer_cb), + EmitBufferCB emit_buffer_cb) + : es_adapter_(std::move(new_video_config_cb), std::move(emit_buffer_cb)), h264_parser_(new H264Parser()), current_access_unit_pos_(0), next_access_unit_pos_(0) @@ -193,10 +193,10 @@ #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) EsParserH264::EsParserH264(NewVideoConfigCB new_video_config_cb, - const EmitBufferCB& emit_buffer_cb, + EmitBufferCB emit_buffer_cb, EncryptionScheme init_encryption_scheme, const GetDecryptConfigCB& get_decrypt_config_cb) - : es_adapter_(std::move(new_video_config_cb), emit_buffer_cb), + : es_adapter_(std::move(new_video_config_cb), std::move(emit_buffer_cb)), h264_parser_(new H264Parser()), current_access_unit_pos_(0), next_access_unit_pos_(0),
diff --git a/media/formats/mp2t/es_parser_h264.h b/media/formats/mp2t/es_parser_h264.h index 785d659..74c5a08 100644 --- a/media/formats/mp2t/es_parser_h264.h +++ b/media/formats/mp2t/es_parser_h264.h
@@ -44,10 +44,10 @@ base::RepeatingCallback<void(const VideoDecoderConfig&)>; EsParserH264(NewVideoConfigCB new_video_config_cb, - const EmitBufferCB& emit_buffer_cb); + EmitBufferCB emit_buffer_cb); #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) EsParserH264(NewVideoConfigCB new_video_config_cb, - const EmitBufferCB& emit_buffer_cb, + EmitBufferCB emit_buffer_cb, EncryptionScheme init_encryption_scheme, const GetDecryptConfigCB& get_decrypt_config_cb); #endif
diff --git a/media/formats/mp2t/es_parser_h264_fuzzer.cc b/media/formats/mp2t/es_parser_h264_fuzzer.cc index c4581435..69e2365 100644 --- a/media/formats/mp2t/es_parser_h264_fuzzer.cc +++ b/media/formats/mp2t/es_parser_h264_fuzzer.cc
@@ -13,8 +13,8 @@ // Entry point for LibFuzzer. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - media::mp2t::EsParserH264 es_parser(base::Bind(&NewVideoConfig), - base::Bind(&EmitBuffer)); + media::mp2t::EsParserH264 es_parser(base::BindRepeating(&NewVideoConfig), + base::BindRepeating(&EmitBuffer)); if (!es_parser.Parse(data, size, media::kNoTimestamp, media::kNoDecodeTimestamp())) { return 0;
diff --git a/media/formats/mp2t/es_parser_mpeg1audio.cc b/media/formats/mp2t/es_parser_mpeg1audio.cc index efcd7a1..0a4cb15 100644 --- a/media/formats/mp2t/es_parser_mpeg1audio.cc +++ b/media/formats/mp2t/es_parser_mpeg1audio.cc
@@ -38,11 +38,11 @@ EsParserMpeg1Audio::EsParserMpeg1Audio( const NewAudioConfigCB& new_audio_config_cb, - const EmitBufferCB& emit_buffer_cb, + EmitBufferCB emit_buffer_cb, MediaLog* media_log) : media_log_(media_log), new_audio_config_cb_(new_audio_config_cb), - emit_buffer_cb_(emit_buffer_cb) {} + emit_buffer_cb_(std::move(emit_buffer_cb)) {} EsParserMpeg1Audio::~EsParserMpeg1Audio() { }
diff --git a/media/formats/mp2t/es_parser_mpeg1audio.h b/media/formats/mp2t/es_parser_mpeg1audio.h index 56e5a8b..e1cad36 100644 --- a/media/formats/mp2t/es_parser_mpeg1audio.h +++ b/media/formats/mp2t/es_parser_mpeg1audio.h
@@ -32,7 +32,7 @@ typedef base::Callback<void(const AudioDecoderConfig&)> NewAudioConfigCB; EsParserMpeg1Audio(const NewAudioConfigCB& new_audio_config_cb, - const EmitBufferCB& emit_buffer_cb, + EmitBufferCB emit_buffer_cb, MediaLog* media_log); ~EsParserMpeg1Audio() override;
diff --git a/media/formats/mp2t/es_parser_mpeg1audio_fuzzer.cc b/media/formats/mp2t/es_parser_mpeg1audio_fuzzer.cc index 5f295820b6..b11413d 100644 --- a/media/formats/mp2t/es_parser_mpeg1audio_fuzzer.cc +++ b/media/formats/mp2t/es_parser_mpeg1audio_fuzzer.cc
@@ -17,8 +17,9 @@ // Entry point for LibFuzzer. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { media::NullMediaLog media_log; - media::mp2t::EsParserMpeg1Audio es_parser( - base::Bind(&NewAudioConfig), base::Bind(&EmitBuffer), &media_log); + media::mp2t::EsParserMpeg1Audio es_parser(base::Bind(&NewAudioConfig), + base::BindRepeating(&EmitBuffer), + &media_log); if (es_parser.Parse(data, size, media::kNoTimestamp, media::kNoDecodeTimestamp())) { es_parser.Flush();
diff --git a/media/formats/mp2t/es_parser_mpeg1audio_unittest.cc b/media/formats/mp2t/es_parser_mpeg1audio_unittest.cc index d3e4dd8a..19f8dcb6 100644 --- a/media/formats/mp2t/es_parser_mpeg1audio_unittest.cc +++ b/media/formats/mp2t/es_parser_mpeg1audio_unittest.cc
@@ -41,7 +41,8 @@ EsParserMpeg1Audio es_parser( base::Bind(&EsParserMpeg1AudioTest::NewAudioConfig, base::Unretained(this)), - base::Bind(&EsParserMpeg1AudioTest::EmitBuffer, base::Unretained(this)), + base::BindRepeating(&EsParserMpeg1AudioTest::EmitBuffer, + base::Unretained(this)), &media_log_); return ProcessPesPackets(&es_parser, pes_packets, force_timing); }
diff --git a/media/formats/mp2t/mp2t_stream_parser.cc b/media/formats/mp2t/mp2t_stream_parser.cc index 67fa5971..f7138c9 100644 --- a/media/formats/mp2t/mp2t_stream_parser.cc +++ b/media/formats/mp2t/mp2t_stream_parser.cc
@@ -397,30 +397,31 @@ std::unique_ptr<EsParser> Mp2tStreamParser::CreateH264Parser(int pes_pid) { auto on_video_config_changed = base::BindRepeating( &Mp2tStreamParser::OnVideoConfigChanged, base::Unretained(this), pes_pid); - auto on_emit_video_buffer = base::Bind(&Mp2tStreamParser::OnEmitVideoBuffer, - base::Unretained(this), pes_pid); + auto on_emit_video_buffer = base::BindRepeating( + &Mp2tStreamParser::OnEmitVideoBuffer, base::Unretained(this), pes_pid); return std::make_unique<EsParserH264>(std::move(on_video_config_changed), - on_emit_video_buffer); + std::move(on_emit_video_buffer)); } std::unique_ptr<EsParser> Mp2tStreamParser::CreateAacParser(int pes_pid) { auto on_audio_config_changed = base::Bind( &Mp2tStreamParser::OnAudioConfigChanged, base::Unretained(this), pes_pid); - auto on_emit_audio_buffer = base::Bind(&Mp2tStreamParser::OnEmitAudioBuffer, - base::Unretained(this), pes_pid); + auto on_emit_audio_buffer = base::BindRepeating( + &Mp2tStreamParser::OnEmitAudioBuffer, base::Unretained(this), pes_pid); return std::make_unique<EsParserAdts>(on_audio_config_changed, - on_emit_audio_buffer, sbr_in_mimetype_); + std::move(on_emit_audio_buffer), + sbr_in_mimetype_); } std::unique_ptr<EsParser> Mp2tStreamParser::CreateMpeg1AudioParser( int pes_pid) { auto on_audio_config_changed = base::Bind( &Mp2tStreamParser::OnAudioConfigChanged, base::Unretained(this), pes_pid); - auto on_emit_audio_buffer = base::Bind(&Mp2tStreamParser::OnEmitAudioBuffer, - base::Unretained(this), pes_pid); - return std::make_unique<EsParserMpeg1Audio>(on_audio_config_changed, - on_emit_audio_buffer, media_log_); + auto on_emit_audio_buffer = base::BindRepeating( + &Mp2tStreamParser::OnEmitAudioBuffer, base::Unretained(this), pes_pid); + return std::make_unique<EsParserMpeg1Audio>( + on_audio_config_changed, std::move(on_emit_audio_buffer), media_log_); } #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) @@ -437,15 +438,16 @@ bool emit_clear_buffers) { auto on_video_config_changed = base::BindRepeating( &Mp2tStreamParser::OnVideoConfigChanged, base::Unretained(this), pes_pid); - auto on_emit_video_buffer = base::Bind(&Mp2tStreamParser::OnEmitVideoBuffer, - base::Unretained(this), pes_pid); - auto get_decrypt_config = - emit_clear_buffers ? EsParser::GetDecryptConfigCB() - : base::Bind(&Mp2tStreamParser::GetDecryptConfig, - base::Unretained(this)); + auto on_emit_video_buffer = base::BindRepeating( + &Mp2tStreamParser::OnEmitVideoBuffer, base::Unretained(this), pes_pid); + EsParserAdts::GetDecryptConfigCB get_decrypt_config; + if (!emit_clear_buffers) { + get_decrypt_config = base::BindRepeating( + &Mp2tStreamParser::GetDecryptConfig, base::Unretained(this)); + } return std::make_unique<EsParserH264>( std::move(on_video_config_changed), on_emit_video_buffer, - initial_encryption_scheme_, get_decrypt_config); + initial_encryption_scheme_, std::move(get_decrypt_config)); } std::unique_ptr<EsParser> Mp2tStreamParser::CreateEncryptedAacParser( @@ -453,15 +455,17 @@ bool emit_clear_buffers) { auto on_audio_config_changed = base::Bind( &Mp2tStreamParser::OnAudioConfigChanged, base::Unretained(this), pes_pid); - auto on_emit_audio_buffer = base::Bind(&Mp2tStreamParser::OnEmitAudioBuffer, - base::Unretained(this), pes_pid); - auto get_decrypt_config = - emit_clear_buffers ? EsParser::GetDecryptConfigCB() - : base::Bind(&Mp2tStreamParser::GetDecryptConfig, - base::Unretained(this)); + auto on_emit_audio_buffer = base::BindRepeating( + &Mp2tStreamParser::OnEmitAudioBuffer, base::Unretained(this), pes_pid); + EsParserAdts::GetDecryptConfigCB get_decrypt_config; + if (!emit_clear_buffers) { + get_decrypt_config = base::BindRepeating( + &Mp2tStreamParser::GetDecryptConfig, base::Unretained(this)); + } return std::make_unique<EsParserAdts>( - on_audio_config_changed, on_emit_audio_buffer, get_decrypt_config, - initial_encryption_scheme_, sbr_in_mimetype_); + on_audio_config_changed, std::move(on_emit_audio_buffer), + std::move(get_decrypt_config), initial_encryption_scheme_, + sbr_in_mimetype_); } #endif
diff --git a/media/gpu/test/video_frame_file_writer.cc b/media/gpu/test/video_frame_file_writer.cc index 1df470a343..c5df651 100644 --- a/media/gpu/test/video_frame_file_writer.cc +++ b/media/gpu/test/video_frame_file_writer.cc
@@ -88,6 +88,13 @@ if (num_frames_writes_requested_ >= output_limit_) return; + if (video_frame->visible_rect().IsEmpty()) { + // This occurs in bitstream buffer in webrtc scenario. + DLOG(WARNING) << "Skipping writing, frame_index=" << frame_index + << " because visible_rect is empty"; + return; + } + num_frames_writes_requested_++; base::AutoLock auto_lock(frame_writer_lock_);
diff --git a/media/gpu/test/video_frame_validator.cc b/media/gpu/test/video_frame_validator.cc index 0f44c78..5fd9ac2 100644 --- a/media/gpu/test/video_frame_validator.cc +++ b/media/gpu/test/video_frame_validator.cc
@@ -146,6 +146,13 @@ ASSERT_TRUE(model_frame); } + if (video_frame->visible_rect().IsEmpty()) { + // This occurs in bitstream buffer in webrtc scenario. + DLOG(WARNING) << "Skipping validation, frame_index=" << frame_index + << " because visible_rect is empty"; + return; + } + base::AutoLock auto_lock(frame_validator_lock_); num_frames_validating_++;
diff --git a/media/gpu/test/video_test_helpers.cc b/media/gpu/test/video_test_helpers.cc index 426a564..e1ca359 100644 --- a/media/gpu/test/video_test_helpers.cc +++ b/media/gpu/test/video_test_helpers.cc
@@ -7,6 +7,7 @@ #include <limits> #include "base/stl_util.h" +#include "base/sys_byteorder.h" #include "media/base/video_decoder_config.h" #include "media/video/h264_parser.h" #include "testing/gtest/include/gtest/gtest.h" @@ -14,6 +15,20 @@ namespace media { namespace test { +// The structure for IVF frame header. IVF is a video file format. +// The helpful description is in https://wiki.multimedia.cx/index.php/IVF. +struct EncodedDataHelper::IVFHeader { + uint32_t frame_size; + uint64_t timestamp; +}; + +// The structure for IVF frame data and header. +// The data to be read is |header.frame_size| bytes from |data|. +struct EncodedDataHelper::IVFFrame { + const char* data; + IVFHeader header; +}; + EncodedDataHelper::EncodedDataHelper(const std::vector<uint8_t>& stream, VideoCodecProfile profile) : data_(std::string(reinterpret_cast<const char*>(stream.data()), @@ -94,39 +109,119 @@ scoped_refptr<DecoderBuffer> EncodedDataHelper::GetNextFrame() { // Helpful description: http://wiki.multimedia.cx/index.php?title=IVF constexpr size_t kIVFHeaderSize = 32; - constexpr size_t kIVFFrameHeaderSize = 12; - - size_t pos = next_pos_to_decode_; - // Only IVF video files are supported. The first 4bytes of an IVF video file's // header should be "DKIF". - if (pos == 0) { + if (next_pos_to_decode_ == 0) { if ((data_.size() < kIVFHeaderSize) || strncmp(&data_[0], "DKIF", 4) != 0) { LOG(ERROR) << "Unexpected data encountered while parsing IVF header"; return nullptr; } - pos = kIVFHeaderSize; // Skip IVF header. + next_pos_to_decode_ = kIVFHeaderSize; // Skip IVF header. } + // Group IVF data whose timestamps are the same. Spatial layers in a + // spatial-SVC stream may separately be stored in IVF data, where the + // timestamps of the IVF frame headers are the same. However, it is necessary + // for VD(A) to feed the spatial layers by a single DecoderBuffer. So this + // grouping is required. + std::vector<IVFFrame> ivf_frames; + while (!ReachEndOfStream()) { + auto frame_header = GetNextIVFFrameHeader(); + if (!frame_header) + return nullptr; + + // Timestamp is different from the current one. The next IVF data must be + // grouped in the next group. + if (!ivf_frames.empty() && + frame_header->timestamp != ivf_frames[0].header.timestamp) { + break; + } + + auto frame_data = ReadNextIVFFrame(); + if (!frame_data) + return nullptr; + + ivf_frames.push_back(*frame_data); + } + + if (ivf_frames.empty()) { + LOG(ERROR) << "No IVF frame is available"; + return nullptr; + } + + // Standard stream case. + if (ivf_frames.size() == 1) { + return DecoderBuffer::CopyFrom( + reinterpret_cast<const uint8_t*>(ivf_frames[0].data), + ivf_frames[0].header.frame_size); + } + + if (ivf_frames.size() > 3) { + LOG(ERROR) << "Number of IVF frames with same timestamps exceeds maximum of" + << "3: ivf_frames.size()=" << ivf_frames.size(); + return nullptr; + } + + std::string data; + std::vector<uint32_t> frame_sizes; + frame_sizes.reserve(ivf_frames.size()); + for (const IVFFrame& ivf : ivf_frames) { + data.append(ivf.data, ivf.header.frame_size); + frame_sizes.push_back(ivf.header.frame_size); + } + + // Copy frame_sizes information to DecoderBuffer's side data. Since side_data + // is uint8_t*, we need to copy as uint8_t from uint32_t. The copied data is + // recognized as uint32_t in VD(A). + const uint8_t* side_data = + reinterpret_cast<const uint8_t*>(frame_sizes.data()); + size_t side_data_size = + frame_sizes.size() * sizeof(uint32_t) / sizeof(uint8_t); + + return DecoderBuffer::CopyFrom(reinterpret_cast<const uint8_t*>(data.data()), + data.size(), side_data, side_data_size); +} + +base::Optional<EncodedDataHelper::IVFHeader> +EncodedDataHelper::GetNextIVFFrameHeader() const { + constexpr size_t kIVFFrameHeaderSize = 12; + + const size_t pos = next_pos_to_decode_; + // Read VP8/9 frame size from IVF header. if (pos + kIVFFrameHeaderSize > data_.size()) { LOG(ERROR) << "Unexpected data encountered while parsing IVF frame header"; - return nullptr; + return base::nullopt; } - const uint32_t frame_size = *reinterpret_cast<uint32_t*>(&data_[pos]); - pos += kIVFFrameHeaderSize; // Skip IVF frame header. + + uint32_t frame_size = 0; + uint64_t timestamp = 0; + memcpy(&frame_size, &data_[pos], 4); + memcpy(×tamp, &data_[pos + 4], 8); + return IVFHeader{frame_size, timestamp}; +} + +base::Optional<EncodedDataHelper::IVFFrame> +EncodedDataHelper::ReadNextIVFFrame() { + constexpr size_t kIVFFrameHeaderSize = 12; + auto frame_header = GetNextIVFFrameHeader(); + if (!frame_header) + return base::nullopt; + + // Skip IVF frame header. + const size_t pos = next_pos_to_decode_ + kIVFFrameHeaderSize; // Make sure we are not reading out of bounds. - if (pos + frame_size > data_.size()) { + if (pos + frame_header->frame_size > data_.size()) { LOG(ERROR) << "Unexpected data encountered while parsing IVF frame header"; next_pos_to_decode_ = data_.size(); - return nullptr; + return base::nullopt; } // Update next_pos_to_decode_. - next_pos_to_decode_ = pos + frame_size; - return DecoderBuffer::CopyFrom(reinterpret_cast<const uint8_t*>(&data_[pos]), - frame_size); + next_pos_to_decode_ = pos + frame_header->frame_size; + + return IVFFrame{&data_[pos], *frame_header}; } // static
diff --git a/media/gpu/test/video_test_helpers.h b/media/gpu/test/video_test_helpers.h index cffff22..5908510 100644 --- a/media/gpu/test/video_test_helpers.h +++ b/media/gpu/test/video_test_helpers.h
@@ -87,10 +87,15 @@ size_t num_skipped_fragments() { return num_skipped_fragments_; } private: + struct IVFHeader; + struct IVFFrame; + // For h.264. scoped_refptr<DecoderBuffer> GetNextFragment(); // For VP8/9. scoped_refptr<DecoderBuffer> GetNextFrame(); + base::Optional<IVFHeader> GetNextIVFFrameHeader() const; + base::Optional<IVFFrame> ReadNextIVFFrame(); // Helpers for GetBytesForNextFragment above. size_t GetBytesForNextNALU(size_t pos);
diff --git a/net/dns/mdns_cache.h b/net/dns/mdns_cache.h index d1ea1c1..6e91a9c0 100644 --- a/net/dns/mdns_cache.h +++ b/net/dns/mdns_cache.h
@@ -50,7 +50,8 @@ std::string optional_; }; - typedef base::Callback<void(const RecordParsed*)> RecordRemovedCallback; + typedef base::RepeatingCallback<void(const RecordParsed*)> + RecordRemovedCallback; enum UpdateType { RecordAdded,
diff --git a/net/dns/mdns_cache_unittest.cc b/net/dns/mdns_cache_unittest.cc index 2e4ee8f..aa83e615 100644 --- a/net/dns/mdns_cache_unittest.cc +++ b/net/dns/mdns_cache_unittest.cc
@@ -184,8 +184,10 @@ EXPECT_CALL(record_removal_, OnRecordRemoved(record_to_be_deleted)); - cache_.CleanupRecords(default_time_ + ttl2, base::Bind( - &RecordRemovalMock::OnRecordRemoved, base::Unretained(&record_removal_))); + cache_.CleanupRecords( + default_time_ + ttl2, + base::BindRepeating(&RecordRemovalMock::OnRecordRemoved, + base::Unretained(&record_removal_))); // To make sure that we've indeed removed them from the map, check no funny // business happens once they're deleted for good.
diff --git a/net/dns/mdns_client_impl.cc b/net/dns/mdns_client_impl.cc index 050d40c..65adb27 100644 --- a/net/dns/mdns_client_impl.cc +++ b/net/dns/mdns_client_impl.cc
@@ -402,9 +402,9 @@ } void MDnsClientImpl::Core::DoCleanup() { - cache_.CleanupRecords(clock_->Now(), - base::Bind(&MDnsClientImpl::Core::OnRecordRemoved, - base::Unretained(this))); + cache_.CleanupRecords( + clock_->Now(), base::BindRepeating(&MDnsClientImpl::Core::OnRecordRemoved, + base::Unretained(this))); ScheduleCleanup(cache_.next_expiration()); }
diff --git a/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.cc b/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.cc index deb86879..406b430 100644 --- a/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.cc +++ b/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.cc
@@ -63,10 +63,10 @@ scoped_refptr<DhcpQuery> dhcp_query(ImplCreateDhcpQuery()); task_runner_->PostTaskAndReply( FROM_HERE, - base::Bind(&DhcpPacFileAdapterFetcher::DhcpQuery::GetPacURLForAdapter, - dhcp_query.get(), adapter_name), - base::Bind(&DhcpPacFileAdapterFetcher::OnDhcpQueryDone, AsWeakPtr(), - dhcp_query, traffic_annotation)); + base::BindOnce(&DhcpPacFileAdapterFetcher::DhcpQuery::GetPacURLForAdapter, + dhcp_query.get(), adapter_name), + base::BindOnce(&DhcpPacFileAdapterFetcher::OnDhcpQueryDone, AsWeakPtr(), + dhcp_query, traffic_annotation)); } void DhcpPacFileAdapterFetcher::Cancel() { @@ -154,10 +154,11 @@ } else { state_ = STATE_WAIT_URL; script_fetcher_ = ImplCreateScriptFetcher(); - script_fetcher_->Fetch(pac_url_, &pac_script_, - base::Bind(&DhcpPacFileAdapterFetcher::OnFetcherDone, - base::Unretained(this)), - traffic_annotation); + script_fetcher_->Fetch( + pac_url_, &pac_script_, + base::BindOnce(&DhcpPacFileAdapterFetcher::OnFetcherDone, + base::Unretained(this)), + traffic_annotation); } }
diff --git a/net/proxy_resolution/dhcp_pac_file_fetcher_win.cc b/net/proxy_resolution/dhcp_pac_file_fetcher_win.cc index 8b75311..7990f189 100644 --- a/net/proxy_resolution/dhcp_pac_file_fetcher_win.cc +++ b/net/proxy_resolution/dhcp_pac_file_fetcher_win.cc
@@ -299,10 +299,11 @@ task_runner_->PostTaskAndReply( FROM_HERE, - base::Bind(&DhcpPacFileFetcherWin::AdapterQuery::GetCandidateAdapterNames, - last_query_.get()), - base::Bind(&DhcpPacFileFetcherWin::OnGetCandidateAdapterNamesDone, - AsWeakPtr(), last_query_, traffic_annotation)); + base::BindOnce( + &DhcpPacFileFetcherWin::AdapterQuery::GetCandidateAdapterNames, + last_query_.get()), + base::BindOnce(&DhcpPacFileFetcherWin::OnGetCandidateAdapterNamesDone, + AsWeakPtr(), last_query_, traffic_annotation)); return ERR_IO_PENDING; } @@ -380,8 +381,8 @@ ImplCreateAdapterFetcher()); size_t fetcher_index = fetchers_.size(); fetcher->Fetch(adapter_name, - base::Bind(&DhcpPacFileFetcherWin::OnFetcherDone, - base::Unretained(this), fetcher_index), + base::BindOnce(&DhcpPacFileFetcherWin::OnFetcherDone, + base::Unretained(this), fetcher_index), traffic_annotation); fetchers_.push_back(std::move(fetcher)); }
diff --git a/net/proxy_resolution/dhcp_pac_file_fetcher_win_unittest.cc b/net/proxy_resolution/dhcp_pac_file_fetcher_win_unittest.cc index 9deabb4..1bd7736 100644 --- a/net/proxy_resolution/dhcp_pac_file_fetcher_win_unittest.cc +++ b/net/proxy_resolution/dhcp_pac_file_fetcher_win_unittest.cc
@@ -60,7 +60,7 @@ void RunTest() { int result = fetcher_->Fetch( &pac_text_, - base::Bind(&RealFetchTester::OnCompletion, base::Unretained(this)), + base::BindOnce(&RealFetchTester::OnCompletion, base::Unretained(this)), NetLogWithSource(), TRAFFIC_ANNOTATION_FOR_TESTS); if (result != ERR_IO_PENDING) finished_ = true; @@ -386,7 +386,7 @@ void RunTest() { int result = fetcher_.Fetch( &pac_text_, - base::Bind(&FetcherClient::OnCompletion, base::Unretained(this)), + base::BindOnce(&FetcherClient::OnCompletion, base::Unretained(this)), NetLogWithSource(), TRAFFIC_ANNOTATION_FOR_TESTS); ASSERT_THAT(result, IsError(ERR_IO_PENDING)); } @@ -394,7 +394,7 @@ int RunTestThatMayFailSync() { int result = fetcher_.Fetch( &pac_text_, - base::Bind(&FetcherClient::OnCompletion, base::Unretained(this)), + base::BindOnce(&FetcherClient::OnCompletion, base::Unretained(this)), NetLogWithSource(), TRAFFIC_ANNOTATION_FOR_TESTS); if (result != ERR_IO_PENDING) result_ = result;
diff --git a/remoting/host/input_monitor/BUILD.gn b/remoting/host/input_monitor/BUILD.gn index 3fde2d1..c25d0c5 100644 --- a/remoting/host/input_monitor/BUILD.gn +++ b/remoting/host/input_monitor/BUILD.gn
@@ -31,6 +31,7 @@ deps = [ "//remoting/proto", "//third_party/webrtc_overrides:webrtc_component", + "//ui/events", ] if (use_ozone) {
diff --git a/services/tracing/BUILD.gn b/services/tracing/BUILD.gn index 101b8c61..8a4a066 100644 --- a/services/tracing/BUILD.gn +++ b/services/tracing/BUILD.gn
@@ -47,7 +47,6 @@ deps = [ "//base", "//third_party/perfetto:libperfetto", - "//third_party/perfetto/src/protozero:protozero", ] }
diff --git a/services/tracing/perfetto/perfetto_service.cc b/services/tracing/perfetto/perfetto_service.cc index 93222c1..de5e660b 100644 --- a/services/tracing/perfetto/perfetto_service.cc +++ b/services/tracing/perfetto/perfetto_service.cc
@@ -12,6 +12,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/task/post_task.h" +#include "mojo/public/cpp/bindings/message.h" #include "services/tracing/perfetto/consumer_host.h" #include "services/tracing/perfetto/producer_host.h" #include "services/tracing/public/cpp/perfetto/shared_memory.h" @@ -62,7 +63,6 @@ // Chromium uses scraping of the shared memory chunks to ensure that data // from threads without a MessageLoop doesn't get lost. service_->SetSMBScrapingEnabled(true); - DCHECK(service_); receivers_.set_disconnect_handler(base::BindRepeating( &PerfettoService::OnServiceDisconnect, base::Unretained(this))); @@ -85,12 +85,25 @@ void PerfettoService::ConnectToProducerHost( mojo::PendingRemote<mojom::ProducerClient> producer_client, - mojo::PendingReceiver<mojom::ProducerHost> producer_host_receiver) { - auto new_producer = std::make_unique<ProducerHost>(); + mojo::PendingReceiver<mojom::ProducerHost> producer_host_receiver, + mojo::ScopedSharedBufferHandle shared_memory, + uint64_t shared_memory_buffer_page_size_bytes) { + if (!shared_memory.is_valid()) { + mojo::ReportBadMessage("Producer connection request without valid SMB"); + return; + } + + auto new_producer = std::make_unique<ProducerHost>(&perfetto_task_runner_); uint32_t producer_pid = receivers_.current_context(); - new_producer->Initialize(std::move(producer_client), service_.get(), - base::StrCat({mojom::kPerfettoProducerNamePrefix, - base::NumberToString(producer_pid)})); + DCHECK(shared_memory.is_valid()); + if (!new_producer->Initialize( + std::move(producer_client), service_.get(), + base::StrCat({mojom::kPerfettoProducerNamePrefix, + base::NumberToString(producer_pid)}), + std::move(shared_memory), shared_memory_buffer_page_size_bytes)) { + mojo::ReportBadMessage("Producer connection failed"); + return; + } ++num_active_connections_[producer_pid]; producer_receivers_.Add(std::move(new_producer),
diff --git a/services/tracing/perfetto/perfetto_service.h b/services/tracing/perfetto/perfetto_service.h index 64e6183..a54618f 100644 --- a/services/tracing/perfetto/perfetto_service.h +++ b/services/tracing/perfetto/perfetto_service.h
@@ -43,8 +43,9 @@ // mojom::PerfettoService implementation. void ConnectToProducerHost( mojo::PendingRemote<mojom::ProducerClient> producer_client, - mojo::PendingReceiver<mojom::ProducerHost> producer_host_receiver) - override; + mojo::PendingReceiver<mojom::ProducerHost> producer_host_receiver, + mojo::ScopedSharedBufferHandle shared_memory, + uint64_t shared_memory_buffer_page_size_bytes) override; perfetto::TracingService* GetService() const; @@ -74,6 +75,8 @@ return active_service_pids_initialized_; } + PerfettoTaskRunner* perfetto_task_runner() { return &perfetto_task_runner_; } + private: void BindOnSequence(mojo::PendingReceiver<mojom::PerfettoService> receiver); void CreateServiceOnSequence();
diff --git a/services/tracing/perfetto/producer_host.cc b/services/tracing/perfetto/producer_host.cc index 1cdc0788..e2e77e3dd 100644 --- a/services/tracing/perfetto/producer_host.cc +++ b/services/tracing/perfetto/producer_host.cc
@@ -12,6 +12,7 @@ #include "services/tracing/perfetto/perfetto_service.h" #include "services/tracing/public/cpp/perfetto/producer_client.h" #include "services/tracing/public/cpp/perfetto/shared_memory.h" +#include "services/tracing/public/cpp/perfetto/task_runner.h" #include "services/tracing/public/cpp/tracing_features.h" #include "third_party/perfetto/include/perfetto/ext/tracing/core/commit_data_request.h" #include "third_party/perfetto/include/perfetto/tracing/core/data_source_descriptor.h" @@ -19,16 +20,8 @@ namespace tracing { -// TODO(oysteine): Find a good compromise between performance and -// data granularity (mainly relevant to running with small buffer sizes -// when we use background tracing) on Android. -#if defined(OS_ANDROID) -constexpr size_t kSMBPageSizeInBytes = 4 * 1024; -#else -constexpr size_t kSMBPageSizeInBytes = 32 * 1024; -#endif - -ProducerHost::ProducerHost() = default; +ProducerHost::ProducerHost(PerfettoTaskRunner* task_runner) + : task_runner_(task_runner) {} ProducerHost::~ProducerHost() { // Manually reset to prevent any callbacks from the ProducerEndpoint @@ -36,44 +29,52 @@ producer_endpoint_.reset(); } -void ProducerHost::Initialize( +bool ProducerHost::Initialize( mojo::PendingRemote<mojom::ProducerClient> producer_client, perfetto::TracingService* service, - const std::string& name) { + const std::string& name, + mojo::ScopedSharedBufferHandle shared_memory, + uint64_t shared_memory_buffer_page_size_bytes) { DCHECK(service); DCHECK(!producer_endpoint_); producer_client_.Bind(std::move(producer_client)); - // Attempt to parse the PID out of the producer name. - // If the Producer is in-process, we: - // * Signal Perfetto that it should create and manage its own - // SharedMemoryArbiter - // when we call ConnectProducer. - // * Set the local ProducerClient instance to use this SMA instead of passing - // an SMB handle over Mojo and letting it create its own. - // * After that point, any TraceWriter created by TraceEventDataSource will - // use this in-process SMA, and hence be able to synchronously flush full - // SMB chunks if we're running on the same sequence as the Perfetto service, - // hence we avoid any deadlocking occurring from trace events emitted from - // the Perfetto sequence filling up the SMB and stalling while waiting for - // Perfetto to free the chunks. - if (!base::FeatureList::IsEnabled( - features::kPerfettoForceOutOfProcessProducer)) { - base::ProcessId pid; - if (PerfettoService::ParsePidFromProducerName(name, &pid)) { - is_in_process_ = (pid == base::Process::Current().Pid()); + auto shm = std::make_unique<MojoSharedMemory>(std::move(shared_memory)); + size_t shm_size = shm->size(); + MojoSharedMemory* shm_raw = shm.get(); + + // TODO(oysteine): Figure out a uid once we need it. + producer_endpoint_ = service->ConnectProducer( + this, 0 /* uid */, name, shm_size, /*in_process=*/false, + perfetto::TracingService::ProducerSMBScrapingMode::kDefault, + shared_memory_buffer_page_size_bytes, std::move(shm)); + + // In some cases, the service may deny the producer connection (e.g. if too + // many producers are registered). The service will adopt the shared memory + // buffer provided by the ProducerClient as long as it is correctly sized. + if (!producer_endpoint_ || producer_endpoint_->shared_memory() != shm_raw) { + return false; + } + + // When we are in-process, we don't use the in-process arbiter perfetto would + // provide (thus pass |in_process = false| to ConnectProducer), but rather + // bind the ProducerClient's arbiter to the service's endpoint and task runner + // directly. This allows us to use startup tracing via an unbound SMA, while + // avoiding some cross-sequence PostTasks when committing chunks (since we + // bypass mojo). + base::ProcessId pid; + if (PerfettoService::ParsePidFromProducerName(name, &pid)) { + bool in_process = (pid == base::Process::Current().Pid()); + if (in_process) { + PerfettoTracedProcess::Get() + ->producer_client() + ->BindInProcessSharedMemoryArbiter(producer_endpoint_.get(), + task_runner_); } } - // TODO(oysteine): Figure out an uid once we need it. - // TODO(oysteine): Figure out a good buffer size. - producer_endpoint_ = service->ConnectProducer( - this, 0 /* uid */, name, - /*shared_memory_size_hint_bytes=*/4 * 1024 * 1024, is_in_process_, - perfetto::TracingService::ProducerSMBScrapingMode::kDefault, - /*shared_memory_page_size_hint_bytes=*/kSMBPageSizeInBytes); - DCHECK(producer_endpoint_); + return true; } void ProducerHost::OnConnect() { @@ -85,24 +86,7 @@ } void ProducerHost::OnTracingSetup() { - if (is_in_process_) { - DCHECK(producer_endpoint_->MaybeSharedMemoryArbiter()); - PerfettoTracedProcess::Get() - ->producer_client() - ->set_in_process_shmem_arbiter( - producer_endpoint_->MaybeSharedMemoryArbiter()); - return; - } - - MojoSharedMemory* shared_memory = - static_cast<MojoSharedMemory*>(producer_endpoint_->shared_memory()); - DCHECK(shared_memory); - DCHECK(producer_client_); - mojo::ScopedSharedBufferHandle shm = shared_memory->Clone(); - DCHECK(shm.is_valid()); - - producer_client_->OnTracingStart( - std::move(shm), producer_endpoint_->shared_buffer_page_size_kb() * 1024); + producer_client_->OnTracingStart(); } void ProducerHost::SetupDataSource(perfetto::DataSourceInstanceID,
diff --git a/services/tracing/perfetto/producer_host.h b/services/tracing/perfetto/producer_host.h index 45a0468..b93aafa 100644 --- a/services/tracing/perfetto/producer_host.h +++ b/services/tracing/perfetto/producer_host.h
@@ -20,6 +20,8 @@ namespace tracing { +class PerfettoTaskRunner; + // This class is the service-side part of the Perfetto Producer pair // and is responsible for registering any available DataSources // with Perfetto (like ChromeTracing) in OnConnect(). It will forward @@ -32,15 +34,18 @@ class ProducerHost : public tracing::mojom::ProducerHost, public perfetto::Producer { public: - ProducerHost(); + explicit ProducerHost(PerfettoTaskRunner*); ~ProducerHost() override; - // Called by the ProducerService to register the - // Producer with Perfetto and connect to the - // corresponding remote ProducerClient. - void Initialize(mojo::PendingRemote<mojom::ProducerClient> producer_client, + // Called by the ProducerService to register the Producer with Perfetto, + // connect to the corresponding remote ProducerClient, and setup the provided + // shared memory buffer for tracing data exchange. Returns false if the + // service failed to connect the producer or adopt the provided SMB. + bool Initialize(mojo::PendingRemote<mojom::ProducerClient> producer_client, perfetto::TracingService* service, - const std::string& name); + const std::string& name, + mojo::ScopedSharedBufferHandle shared_memory, + uint64_t shared_memory_buffer_page_size_bytes); // perfetto::Producer implementation. // Gets called by perfetto::TracingService to toggle specific data sources @@ -87,7 +92,7 @@ private: mojo::Remote<mojom::ProducerClient> producer_client_; - bool is_in_process_ = false; + PerfettoTaskRunner* task_runner_; protected: // Perfetto guarantees that no OnXX callbacks are invoked on |this|
diff --git a/services/tracing/perfetto/test_utils.cc b/services/tracing/perfetto/test_utils.cc index ed0f85c..de63052 100644 --- a/services/tracing/perfetto/test_utils.cc +++ b/services/tracing/perfetto/test_utils.cc
@@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/run_loop.h" +#include "services/tracing/public/cpp/perfetto/shared_memory.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/perfetto/include/perfetto/ext/tracing/core/commit_data_request.h" #include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_packet.h" @@ -111,6 +112,9 @@ client.reset(this); old_producer_ = PerfettoTracedProcess::Get()->SetProducerClientForTesting( std::move(client)); + + // Create SMB immediately since we never call ProducerClient's Connect(). + CHECK(InitSharedMemoryIfNeeded()); } MockProducerClient::~MockProducerClient() { @@ -305,13 +309,18 @@ PerfettoService* service, MockProducerClient* producer_client, base::OnceClosure datasource_registered_callback) - : producer_name_(producer_name), + : ProducerHost(service->perfetto_task_runner()), + producer_name_(producer_name), datasource_registered_callback_( std::move(datasource_registered_callback)) { mojo::PendingRemote<mojom::ProducerClient> client; mojo::PendingRemote<mojom::ProducerHost> host_remote; auto client_receiver = client.InitWithNewPipeAndPassReceiver(); - Initialize(std::move(client), service->GetService(), producer_name_); + Initialize(std::move(client), service->GetService(), producer_name_, + static_cast<MojoSharedMemory*>( + producer_client->shared_memory_for_testing()) + ->Clone(), + PerfettoProducer::kSMBPageSizeBytes); receiver_.Bind(host_remote.InitWithNewPipeAndPassReceiver()); producer_client->BindClientAndHostPipesForTesting(std::move(client_receiver), std::move(host_remote));
diff --git a/services/tracing/public/cpp/BUILD.gn b/services/tracing/public/cpp/BUILD.gn index 4e333ca..f1e605d 100644 --- a/services/tracing/public/cpp/BUILD.gn +++ b/services/tracing/public/cpp/BUILD.gn
@@ -56,6 +56,8 @@ "base_agent.h", "perfetto/dummy_producer.cc", "perfetto/dummy_producer.h", + "perfetto/flow_event_utils.cc", + "perfetto/flow_event_utils.h", "perfetto/interning_index.h", "perfetto/java_heap_profiler/hprof_buffer_android.cc", "perfetto/java_heap_profiler/hprof_buffer_android.h",
diff --git a/services/tracing/public/cpp/perfetto/dummy_producer.cc b/services/tracing/public/cpp/perfetto/dummy_producer.cc index 4669dda..0b42e82 100644 --- a/services/tracing/public/cpp/perfetto/dummy_producer.cc +++ b/services/tracing/public/cpp/perfetto/dummy_producer.cc
@@ -27,6 +27,9 @@ size_t num_data_sources) {} // PerfettoProducer implementation. +bool DummyProducer::SetupStartupTracing() { + return false; +} perfetto::SharedMemoryArbiter* DummyProducer::MaybeSharedMemoryArbiter() { return nullptr; }
diff --git a/services/tracing/public/cpp/perfetto/dummy_producer.h b/services/tracing/public/cpp/perfetto/dummy_producer.h index b03cae5..2fff6a0 100644 --- a/services/tracing/public/cpp/perfetto/dummy_producer.h +++ b/services/tracing/public/cpp/perfetto/dummy_producer.h
@@ -32,6 +32,7 @@ size_t num_data_sources) override; // PerfettoProducer implementation. + bool SetupStartupTracing() override; perfetto::SharedMemoryArbiter* MaybeSharedMemoryArbiter() override; bool IsTracingActive() override; void NewDataSourceAdded(
diff --git a/services/tracing/public/cpp/perfetto/flow_event_utils.cc b/services/tracing/public/cpp/perfetto/flow_event_utils.cc new file mode 100644 index 0000000..055019ca --- /dev/null +++ b/services/tracing/public/cpp/perfetto/flow_event_utils.cc
@@ -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. + +#include "services/tracing/public/cpp/perfetto/flow_event_utils.h" + +namespace tracing { + +// Fill the information about flow event in EventContext. +// +// BEWARE: this function currently sets the TrackEvent's LegacyEvent field, and +// thus should be used from within trace macros that do not set the LegacyEvent +// field themselves. As it is, it is fine to call this method from the typed +// TRACE_EVENT macro. +// +// TODO(b/TODO): Change to the new model flow events when finalized +void FillFlowEvent( + const perfetto::EventContext& ctx, + perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection direction, + uint64_t bind_id) { + perfetto::protos::pbzero::TrackEvent_LegacyEvent* legacy_event = + ctx.event()->set_legacy_event(); + legacy_event->set_flow_direction(direction); + legacy_event->set_bind_id(bind_id); +} + +} // namespace tracing \ No newline at end of file
diff --git a/services/tracing/public/cpp/perfetto/flow_event_utils.h b/services/tracing/public/cpp/perfetto/flow_event_utils.h new file mode 100644 index 0000000..de5694d --- /dev/null +++ b/services/tracing/public/cpp/perfetto/flow_event_utils.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 SERVICES_TRACING_PUBLIC_CPP_PERFETTO_FLOW_EVENT_UTILS_H_ +#define SERVICES_TRACING_PUBLIC_CPP_PERFETTO_FLOW_EVENT_UTILS_H_ + +#include "base/component_export.h" +#include "services/tracing/public/cpp/perfetto/macros.h" +#include "third_party/perfetto/protos/perfetto/trace/track_event/chrome_latency_info.pbzero.h" +#include "third_party/perfetto/protos/perfetto/trace/track_event/track_event.pbzero.h" + +namespace tracing { + +// Fill the information about flow event in EventContext. +// +// BEWARE: this function currently sets the TrackEvent's LegacyEvent field, and +// thus should be used from within trace macros that do not set the LegacyEvent +// field themselves. As it is, it is fine to call this method from the typed +// TRACE_EVENT macro. +// +// TODO(b/147673438): Change to the new model flow events when finalized +void COMPONENT_EXPORT(TRACING_CPP) FillFlowEvent( + const perfetto::EventContext&, + perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection, + uint64_t bind_id); + +} // namespace tracing + +#endif // SERVICES_TRACING_PUBLIC_CPP_PERFETTO_FLOW_EVENT_UTILS_H_
diff --git a/services/tracing/public/cpp/perfetto/macros.h b/services/tracing/public/cpp/perfetto/macros.h index 935fdbd..3d7b473 100644 --- a/services/tracing/public/cpp/perfetto/macros.h +++ b/services/tracing/public/cpp/perfetto/macros.h
@@ -43,6 +43,8 @@ // auto* event = ctx.event(); // // Fill in some field in track_event. // }); +// +// When lambda is passed as an argument, it is executed synchronously. #define TRACE_EVENT_BEGIN(category, name, ...) \ TRACING_INTERNAL_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_BEGIN, category, name, \ TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__) @@ -55,6 +57,9 @@ // Begin a thread-scoped slice which gets automatically closed when going out // of scope. +// +// Similarly to TRACE_EVENT_BEGIN, when lambda is passed as an argument, it is +// executed synchronously. #define TRACE_EVENT(category, name, ...) \ TRACING_INTERNAL_SCOPED_ADD_TRACE_EVENT(category, name, ##__VA_ARGS__)
diff --git a/services/tracing/public/cpp/perfetto/perfetto_producer.cc b/services/tracing/public/cpp/perfetto/perfetto_producer.cc index f7457d7b..1f26548 100644 --- a/services/tracing/public/cpp/perfetto/perfetto_producer.cc +++ b/services/tracing/public/cpp/perfetto/perfetto_producer.cc
@@ -10,6 +10,12 @@ namespace tracing { +// static +constexpr size_t PerfettoProducer::kSMBPageSizeBytes; + +// static +constexpr size_t PerfettoProducer::kSMBSizeBytes; + PerfettoProducer::PerfettoProducer(PerfettoTaskRunner* task_runner) : task_runner_(task_runner) { DCHECK(task_runner_); @@ -17,12 +23,19 @@ PerfettoProducer::~PerfettoProducer() = default; -void PerfettoProducer::BindStartupTraceWriterRegistry( - std::unique_ptr<perfetto::StartupTraceWriterRegistry> registry, - perfetto::BufferID target_buffer) { +std::unique_ptr<perfetto::TraceWriter> +PerfettoProducer::CreateStartupTraceWriter(uint32_t startup_session_id) { DCHECK(MaybeSharedMemoryArbiter()); - return MaybeSharedMemoryArbiter()->BindStartupTraceWriterRegistry( - std::move(registry), target_buffer); + return MaybeSharedMemoryArbiter()->CreateStartupTraceWriter( + startup_session_id); +} + +void PerfettoProducer::BindStartupTargetBuffer( + uint32_t startup_session_id, + perfetto::BufferID startup_target_buffer) { + DCHECK(MaybeSharedMemoryArbiter()); + MaybeSharedMemoryArbiter()->BindStartupTargetBuffer(startup_session_id, + startup_target_buffer); } std::unique_ptr<perfetto::TraceWriter> PerfettoProducer::CreateTraceWriter(
diff --git a/services/tracing/public/cpp/perfetto/perfetto_producer.h b/services/tracing/public/cpp/perfetto/perfetto_producer.h index cd5b9db..9997120 100644 --- a/services/tracing/public/cpp/perfetto/perfetto_producer.h +++ b/services/tracing/public/cpp/perfetto/perfetto_producer.h
@@ -8,12 +8,13 @@ #include <memory> #include "base/component_export.h" +#include "build/build_config.h" #include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/basic_types.h" #include "third_party/perfetto/include/perfetto/ext/tracing/core/tracing_service.h" namespace perfetto { class SharedMemoryArbiter; -class StartupTraceWriterRegistry; } // namespace perfetto namespace tracing { @@ -30,15 +31,19 @@ virtual ~PerfettoProducer(); - // Binds the registry and its trace writers to the ProducerClient's SMB, to - // write into the given target buffer. The ownership of |registry| is - // transferred to PerfettoProducer (and its SharedMemoryArbiter). - // - // Should only be called while a tracing session is active and a - // SharedMemoryArbiter exists. - void BindStartupTraceWriterRegistry( - std::unique_ptr<perfetto::StartupTraceWriterRegistry> registry, - perfetto::BufferID target_buffer); + // Setup the shared memory buffer for startup tracing. Returns false on + // failure. + virtual bool SetupStartupTracing() = 0; + + // See SharedMemoryArbiter::CreateStartupTraceWriter. + std::unique_ptr<perfetto::TraceWriter> CreateStartupTraceWriter( + uint32_t startup_session_id); + + // See SharedMemoryArbiter::BindStartupTargetBuffer. Should be called on the + // producer's task runner. + virtual void BindStartupTargetBuffer( + uint32_t startup_session_id, + perfetto::BufferID startup_target_buffer); // Used by the DataSource implementations to create TraceWriters // for writing their protobufs, and respond to flushes. @@ -71,6 +76,20 @@ std::unique_ptr<PerfettoProducer> perfetto_producer); protected: + friend class MockProducerHost; + + // TODO(oysteine): Find a good compromise between performance and + // data granularity (mainly relevant to running with small buffer sizes + // when we use background tracing) on Android. +#if defined(OS_ANDROID) + static constexpr size_t kSMBPageSizeBytes = 4 * 1024; +#else + static constexpr size_t kSMBPageSizeBytes = 32 * 1024; +#endif + + // TODO(oysteine): Figure out a good buffer size. + static constexpr size_t kSMBSizeBytes = 4 * 1024 * 1024; + PerfettoTaskRunner* task_runner(); private:
diff --git a/services/tracing/public/cpp/perfetto/perfetto_traced_process.cc b/services/tracing/public/cpp/perfetto/perfetto_traced_process.cc index ae29b913..d9aded1 100644 --- a/services/tracing/public/cpp/perfetto/perfetto_traced_process.cc +++ b/services/tracing/public/cpp/perfetto/perfetto_traced_process.cc
@@ -62,7 +62,8 @@ PerfettoProducer* producer, const perfetto::DataSourceConfig& data_source_config) { data_source_id_ = data_source_id; - DCHECK(!producer_) << name_; + // Producer may already be set if startup tracing in TraceEventDataSource. + DCHECK(!producer_ || producer_ == producer) << name_; producer_ = producer; StartTracing(producer_, data_source_config); }
diff --git a/services/tracing/public/cpp/perfetto/posix_system_producer.cc b/services/tracing/public/cpp/perfetto/posix_system_producer.cc index b97c6d4a..1f041619 100644 --- a/services/tracing/public/cpp/perfetto/posix_system_producer.cc +++ b/services/tracing/public/cpp/perfetto/posix_system_producer.cc
@@ -93,6 +93,12 @@ DisconnectWithReply(base::OnceClosure()); } +bool PosixSystemProducer::SetupStartupTracing() { + // TODO(eseckler): Support startup tracing using an unbound SMA. + NOTIMPLEMENTED(); + return false; +} + perfetto::SharedMemoryArbiter* PosixSystemProducer::MaybeSharedMemoryArbiter() { base::AutoLock lock(services_lock_); DCHECK(GetService());
diff --git a/services/tracing/public/cpp/perfetto/posix_system_producer.h b/services/tracing/public/cpp/perfetto/posix_system_producer.h index 7aa6771..d814f6f 100644 --- a/services/tracing/public/cpp/perfetto/posix_system_producer.h +++ b/services/tracing/public/cpp/perfetto/posix_system_producer.h
@@ -54,6 +54,7 @@ void SetNewSocketForTesting(const char* socket); // PerfettoProducer implementation. + bool SetupStartupTracing() override; perfetto::SharedMemoryArbiter* MaybeSharedMemoryArbiter() override; void NewDataSourceAdded( const PerfettoTracedProcess::DataSourceBase* const data_source) override;
diff --git a/services/tracing/public/cpp/perfetto/producer_client.cc b/services/tracing/public/cpp/perfetto/producer_client.cc index 50fa86f75..e2d4287 100644 --- a/services/tracing/public/cpp/perfetto/producer_client.cc +++ b/services/tracing/public/cpp/perfetto/producer_client.cc
@@ -7,9 +7,11 @@ #include <utility> #include "base/bind.h" +#include "base/debug/dump_without_crashing.h" #include "base/no_destructor.h" #include "base/process/process.h" #include "base/task/post_task.h" +#include "build/build_config.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/tracing/public/cpp/perfetto/shared_memory.h" #include "services/tracing/public/cpp/perfetto/trace_event_data_source.h" @@ -36,13 +38,26 @@ void ProducerClient::Connect( mojo::PendingRemote<mojom::PerfettoService> perfetto_service) { + if (!InitSharedMemoryIfNeeded()) { + LOG(ERROR) << "Failed to setup tracing service connection for this process"; + return; + } + + mojo::ScopedSharedBufferHandle shm; + { + base::AutoLock lock(shared_memory_lock_); + shm = shared_memory_->Clone(); + } + CHECK(shm.is_valid()); + mojo::PendingRemote<mojom::ProducerClient> client; auto client_receiver = client.InitWithNewPipeAndPassReceiver(); mojo::PendingRemote<mojom::ProducerHost> producer_host_remote; mojo::Remote<mojom::PerfettoService>(std::move(perfetto_service)) ->ConnectToProducerHost( std::move(client), - producer_host_remote.InitWithNewPipeAndPassReceiver()); + producer_host_remote.InitWithNewPipeAndPassReceiver(), std::move(shm), + kSMBPageSizeBytes); task_runner()->GetOrCreateTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&ProducerClient::BindClientAndHostPipesOnSequence, @@ -50,9 +65,51 @@ std::move(producer_host_remote))); } +void ProducerClient::BindInProcessSharedMemoryArbiter( + perfetto::TracingService::ProducerEndpoint* producer_endpoint, + PerfettoTaskRunner* task_runner) { + DCHECK(!in_process_arbiter_task_runner_); + in_process_arbiter_task_runner_ = task_runner; + + perfetto::SharedMemoryArbiter* arbiter; + { + base::AutoLock lock(shared_memory_lock_); + // Shared memory should have been created before connecting to ProducerHost. + DCHECK(shared_memory_arbiter_); + // |shared_memory_arbiter_| is never destroyed, thus OK to call + // BindToProducerEndpoint() without holding the lock. + arbiter = shared_memory_arbiter_.get(); + } + arbiter->BindToProducerEndpoint(producer_endpoint, task_runner); +} + +bool ProducerClient::SetupStartupTracing() { + return InitSharedMemoryIfNeeded(); +} + +void ProducerClient::BindStartupTargetBuffer( + uint32_t startup_session_id, + perfetto::BufferID startup_target_buffer) { + // While we should be called on the ProducerClient's task runner, it's + // possible that the SMA lives on a different sequence (when in process). + if (in_process_arbiter_task_runner_ && + !in_process_arbiter_task_runner_->RunsTasksOnCurrentThread()) { + // |this| is never destroyed, except in tests. + in_process_arbiter_task_runner_->GetOrCreateTaskRunner()->PostTask( + FROM_HERE, base::BindOnce(&ProducerClient::BindStartupTargetBuffer, + base::Unretained(this), startup_session_id, + startup_target_buffer)); + return; + } + PerfettoProducer::BindStartupTargetBuffer(startup_session_id, + startup_target_buffer); +} + perfetto::SharedMemoryArbiter* ProducerClient::MaybeSharedMemoryArbiter() { - return in_process_arbiter_ ? in_process_arbiter_ - : shared_memory_arbiter_.get(); + base::AutoLock lock(shared_memory_lock_); + // |shared_memory_arbiter_| is never destroyed, thus OK to return a + // reference here. + return shared_memory_arbiter_.get(); } void ProducerClient::NewDataSourceAdded( @@ -87,25 +144,22 @@ return data_sources_tracing_ > 0; } -void ProducerClient::OnTracingStart( - mojo::ScopedSharedBufferHandle shared_memory, - uint64_t shared_memory_buffer_page_size_bytes) { - // If we're using in-process mode, we don't need to set up our - // own SharedMemoryArbiter. - DCHECK(!in_process_arbiter_); +void ProducerClient::OnTracingStart() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(producer_host_); - if (!shared_memory_) { - shared_memory_ = - std::make_unique<MojoSharedMemory>(std::move(shared_memory)); - shared_memory_arbiter_ = perfetto::SharedMemoryArbiter::CreateInstance( - shared_memory_.get(), shared_memory_buffer_page_size_bytes, this, - PerfettoTracedProcess::GetTaskRunner()); - } else { - // TODO(oysteine): This is assuming the SMB is the same, currently. Swapping - // out SharedMemoryBuffers would require more thread synchronization. - DCHECK_EQ(shared_memory_->shared_buffer()->value(), shared_memory->value()); + // In-process ProducerClient's arbiter is bound via + // BindInProcessSharedMemoryArbiter() instead. + if (!in_process_arbiter_task_runner_) { + perfetto::SharedMemoryArbiter* arbiter; + { + base::AutoLock lock(shared_memory_lock_); + // |shared_memory_arbiter_| is never destroyed, thus OK to call + // BindToProducerEndpoint() without holding the lock. + arbiter = shared_memory_arbiter_.get(); + } + DCHECK(arbiter); + arbiter->BindToProducerEndpoint(this, task_runner()); } } @@ -291,10 +345,37 @@ DETACH_FROM_SEQUENCE(sequence_checker_); } -perfetto::SharedMemory* ProducerClient::shared_memory_for_testing() const { +perfetto::SharedMemory* ProducerClient::shared_memory_for_testing() { + base::AutoLock lock(shared_memory_lock_); + // |shared_memory_| is never destroyed except in tests, thus OK to return a + // reference here. return shared_memory_.get(); } +bool ProducerClient::InitSharedMemoryIfNeeded() { + base::AutoLock lock(shared_memory_lock_); + if (shared_memory_) { + return true; + } + + // The shared memory buffer is always provided by the ProducerClient, but only + // created upon the first tracing request. + shared_memory_ = std::make_unique<MojoSharedMemory>(kSMBSizeBytes); + + if (!shared_memory_->shared_buffer().is_valid()) { + // TODO(crbug/1057614): We see shared memory buffer creation fail on windows + // in the field. Investigate why this can happen. + base::debug::DumpWithoutCrashing(); + LOG(ERROR) << "Failed to create tracing SMB"; + shared_memory_.reset(); + return false; + } + + shared_memory_arbiter_ = perfetto::SharedMemoryArbiter::CreateUnboundInstance( + shared_memory_.get(), kSMBPageSizeBytes); + return true; +} + // The Mojo binding should run on the same sequence as the one we get // callbacks from Perfetto on, to avoid additional PostTasks. void ProducerClient::BindClientAndHostPipesOnSequence(
diff --git a/services/tracing/public/cpp/perfetto/producer_client.h b/services/tracing/public/cpp/perfetto/producer_client.h index 0661d471..0b5dc8f 100644 --- a/services/tracing/public/cpp/perfetto/producer_client.h +++ b/services/tracing/public/cpp/perfetto/producer_client.h
@@ -16,11 +16,13 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" +#include "base/synchronization/lock.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/tracing/public/cpp/perfetto/perfetto_producer.h" #include "services/tracing/public/cpp/perfetto/task_runner.h" #include "services/tracing/public/mojom/perfetto_service.mojom.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/tracing_service.h" namespace perfetto { class SharedMemoryArbiter; @@ -43,13 +45,15 @@ ~ProducerClient() override; void Connect(mojo::PendingRemote<mojom::PerfettoService> perfetto_service); - - void set_in_process_shmem_arbiter(perfetto::SharedMemoryArbiter* arbiter) { - DCHECK(!in_process_arbiter_); - in_process_arbiter_ = arbiter; - } + void BindInProcessSharedMemoryArbiter( + perfetto::TracingService::ProducerEndpoint*, + PerfettoTaskRunner*); // PerfettoProducer implementation. + bool SetupStartupTracing() override; + void BindStartupTargetBuffer( + uint32_t startup_session_id, + perfetto::BufferID startup_target_buffer) override; perfetto::SharedMemoryArbiter* MaybeSharedMemoryArbiter() override; void NewDataSourceAdded( const PerfettoTracedProcess::DataSourceBase* const data_source) override; @@ -58,8 +62,7 @@ // mojom::ProducerClient implementation. // Called through Mojo by the ProducerHost on the service-side to control // tracing and toggle specific DataSources. - void OnTracingStart(mojo::ScopedSharedBufferHandle shared_memory, - uint64_t shared_memory_buffer_page_size_bytes) override; + void OnTracingStart() override; void StartDataSource(uint64_t id, const perfetto::DataSourceConfig& data_source_config, StartDataSourceCallback callback) override; @@ -102,7 +105,11 @@ mojo::PendingReceiver<mojom::ProducerClient>, mojo::PendingRemote<mojom::ProducerHost>); void ResetSequenceForTesting(); - perfetto::SharedMemory* shared_memory_for_testing() const; + perfetto::SharedMemory* shared_memory_for_testing(); + + protected: + // Protected for testing. Returns false if SMB creation failed. + bool InitSharedMemoryIfNeeded(); private: friend class base::NoDestructor<ProducerClient>; @@ -117,13 +124,20 @@ uint32_t data_sources_tracing_ = 0; std::unique_ptr<mojo::Receiver<mojom::ProducerClient>> receiver_; mojo::Remote<mojom::ProducerHost> producer_host_; - std::unique_ptr<MojoSharedMemory> shared_memory_; - std::unique_ptr<perfetto::SharedMemoryArbiter> shared_memory_arbiter_; - perfetto::SharedMemoryArbiter* in_process_arbiter_ = nullptr; + PerfettoTaskRunner* in_process_arbiter_task_runner_ = nullptr; // First value is the flush ID, the second is the number of // replies we're still waiting for. std::pair<uint64_t, size_t> pending_replies_for_latest_flush_; + // Guards initialization of |shared_memory_| and |shared_memory_arbiter_|. + // TODO(eseckler): Consider accessing these without locks after setup was + // completed, since we never destroy or unset them. + base::Lock shared_memory_lock_; + std::unique_ptr<MojoSharedMemory> shared_memory_ + GUARDED_BY(shared_memory_lock_); + std::unique_ptr<perfetto::SharedMemoryArbiter> shared_memory_arbiter_ + GUARDED_BY(shared_memory_lock_); + SEQUENCE_CHECKER(sequence_checker_); // NOTE: Weak pointers must be invalidated before all other member variables.
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc index 89142e7..3cd3af6 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
@@ -45,8 +45,6 @@ #include "services/tracing/public/cpp/trace_startup.h" #include "services/tracing/public/mojom/constants.mojom.h" #include "third_party/perfetto/include/perfetto/ext/tracing/core/shared_memory_arbiter.h" -#include "third_party/perfetto/include/perfetto/ext/tracing/core/startup_trace_writer.h" -#include "third_party/perfetto/include/perfetto/ext/tracing/core/startup_trace_writer_registry.h" #include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_writer.h" #include "third_party/perfetto/include/perfetto/tracing/track.h" #include "third_party/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pbzero.h" @@ -422,11 +420,6 @@ TraceEventDataSource* g_trace_event_data_source_for_testing = nullptr; -// crbug.com/914092: This has to be large enough for DevTools to be able to -// start up and telemetry to start tracing through it before the buffer is -// exhausted. -constexpr size_t kMaxStartupWriterBufferSize = 10 * 1024 * 1024; - } // namespace // static @@ -535,24 +528,25 @@ return is_enabled_; } -void TraceEventDataSource::SetupStartupTracing(bool privacy_filtering_enabled) { +void TraceEventDataSource::SetupStartupTracing(PerfettoProducer* producer, + bool privacy_filtering_enabled) { { AutoLockWithDeferredTaskPosting lock(lock_); - // Do not enable startup registry if trace log is being flushed. The + // Do not enable startup tracing if trace log is being flushed. The // previous tracing session has not ended yet. if (flushing_trace_log_) { return; } // No need to do anything if startup tracing has already been set, // or we know Perfetto has already been setup. - if (startup_writer_registry_ || producer_) { + if (IsStartupTracingActive() || producer_) { DCHECK(!privacy_filtering_enabled || privacy_filtering_enabled_); return; } + producer_ = producer; privacy_filtering_enabled_ = privacy_filtering_enabled; - startup_writer_registry_ = - std::make_unique<perfetto::StartupTraceWriterRegistry>(); + SetStartupTracingFlagsWhileLocked(); DCHECK(!trace_writer_); @@ -569,8 +563,9 @@ CHECK(IsTracingInitialized()); { base::AutoLock lock(lock_); - if (!startup_writer_registry_) + if (!IsStartupTracingActive()) { return; + } } startup_tracing_timer_.Start( FROM_HERE, startup_tracing_timeout_, @@ -589,18 +584,22 @@ return; } DCHECK_CALLED_ON_VALID_SEQUENCE(perfetto_sequence_checker_); - std::unique_ptr<perfetto::StartupTraceWriterRegistry> registry; - std::unique_ptr<perfetto::StartupTraceWriter> trace_writer; + std::unique_ptr<perfetto::TraceWriter> trace_writer; { AutoLockWithDeferredTaskPosting lock(lock_); - if (!startup_writer_registry_) { + if (!IsStartupTracingActive()) { return; } - // Set startup_writer_registry_ to null so that no further writers are - // created. - startup_writer_registry_.reset(); + + // Prevent recreation of ThreadLocalEventSinks after flush. + producer_ = nullptr; + target_buffer_ = 0; flushing_trace_log_ = true; trace_writer = std::move(trace_writer_); + + // Increment the session id to make sure that any subsequent tracing session + // uses fresh trace writers. + IncrementSessionIdOrClearStartupFlagWhileLocked(); } if (trace_writer) { ReturnTraceWriter(std::move(trace_writer)); @@ -612,7 +611,8 @@ /*use_worker_thread=*/false); } -void TraceEventDataSource::IncrementSessionIdOrClearStartupFlagWhileLocked() { +uint32_t +TraceEventDataSource::IncrementSessionIdOrClearStartupFlagWhileLocked() { // Protected by |lock_| for CreateThreadLocalEventSink() and // SetStartupTracingFlagsWhileLocked(). lock_.AssertAcquired(); @@ -628,6 +628,7 @@ flags.session_id++; } session_flags_.store(flags, std::memory_order_relaxed); + return flags.session_id; } void TraceEventDataSource::SetStartupTracingFlagsWhileLocked() { @@ -640,6 +641,11 @@ session_flags_.store(flags, std::memory_order_relaxed); } +bool TraceEventDataSource::IsStartupTracingActive() const { + SessionFlags flags = session_flags_.load(std::memory_order_relaxed); + return flags.is_startup_tracing; +} + void TraceEventDataSource::OnFlushFinished( const scoped_refptr<base::RefCountedString>&, bool has_more_events) { @@ -656,11 +662,6 @@ // task. task = std::move(flush_complete_task_); flushing_trace_log_ = false; - - // Increment the session id to make sure that once tracing starts the events - // are added to a new trace writer that comes from perfetto producer, - // instead of holding on to the startup registry's writers. - IncrementSessionIdOrClearStartupFlagWhileLocked(); } if (task) { std::move(task).Run(); @@ -690,37 +691,43 @@ PerfettoProducer* producer, const perfetto::DataSourceConfig& data_source_config) { DCHECK_CALLED_ON_VALID_SEQUENCE(perfetto_sequence_checker_); - std::unique_ptr<perfetto::StartupTraceWriterRegistry> unbound_writer_registry; + bool startup_tracing_active; + uint32_t session_id; { AutoLockWithDeferredTaskPosting lock(lock_); + bool should_enable_filtering = data_source_config.chrome_config().privacy_filtering_enabled(); - if (should_enable_filtering) { - CHECK(!startup_writer_registry_ || privacy_filtering_enabled_) - << "Unexpected StartTracing received when startup tracing is " - "running."; - } - privacy_filtering_enabled_ = should_enable_filtering; + startup_tracing_active = IsStartupTracingActive(); + if (startup_tracing_active) { + CHECK(!should_enable_filtering || privacy_filtering_enabled_) + << "Startup tracing was active without privacy filtering when " + "service started tracing with privacy filtering."; + DCHECK_EQ(producer_, producer) + << "Startup tracing was taken over by a different PerfettoProducer"; + } + + privacy_filtering_enabled_ = should_enable_filtering; producer_ = producer; target_buffer_ = data_source_config.target_buffer(); - // Reduce lock contention by binding the registry without holding the lock. - unbound_writer_registry = std::move(startup_writer_registry_); - - IncrementSessionIdOrClearStartupFlagWhileLocked(); + session_id = IncrementSessionIdOrClearStartupFlagWhileLocked(); if (!trace_writer_) { trace_writer_ = CreateTraceWriterLocked(); } } - if (unbound_writer_registry) { - // TODO(oysteine): Investigate why trace events emitted by something in - // BindStartupTraceWriterRegistry() causes deadlocks. + // SetupStartupTracing() will not setup a new startup session after we set + // |producer_| above, so accessing |startup_tracing_active| outside the lock + // is safe. + if (startup_tracing_active) { + // Binding startup buffers may cause tasks to be posted. Disable trace + // events to avoid deadlocks due to reentrancy into tracing code. AutoThreadLocalBoolean thread_is_in_trace_event( GetThreadIsInTraceEventTLS()); - producer->BindStartupTraceWriterRegistry( - std::move(unbound_writer_registry), data_source_config.target_buffer()); + producer->BindStartupTargetBuffer(session_id, + data_source_config.target_buffer()); } else { RegisterWithTraceLog(); } @@ -778,7 +785,7 @@ TraceLog::GetInstance()->SetDisabled(); } - std::unique_ptr<perfetto::StartupTraceWriter> trace_writer; + std::unique_ptr<perfetto::TraceWriter> trace_writer; { AutoLockWithDeferredTaskPosting lock(lock_); if (flush_complete_task_) { @@ -883,27 +890,24 @@ EmitTrackDescriptor(); } -std::unique_ptr<perfetto::StartupTraceWriter> +std::unique_ptr<perfetto::TraceWriter> TraceEventDataSource::CreateTraceWriterLocked() { lock_.AssertAcquired(); - // |startup_writer_registry_| only exists during startup tracing before we - // connect to the service. |producer_| is reset when tracing is - // stopped. - std::unique_ptr<perfetto::StartupTraceWriter> trace_writer; - if (startup_writer_registry_) { - // Chromium uses BufferExhaustedPolicy::kDrop to avoid stalling trace - // writers when the chunks in the SMB are exhausted. Stalling could - // otherwise lead to deadlocks in chromium, because a stalled mojo IPC - // thread could prevent CommitRequest messages from reaching the perfetto - // service. - auto buffer_exhausted_policy = perfetto::BufferExhaustedPolicy::kDrop; - trace_writer = startup_writer_registry_->CreateUnboundTraceWriter( - buffer_exhausted_policy, kMaxStartupWriterBufferSize); - } else if (producer_) { - trace_writer = std::make_unique<perfetto::StartupTraceWriter>( - producer_->CreateTraceWriter(target_buffer_)); + + if (IsStartupTracingActive()) { + DCHECK(producer_); + uint32_t session_id = + session_flags_.load(std::memory_order_relaxed).session_id; + return producer_->CreateStartupTraceWriter(session_id); } - return trace_writer; + + // |producer_| is reset when tracing is stopped, and trace writer creation can + // happen in parallel on any thread. + if (producer_) { + return producer_->CreateTraceWriter(target_buffer_); + } + + return nullptr; } TrackEventThreadLocalEventSink* @@ -1005,29 +1009,29 @@ } void TraceEventDataSource::ReturnTraceWriter( - std::unique_ptr<perfetto::StartupTraceWriter> trace_writer) { + std::unique_ptr<perfetto::TraceWriter> trace_writer) { { - // Prevent concurrent binding of the registry. + // Prevent concurrent changes to |session_flags_|. AutoLockWithDeferredTaskPosting lock(lock_); - // If we don't have a task runner yet, we must be attempting to return a - // writer before the (very first) registry was bound. We cannot create the - // task runner safely in this case, because the thread pool may not have - // been brought up yet. + // If we don't have a task runner yet, we cannot create the task runner + // safely, because the thread pool may not have been brought up yet. This + // should only happen during startup tracing. if (!PerfettoTracedProcess::GetTaskRunner()->HasTaskRunner()) { - DCHECK(startup_writer_registry_); - // It's safe to call ReturnToRegistry on the current sequence, as it won't - // destroy the writer since the registry was not bound yet. Will keep - // |trace_writer| alive until the registry is bound later. - perfetto::StartupTraceWriter::ReturnToRegistry(std::move(trace_writer)); + DCHECK(IsStartupTracingActive()); + // It's safe to destroy the TraceWriter on the current sequence, as the + // destruction won't post tasks or make mojo calls, because the arbiter + // wasn't bound yet. + trace_writer.reset(); return; } } - // Return the TraceWriter on the sequence that Perfetto runs on. Needed as the - // ThreadLocalEventSink gets deleted on thread shutdown and we can't safely - // call TaskRunnerHandle::Get() at that point (which can happen as the - // TraceWriter destructor might make a Mojo call and trigger it). + // Return the TraceWriter on the sequence that the PerfettoProducers run on. + // Needed as the TrackEventThreadLocalEventSink gets deleted on thread + // shutdown and we can't safely call TaskRunnerHandle::Get() at that point + // (which can happen as the TraceWriter destructor might issue a Mojo call + // synchronously, which can trigger a call to TaskRunnerHandle::Get()). auto* trace_writer_raw = trace_writer.release(); ANNOTATE_LEAKING_OBJECT_PTR(trace_writer_raw); PerfettoTracedProcess::GetTaskRunner()->GetOrCreateTaskRunner()->PostTask( @@ -1035,14 +1039,7 @@ base::BindOnce( // Pass writer as raw pointer so that we leak it if task posting fails // (during shutdown). - [](perfetto::StartupTraceWriter* trace_writer) { - // May destroy |trace_writer|. If the writer is still unbound, the - // registry will keep it alive until it was bound and its buffered - // data was copied. This ensures that we don't lose data from - // threads that are shut down during startup. - perfetto::StartupTraceWriter::ReturnToRegistry( - base::WrapUnique<perfetto::StartupTraceWriter>(trace_writer)); - }, + [](perfetto::TraceWriter* trace_writer) { delete trace_writer; }, trace_writer_raw)); }
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source.h b/services/tracing/public/cpp/perfetto/trace_event_data_source.h index c1beb51f..2b3a30532 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source.h +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source.h
@@ -34,8 +34,6 @@ } // namespace base namespace perfetto { -class StartupTraceWriter; -class StartupTraceWriterRegistry; class TraceWriter; class EventContext; } @@ -158,7 +156,8 @@ // Enables startup tracing. Trace data is locally buffered until connection to // the perfetto service is established. Expects a later call to StartTracing() // to bind to the perfetto service. Should only be called once. - void SetupStartupTracing(bool privacy_filtering_enabled); + void SetupStartupTracing(PerfettoProducer* producer, + bool privacy_filtering_enabled); // Installs TraceLog overrides for tracing during Chrome startup. void RegisterStartupHooks(); @@ -179,8 +178,7 @@ void ClearIncrementalState() override; // Deletes TraceWriter safely on behalf of a ThreadLocalEventSink. - void ReturnTraceWriter( - std::unique_ptr<perfetto::StartupTraceWriter> trace_writer); + void ReturnTraceWriter(std::unique_ptr<perfetto::TraceWriter> trace_writer); void set_startup_tracing_timeout_for_testing(base::TimeDelta timeout_us) { startup_tracing_timeout_ = timeout_us; @@ -235,7 +233,7 @@ void RegisterWithTraceLog(); void UnregisterFromTraceLog(); - std::unique_ptr<perfetto::StartupTraceWriter> CreateTraceWriterLocked(); + std::unique_ptr<perfetto::TraceWriter> CreateTraceWriterLocked(); TrackEventThreadLocalEventSink* CreateThreadLocalEventSink( bool thread_will_flush); @@ -262,8 +260,9 @@ void LogHistogram(base::HistogramBase* histogram); void EmitTrackDescriptor(); - void IncrementSessionIdOrClearStartupFlagWhileLocked(); + uint32_t IncrementSessionIdOrClearStartupFlagWhileLocked(); void SetStartupTracingFlagsWhileLocked(); + bool IsStartupTracingActive() const; bool disable_interning_ = false; base::OnceClosure stop_complete_callback_; @@ -281,12 +280,7 @@ // base::AutoLock to protect code paths which may post tasks. base::Lock lock_; // Protects subsequent members. uint32_t target_buffer_ = 0; - // We own the registry during startup, but transfer its ownership to the - // PerfettoProducer once the perfetto service is available. Only set if - // SetupStartupTracing() is called. - std::unique_ptr<perfetto::StartupTraceWriterRegistry> - startup_writer_registry_; - std::unique_ptr<perfetto::StartupTraceWriter> trace_writer_; + std::unique_ptr<perfetto::TraceWriter> trace_writer_; base::OneShotTimer startup_tracing_timer_; bool is_enabled_ = false; bool flushing_trace_log_ = false;
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc b/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc index 73342e63..bd063ef2 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc
@@ -1477,7 +1477,9 @@ // Start startup tracing registry with no timeout. This would cause startup // tracing to abort and flush as soon the current thread can run tasks. data_source->set_startup_tracing_timeout_for_testing(base::TimeDelta()); - data_source->SetupStartupTracing(true); + producer_client()->SetupStartupTracing(); + data_source->SetupStartupTracing(producer_client(), + /*privacy_filtering_enabled=*/true); base::trace_event::TraceLog::GetInstance()->SetEnabled( base::trace_event::TraceConfig(), base::trace_event::TraceLog::RECORDING_MODE);
diff --git a/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc b/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc index 0339d15a..b61f26d1 100644 --- a/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc +++ b/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc
@@ -200,7 +200,7 @@ : src_loc(std::move(src)) {} TrackEventThreadLocalEventSink::TrackEventThreadLocalEventSink( - std::unique_ptr<perfetto::StartupTraceWriter> trace_writer, + std::unique_ptr<perfetto::TraceWriter> trace_writer, uint32_t session_id, bool disable_interning, bool proto_writer_filtering_enabled)
diff --git a/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h b/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h index 975421b..559ec4a 100644 --- a/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h +++ b/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h
@@ -17,7 +17,6 @@ #include "base/time/time.h" #include "base/trace_event/thread_instruction_count.h" #include "services/tracing/public/cpp/perfetto/interning_index.h" -#include "third_party/perfetto/include/perfetto/ext/tracing/core/startup_trace_writer.h" #include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_writer.h" #include "third_party/perfetto/include/perfetto/protozero/message_handle.h" #include "third_party/perfetto/include/perfetto/tracing/event_context.h" @@ -25,10 +24,6 @@ #include "third_party/perfetto/protos/perfetto/trace/track_event/chrome_thread_descriptor.pbzero.h" #include "third_party/perfetto/protos/perfetto/trace/track_event/track_event.pbzero.h" -namespace perfetto { -class StartupTraceWriter; -} // namespace perfetto - namespace tracing { // ThreadLocalEventSink that emits TrackEvent protos. @@ -61,7 +56,7 @@ std::vector<std::tuple<IndexType, IndexData, InterningIndexEntry>>; TrackEventThreadLocalEventSink( - std::unique_ptr<perfetto::StartupTraceWriter> trace_writer, + std::unique_ptr<perfetto::TraceWriter> trace_writer, uint32_t session_id, bool disable_interning, bool proto_writer_filtering_enabled); @@ -174,7 +169,7 @@ const bool privacy_filtering_enabled_; - std::unique_ptr<perfetto::StartupTraceWriter> trace_writer_; + std::unique_ptr<perfetto::TraceWriter> trace_writer_; uint32_t session_id_; bool disable_interning_; uint32_t sink_id_;
diff --git a/services/tracing/public/cpp/trace_startup.cc b/services/tracing/public/cpp/trace_startup.cc index a373fb66..1542ebe2 100644 --- a/services/tracing/public/cpp/trace_startup.cc +++ b/services/tracing/public/cpp/trace_startup.cc
@@ -11,6 +11,7 @@ #include "components/tracing/common/trace_startup_config.h" #include "components/tracing/common/trace_to_console.h" #include "components/tracing/common/tracing_switches.h" +#include "services/tracing/public/cpp/perfetto/producer_client.h" #include "services/tracing/public/cpp/perfetto/system_producer.h" #include "services/tracing/public/cpp/perfetto/trace_event_data_source.h" #include "services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.h" @@ -21,8 +22,30 @@ namespace tracing { namespace { + using base::trace_event::TraceConfig; using base::trace_event::TraceLog; + +bool SetupStartupTracing(PerfettoProducer* producer, + bool privacy_filtering_enabled, + bool enable_sampler_profiler) { + // TODO(eseckler): This should really go through PerfettoTracedProcess + // somehow, so that the "correct" producer gets to take over the session. + + if (!producer->SetupStartupTracing()) { + LOG(ERROR) << "Failed to setup startup tracing for this process"; + return false; + } + + TraceEventDataSource::GetInstance()->SetupStartupTracing( + producer, privacy_filtering_enabled); + + if (enable_sampler_profiler) + TracingSamplerProfiler::SetupStartupTracing(); + + return true; +} + } // namespace bool g_tracing_initialized_after_threadpool_and_featurelist = false; @@ -40,8 +63,7 @@ perfetto::internal::TrackRegistry::InitializeInstance(); // TODO(oysteine): Support startup tracing to a perfetto protobuf trace. This - // should also enable TraceLog and call - // TraceEventDataSource::SetupStartupTracing(). + // should also enable TraceLog and call SetupStartupTracing(). if (command_line.HasSwitch(switches::kPerfettoOutputFile)) return; @@ -71,32 +93,41 @@ trace_config.SetTraceBufferSizeInKb(0); trace_config.SetTraceBufferSizeInEvents(0); - if (trace_config.IsCategoryGroupEnabled( - TRACE_DISABLED_BY_DEFAULT("cpu_profiler"))) { - TracingSamplerProfiler::SetupStartupTracing(); + PerfettoProducer* producer = + PerfettoTracedProcess::Get()->producer_client(); + if (startup_config->GetSessionOwner() == + TraceStartupConfig::SessionOwner::kSystemTracing) { + producer = PerfettoTracedProcess::Get()->system_producer(); } - TraceEventDataSource::GetInstance()->SetupStartupTracing( + + bool privacy_filtering_enabled = startup_config->GetSessionOwner() == TraceStartupConfig::SessionOwner::kBackgroundTracing || - command_line.HasSwitch(switches::kTraceStartupEnablePrivacyFiltering)); + command_line.HasSwitch(switches::kTraceStartupEnablePrivacyFiltering); + + bool enable_sampler_profiler = trace_config.IsCategoryGroupEnabled( + TRACE_DISABLED_BY_DEFAULT("cpu_profiler")); + + if (!SetupStartupTracing(producer, privacy_filtering_enabled, + enable_sampler_profiler)) { + startup_config->SetDisabled(); + return; + } uint8_t modes = TraceLog::RECORDING_MODE; if (!trace_config.event_filters().empty()) modes |= TraceLog::FILTERING_MODE; trace_log->SetEnabled(trace_config, modes); - } else if (command_line.HasSwitch(switches::kTraceToConsole)) { - // TODO(eseckler): Remove ability to trace to the console, perfetto doesn't - // support this and noone seems to use it. - TraceConfig trace_config = GetConfigForTraceToConsole(); - LOG(ERROR) << "Start " << switches::kTraceToConsole - << " with CategoryFilter '" - << trace_config.ToCategoryFilterString() << "'."; - TraceEventDataSource::GetInstance()->SetupStartupTracing( - /*privacy_filtering_enabled=*/false); - trace_log->SetEnabled(trace_config, TraceLog::RECORDING_MODE); } } +bool SetupStartupTracingForProcess(bool privacy_filtering_enabled, + bool enable_sampler_profiler) { + return SetupStartupTracing(PerfettoTracedProcess::Get()->producer_client(), + privacy_filtering_enabled, + enable_sampler_profiler); +} + void InitTracingPostThreadPoolStartAndFeatureList() { if (g_tracing_initialized_after_threadpool_and_featurelist) return;
diff --git a/services/tracing/public/cpp/trace_startup.h b/services/tracing/public/cpp/trace_startup.h index 089ba9d..b50c42f 100644 --- a/services/tracing/public/cpp/trace_startup.h +++ b/services/tracing/public/cpp/trace_startup.h
@@ -17,11 +17,27 @@ // for this process. bool COMPONENT_EXPORT(TRACING_CPP) IsTracingInitialized(); -// TraceLog with config based on the command line flags. Also hooks up service -// callbacks in TraceLog if necessary. The latter is required when the perfetto -// tracing backend is used. +// Hooks up hooks up service callbacks in TraceLog for the perfetto backend and, +// if startup tracing command line flags are present, enables TraceLog with a +// config based on the flags. In zygote children, this should only be called +// after mojo is initialized, as the zygote's sandbox prevents creation of the +// tracing SMB before that point. +// +// TODO(eseckler): Consider allocating the SMB in parent processes outside the +// sandbox and supply it via the command line. Then, we can revert to call this +// earlier and from fewer places again. void COMPONENT_EXPORT(TRACING_CPP) EnableStartupTracingIfNeeded(); +// Prepare ProducerClient and trace event and/or sampler profiler data sources +// for startup tracing with chrome's tracing service. Returns false on failure. +// Note that TraceLog still needs to be enabled separately. +// +// TODO(eseckler): Figure out what startup tracing APIs should look like with +// the client lib. +bool COMPONENT_EXPORT(TRACING_CPP) + SetupStartupTracingForProcess(bool privacy_filtering_enabled, + bool enable_sampler_profiler); + // Initialize tracing components that require task runners. Will switch // IsTracingInitialized() to return true. void COMPONENT_EXPORT(TRACING_CPP)
diff --git a/services/tracing/public/cpp/tracing_features.cc b/services/tracing/public/cpp/tracing_features.cc index fece9b5bc..0b3cce6c 100644 --- a/services/tracing/public/cpp/tracing_features.cc +++ b/services/tracing/public/cpp/tracing_features.cc
@@ -30,10 +30,6 @@ #endif }; -// Causes Perfetto to run in-process mode for in-process tracing producers. -const base::Feature kPerfettoForceOutOfProcessProducer{ - "PerfettoForceOutOfProcessProducer", base::FEATURE_DISABLED_BY_DEFAULT}; - // Runs the tracing service as an in-process browser service. const base::Feature kTracingServiceInProcess { "TracingServiceInProcess",
diff --git a/services/tracing/public/cpp/tracing_features.h b/services/tracing/public/cpp/tracing_features.h index 9bd1a12..d93d074 100644 --- a/services/tracing/public/cpp/tracing_features.h +++ b/services/tracing/public/cpp/tracing_features.h
@@ -22,9 +22,6 @@ kBackgroundTracingProtoOutput; extern const COMPONENT_EXPORT(TRACING_CPP) base::Feature - kPerfettoForceOutOfProcessProducer; - -extern const COMPONENT_EXPORT(TRACING_CPP) base::Feature kEnablePerfettoSystemTracing; } // namespace features
diff --git a/services/tracing/public/mojom/perfetto_service.mojom b/services/tracing/public/mojom/perfetto_service.mojom index e17f002..3a8e2e5 100644 --- a/services/tracing/public/mojom/perfetto_service.mojom +++ b/services/tracing/public/mojom/perfetto_service.mojom
@@ -122,8 +122,8 @@ // this interface and use the PerfettoService interface within the tracing // service to register itself. interface ProducerClient { - OnTracingStart(handle<shared_buffer> shared_memory, - uint64 shared_memory_buffer_page_size_bytes); + // Called when tracing is first enabled, before any data sources are started. + OnTracingStart(); // Called by Perfetto (via ProducerHost) to request a data source to start // logging. @@ -138,10 +138,15 @@ // This is implemented by the tracing service, and is essentially a singleton // factory for establishing bi-directional communication with the Perfetto // tracing system. A client that wishes to provide tracing data when requested, -// should implement ProducerClient for callbacks and pass along. +// should implement ProducerClient for callbacks and pass along, together with +// the shared memory buffer that'll be used to pass the data. interface PerfettoService { + // Connect a new ProducerClient to a ProducerHost in the tracing service, + // providing the shared memory buffer that will be used to send trace data. ConnectToProducerHost(pending_remote<ProducerClient> producer_client, - pending_receiver<ProducerHost> producer_host_receiver); + pending_receiver<ProducerHost> producer_host_receiver, + handle<shared_buffer> shared_memory, + uint64 shared_memory_buffer_page_size_bytes); }; // The policy for filling the trace buffer.
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 0c172c26..526d4e6c 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -294,26 +294,6 @@ ] } ], - "AndroidInProductHelpQuietNotificationPrompts": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "Enabled", - "params": { - "availability": "any", - "event_trigger": "name:tabgroups_dummy;comparator:any;window:1;storage:1", - "event_used": "name:tabgroups_dummy;comparator:any;window:1;storage:1" - }, - "enable_features": [ - "IPH_QuietNotificationPrompts" - ] - } - ] - } - ], "AndroidInlineUpdateFlowStudy": [ { "platforms": [ @@ -365,24 +345,6 @@ ] } ], - "AndroidPasswordManagerOnboarding": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "EnabledWithSafetyStory", - "params": { - "story": "safety" - }, - "enable_features": [ - "PasswordManagerOnboardingAndroid" - ] - } - ] - } - ], "AndroidPictureInPictureAPI": [ { "platforms": [ @@ -3959,21 +3921,6 @@ ] } ], - "Precache": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "EnabledCGRUV20b", - "params": { - "config_url": "https://www.gstatic.com/chrome/wifiprefetch/precache_config_g20" - } - } - ] - } - ], "PreconnectOnDidFinishNavigation": [ { "platforms": [ @@ -4274,10 +4221,15 @@ { "name": "EnableWithAdaptiveActivation", "params": { + "availability": "any", "enable_adaptive_activation": "true", - "enable_crowd_deny_triggering": "true" + "enable_crowd_deny_triggering": "true", + "event_trigger": "name:tabgroups_dummy;comparator:any;window:1;storage:1", + "event_used": "name:tabgroups_dummy;comparator:any;window:1;storage:1", + "session_rate": "any" }, "enable_features": [ + "IPH_QuietNotificationPrompts", "QuietNotificationPrompts" ] }
diff --git a/third_party/android_deps/BUILD.gn b/third_party/android_deps/BUILD.gn index c5a8c2cd..d241937 100644 --- a/third_party/android_deps/BUILD.gn +++ b/third_party/android_deps/BUILD.gn
@@ -117,14 +117,6 @@ ] } -java_group("com_android_support_asynclayoutinflater_java") { - deps = [ - ":${target_name}_orig__unpack_aar", - ":androidx_asynclayoutinflater_asynclayoutinflater_java", - ] - input_jars_paths = [ "${target_out_dir}/com_android_support_asynclayoutinflater_java_orig/classes.jar" ] -} - java_group("com_android_support_cardview_v7_java") { deps = [ ":${target_name}_orig__unpack_aar",
diff --git a/third_party/blink/common/bluetooth/web_bluetooth_device_id.cc b/third_party/blink/common/bluetooth/web_bluetooth_device_id.cc index 7ba88c0..b3d9ba9 100644 --- a/third_party/blink/common/bluetooth/web_bluetooth_device_id.cc +++ b/third_party/blink/common/bluetooth/web_bluetooth_device_id.cc
@@ -4,8 +4,6 @@ #include "third_party/blink/public/common/bluetooth/web_bluetooth_device_id.h" -#include <utility> - #include "base/base64.h" #include "base/strings/string_util.h" #include "crypto/random.h" @@ -85,11 +83,6 @@ return !(*this == device_id); } -bool WebBluetoothDeviceId::operator<( - const WebBluetoothDeviceId& device_id) const { - return str() < device_id.str(); -} - std::ostream& operator<<(std::ostream& out, const WebBluetoothDeviceId& device_id) { return out << device_id.str();
diff --git a/third_party/blink/public/common/bluetooth/web_bluetooth_device_id.h b/third_party/blink/public/common/bluetooth/web_bluetooth_device_id.h index 0177372..5d00935 100644 --- a/third_party/blink/public/common/bluetooth/web_bluetooth_device_id.h +++ b/third_party/blink/public/common/bluetooth/web_bluetooth_device_id.h
@@ -41,7 +41,6 @@ bool operator==(const WebBluetoothDeviceId& device_id) const; bool operator!=(const WebBluetoothDeviceId& device_id) const; - bool operator<(const WebBluetoothDeviceId& device_id) const; private: std::string device_id_;
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl index fb2f7d2..2511123 100644 --- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl +++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -2845,6 +2845,22 @@ # Media features to emulate. optional array of MediaFeature features + # Emulates the given vision deficiency. + experimental command setEmulatedVisionDeficiency + parameters + # Vision deficiency to emulate. + enum type + none + achromatomaly + achromatopsia + blurredVision + deuteranomaly + deuteranopia + protanomaly + protanopia + tritanomaly + tritanopia + # Overrides the Geolocation Position or Error. Omitting any of the parameters emulates position # unavailable. command setGeolocationOverride
diff --git a/third_party/blink/public/mojom/frame/frame.mojom b/third_party/blink/public/mojom/frame/frame.mojom index f3187d36..5542faa 100644 --- a/third_party/blink/public/mojom/frame/frame.mojom +++ b/third_party/blink/public/mojom/frame/frame.mojom
@@ -602,6 +602,9 @@ // // This interface will only be provided when the LocalFrame is a main frame. interface LocalMainFrame { + // Requests performing a page scale animation based on the point/rect provided. + AnimateDoubleTapZoom(gfx.mojom.Point point, gfx.mojom.Rect rect); + // Scales the view without affecting layout by using the visual viewport. SetScaleFactor(float scale);
diff --git a/third_party/blink/public/web/web_view.h b/third_party/blink/public/web/web_view.h index fb8b8c1e..dbe3cd3 100644 --- a/third_party/blink/public/web/web_view.h +++ b/third_party/blink/public/web/web_view.h
@@ -278,9 +278,6 @@ // WebView. virtual WebSize ContentsPreferredMinimumSize() = 0; - // Requests a page-scale animation based on the specified point/rect. - virtual void AnimateDoubleTapZoom(const gfx::Point&, const WebRect&) = 0; - // Requests a page-scale animation based on the specified rect. virtual void ZoomToFindInPageRect(const WebRect&) = 0;
diff --git a/third_party/blink/renderer/core/css/BUILD.gn b/third_party/blink/renderer/core/css/BUILD.gn index 8f8b6f4..b70a955 100644 --- a/third_party/blink/renderer/core/css/BUILD.gn +++ b/third_party/blink/renderer/core/css/BUILD.gn
@@ -584,6 +584,8 @@ "style_traversal_root.h", "tree_scope_style_sheet_collection.cc", "tree_scope_style_sheet_collection.h", + "vision_deficiency.cc", + "vision_deficiency.h", "zoom_adjusted_pixel_value.h", ] }
diff --git a/third_party/blink/renderer/core/css/css_axis_value.h b/third_party/blink/renderer/core/css/css_axis_value.h index 910f55f..70017c2 100644 --- a/third_party/blink/renderer/core/css/css_axis_value.h +++ b/third_party/blink/renderer/core/css/css_axis_value.h
@@ -25,7 +25,7 @@ double Z() const; - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { CSSValueList::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_basic_shape_values.cc b/third_party/blink/renderer/core/css/css_basic_shape_values.cc index 8c8aa51..2de790b7 100644 --- a/third_party/blink/renderer/core/css/css_basic_shape_values.cc +++ b/third_party/blink/renderer/core/css/css_basic_shape_values.cc
@@ -143,7 +143,8 @@ DataEquivalent(radius_, other.radius_); } -void CSSBasicShapeCircleValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSBasicShapeCircleValue::TraceAfterDispatch( + blink::Visitor* visitor) const { visitor->Trace(center_x_); visitor->Trace(center_y_); visitor->Trace(radius_); @@ -226,7 +227,8 @@ DataEquivalent(radius_y_, other.radius_y_); } -void CSSBasicShapeEllipseValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSBasicShapeEllipseValue::TraceAfterDispatch( + blink::Visitor* visitor) const { visitor->Trace(center_x_); visitor->Trace(center_y_); visitor->Trace(radius_x_); @@ -287,7 +289,8 @@ return CompareCSSValueVector(values_, other.values_); } -void CSSBasicShapePolygonValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSBasicShapePolygonValue::TraceAfterDispatch( + blink::Visitor* visitor) const { visitor->Trace(values_); CSSValue::TraceAfterDispatch(visitor); } @@ -435,7 +438,8 @@ DataEquivalent(bottom_left_radius_, other.bottom_left_radius_); } -void CSSBasicShapeInsetValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSBasicShapeInsetValue::TraceAfterDispatch( + blink::Visitor* visitor) const { visitor->Trace(top_); visitor->Trace(right_); visitor->Trace(bottom_);
diff --git a/third_party/blink/renderer/core/css/css_basic_shape_values.h b/third_party/blink/renderer/core/css/css_basic_shape_values.h index 027d284..bfadef6 100644 --- a/third_party/blink/renderer/core/css/css_basic_shape_values.h +++ b/third_party/blink/renderer/core/css/css_basic_shape_values.h
@@ -58,7 +58,7 @@ void SetCenterY(CSSValue* center_y) { center_y_ = center_y; } void SetRadius(CSSValue* radius) { radius_ = radius; } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: Member<CSSValue> center_x_; @@ -84,7 +84,7 @@ void SetRadiusX(CSSValue* radius_x) { radius_x_ = radius_x; } void SetRadiusY(CSSValue* radius_y) { radius_y_ = radius_y; } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: Member<CSSValue> center_x_; @@ -116,7 +116,7 @@ String CustomCSSText() const; bool Equals(const CSSBasicShapePolygonValue&) const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: HeapVector<Member<CSSPrimitiveValue>> values_; @@ -180,7 +180,7 @@ String CustomCSSText() const; bool Equals(const CSSBasicShapeInsetValue&) const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: Member<CSSPrimitiveValue> top_;
diff --git a/third_party/blink/renderer/core/css/css_border_image_slice_value.cc b/third_party/blink/renderer/core/css/css_border_image_slice_value.cc index a762bde..d18e899 100644 --- a/third_party/blink/renderer/core/css/css_border_image_slice_value.cc +++ b/third_party/blink/renderer/core/css/css_border_image_slice_value.cc
@@ -51,7 +51,8 @@ return fill_ == other.fill_ && DataEquivalent(slices_, other.slices_); } -void CSSBorderImageSliceValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSBorderImageSliceValue::TraceAfterDispatch( + blink::Visitor* visitor) const { visitor->Trace(slices_); CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_border_image_slice_value.h b/third_party/blink/renderer/core/css/css_border_image_slice_value.h index 27468d6..6438b0c 100644 --- a/third_party/blink/renderer/core/css/css_border_image_slice_value.h +++ b/third_party/blink/renderer/core/css/css_border_image_slice_value.h
@@ -46,7 +46,7 @@ bool Equals(const CSSBorderImageSliceValue&) const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: // These four values are used to make "cuts" in the border image. They can be
diff --git a/third_party/blink/renderer/core/css/css_color_value.h b/third_party/blink/renderer/core/css/css_color_value.h index c752b9a4..2b4d16b 100644 --- a/third_party/blink/renderer/core/css/css_color_value.h +++ b/third_party/blink/renderer/core/css/css_color_value.h
@@ -32,7 +32,7 @@ return color_ == other.color_; } - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_content_distribution_value.h b/third_party/blink/renderer/core/css/css_content_distribution_value.h index ce32858..6b96107 100644 --- a/third_party/blink/renderer/core/css/css_content_distribution_value.h +++ b/third_party/blink/renderer/core/css/css_content_distribution_value.h
@@ -30,7 +30,7 @@ bool Equals(const CSSContentDistributionValue&) const; - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_counter_value.cc b/third_party/blink/renderer/core/css/css_counter_value.cc index af96186f..34f1f796 100644 --- a/third_party/blink/renderer/core/css/css_counter_value.cc +++ b/third_party/blink/renderer/core/css/css_counter_value.cc
@@ -33,7 +33,7 @@ return result.ToString(); } -void CSSCounterValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSCounterValue::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(identifier_); visitor->Trace(list_style_); visitor->Trace(separator_);
diff --git a/third_party/blink/renderer/core/css/css_counter_value.h b/third_party/blink/renderer/core/css/css_counter_value.h index 6c5e9b68..004b5684 100644 --- a/third_party/blink/renderer/core/css/css_counter_value.h +++ b/third_party/blink/renderer/core/css/css_counter_value.h
@@ -52,7 +52,7 @@ String CustomCSSText() const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: Member<CSSCustomIdentValue> identifier_; // string
diff --git a/third_party/blink/renderer/core/css/css_crossfade_value.cc b/third_party/blink/renderer/core/css/css_crossfade_value.cc index 3a8d2ea9..5051a54 100644 --- a/third_party/blink/renderer/core/css/css_crossfade_value.cc +++ b/third_party/blink/renderer/core/css/css_crossfade_value.cc
@@ -309,7 +309,7 @@ DataEquivalent(percentage_value_, other.percentage_value_); } -void CSSCrossfadeValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSCrossfadeValue::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(from_value_); visitor->Trace(to_value_); visitor->Trace(percentage_value_);
diff --git a/third_party/blink/renderer/core/css/css_crossfade_value.h b/third_party/blink/renderer/core/css/css_crossfade_value.h index c33d5ee..35bc6bb 100644 --- a/third_party/blink/renderer/core/css/css_crossfade_value.h +++ b/third_party/blink/renderer/core/css/css_crossfade_value.h
@@ -71,7 +71,7 @@ CSSCrossfadeValue* ComputedCSSValue(const ComputedStyle&, bool allow_visited_style); - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: void Dispose();
diff --git a/third_party/blink/renderer/core/css/css_cursor_image_value.cc b/third_party/blink/renderer/core/css/css_cursor_image_value.cc index 226ba48c..913c7b6 100644 --- a/third_party/blink/renderer/core/css/css_cursor_image_value.cc +++ b/third_party/blink/renderer/core/css/css_cursor_image_value.cc
@@ -57,7 +57,7 @@ DataEquivalent(image_value_, other.image_value_); } -void CSSCursorImageValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSCursorImageValue::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(image_value_); CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_cursor_image_value.h b/third_party/blink/renderer/core/css/css_cursor_image_value.h index 75107dcb..8fd4c47 100644 --- a/third_party/blink/renderer/core/css/css_cursor_image_value.h +++ b/third_party/blink/renderer/core/css/css_cursor_image_value.h
@@ -43,7 +43,7 @@ bool Equals(const CSSCursorImageValue&) const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: Member<const CSSValue> image_value_;
diff --git a/third_party/blink/renderer/core/css/css_custom_ident_value.cc b/third_party/blink/renderer/core/css/css_custom_ident_value.cc index 257cc01..b3927288 100644 --- a/third_party/blink/renderer/core/css/css_custom_ident_value.cc +++ b/third_party/blink/renderer/core/css/css_custom_ident_value.cc
@@ -31,7 +31,7 @@ return builder.ToString(); } -void CSSCustomIdentValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSCustomIdentValue::TraceAfterDispatch(blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_custom_ident_value.h b/third_party/blink/renderer/core/css/css_custom_ident_value.h index d60d893b..0179c94 100644 --- a/third_party/blink/renderer/core/css/css_custom_ident_value.h +++ b/third_party/blink/renderer/core/css/css_custom_ident_value.h
@@ -36,7 +36,7 @@ : string_ == other.string_; } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: AtomicString string_;
diff --git a/third_party/blink/renderer/core/css/css_custom_property_declaration.cc b/third_party/blink/renderer/core/css/css_custom_property_declaration.cc index f0e2f873..887cbed4 100644 --- a/third_party/blink/renderer/core/css/css_custom_property_declaration.cc +++ b/third_party/blink/renderer/core/css/css_custom_property_declaration.cc
@@ -8,7 +8,8 @@ namespace blink { -void CSSCustomPropertyDeclaration::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSCustomPropertyDeclaration::TraceAfterDispatch( + blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_custom_property_declaration.h b/third_party/blink/renderer/core/css/css_custom_property_declaration.h index 57cbd75..f7d09e70 100644 --- a/third_party/blink/renderer/core/css/css_custom_property_declaration.h +++ b/third_party/blink/renderer/core/css/css_custom_property_declaration.h
@@ -50,7 +50,7 @@ return this == &other; } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: const AtomicString name_;
diff --git a/third_party/blink/renderer/core/css/css_font_face_src_value.h b/third_party/blink/renderer/core/css/css_font_face_src_value.h index bf1a1b9..b51006a 100644 --- a/third_party/blink/renderer/core/css/css_font_face_src_value.h +++ b/third_party/blink/renderer/core/css/css_font_face_src_value.h
@@ -91,7 +91,7 @@ bool Equals(const CSSFontFaceSrcValue&) const; - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(fetched_); CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_font_family_value.cc b/third_party/blink/renderer/core/css/css_font_family_value.cc index 99e4f96..e503a32 100644 --- a/third_party/blink/renderer/core/css/css_font_family_value.cc +++ b/third_party/blink/renderer/core/css/css_font_family_value.cc
@@ -29,7 +29,7 @@ return SerializeFontFamily(string_); } -void CSSFontFamilyValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSFontFamilyValue::TraceAfterDispatch(blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_font_family_value.h b/third_party/blink/renderer/core/css/css_font_family_value.h index 197efeb0..0b2dfb0 100644 --- a/third_party/blink/renderer/core/css/css_font_family_value.h +++ b/third_party/blink/renderer/core/css/css_font_family_value.h
@@ -25,7 +25,7 @@ return string_ == other.string_; } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: friend class CSSValuePool;
diff --git a/third_party/blink/renderer/core/css/css_font_feature_value.h b/third_party/blink/renderer/core/css/css_font_feature_value.h index aa7db9ed..3eb15cd 100644 --- a/third_party/blink/renderer/core/css/css_font_feature_value.h +++ b/third_party/blink/renderer/core/css/css_font_feature_value.h
@@ -42,7 +42,7 @@ bool Equals(const CSSFontFeatureValue&) const; - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_font_style_range_value.cc b/third_party/blink/renderer/core/css/css_font_style_range_value.cc index 17e54db..336ac79 100644 --- a/third_party/blink/renderer/core/css/css_font_style_range_value.cc +++ b/third_party/blink/renderer/core/css/css_font_style_range_value.cc
@@ -48,7 +48,7 @@ *oblique_values_ == *other.oblique_values_; } -void CSSFontStyleRangeValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSFontStyleRangeValue::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(font_style_value_); visitor->Trace(oblique_values_); CSSValue::TraceAfterDispatch(visitor);
diff --git a/third_party/blink/renderer/core/css/css_font_style_range_value.h b/third_party/blink/renderer/core/css/css_font_style_range_value.h index 0427b30..a68c764 100644 --- a/third_party/blink/renderer/core/css/css_font_style_range_value.h +++ b/third_party/blink/renderer/core/css/css_font_style_range_value.h
@@ -55,7 +55,7 @@ bool Equals(const CSSFontStyleRangeValue&) const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: Member<const CSSIdentifierValue> font_style_value_;
diff --git a/third_party/blink/renderer/core/css/css_font_variation_value.h b/third_party/blink/renderer/core/css/css_font_variation_value.h index bce8e1dd..5488e51 100644 --- a/third_party/blink/renderer/core/css/css_font_variation_value.h +++ b/third_party/blink/renderer/core/css/css_font_variation_value.h
@@ -22,7 +22,7 @@ bool Equals(const CSSFontVariationValue&) const; - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_function_value.h b/third_party/blink/renderer/core/css/css_function_value.h index 2ecd2e5..2ce074cb 100644 --- a/third_party/blink/renderer/core/css/css_function_value.h +++ b/third_party/blink/renderer/core/css/css_function_value.h
@@ -23,7 +23,7 @@ } CSSValueID FunctionType() const { return value_id_; } - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { CSSValueList::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_gradient_value.cc b/third_party/blink/renderer/core/css/css_gradient_value.cc index fc11775..14af20c 100644 --- a/third_party/blink/renderer/core/css/css_gradient_value.cc +++ b/third_party/blink/renderer/core/css/css_gradient_value.cc
@@ -775,7 +775,7 @@ return stop_colors; } -void CSSGradientValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSGradientValue::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(stops_); CSSImageGeneratorValue::TraceAfterDispatch(visitor); } @@ -1051,7 +1051,7 @@ return result; } -void CSSLinearGradientValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSLinearGradientValue::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(first_x_); visitor->Trace(first_y_); visitor->Trace(second_x_); @@ -1448,7 +1448,7 @@ return result; } -void CSSRadialGradientValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSRadialGradientValue::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(first_x_); visitor->Trace(first_y_); visitor->Trace(second_x_); @@ -1528,7 +1528,7 @@ return result; } -void CSSConicGradientValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSConicGradientValue::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(x_); visitor->Trace(y_); visitor->Trace(from_angle_);
diff --git a/third_party/blink/renderer/core/css/css_gradient_value.h b/third_party/blink/renderer/core/css/css_gradient_value.h index 9bb0b9f..54f88df9 100644 --- a/third_party/blink/renderer/core/css/css_gradient_value.h +++ b/third_party/blink/renderer/core/css/css_gradient_value.h
@@ -119,7 +119,7 @@ Vector<Color> GetStopColors(const Document&, const ComputedStyle&) const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; struct GradientDesc; @@ -183,7 +183,7 @@ CSSLinearGradientValue* ComputedCSSValue(const ComputedStyle&, bool allow_visited_style); - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: // Any of these may be null. @@ -281,7 +281,7 @@ CSSRadialGradientValue* ComputedCSSValue(const ComputedStyle&, bool allow_visited_style); - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: // Any of these may be null. @@ -327,7 +327,7 @@ CSSConicGradientValue* ComputedCSSValue(const ComputedStyle&, bool allow_visited_style); - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: // Any of these may be null.
diff --git a/third_party/blink/renderer/core/css/css_grid_auto_repeat_value.h b/third_party/blink/renderer/core/css/css_grid_auto_repeat_value.h index 93f2f90..44dd00b 100644 --- a/third_party/blink/renderer/core/css/css_grid_auto_repeat_value.h +++ b/third_party/blink/renderer/core/css/css_grid_auto_repeat_value.h
@@ -38,7 +38,7 @@ CSSValueID AutoRepeatID() const { return auto_repeat_id_; } - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { CSSValueList::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_grid_integer_repeat_value.h b/third_party/blink/renderer/core/css/css_grid_integer_repeat_value.h index 0e86202..e7b5c8b 100644 --- a/third_party/blink/renderer/core/css/css_grid_integer_repeat_value.h +++ b/third_party/blink/renderer/core/css/css_grid_integer_repeat_value.h
@@ -33,7 +33,7 @@ size_t Repetitions() const { return repetitions_; } - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { CSSValueList::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_grid_line_names_value.h b/third_party/blink/renderer/core/css/css_grid_line_names_value.h index 8fa3bfb..2986ed8 100644 --- a/third_party/blink/renderer/core/css/css_grid_line_names_value.h +++ b/third_party/blink/renderer/core/css/css_grid_line_names_value.h
@@ -43,7 +43,7 @@ String CustomCSSText() const; - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { CSSValueList::TraceAfterDispatch(visitor); } };
diff --git a/third_party/blink/renderer/core/css/css_grid_template_areas_value.h b/third_party/blink/renderer/core/css/css_grid_template_areas_value.h index a847793..69e7b35f 100644 --- a/third_party/blink/renderer/core/css/css_grid_template_areas_value.h +++ b/third_party/blink/renderer/core/css/css_grid_template_areas_value.h
@@ -54,7 +54,7 @@ bool Equals(const CSSGridTemplateAreasValue&) const; - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_identifier_value.cc b/third_party/blink/renderer/core/css/css_identifier_value.cc index 92099bf..0498875 100644 --- a/third_party/blink/renderer/core/css/css_identifier_value.cc +++ b/third_party/blink/renderer/core/css/css_identifier_value.cc
@@ -63,7 +63,7 @@ } } -void CSSIdentifierValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSIdentifierValue::TraceAfterDispatch(blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_identifier_value.h b/third_party/blink/renderer/core/css/css_identifier_value.h index 669b9a4..585a5ec 100644 --- a/third_party/blink/renderer/core/css/css_identifier_value.h +++ b/third_party/blink/renderer/core/css/css_identifier_value.h
@@ -59,7 +59,7 @@ return CssValueIDToPlatformEnum<T>(value_id_); } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: CSSValueID value_id_;
diff --git a/third_party/blink/renderer/core/css/css_image_generator_value.h b/third_party/blink/renderer/core/css/css_image_generator_value.h index 9418049..2d6f9b3 100644 --- a/third_party/blink/renderer/core/css/css_image_generator_value.h +++ b/third_party/blink/renderer/core/css/css_image_generator_value.h
@@ -108,7 +108,7 @@ bool IsUsingCustomProperty(const AtomicString& custom_property_name, const Document&) const; - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_image_set_value.cc b/third_party/blink/renderer/core/css/css_image_set_value.cc index 7bbe52d..6a9f23a 100644 --- a/third_party/blink/renderer/core/css/css_image_set_value.cc +++ b/third_party/blink/renderer/core/css/css_image_set_value.cc
@@ -174,7 +174,7 @@ return true; } -void CSSImageSetValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSImageSetValue::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(cached_image_); CSSValueList::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_image_set_value.h b/third_party/blink/renderer/core/css/css_image_set_value.h index de879b89..846cebf 100644 --- a/third_party/blink/renderer/core/css/css_image_set_value.h +++ b/third_party/blink/renderer/core/css/css_image_set_value.h
@@ -65,7 +65,7 @@ bool HasFailedOrCanceledSubresources() const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; protected: ImageWithScale BestImageForScaleFactor(float scale_factor);
diff --git a/third_party/blink/renderer/core/css/css_image_value.cc b/third_party/blink/renderer/core/css/css_image_value.cc index 0bce383..118e117 100644 --- a/third_party/blink/renderer/core/css/css_image_value.cc +++ b/third_party/blink/renderer/core/css/css_image_value.cc
@@ -150,7 +150,7 @@ : false; } -void CSSImageValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSImageValue::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(cached_image_); CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_image_value.h b/third_party/blink/renderer/core/css/css_image_value.h index 25bc88e5..39469ee 100644 --- a/third_party/blink/renderer/core/css/css_image_value.h +++ b/third_party/blink/renderer/core/css/css_image_value.h
@@ -86,7 +86,7 @@ void SetInitiator(const AtomicString& name) { initiator_name_ = name; } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; void RestoreCachedResourceIfNeeded(const Document&) const; private:
diff --git a/third_party/blink/renderer/core/css/css_inherited_value.h b/third_party/blink/renderer/core/css/css_inherited_value.h index e9d9352..b249c963 100644 --- a/third_party/blink/renderer/core/css/css_inherited_value.h +++ b/third_party/blink/renderer/core/css/css_inherited_value.h
@@ -39,7 +39,7 @@ bool Equals(const CSSInheritedValue&) const { return true; } - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_initial_value.h b/third_party/blink/renderer/core/css/css_initial_value.h index ef3e4194..0e2aebd 100644 --- a/third_party/blink/renderer/core/css/css_initial_value.h +++ b/third_party/blink/renderer/core/css/css_initial_value.h
@@ -38,7 +38,7 @@ bool Equals(const CSSInitialValue&) const { return true; } - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_invalid_variable_value.h b/third_party/blink/renderer/core/css/css_invalid_variable_value.h index 504244f..eb40dcb 100644 --- a/third_party/blink/renderer/core/css/css_invalid_variable_value.h +++ b/third_party/blink/renderer/core/css/css_invalid_variable_value.h
@@ -23,7 +23,7 @@ bool Equals(const CSSInvalidVariableValue&) const { return true; } - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_keyframe_shorthand_value.cc b/third_party/blink/renderer/core/css/css_keyframe_shorthand_value.cc index 7311cb6..6196eef 100644 --- a/third_party/blink/renderer/core/css/css_keyframe_shorthand_value.cc +++ b/third_party/blink/renderer/core/css/css_keyframe_shorthand_value.cc
@@ -43,7 +43,8 @@ return properties_->GetPropertyValue(shorthand_); } -void CSSKeyframeShorthandValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSKeyframeShorthandValue::TraceAfterDispatch( + blink::Visitor* visitor) const { visitor->Trace(properties_); CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_keyframe_shorthand_value.h b/third_party/blink/renderer/core/css/css_keyframe_shorthand_value.h index 43f849f4..d1ea4002 100644 --- a/third_party/blink/renderer/core/css/css_keyframe_shorthand_value.h +++ b/third_party/blink/renderer/core/css/css_keyframe_shorthand_value.h
@@ -45,7 +45,7 @@ return shorthand_ == other.shorthand_ && properties_ == other.properties_; } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: // The shorthand property that these longhands belonged to.
diff --git a/third_party/blink/renderer/core/css/css_keyframes_rule.cc b/third_party/blink/renderer/core/css/css_keyframes_rule.cc index f476c80..734b890 100644 --- a/third_party/blink/renderer/core/css/css_keyframes_rule.cc +++ b/third_party/blink/renderer/core/css/css_keyframes_rule.cc
@@ -74,7 +74,7 @@ return -1; } -void StyleRuleKeyframes::TraceAfterDispatch(blink::Visitor* visitor) { +void StyleRuleKeyframes::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(keyframes_); StyleRuleBase::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_keyframes_rule.h b/third_party/blink/renderer/core/css/css_keyframes_rule.h index 491bed2f..4313c2e 100644 --- a/third_party/blink/renderer/core/css/css_keyframes_rule.h +++ b/third_party/blink/renderer/core/css/css_keyframes_rule.h
@@ -64,7 +64,7 @@ return MakeGarbageCollected<StyleRuleKeyframes>(*this); } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; void StyleChanged() { version_++; } unsigned Version() const { return version_; }
diff --git a/third_party/blink/renderer/core/css/css_layout_function_value.cc b/third_party/blink/renderer/core/css/css_layout_function_value.cc index 3bc61f11..ada6eaf 100644 --- a/third_party/blink/renderer/core/css/css_layout_function_value.cc +++ b/third_party/blink/renderer/core/css/css_layout_function_value.cc
@@ -32,7 +32,7 @@ return GetName() == other.GetName() && IsInline() == other.IsInline(); } -void CSSLayoutFunctionValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSLayoutFunctionValue::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(name_); CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_layout_function_value.h b/third_party/blink/renderer/core/css/css_layout_function_value.h index 13f55aae..853110df 100644 --- a/third_party/blink/renderer/core/css/css_layout_function_value.h +++ b/third_party/blink/renderer/core/css/css_layout_function_value.h
@@ -25,7 +25,7 @@ bool IsInline() const { return is_inline_; } bool Equals(const CSSLayoutFunctionValue&) const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: Member<CSSCustomIdentValue> name_;
diff --git a/third_party/blink/renderer/core/css/css_light_dark_color_pair.h b/third_party/blink/renderer/core/css/css_light_dark_color_pair.h index 84737f5..994dc1b 100644 --- a/third_party/blink/renderer/core/css/css_light_dark_color_pair.h +++ b/third_party/blink/renderer/core/css/css_light_dark_color_pair.h
@@ -14,7 +14,7 @@ CSSLightDarkColorPair(const CSSValue* first, const CSSValue* second) : CSSValuePair(kLightDarkColorPairClass, first, second) {} String CustomCSSText() const; - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { CSSValuePair::TraceAfterDispatch(visitor); } };
diff --git a/third_party/blink/renderer/core/css/css_math_function_value.cc b/third_party/blink/renderer/core/css/css_math_function_value.cc index 49986ea..7df858d 100644 --- a/third_party/blink/renderer/core/css/css_math_function_value.cc +++ b/third_party/blink/renderer/core/css/css_math_function_value.cc
@@ -17,7 +17,7 @@ }; ASSERT_SIZE(CSSMathFunctionValue, SameSizeAsCSSMathFunctionValue); -void CSSMathFunctionValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSMathFunctionValue::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(expression_); CSSPrimitiveValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_math_function_value.h b/third_party/blink/renderer/core/css/css_math_function_value.h index b96b5c9..b098693a 100644 --- a/third_party/blink/renderer/core/css/css_math_function_value.h +++ b/third_party/blink/renderer/core/css/css_math_function_value.h
@@ -90,7 +90,7 @@ bool HasComparisons() const { return expression_->HasComparisons(); } - void TraceAfterDispatch(blink::Visitor* visitor); + void TraceAfterDispatch(blink::Visitor* visitor) const; private: bool IsNonNegative() const { return is_non_negative_math_function_; }
diff --git a/third_party/blink/renderer/core/css/css_numeric_literal_value.cc b/third_party/blink/renderer/core/css/css_numeric_literal_value.cc index 368f079..41e34de 100644 --- a/third_party/blink/renderer/core/css/css_numeric_literal_value.cc +++ b/third_party/blink/renderer/core/css/css_numeric_literal_value.cc
@@ -17,7 +17,7 @@ }; ASSERT_SIZE(CSSNumericLiteralValue, SameSizeAsCSSNumericLiteralValue); -void CSSNumericLiteralValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSNumericLiteralValue::TraceAfterDispatch(blink::Visitor* visitor) const { CSSPrimitiveValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_numeric_literal_value.h b/third_party/blink/renderer/core/css/css_numeric_literal_value.h index 64087343..d07cbea 100644 --- a/third_party/blink/renderer/core/css/css_numeric_literal_value.h +++ b/third_party/blink/renderer/core/css/css_numeric_literal_value.h
@@ -63,7 +63,7 @@ String CustomCSSText() const; bool Equals(const CSSNumericLiteralValue& other) const; - void TraceAfterDispatch(blink::Visitor* visitor); + void TraceAfterDispatch(blink::Visitor* visitor) const; private: double num_;
diff --git a/third_party/blink/renderer/core/css/css_paint_value.cc b/third_party/blink/renderer/core/css/css_paint_value.cc index 5747f01..0a997825 100644 --- a/third_party/blink/renderer/core/css/css_paint_value.cc +++ b/third_party/blink/renderer/core/css/css_paint_value.cc
@@ -249,7 +249,7 @@ CustomCSSText() == other.CustomCSSText(); } -void CSSPaintValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSPaintValue::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(name_); visitor->Trace(generators_); visitor->Trace(paint_image_generator_observer_);
diff --git a/third_party/blink/renderer/core/css/css_paint_value.h b/third_party/blink/renderer/core/css/css_paint_value.h index a54d08c..06d1cced 100644 --- a/third_party/blink/renderer/core/css/css_paint_value.h +++ b/third_party/blink/renderer/core/css/css_paint_value.h
@@ -71,7 +71,7 @@ } unsigned NumberOfGeneratorsForTesting() const { return generators_.size(); } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: class Observer final : public CSSPaintImageGenerator::Observer {
diff --git a/third_party/blink/renderer/core/css/css_path_value.cc b/third_party/blink/renderer/core/css/css_path_value.cc index 9e8982f..3c1ae0b 100644 --- a/third_party/blink/renderer/core/css/css_path_value.cc +++ b/third_party/blink/renderer/core/css/css_path_value.cc
@@ -53,7 +53,7 @@ return ByteStream() == other.ByteStream(); } -void CSSPathValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSPathValue::TraceAfterDispatch(blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_path_value.h b/third_party/blink/renderer/core/css/css_path_value.h index 6ff0f908..ee3d8128 100644 --- a/third_party/blink/renderer/core/css/css_path_value.h +++ b/third_party/blink/renderer/core/css/css_path_value.h
@@ -33,7 +33,7 @@ bool Equals(const CSSPathValue&) const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; const SVGPathByteStream& ByteStream() const { return style_path_->ByteStream();
diff --git a/third_party/blink/renderer/core/css/css_pending_substitution_value.cc b/third_party/blink/renderer/core/css/css_pending_substitution_value.cc index c2a141e..40bf775 100644 --- a/third_party/blink/renderer/core/css/css_pending_substitution_value.cc +++ b/third_party/blink/renderer/core/css/css_pending_substitution_value.cc
@@ -7,7 +7,8 @@ namespace blink { namespace cssvalue { -void CSSPendingSubstitutionValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSPendingSubstitutionValue::TraceAfterDispatch( + blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); visitor->Trace(shorthand_value_); }
diff --git a/third_party/blink/renderer/core/css/css_pending_substitution_value.h b/third_party/blink/renderer/core/css/css_pending_substitution_value.h index b5931b6..7af6162 100644 --- a/third_party/blink/renderer/core/css/css_pending_substitution_value.h +++ b/third_party/blink/renderer/core/css/css_pending_substitution_value.h
@@ -32,7 +32,7 @@ } String CustomCSSText() const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: CSSPropertyID shorthand_property_id_;
diff --git a/third_party/blink/renderer/core/css/css_primitive_value.cc b/third_party/blink/renderer/core/css/css_primitive_value.cc index 62f9867..0c63781 100644 --- a/third_party/blink/renderer/core/css/css_primitive_value.cc +++ b/third_party/blink/renderer/core/css/css_primitive_value.cc
@@ -553,7 +553,7 @@ return To<CSSNumericLiteralValue>(this)->CustomCSSText(); } -void CSSPrimitiveValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSPrimitiveValue::TraceAfterDispatch(blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_primitive_value.h b/third_party/blink/renderer/core/css/css_primitive_value.h index b1eb9251..2cfe667 100644 --- a/third_party/blink/renderer/core/css/css_primitive_value.h +++ b/third_party/blink/renderer/core/css/css_primitive_value.h
@@ -248,7 +248,7 @@ String CustomCSSText() const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; static UnitType CanonicalUnitTypeForCategory(UnitCategory); static double ConversionToCanonicalUnitsScaleFactor(UnitType);
diff --git a/third_party/blink/renderer/core/css/css_property_value_set.cc b/third_party/blink/renderer/core/css/css_property_value_set.cc index fc32d31..e1488e5 100644 --- a/third_party/blink/renderer/core/css/css_property_value_set.cc +++ b/third_party/blink/renderer/core/css/css_property_value_set.cc
@@ -169,7 +169,8 @@ template CORE_EXPORT int ImmutableCSSPropertyValueSet::FindPropertyIndex( AtRuleDescriptorID) const; -void ImmutableCSSPropertyValueSet::TraceAfterDispatch(blink::Visitor* visitor) { +void ImmutableCSSPropertyValueSet::TraceAfterDispatch( + blink::Visitor* visitor) const { const Member<const CSSValue>* values = ValueArray(); for (unsigned i = 0; i < array_size_; i++) visitor->Trace(values[i]); @@ -637,7 +638,8 @@ template CORE_EXPORT int MutableCSSPropertyValueSet::FindPropertyIndex( AtomicString) const; -void MutableCSSPropertyValueSet::TraceAfterDispatch(blink::Visitor* visitor) { +void MutableCSSPropertyValueSet::TraceAfterDispatch( + blink::Visitor* visitor) const { visitor->Trace(cssom_wrapper_); visitor->Trace(property_vector_); CSSPropertyValueSet::TraceAfterDispatch(visitor);
diff --git a/third_party/blink/renderer/core/css/css_property_value_set.h b/third_party/blink/renderer/core/css/css_property_value_set.h index dcf8b45..44bcdab 100644 --- a/third_party/blink/renderer/core/css/css_property_value_set.h +++ b/third_party/blink/renderer/core/css/css_property_value_set.h
@@ -139,7 +139,7 @@ bool PropertyMatches(CSSPropertyID, const CSSValue&) const; void Trace(Visitor*); - void TraceAfterDispatch(blink::Visitor* visitor) {} + void TraceAfterDispatch(blink::Visitor* visitor) const {} protected: enum { kMaxArraySize = (1 << 28) - 1 }; @@ -195,7 +195,7 @@ template <typename T> // CSSPropertyID or AtomicString int FindPropertyIndex(T property) const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; }; inline const Member<const CSSValue>* ImmutableCSSPropertyValueSet::ValueArray() @@ -283,7 +283,7 @@ template <typename T> // CSSPropertyID or AtomicString int FindPropertyIndex(T property) const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: bool RemovePropertyAtIndex(int, String* return_text);
diff --git a/third_party/blink/renderer/core/css/css_quad_value.cc b/third_party/blink/renderer/core/css/css_quad_value.cc index 21a7c60..5ecec7e 100644 --- a/third_party/blink/renderer/core/css/css_quad_value.cc +++ b/third_party/blink/renderer/core/css/css_quad_value.cc
@@ -37,7 +37,7 @@ return result.ToString(); } -void CSSQuadValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSQuadValue::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(top_); visitor->Trace(right_); visitor->Trace(bottom_);
diff --git a/third_party/blink/renderer/core/css/css_quad_value.h b/third_party/blink/renderer/core/css/css_quad_value.h index 7f02d75..711b74b 100644 --- a/third_party/blink/renderer/core/css/css_quad_value.h +++ b/third_party/blink/renderer/core/css/css_quad_value.h
@@ -68,7 +68,7 @@ DataEquivalent(bottom_, other.bottom_); } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: TypeForSerialization serialization_type_;
diff --git a/third_party/blink/renderer/core/css/css_ray_value.cc b/third_party/blink/renderer/core/css/css_ray_value.cc index d54da15..65fac43 100644 --- a/third_party/blink/renderer/core/css/css_ray_value.cc +++ b/third_party/blink/renderer/core/css/css_ray_value.cc
@@ -36,7 +36,7 @@ DataEquivalent(contain_, other.contain_); } -void CSSRayValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSRayValue::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(angle_); visitor->Trace(size_); visitor->Trace(contain_);
diff --git a/third_party/blink/renderer/core/css/css_ray_value.h b/third_party/blink/renderer/core/css/css_ray_value.h index dd642cd77..ea27a1d 100644 --- a/third_party/blink/renderer/core/css/css_ray_value.h +++ b/third_party/blink/renderer/core/css/css_ray_value.h
@@ -29,7 +29,7 @@ bool Equals(const CSSRayValue&) const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: Member<const CSSPrimitiveValue> angle_;
diff --git a/third_party/blink/renderer/core/css/css_reflect_value.cc b/third_party/blink/renderer/core/css/css_reflect_value.cc index 7974b236..4d92d42 100644 --- a/third_party/blink/renderer/core/css/css_reflect_value.cc +++ b/third_party/blink/renderer/core/css/css_reflect_value.cc
@@ -44,7 +44,7 @@ DataEquivalent(mask_, other.mask_); } -void CSSReflectValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSReflectValue::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(direction_); visitor->Trace(offset_); visitor->Trace(mask_);
diff --git a/third_party/blink/renderer/core/css/css_reflect_value.h b/third_party/blink/renderer/core/css/css_reflect_value.h index 50e206b..1b6e5749 100644 --- a/third_party/blink/renderer/core/css/css_reflect_value.h +++ b/third_party/blink/renderer/core/css/css_reflect_value.h
@@ -55,7 +55,7 @@ bool Equals(const CSSReflectValue&) const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: Member<CSSIdentifierValue> direction_;
diff --git a/third_party/blink/renderer/core/css/css_shadow_value.cc b/third_party/blink/renderer/core/css/css_shadow_value.cc index 49972ca..5ac6c6b4 100644 --- a/third_party/blink/renderer/core/css/css_shadow_value.cc +++ b/third_party/blink/renderer/core/css/css_shadow_value.cc
@@ -77,7 +77,7 @@ DataEquivalent(style, other.style); } -void CSSShadowValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSShadowValue::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(x); visitor->Trace(y); visitor->Trace(blur);
diff --git a/third_party/blink/renderer/core/css/css_shadow_value.h b/third_party/blink/renderer/core/css/css_shadow_value.h index 34223f84..9cd0d95 100644 --- a/third_party/blink/renderer/core/css/css_shadow_value.h +++ b/third_party/blink/renderer/core/css/css_shadow_value.h
@@ -52,7 +52,7 @@ Member<CSSIdentifierValue> style; Member<CSSValue> color; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; }; template <>
diff --git a/third_party/blink/renderer/core/css/css_string_value.cc b/third_party/blink/renderer/core/css/css_string_value.cc index b988113..3795a10 100644 --- a/third_party/blink/renderer/core/css/css_string_value.cc +++ b/third_party/blink/renderer/core/css/css_string_value.cc
@@ -16,7 +16,7 @@ return SerializeString(string_); } -void CSSStringValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSStringValue::TraceAfterDispatch(blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_string_value.h b/third_party/blink/renderer/core/css/css_string_value.h index b2b71ee..2641f37 100644 --- a/third_party/blink/renderer/core/css/css_string_value.h +++ b/third_party/blink/renderer/core/css/css_string_value.h
@@ -23,7 +23,7 @@ return string_ == other.string_; } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: String string_;
diff --git a/third_party/blink/renderer/core/css/css_timing_function_value.h b/third_party/blink/renderer/core/css/css_timing_function_value.h index 795abd9..26e09608 100644 --- a/third_party/blink/renderer/core/css/css_timing_function_value.h +++ b/third_party/blink/renderer/core/css/css_timing_function_value.h
@@ -53,7 +53,7 @@ bool Equals(const CSSCubicBezierTimingFunctionValue&) const; - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); } @@ -81,7 +81,7 @@ bool Equals(const CSSStepsTimingFunctionValue&) const; - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_unicode_range_value.h b/third_party/blink/renderer/core/css/css_unicode_range_value.h index 506c080..4db1508 100644 --- a/third_party/blink/renderer/core/css/css_unicode_range_value.h +++ b/third_party/blink/renderer/core/css/css_unicode_range_value.h
@@ -45,7 +45,7 @@ bool Equals(const CSSUnicodeRangeValue&) const; - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_unset_value.h b/third_party/blink/renderer/core/css/css_unset_value.h index 91f23e06..dfbf7a8 100644 --- a/third_party/blink/renderer/core/css/css_unset_value.h +++ b/third_party/blink/renderer/core/css/css_unset_value.h
@@ -26,7 +26,7 @@ bool Equals(const CSSUnsetValue&) const { return true; } - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); } };
diff --git a/third_party/blink/renderer/core/css/css_uri_value.cc b/third_party/blink/renderer/core/css/css_uri_value.cc index 242c7273..ce4e757 100644 --- a/third_party/blink/renderer/core/css/css_uri_value.cc +++ b/third_party/blink/renderer/core/css/css_uri_value.cc
@@ -83,7 +83,7 @@ AtomicString(KURL(base_url, relative_url_, charset).GetString())); } -void CSSURIValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSURIValue::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(resource_); CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_uri_value.h b/third_party/blink/renderer/core/css/css_uri_value.h index 3999c76..909779e 100644 --- a/third_party/blink/renderer/core/css/css_uri_value.h +++ b/third_party/blink/renderer/core/css/css_uri_value.h
@@ -43,7 +43,7 @@ CSSURIValue* ValueWithURLMadeAbsolute(const KURL& base_url, const WTF::TextEncoding&) const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: KURL AbsoluteUrl() const;
diff --git a/third_party/blink/renderer/core/css/css_value.h b/third_party/blink/renderer/core/css/css_value.h index f37fe6e82..29eac1b6 100644 --- a/third_party/blink/renderer/core/css/css_value.h +++ b/third_party/blink/renderer/core/css/css_value.h
@@ -180,7 +180,7 @@ bool operator==(const CSSValue&) const; void FinalizeGarbageCollectedObject(); - void TraceAfterDispatch(blink::Visitor* visitor) {} + void TraceAfterDispatch(blink::Visitor* visitor) const {} void Trace(Visitor*); // ~CSSValue should be public, because non-public ~CSSValue causes C2248
diff --git a/third_party/blink/renderer/core/css/css_value_list.cc b/third_party/blink/renderer/core/css/css_value_list.cc index 1e02ae2..fb8bf147 100644 --- a/third_party/blink/renderer/core/css/css_value_list.cc +++ b/third_party/blink/renderer/core/css/css_value_list.cc
@@ -138,7 +138,7 @@ value->ReResolveUrl(document); } -void CSSValueList::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSValueList::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(values_); CSSValue::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/css_value_list.h b/third_party/blink/renderer/core/css/css_value_list.h index 6883efc..eb63aff 100644 --- a/third_party/blink/renderer/core/css/css_value_list.h +++ b/third_party/blink/renderer/core/css/css_value_list.h
@@ -75,7 +75,7 @@ bool MayContainUrl() const; void ReResolveUrl(const Document&) const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: HeapVector<Member<const CSSValue>, 4> values_;
diff --git a/third_party/blink/renderer/core/css/css_value_pair.cc b/third_party/blink/renderer/core/css/css_value_pair.cc index 3ca5de6b..820b646 100644 --- a/third_party/blink/renderer/core/css/css_value_pair.cc +++ b/third_party/blink/renderer/core/css/css_value_pair.cc
@@ -6,7 +6,7 @@ namespace blink { -void CSSValuePair::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSValuePair::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(first_); visitor->Trace(second_); CSSValue::TraceAfterDispatch(visitor);
diff --git a/third_party/blink/renderer/core/css/css_value_pair.h b/third_party/blink/renderer/core/css/css_value_pair.h index 2cd6b476..db0081bf 100644 --- a/third_party/blink/renderer/core/css/css_value_pair.h +++ b/third_party/blink/renderer/core/css/css_value_pair.h
@@ -64,7 +64,7 @@ DataEquivalent(second_, other.second_); } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; protected: CSSValuePair(ClassType class_type,
diff --git a/third_party/blink/renderer/core/css/css_variable_reference_value.cc b/third_party/blink/renderer/core/css/css_variable_reference_value.cc index 859749f..699091f0 100644 --- a/third_party/blink/renderer/core/css/css_variable_reference_value.cc +++ b/third_party/blink/renderer/core/css/css_variable_reference_value.cc
@@ -6,7 +6,8 @@ namespace blink { -void CSSVariableReferenceValue::TraceAfterDispatch(blink::Visitor* visitor) { +void CSSVariableReferenceValue::TraceAfterDispatch( + blink::Visitor* visitor) const { CSSValue::TraceAfterDispatch(visitor); visitor->Trace(parser_context_); }
diff --git a/third_party/blink/renderer/core/css/css_variable_reference_value.h b/third_party/blink/renderer/core/css/css_variable_reference_value.h index 7ec8b2d..d3dcf20 100644 --- a/third_party/blink/renderer/core/css/css_variable_reference_value.h +++ b/third_party/blink/renderer/core/css/css_variable_reference_value.h
@@ -38,7 +38,7 @@ } String CustomCSSText() const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: scoped_refptr<CSSVariableData> data_;
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 275dc47..b6863df 100644 --- a/third_party/blink/renderer/core/css/media_query_evaluator.cc +++ b/third_party/blink/renderer/core/css/media_query_evaluator.cc
@@ -158,6 +158,15 @@ return result; } +bool MediaQueryEvaluator::DidResultsChange( + const MediaQueryResultList& results) const { + for (auto& result : results) { + if (Eval(result.Expression()) != result.Result()) + 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 57d6a8a..2d9e016d 100644 --- a/third_party/blink/renderer/core/css/media_query_evaluator.h +++ b/third_party/blink/renderer/core/css/media_query_evaluator.h
@@ -94,6 +94,10 @@ // Evaluates media query subexpression, ie "and (media-feature: value)" part. bool Eval(const MediaQueryExp&) const; + // Returns true if any of the expressions in the results lists changed its + // evaluation. + bool DidResultsChange(const MediaQueryResultList& results) const; + void Trace(Visitor*); private:
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 7293a782..1605896 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -737,6 +737,8 @@ viewport_style->SetOverflowX(EOverflow::kAuto); viewport_style->SetOverflowY(EOverflow::kAuto); + document.GetStyleEngine().ApplyVisionDeficiencyStyle(viewport_style); + return viewport_style; }
diff --git a/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc b/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc index 797836e0..e7a0dde 100644 --- a/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc
@@ -358,13 +358,9 @@ if (has_viewport_units_) needs_update_ = kResolve; - auto& results = viewport_dependent_media_query_results_; - for (unsigned i = 0; i < results.size(); i++) { - if (initial_viewport_medium_->Eval(results[i].Expression()) != - results[i].Result()) { - needs_update_ = kCollectRules; - break; - } + if (initial_viewport_medium_->DidResultsChange( + viewport_dependent_media_query_results_)) { + needs_update_ = kCollectRules; } if (needs_update_ == kNoUpdate) return;
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index fd300fb..5ab331c8 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -36,6 +36,7 @@ #include "third_party/blink/renderer/core/css/css_font_selector.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" #include "third_party/blink/renderer/core/css/css_style_sheet.h" +#include "third_party/blink/renderer/core/css/css_uri_value.h" #include "third_party/blink/renderer/core/css/css_value_list.h" #include "third_party/blink/renderer/core/css/document_style_environment_variables.h" #include "third_party/blink/renderer/core/css/document_style_sheet_collector.h" @@ -78,7 +79,9 @@ #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/style/computed_style.h" +#include "third_party/blink/renderer/core/style/filter_operations.h" #include "third_party/blink/renderer/core/style/style_initial_data.h" +#include "third_party/blink/renderer/core/svg/svg_resource.h" #include "third_party/blink/renderer/core/svg/svg_style_element.h" #include "third_party/blink/renderer/platform/fonts/font_cache.h" #include "third_party/blink/renderer/platform/fonts/font_selector.h" @@ -1626,6 +1629,42 @@ kInvalidateCurrentScope, has_rebuilt_font_cache); } +void StyleEngine::LoadVisionDeficiencyFilter() { + VisionDeficiency old_vision_deficiency = vision_deficiency_; + vision_deficiency_ = GetDocument().GetPage()->GetVisionDeficiency(); + if (vision_deficiency_ == old_vision_deficiency) + return; + + if (vision_deficiency_ == VisionDeficiency::kNoVisionDeficiency) { + vision_deficiency_filter_ = nullptr; + } else { + AtomicString url = CreateVisionDeficiencyFilterUrl(vision_deficiency_); + cssvalue::CSSURIValue css_uri_value(url); + SVGResource* svg_resource = css_uri_value.EnsureResourceReference(); + // Note: The fact that we're using data: URLs here is an + // implementation detail. Emulating vision deficiencies should still + // work even if the Document's Content-Security-Policy disallows + // data: URLs. + svg_resource->LoadWithoutCSP(GetDocument()); + vision_deficiency_filter_ = + MakeGarbageCollected<ReferenceFilterOperation>(url, svg_resource); + } +} + +void StyleEngine::VisionDeficiencyChanged() { + MarkViewportStyleDirty(); +} + +void StyleEngine::ApplyVisionDeficiencyStyle( + scoped_refptr<ComputedStyle> layout_view_style) { + LoadVisionDeficiencyFilter(); + if (vision_deficiency_filter_) { + FilterOperations ops; + ops.Operations().push_back(vision_deficiency_filter_); + layout_view_style->SetFilter(ops); + } +} + const MediaQueryEvaluator& StyleEngine::EnsureMediaQueryEvaluator() { if (!media_query_evaluator_) { if (GetDocument().GetFrame()) { @@ -1641,27 +1680,16 @@ bool StyleEngine::MediaQueryAffectedByViewportChange() { DCHECK(IsMaster()); DCHECK(global_rule_set_); - const MediaQueryEvaluator& evaluator = EnsureMediaQueryEvaluator(); - const auto& results = global_rule_set_->GetRuleFeatureSet() - .ViewportDependentMediaQueryResults(); - for (unsigned i = 0; i < results.size(); ++i) { - if (evaluator.Eval(results[i].Expression()) != results[i].Result()) - return true; - } - return false; + return EnsureMediaQueryEvaluator().DidResultsChange( + global_rule_set_->GetRuleFeatureSet() + .ViewportDependentMediaQueryResults()); } bool StyleEngine::MediaQueryAffectedByDeviceChange() { DCHECK(IsMaster()); DCHECK(global_rule_set_); - const MediaQueryEvaluator& evaluator = EnsureMediaQueryEvaluator(); - const auto& results = - global_rule_set_->GetRuleFeatureSet().DeviceDependentMediaQueryResults(); - for (unsigned i = 0; i < results.size(); ++i) { - if (evaluator.Eval(results[i].Expression()) != results[i].Result()) - return true; - } - return false; + return EnsureMediaQueryEvaluator().DidResultsChange( + global_rule_set_->GetRuleFeatureSet().DeviceDependentMediaQueryResults()); } bool StyleEngine::UpdateRemUnits(const ComputedStyle* old_root_style, @@ -2146,6 +2174,7 @@ visitor->Trace(active_tree_scopes_); visitor->Trace(tree_boundary_crossing_scopes_); visitor->Trace(resolver_); + visitor->Trace(vision_deficiency_filter_); visitor->Trace(viewport_resolver_); visitor->Trace(media_query_evaluator_); visitor->Trace(global_rule_set_);
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h index e750feac..05a79dfd 100644 --- a/third_party/blink/renderer/core/css/style_engine.h +++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -51,6 +51,7 @@ #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/tree_ordered_list.h" #include "third_party/blink/renderer/core/html/track/text_track.h" +#include "third_party/blink/renderer/core/style/filter_operations.h" #include "third_party/blink/renderer/platform/bindings/name_client.h" #include "third_party/blink/renderer/platform/fonts/font_selector_client.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -80,7 +81,7 @@ // The StyleEngine class manages style-related state for the document. There is // a 1-1 relationship of Document to StyleEngine. The document calls the -// StyleEngine when the the document is updated in a way that impacts styles. +// StyleEngine when the document is updated in a way that impacts styles. class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>, public FontSelectorClient, public NameClient { @@ -324,6 +325,10 @@ void ApplyUserRuleSetChanges(const ActiveStyleSheetVector& old_style_sheets, const ActiveStyleSheetVector& new_style_sheets); + void VisionDeficiencyChanged(); + void ApplyVisionDeficiencyStyle( + scoped_refptr<ComputedStyle> layout_view_style); + void CollectMatchingUserRules(ElementRuleCollector&) const; void CustomPropertyRegistered(); @@ -386,6 +391,8 @@ // FontSelectorClient implementation. void FontsNeedUpdate(FontSelector*) override; + void LoadVisionDeficiencyFilter(); + private: bool NeedsActiveStyleSheetUpdate() const { return all_tree_scopes_dirty_ || tree_scopes_removed_ || @@ -538,6 +545,9 @@ bool viewport_style_dirty_ = false; bool fonts_need_update_ = false; + VisionDeficiency vision_deficiency_ = VisionDeficiency::kNoVisionDeficiency; + Member<ReferenceFilterOperation> vision_deficiency_filter_; + Member<StyleResolver> resolver_; Member<ViewportStyleResolver> viewport_resolver_; Member<MediaQueryEvaluator> media_query_evaluator_;
diff --git a/third_party/blink/renderer/core/css/style_rule.cc b/third_party/blink/renderer/core/css/style_rule.cc index 138731c..1220ed8 100644 --- a/third_party/blink/renderer/core/css/style_rule.cc +++ b/third_party/blink/renderer/core/css/style_rule.cc
@@ -287,7 +287,7 @@ return !lazy_property_parser_; } -void StyleRule::TraceAfterDispatch(blink::Visitor* visitor) { +void StyleRule::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(properties_); visitor->Trace(lazy_property_parser_); StyleRuleBase::TraceAfterDispatch(visitor); @@ -312,7 +312,7 @@ return *To<MutableCSSPropertyValueSet>(properties_.Get()); } -void StyleRulePage::TraceAfterDispatch(blink::Visitor* visitor) { +void StyleRulePage::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(properties_); StyleRuleBase::TraceAfterDispatch(visitor); } @@ -333,7 +333,7 @@ return *To<MutableCSSPropertyValueSet>(properties_.Get()); } -void StyleRuleProperty::TraceAfterDispatch(blink::Visitor* visitor) { +void StyleRuleProperty::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(properties_); StyleRuleBase::TraceAfterDispatch(visitor); } @@ -351,7 +351,7 @@ return *To<MutableCSSPropertyValueSet>(properties_.Get()); } -void StyleRuleFontFace::TraceAfterDispatch(blink::Visitor* visitor) { +void StyleRuleFontFace::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(properties_); StyleRuleBase::TraceAfterDispatch(visitor); } @@ -376,7 +376,7 @@ child_rules_.EraseAt(index); } -void StyleRuleGroup::TraceAfterDispatch(blink::Visitor* visitor) { +void StyleRuleGroup::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(child_rules_); StyleRuleBase::TraceAfterDispatch(visitor); } @@ -412,7 +412,7 @@ : StyleRuleCondition(kSupports, condition_text, adopt_rules), condition_is_supported_(condition_is_supported) {} -void StyleRuleMedia::TraceAfterDispatch(blink::Visitor* visitor) { +void StyleRuleMedia::TraceAfterDispatch(blink::Visitor* visitor) const { StyleRuleCondition::TraceAfterDispatch(visitor); } @@ -433,7 +433,7 @@ return *To<MutableCSSPropertyValueSet>(properties_.Get()); } -void StyleRuleViewport::TraceAfterDispatch(blink::Visitor* visitor) { +void StyleRuleViewport::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(properties_); StyleRuleBase::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/style_rule.h b/third_party/blink/renderer/core/css/style_rule.h index ddf2b30d..4d1a1b01 100644 --- a/third_party/blink/renderer/core/css/style_rule.h +++ b/third_party/blink/renderer/core/css/style_rule.h
@@ -74,7 +74,7 @@ CSSRule* CreateCSSOMWrapper(CSSRule* parent_rule) const; void Trace(Visitor*); - void TraceAfterDispatch(blink::Visitor* visitor) {} + void TraceAfterDispatch(blink::Visitor* visitor) const {} void FinalizeGarbageCollectedObject(); // ~StyleRuleBase should be public, because non-public ~StyleRuleBase @@ -121,7 +121,7 @@ bool PropertiesHaveFailedOrCanceledSubresources() const; bool ShouldConsiderForMatchingRules(bool include_empty_rules) const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: friend class CSSLazyParsingTest; @@ -155,7 +155,7 @@ return MakeGarbageCollected<StyleRuleFontFace>(*this); } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: Member<CSSPropertyValueSet> properties_; // Cannot be null. @@ -179,7 +179,7 @@ return MakeGarbageCollected<StyleRulePage>(*this); } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: Member<CSSPropertyValueSet> properties_; // Cannot be null. @@ -200,7 +200,7 @@ return MakeGarbageCollected<StyleRuleProperty>(*this); } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: String name_; @@ -216,7 +216,7 @@ void WrapperInsertRule(unsigned, StyleRuleBase*); void WrapperRemoveRule(unsigned); - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; protected: StyleRuleGroup(RuleType, HeapVector<Member<StyleRuleBase>>& adopt_rule); @@ -230,7 +230,7 @@ public: String ConditionText() const { return condition_text_; } - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { StyleRuleGroup::TraceAfterDispatch(visitor); } @@ -255,7 +255,7 @@ return MakeGarbageCollected<StyleRuleMedia>(*this); } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: scoped_refptr<MediaQuerySet> media_queries_; @@ -273,7 +273,7 @@ return MakeGarbageCollected<StyleRuleSupports>(*this); } - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { StyleRuleCondition::TraceAfterDispatch(visitor); } @@ -294,7 +294,7 @@ return MakeGarbageCollected<StyleRuleViewport>(*this); } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: Member<CSSPropertyValueSet> properties_; // Cannot be null @@ -304,7 +304,7 @@ class StyleRuleCharset : public StyleRuleBase { public: StyleRuleCharset() : StyleRuleBase(kCharset) {} - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { StyleRuleBase::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/style_rule_import.cc b/third_party/blink/renderer/core/css/style_rule_import.cc index 900b29c..ed89757 100644 --- a/third_party/blink/renderer/core/css/style_rule_import.cc +++ b/third_party/blink/renderer/core/css/style_rule_import.cc
@@ -54,7 +54,7 @@ style_sheet_client_->Dispose(); } -void StyleRuleImport::TraceAfterDispatch(blink::Visitor* visitor) { +void StyleRuleImport::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(style_sheet_client_); visitor->Trace(parent_style_sheet_); visitor->Trace(style_sheet_);
diff --git a/third_party/blink/renderer/core/css/style_rule_import.h b/third_party/blink/renderer/core/css/style_rule_import.h index 8359418..db062f0 100644 --- a/third_party/blink/renderer/core/css/style_rule_import.h +++ b/third_party/blink/renderer/core/css/style_rule_import.h
@@ -57,7 +57,7 @@ void RequestStyleSheet(); - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: // FIXME: inherit from ResourceClient directly to eliminate back
diff --git a/third_party/blink/renderer/core/css/style_rule_keyframe.cc b/third_party/blink/renderer/core/css/style_rule_keyframe.cc index f9aa723..d688193 100644 --- a/third_party/blink/renderer/core/css/style_rule_keyframe.cc +++ b/third_party/blink/renderer/core/css/style_rule_keyframe.cc
@@ -63,7 +63,7 @@ return result.ToString(); } -void StyleRuleKeyframe::TraceAfterDispatch(blink::Visitor* visitor) { +void StyleRuleKeyframe::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(properties_); StyleRuleBase::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/style_rule_keyframe.h b/third_party/blink/renderer/core/css/style_rule_keyframe.h index cb8cac2e..37493bc 100644 --- a/third_party/blink/renderer/core/css/style_rule_keyframe.h +++ b/third_party/blink/renderer/core/css/style_rule_keyframe.h
@@ -30,7 +30,7 @@ String CssText() const; - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: Member<CSSPropertyValueSet> properties_;
diff --git a/third_party/blink/renderer/core/css/style_rule_namespace.h b/third_party/blink/renderer/core/css/style_rule_namespace.h index 76331b5..b1875ca 100644 --- a/third_party/blink/renderer/core/css/style_rule_namespace.h +++ b/third_party/blink/renderer/core/css/style_rule_namespace.h
@@ -24,7 +24,7 @@ AtomicString Prefix() const { return prefix_; } AtomicString Uri() const { return uri_; } - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { StyleRuleBase::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/vision_deficiency.cc b/third_party/blink/renderer/core/css/vision_deficiency.cc new file mode 100644 index 0000000..66e9d39 --- /dev/null +++ b/third_party/blink/renderer/core/css/vision_deficiency.cc
@@ -0,0 +1,100 @@ +// 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 "third_party/blink/renderer/core/css/vision_deficiency.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { + +AtomicString CreateFilterDataUrl(AtomicString piece) { + // clang-format off + AtomicString url = + "data:image/svg+xml," + "<svg xmlns=\"http://www.w3.org/2000/svg\">" + "<filter id=\"f\">" + + piece + + "</filter>" + "</svg>" + "#f"; + // clang-format on + return url; +} + +AtomicString CreateVisionDeficiencyFilterUrl( + VisionDeficiency vision_deficiency) { + switch (vision_deficiency) { + case VisionDeficiency::kAchromatomaly: + return CreateFilterDataUrl( + "<feColorMatrix values=\"" + "0.618 0.320 0.062 0.000 0.000 " + "0.163 0.775 0.062 0.000 0.000 " + "0.163 0.320 0.516 0.000 0.000 " + "0.000 0.000 0.000 1.000 0.000 " + "\"/>"); + case VisionDeficiency::kAchromatopsia: + return CreateFilterDataUrl( + "<feColorMatrix values=\"" + "0.299 0.587 0.114 0.000 0.000 " + "0.299 0.587 0.114 0.000 0.000 " + "0.299 0.587 0.114 0.000 0.000 " + "0.000 0.000 0.000 1.000 0.000 " + "\"/>"); + case VisionDeficiency::kBlurredVision: + return CreateFilterDataUrl( + "<feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"2\"/>"); + case VisionDeficiency::kDeuteranomaly: + return CreateFilterDataUrl( + "<feColorMatrix values=\"" + "0.800 0.200 0.000 0.000 0.000 " + "0.258 0.742 0.000 0.000 0.000 " + "0.000 0.142 0.858 0.000 0.000 " + "0.000 0.000 0.000 1.000 0.000 " + "\"/>"); + case VisionDeficiency::kDeuteranopia: + return CreateFilterDataUrl( + "<feColorMatrix values=\"" + "0.625 0.375 0.000 0.000 0.000 " + "0.700 0.300 0.000 0.000 0.000 " + "0.000 0.300 0.700 0.000 0.000 " + "0.000 0.000 0.000 1.000 0.000 " + "\"/>"); + case VisionDeficiency::kProtanomaly: + return CreateFilterDataUrl( + "<feColorMatrix values=\"" + "0.817 0.183 0.000 0.000 0.000 " + "0.333 0.667 0.000 0.000 0.000 " + "0.000 0.125 0.875 0.000 0.000 " + "0.000 0.000 0.000 1.000 0.000 " + "\"/>"); + case VisionDeficiency::kProtanopia: + return CreateFilterDataUrl( + "<feColorMatrix values=\"" + "0.567 0.433 0.000 0.000 0.000 " + "0.558 0.442 0.000 0.000 0.000 " + "0.000 0.242 0.758 0.000 0.000 " + "0.000 0.000 0.000 1.000 0.000 " + "\"/>"); + case VisionDeficiency::kTritanomaly: + return CreateFilterDataUrl( + "<feColorMatrix values=\"" + "0.967 0.033 0.000 0.000 0.000 " + "0.000 0.733 0.267 0.000 0.000 " + "0.000 0.183 0.817 0.000 0.000 " + "0.000 0.000 0.000 1.000 0.000 " + "\"/>"); + case VisionDeficiency::kTritanopia: + return CreateFilterDataUrl( + "<feColorMatrix values=\"" + "0.950 0.050 0.000 0.000 0.000 " + "0.000 0.433 0.567 0.000 0.000 " + "0.000 0.475 0.525 0.000 0.000 " + "0.000 0.000 0.000 1.000 0.000 " + "\"/>"); + case VisionDeficiency::kNoVisionDeficiency: + NOTREACHED(); + return ""; + } +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/css/vision_deficiency.h b/third_party/blink/renderer/core/css/vision_deficiency.h new file mode 100644 index 0000000..b91d422 --- /dev/null +++ b/third_party/blink/renderer/core/css/vision_deficiency.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 THIRD_PARTY_BLINK_RENDERER_CORE_CSS_VISION_DEFICIENCY_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_VISION_DEFICIENCY_H_ + +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { + +enum class VisionDeficiency { + kNoVisionDeficiency, + kAchromatomaly, + kAchromatopsia, + kBlurredVision, + kDeuteranomaly, + kDeuteranopia, + kProtanomaly, + kProtanopia, + kTritanomaly, + kTritanopia, +}; + +AtomicString CreateVisionDeficiencyFilterUrl( + VisionDeficiency vision_deficiency); + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_VISION_DEFICIENCY_H_
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 87cfca1a..fa3b053 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -8606,6 +8606,10 @@ MediaQueryAffectingValueChanged(); } +void Document::VisionDeficiencyChanged() { + GetStyleEngine().VisionDeficiencyChanged(); +} + void Document::UpdateForcedColors() { auto* web_theme_engine = RuntimeEnabledFeatures::ForcedColorsEnabled() && Platform::Current()
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index de5330e..e2ca926 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h
@@ -44,6 +44,7 @@ #include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.h" #include "third_party/blink/renderer/core/accessibility/axid.h" #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/css/vision_deficiency.h" #include "third_party/blink/renderer/core/dom/container_node.h" #include "third_party/blink/renderer/core/dom/create_element_flags.h" #include "third_party/blink/renderer/core/dom/document_encoding_data.h" @@ -1698,6 +1699,9 @@ void ColorSchemeChanged(); + // A new vision deficiency is being emulated through DevTools. + void VisionDeficiencyChanged(); + void ClearIsolatedWorldCSPForTesting(int32_t world_id); // A META element with name=color-scheme was added, removed, or modified.
diff --git a/third_party/blink/renderer/core/dom/element_data.cc b/third_party/blink/renderer/core/dom/element_data.cc index cd728be..c64ec79 100644 --- a/third_party/blink/renderer/core/dom/element_data.cc +++ b/third_party/blink/renderer/core/dom/element_data.cc
@@ -120,7 +120,7 @@ } } -void ElementData::TraceAfterDispatch(blink::Visitor* visitor) { +void ElementData::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(inline_style_); } @@ -185,7 +185,7 @@ *this); } -void UniqueElementData::TraceAfterDispatch(blink::Visitor* visitor) { +void UniqueElementData::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(presentation_attribute_style_); ElementData::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/dom/element_data.h b/third_party/blink/renderer/core/dom/element_data.h index 373bcebca..0164868f 100644 --- a/third_party/blink/renderer/core/dom/element_data.h +++ b/third_party/blink/renderer/core/dom/element_data.h
@@ -80,7 +80,7 @@ bool IsUnique() const { return is_unique_; } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; void Trace(Visitor*); protected: @@ -127,7 +127,7 @@ explicit ShareableElementData(const UniqueElementData&); ~ShareableElementData(); - void TraceAfterDispatch(blink::Visitor* visitor) { + void TraceAfterDispatch(blink::Visitor* visitor) const { ElementData::TraceAfterDispatch(visitor); } @@ -162,7 +162,7 @@ explicit UniqueElementData(const ShareableElementData&); explicit UniqueElementData(const UniqueElementData&); - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; // FIXME: We might want to support sharing element data for elements with // presentation attribute style. Lots of table cells likely have the same
diff --git a/third_party/blink/renderer/core/dom/element_rare_data.cc b/third_party/blink/renderer/core/dom/element_rare_data.cc index 7003e5c..0f6056b 100644 --- a/third_party/blink/renderer/core/dom/element_rare_data.cc +++ b/third_party/blink/renderer/core/dom/element_rare_data.cc
@@ -93,7 +93,7 @@ return *element_internals_; } -void ElementRareData::TraceAfterDispatch(blink::Visitor* visitor) { +void ElementRareData::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(dataset_); visitor->Trace(class_list_); visitor->Trace(part_);
diff --git a/third_party/blink/renderer/core/dom/element_rare_data.h b/third_party/blink/renderer/core/dom/element_rare_data.h index dd0b37e..e72d697 100644 --- a/third_party/blink/renderer/core/dom/element_rare_data.h +++ b/third_party/blink/renderer/core/dom/element_rare_data.h
@@ -207,7 +207,7 @@ const AtomicString& GetNonce() const { return nonce_; } void SetNonce(const AtomicString& nonce) { nonce_ = nonce; } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; private: ScrollOffset saved_layer_scroll_offset_;
diff --git a/third_party/blink/renderer/core/dom/node_rare_data.cc b/third_party/blink/renderer/core/dom/node_rare_data.cc index f59977d..43337f3 100644 --- a/third_party/blink/renderer/core/dom/node_rare_data.cc +++ b/third_party/blink/renderer/core/dom/node_rare_data.cc
@@ -108,7 +108,7 @@ return *shared_empty_data; } -void NodeRareData::TraceAfterDispatch(blink::Visitor* visitor) { +void NodeRareData::TraceAfterDispatch(blink::Visitor* visitor) const { visitor->Trace(mutation_observer_data_); visitor->Trace(flat_tree_node_data_); visitor->Trace(node_layout_data_);
diff --git a/third_party/blink/renderer/core/dom/node_rare_data.h b/third_party/blink/renderer/core/dom/node_rare_data.h index 56eb104..0c3b213 100644 --- a/third_party/blink/renderer/core/dom/node_rare_data.h +++ b/third_party/blink/renderer/core/dom/node_rare_data.h
@@ -78,7 +78,7 @@ DCHECK(!is_element_rare_data || is_rare_data); } void Trace(Visitor*); - void TraceAfterDispatch(blink::Visitor*) {} + void TraceAfterDispatch(blink::Visitor*) const {} enum { kConnectedFrameCountBits = 10, // Must fit Page::maxNumberOfFrames. @@ -118,7 +118,7 @@ static NodeRenderingData& SharedEmptyData(); bool IsSharedEmptyData() { return this == &SharedEmptyData(); } - void TraceAfterDispatch(Visitor* visitor) { + void TraceAfterDispatch(Visitor* visitor) const { NodeData::TraceAfterDispatch(visitor); } @@ -193,7 +193,7 @@ bool HasRestyleFlags() const { return restyle_flags_; } void ClearRestyleFlags() { restyle_flags_ = 0; } - void TraceAfterDispatch(blink::Visitor*); + void TraceAfterDispatch(blink::Visitor*) const; void FinalizeGarbageCollectedObject(); protected:
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h index e170d5d..9eaaf86 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.h +++ b/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -178,8 +178,6 @@ void SetIgnoreViewportTagScaleLimits(bool) override; WebSize ContentsPreferredMinimumSize() override; void SetDisplayMode(blink::mojom::DisplayMode) override; - void AnimateDoubleTapZoom(const gfx::Point&, - const WebRect& block_bounds) override; void ZoomToFindInPageRect(const WebRect&) override; void SetDeviceScaleFactor(float) override; void SetZoomFactorForDeviceScaleFactor(float) override; @@ -216,6 +214,9 @@ void PaintContent(cc::PaintCanvas*, const gfx::Rect&) override; void SetTextAutosizerPageInfo(const WebTextAutosizerPageInfo&) override; + // Requests a page-scale animation based on the specified point/rect. + void AnimateDoubleTapZoom(const gfx::Point&, const WebRect& block_bounds); + float DefaultMinimumPageScaleFactor() const; float DefaultMaximumPageScaleFactor() const; float ClampPageScaleFactorToLimits(float) const;
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 90b7868e..aab8e14 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -2019,6 +2019,11 @@ GetLocalFrameHostRemote().EvictFromBackForwardCache(); } +void LocalFrame::AnimateDoubleTapZoom(const gfx::Point& point, + const gfx::Rect& rect) { + GetPage()->GetChromeClient().AnimateDoubleTapZoom(point, rect); +} + void LocalFrame::SetScaleFactor(float scale_factor) { DCHECK(IsMainFrame());
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h index cfe9c624..2ad182d 100644 --- a/third_party/blink/renderer/core/frame/local_frame.h +++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -528,6 +528,8 @@ void DidUpdateFramePolicy(const FramePolicy& frame_policy) final; // blink::mojom::LocalMainFrame overrides: + void AnimateDoubleTapZoom(const gfx::Point& point, + const gfx::Rect& rect) override; void SetScaleFactor(float scale) override; void ClosePage( mojom::blink::LocalMainFrame::ClosePageCallback callback) override;
diff --git a/third_party/blink/renderer/core/frame/settings_delegate.h b/third_party/blink/renderer/core/frame/settings_delegate.h index 1b0bdcf..8919c3d5 100644 --- a/third_party/blink/renderer/core/frame/settings_delegate.h +++ b/third_party/blink/renderer/core/frame/settings_delegate.h
@@ -72,6 +72,7 @@ kColorSchemeChange, kSpatialNavigationChange, kUniversalAccessChange, + kVisionDeficiencyChange, }; virtual void SettingsChanged(ChangeType) = 0;
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.cc b/third_party/blink/renderer/core/html/forms/html_select_element.cc index 1c58e29..e3c59ff 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_select_element.cc
@@ -804,11 +804,7 @@ return; suggested_option_ = option; - select_type_->UpdateTextStyleAndContent(); - if (GetLayoutObject()) - ScrollToOption(option); - if (PopupIsVisible()) - popup_->UpdateFromElement(PopupMenu::kBySelectionChange); + select_type_->DidSetSuggestedOption(option); } void HTMLSelectElement::ScrollToOption(HTMLOptionElement* option) { @@ -1530,12 +1526,7 @@ } void HTMLSelectElement::PopupDidHide() { - SetPopupIsVisible(false); - UnobserveTreeMutation(); - if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache()) { - if (GetLayoutObject() && UsesMenuList()) - cache->DidHideMenuListPopup(GetLayoutObject()); - } + select_type_->PopupDidHide(); } void HTMLSelectElement::SetIndexToSelectOnCancel(int list_index) { @@ -1597,11 +1588,7 @@ void HTMLSelectElement::DidRecalcStyle(const StyleRecalcChange change) { HTMLFormControlElementWithState::DidRecalcStyle(change); - if (change.ReattachLayoutTree()) - return; - select_type_->UpdateTextStyle(); - if (PopupIsVisible()) - popup_->UpdateFromElement(PopupMenu::kByStyleChange); + select_type_->DidRecalcStyle(change); } void HTMLSelectElement::AttachLayoutTree(AttachContext& context) { @@ -1623,11 +1610,7 @@ void HTMLSelectElement::DetachLayoutTree(bool performing_reattach) { HTMLFormControlElementWithState::DetachLayoutTree(performing_reattach); - if (popup_) - popup_->DisconnectClient(); - SetPopupIsVisible(false); - popup_ = nullptr; - UnobserveTreeMutation(); + select_type_->DidDetachLayoutTree(); } void HTMLSelectElement::ResetTypeAheadSessionForTesting() { @@ -1716,6 +1699,7 @@ } void HTMLSelectElement::ChangeRendering() { + select_type_->DidDetachLayoutTree(); UpdateUsesMenuList(); select_type_->WillBeDestroyed(); select_type_ = SelectType::Create(*this);
diff --git a/third_party/blink/renderer/core/html/forms/select_type.cc b/third_party/blink/renderer/core/html/forms/select_type.cc index e7542bde..9751219 100644 --- a/third_party/blink/renderer/core/html/forms/select_type.cc +++ b/third_party/blink/renderer/core/html/forms/select_type.cc
@@ -70,6 +70,9 @@ HTMLSelectElement::SelectOptionFlags flags, bool should_update_popup) override; void DidBlur() override; + void DidDetachLayoutTree() override; + void DidRecalcStyle(const StyleRecalcChange change) override; + void DidSetSuggestedOption(HTMLOptionElement* option) override; void UpdateTextStyle() override { UpdateTextStyleInternal(); } void UpdateTextStyleAndContent() override; @@ -79,6 +82,7 @@ void ShowPopup() override; void HidePopup() override; + void PopupDidHide() override; private: bool ShouldOpenPopupForKeyDownEvent(const KeyboardEvent& event); @@ -290,6 +294,15 @@ select_->popup_->Hide(); } +void MenuListSelectType::PopupDidHide() { + select_->SetPopupIsVisible(false); + select_->UnobserveTreeMutation(); + if (AXObjectCache* cache = select_->GetDocument().ExistingAXObjectCache()) { + if (auto* layout_object = select_->GetLayoutObject()) + cache->DidHideMenuListPopup(layout_object); + } +} + void MenuListSelectType::DidSelectOption( HTMLOptionElement* element, HTMLSelectElement::SelectOptionFlags flags, @@ -340,6 +353,28 @@ SelectType::DidBlur(); } +void MenuListSelectType::DidSetSuggestedOption(HTMLOptionElement*) { + UpdateTextStyleAndContent(); + if (select_->PopupIsVisible()) + select_->popup_->UpdateFromElement(PopupMenu::kBySelectionChange); +} + +void MenuListSelectType::DidDetachLayoutTree() { + if (select_->popup_) + select_->popup_->DisconnectClient(); + select_->SetPopupIsVisible(false); + select_->popup_ = nullptr; + select_->UnobserveTreeMutation(); +} + +void MenuListSelectType::DidRecalcStyle(const StyleRecalcChange change) { + if (change.ReattachLayoutTree()) + return; + UpdateTextStyle(); + if (select_->PopupIsVisible()) + select_->popup_->UpdateFromElement(PopupMenu::kByStyleChange); +} + String MenuListSelectType::UpdateTextStyleInternal() { HTMLOptionElement* option = select_->OptionToBeShown(); String text = g_empty_string; @@ -431,6 +466,7 @@ public: explicit ListBoxSelectType(HTMLSelectElement& select) : SelectType(select) {} bool DefaultEventHandler(const Event& event) override; + void DidSetSuggestedOption(HTMLOptionElement* option) override; void UpdateMultiSelectFocus() override; void SelectAll() override; @@ -690,6 +726,11 @@ return false; } +void ListBoxSelectType::DidSetSuggestedOption(HTMLOptionElement* option) { + if (select_->GetLayoutObject()) + select_->ScrollToOption(option); +} + void ListBoxSelectType::UpdateMultiSelectFocus() { if (!select_->is_multiple_) return; @@ -772,6 +813,10 @@ select_->last_on_change_selection_.clear(); } +void SelectType::DidDetachLayoutTree() {} + +void SelectType::DidRecalcStyle(const StyleRecalcChange) {} + void SelectType::UpdateTextStyle() {} void SelectType::UpdateTextStyleAndContent() {} @@ -795,6 +840,10 @@ NOTREACHED(); } +void SelectType::PopupDidHide() { + NOTREACHED(); +} + // Returns the 1st valid OPTION |skip| items from |list_index| in direction // |direction| if there is one. // Otherwise, it returns the valid OPTION closest to that boundary which is past
diff --git a/third_party/blink/renderer/core/html/forms/select_type.h b/third_party/blink/renderer/core/html/forms/select_type.h index 84cb291..77239ab4 100644 --- a/third_party/blink/renderer/core/html/forms/select_type.h +++ b/third_party/blink/renderer/core/html/forms/select_type.h
@@ -29,6 +29,9 @@ bool should_update_popup); virtual void DidBlur(); + virtual void DidDetachLayoutTree(); + virtual void DidRecalcStyle(const StyleRecalcChange change); + virtual void DidSetSuggestedOption(HTMLOptionElement* option) = 0; // Update style of text in the CSS box on style or selected OPTION change. virtual void UpdateTextStyle(); @@ -46,6 +49,7 @@ virtual void ShowPopup(); virtual void HidePopup(); + virtual void PopupDidHide(); enum SkipDirection { kSkipBackwards = -1, kSkipForwards = 1 }; CORE_EXPORT HTMLOptionElement* NextSelectableOption(HTMLOptionElement*) const;
diff --git a/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc b/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc index 3d94b51..70efd14 100644 --- a/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc
@@ -6,6 +6,7 @@ #include "third_party/blink/public/common/input/web_touch_event.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/renderer/core/css/vision_deficiency.h" #include "third_party/blink/renderer/core/exported/web_view_impl.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/settings.h" @@ -39,6 +40,8 @@ max_touch_points_(&agent_state_, /*default_value=*/1), emulated_media_(&agent_state_, /*default_value=*/WTF::String()), emulated_media_features_(&agent_state_, /*default_value=*/WTF::String()), + emulated_vision_deficiency_(&agent_state_, + /*default_value=*/WTF::String()), navigator_platform_override_(&agent_state_, /*default_value=*/WTF::String()), user_agent_override_(&agent_state_, /*default_value=*/WTF::String()), @@ -101,6 +104,8 @@ .build()); } setEmulatedMedia(emulated_media_.Get(), std::move(features)); + if (!emulated_vision_deficiency_.Get().IsNull()) + setEmulatedVisionDeficiency(emulated_vision_deficiency_.Get()); auto rgba = ParseRGBA(default_background_color_override_rgba_.Get()); if (rgba) setDefaultBackgroundColorOverride(std::move(rgba)); @@ -166,6 +171,8 @@ // (e.g. if we allowed two different front-ends with the same // settings to attach to the same page). TODO: support this use case. setEmulatedMedia(String(), {}); + if (!emulated_vision_deficiency_.Get().IsNull()) + setEmulatedVisionDeficiency(String("none")); setCPUThrottlingRate(1); setFocusEmulationEnabled(false); setDefaultBackgroundColorOverride(Maybe<protocol::DOM::RGBA>()); @@ -272,6 +279,43 @@ return response; } +Response InspectorEmulationAgent::setEmulatedVisionDeficiency( + const String& type) { + Response response = AssertPage(); + if (!response.isSuccess()) + return response; + + VisionDeficiency vision_deficiency; + namespace TypeEnum = + protocol::Emulation::SetEmulatedVisionDeficiency::TypeEnum; + if (type == TypeEnum::None) + vision_deficiency = VisionDeficiency::kNoVisionDeficiency; + else if (type == TypeEnum::Achromatomaly) + vision_deficiency = VisionDeficiency::kAchromatomaly; + else if (type == TypeEnum::Achromatopsia) + vision_deficiency = VisionDeficiency::kAchromatopsia; + else if (type == TypeEnum::BlurredVision) + vision_deficiency = VisionDeficiency::kBlurredVision; + else if (type == TypeEnum::Deuteranomaly) + vision_deficiency = VisionDeficiency::kDeuteranomaly; + else if (type == TypeEnum::Deuteranopia) + vision_deficiency = VisionDeficiency::kDeuteranopia; + else if (type == TypeEnum::Protanomaly) + vision_deficiency = VisionDeficiency::kProtanomaly; + else if (type == TypeEnum::Protanopia) + vision_deficiency = VisionDeficiency::kProtanopia; + else if (type == TypeEnum::Tritanomaly) + vision_deficiency = VisionDeficiency::kTritanomaly; + else if (type == TypeEnum::Tritanopia) + vision_deficiency = VisionDeficiency::kTritanopia; + else + return Response::InvalidParams("Unknown vision deficiency type"); + + emulated_vision_deficiency_.Set(type); + GetWebViewImpl()->GetPage()->SetVisionDeficiency(vision_deficiency); + return response; +} + Response InspectorEmulationAgent::setCPUThrottlingRate(double rate) { Response response = AssertPage(); if (!response.isSuccess())
diff --git a/third_party/blink/renderer/core/inspector/inspector_emulation_agent.h b/third_party/blink/renderer/core/inspector/inspector_emulation_agent.h index 4543033e..4c77396 100644 --- a/third_party/blink/renderer/core/inspector/inspector_emulation_agent.h +++ b/third_party/blink/renderer/core/inspector/inspector_emulation_agent.h
@@ -48,6 +48,7 @@ protocol::Maybe<String> media, protocol::Maybe<protocol::Array<protocol::Emulation::MediaFeature>> features) override; + protocol::Response setEmulatedVisionDeficiency(const String&) override; protocol::Response setCPUThrottlingRate(double) override; protocol::Response setFocusEmulationEnabled(bool) override; protocol::Response setVirtualTimePolicy( @@ -127,6 +128,7 @@ InspectorAgentState::Integer max_touch_points_; InspectorAgentState::String emulated_media_; InspectorAgentState::StringMap emulated_media_features_; + InspectorAgentState::String emulated_vision_deficiency_; InspectorAgentState::String navigator_platform_override_; InspectorAgentState::String user_agent_override_; InspectorAgentState::String accept_language_override_;
diff --git a/third_party/blink/renderer/core/inspector/inspector_protocol_config.json b/third_party/blink/renderer/core/inspector/inspector_protocol_config.json index bafa314..b6ba2f3 100644 --- a/third_party/blink/renderer/core/inspector/inspector_protocol_config.json +++ b/third_party/blink/renderer/core/inspector/inspector_protocol_config.json
@@ -84,7 +84,7 @@ { "domain": "Emulation", "include": ["forceViewport", "resetViewport", "resetPageScaleFactor", "setPageScaleFactor", "setScriptExecutionDisabled", "setTouchEmulationEnabled", - "setEmulatedMedia", "setCPUThrottlingRate", "setVirtualTimePolicy", "setTimezoneOverride", "setNavigatorOverrides", "setDefaultBackgroundColorOverride", "setDeviceMetricsOverride", "clearDeviceMetricsOverride", + "setEmulatedMedia", "setEmulatedVisionDeficiency", "setCPUThrottlingRate", "setVirtualTimePolicy", "setTimezoneOverride", "setNavigatorOverrides", "setDefaultBackgroundColorOverride", "setDeviceMetricsOverride", "clearDeviceMetricsOverride", "setUserAgentOverride", "setScrollbarsHidden", "setDocumentCookieDisabled", "setFocusEmulationEnabled", "setLocaleOverride"], "include_events": ["virtualTimeBudgetExpired", "virtualTimeAdvanced", "virtualTimePaused"] },
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc index 09e1acd..13d5b39 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc
@@ -146,18 +146,14 @@ LayoutObject* before_child) { LayoutInline::AddChild(child, before_child); SVGResourcesCache::ClientWasAddedToTree(*child); - - if (LayoutSVGText* text_layout_object = - LayoutSVGText::LocateLayoutSVGTextAncestor(this)) - text_layout_object->SubtreeChildWasAdded(); + LayoutSVGText::NotifySubtreeStructureChanged( + this, layout_invalidation_reason::kChildChanged); } void LayoutSVGInline::RemoveChild(LayoutObject* child) { SVGResourcesCache::ClientWillBeRemovedFromTree(*child); - - if (LayoutSVGText* text_layout_object = - LayoutSVGText::LocateLayoutSVGTextAncestor(this)) - text_layout_object->SubtreeChildWillBeRemoved(); + LayoutSVGText::NotifySubtreeStructureChanged( + this, layout_invalidation_reason::kChildChanged); LayoutInline::RemoveChild(child); }
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc index d0c70ef1..a5930c7aa 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc
@@ -59,9 +59,8 @@ void LayoutSVGInlineText::TextDidChange() { SetTextInternal(NormalizeWhitespace(GetText().Impl())); LayoutText::TextDidChange(); - if (LayoutSVGText* text_layout_object = - LayoutSVGText::LocateLayoutSVGTextAncestor(this)) - text_layout_object->SubtreeTextDidChange(); + LayoutSVGText::NotifySubtreeStructureChanged( + this, layout_invalidation_reason::kTextChanged); } void LayoutSVGInlineText::StyleDidChange(StyleDifference diff,
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.cc index a5909730..7530f56 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.cc
@@ -25,8 +25,6 @@ #include "third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.h" #include "third_party/blink/renderer/core/svg/svg_filter_element.h" -#include "third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h" -#include "third_party/blink/renderer/core/svg/svg_resource.h" #include "third_party/blink/renderer/platform/graphics/filters/filter_effect.h" namespace blink { @@ -44,45 +42,20 @@ } LayoutSVGResourceFilter::LayoutSVGResourceFilter(SVGFilterElement* node) - : LayoutSVGResourceContainer(node), - filter_(MakeGarbageCollected<FilterMap>()) {} + : LayoutSVGResourceContainer(node) {} LayoutSVGResourceFilter::~LayoutSVGResourceFilter() = default; -void LayoutSVGResourceFilter::DisposeFilterMap() { - for (auto& entry : *filter_) - entry.value->Dispose(); - filter_->clear(); -} - -void LayoutSVGResourceFilter::WillBeDestroyed() { - DisposeFilterMap(); - LayoutSVGResourceContainer::WillBeDestroyed(); -} - bool LayoutSVGResourceFilter::IsChildAllowed(LayoutObject* child, const ComputedStyle&) const { return child->IsSVGResourceFilterPrimitive(); } void LayoutSVGResourceFilter::RemoveAllClientsFromCache() { - // LayoutSVGResourceFilter::removeClientFromCache will be called for - // all clients through markAllClientsForInvalidation so no explicit - // display item invalidation is needed here. - DisposeFilterMap(); MarkAllClientsForInvalidation(SVGResourceClient::kLayoutInvalidation | SVGResourceClient::kBoundariesInvalidation); } -bool LayoutSVGResourceFilter::RemoveClientFromCache(SVGResourceClient& client) { - auto entry = filter_->find(&client); - if (entry == filter_->end()) - return false; - entry->value->Dispose(); - filter_->erase(entry); - return true; -} - FloatRect LayoutSVGResourceFilter::ResourceBoundingBox( const FloatRect& reference_box) const { const auto* filter_element = To<SVGFilterElement>(GetElement()); @@ -104,32 +77,6 @@ ->EnumValue(); } -void LayoutSVGResourceFilter::PrimitiveAttributeChanged( - SVGFilterPrimitiveStandardAttributes& primitive, - const QualifiedName& attribute) { - for (auto& filter : *filter_) { - FilterData* filter_data = filter.value.Get(); - if (filter_data->state_ != FilterData::kReadyToPaint) - continue; - - SVGFilterGraphNodeMap* node_map = filter_data->node_map.Get(); - FilterEffect* effect = node_map->EffectForElement(primitive); - if (!effect) - continue; - // Since all effects shares the same attribute value, all - // or none of them will be changed. - if (!primitive.SetFilterEffectAttribute(effect, attribute)) - return; - node_map->InvalidateDependentEffects(effect); - } - if (auto* resource = - To<SVGFilterElement>(GetElement())->AssociatedResource()) { - resource->NotifyContentChanged( - SVGResourceClient::kPaintInvalidation | - SVGResourceClient::kSkipAncestorInvalidation); - } -} - LayoutSVGResourceFilter* GetFilterResourceForSVG(const ComputedStyle& style) { if (!style.HasFilter()) return nullptr;
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.h b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.h index 667f803..67df89df 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.h +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.h
@@ -32,7 +32,6 @@ class FilterEffect; class SVGFilterElement; class SVGFilterGraphNodeMap; -class SVGFilterPrimitiveStandardAttributes; class FilterData final : public GarbageCollected<FilterData> { public: @@ -77,35 +76,14 @@ } void RemoveAllClientsFromCache() override; - bool RemoveClientFromCache(SVGResourceClient&) override; FloatRect ResourceBoundingBox(const FloatRect& reference_box) const; SVGUnitTypes::SVGUnitType FilterUnits() const; SVGUnitTypes::SVGUnitType PrimitiveUnits() const; - void PrimitiveAttributeChanged(SVGFilterPrimitiveStandardAttributes&, - const QualifiedName&); - static const LayoutSVGResourceType kResourceType = kFilterResourceType; LayoutSVGResourceType ResourceType() const override { return kResourceType; } - - FilterData* GetFilterDataForClient(const SVGResourceClient* client) { - return filter_->at(const_cast<SVGResourceClient*>(client)); - } - void SetFilterDataForClient(const SVGResourceClient* client, - FilterData* filter_data) { - filter_->Set(const_cast<SVGResourceClient*>(client), filter_data); - } - - protected: - void WillBeDestroyed() override; - - private: - void DisposeFilterMap(); - - using FilterMap = HeapHashMap<Member<SVGResourceClient>, Member<FilterData>>; - Persistent<FilterMap> filter_; }; // Get the LayoutSVGResourceFilter from the 'filter' property iff the 'filter'
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc index a0539f0..adb9ac9 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc
@@ -111,15 +111,8 @@ } } -void LayoutSVGText::InvalidatePositioningValues( +void LayoutSVGText::SubtreeStructureChanged( LayoutInvalidationReasonForTracing reason) { - descendant_text_nodes_.clear(); - SetNeedsPositioningValuesUpdate(); - // TODO(fs): Restore the passing of |reason| here. - LayoutSVGResourceContainer::MarkForLayoutAndParentResourceInvalidation(*this); -} - -void LayoutSVGText::SubtreeChildWasAdded() { if (BeingDestroyed() || !EverHadLayout()) { DCHECK(descendant_text_nodes_.IsEmpty()); return; @@ -128,37 +121,20 @@ return; // The positioning elements cache depends on the size of each text - // layoutObject in the subtree. If this changes, clear the cache. It will be + // LayoutObject in the subtree. If this changes, clear the cache. It will be // rebuilt on the next layout. - InvalidatePositioningValues(layout_invalidation_reason::kChildChanged); + descendant_text_nodes_.clear(); + SetNeedsPositioningValuesUpdate(); SetNeedsTextMetricsUpdate(); + // TODO(fs): Restore the passing of |reason| here. + LayoutSVGResourceContainer::MarkForLayoutAndParentResourceInvalidation(*this); } -void LayoutSVGText::SubtreeChildWillBeRemoved() { - if (BeingDestroyed() || !EverHadLayout()) { - DCHECK(descendant_text_nodes_.IsEmpty()); - return; - } - - // The positioning elements cache depends on the size of each text - // layoutObject in the subtree. If this changes, clear the cache. It will be - // rebuilt on the next layout. - InvalidatePositioningValues(layout_invalidation_reason::kChildChanged); - SetNeedsTextMetricsUpdate(); -} - -void LayoutSVGText::SubtreeTextDidChange() { - DCHECK(!BeingDestroyed()); - if (!EverHadLayout()) { - DCHECK(descendant_text_nodes_.IsEmpty()); - return; - } - - // The positioning elements cache depends on the size of each text object in - // the subtree. If this changes, clear the cache and mark it for rebuilding - // in the next layout. - InvalidatePositioningValues(layout_invalidation_reason::kTextChanged); - SetNeedsTextMetricsUpdate(); +void LayoutSVGText::NotifySubtreeStructureChanged( + LayoutObject* object, + LayoutInvalidationReasonForTracing reason) { + if (LayoutSVGText* layout_text = LocateLayoutSVGTextAncestor(object)) + layout_text->SubtreeStructureChanged(reason); } static inline void UpdateFontAndMetrics(LayoutSVGText& text_root) { @@ -429,12 +405,12 @@ LayoutSVGBlock::AddChild(child, before_child); SVGResourcesCache::ClientWasAddedToTree(*child); - SubtreeChildWasAdded(); + SubtreeStructureChanged(layout_invalidation_reason::kChildChanged); } void LayoutSVGText::RemoveChild(LayoutObject* child) { SVGResourcesCache::ClientWillBeRemovedFromTree(*child); - SubtreeChildWillBeRemoved(); + SubtreeStructureChanged(layout_invalidation_reason::kChildChanged); LayoutSVGBlock::RemoveChild(child); }
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_text.h b/third_party/blink/renderer/core/layout/svg/layout_svg_text.h index 2360fe04..c5ebeb9 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_text.h +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_text.h
@@ -53,15 +53,14 @@ static LayoutSVGText* LocateLayoutSVGTextAncestor(LayoutObject*); static const LayoutSVGText* LocateLayoutSVGTextAncestor(const LayoutObject*); + static void NotifySubtreeStructureChanged(LayoutObject*, + LayoutInvalidationReasonForTracing); + bool NeedsReordering() const { return needs_reordering_; } const Vector<LayoutSVGInlineText*>& DescendantTextNodes() const { return descendant_text_nodes_; } - void SubtreeChildWasAdded(); - void SubtreeChildWillBeRemoved(); - void SubtreeTextDidChange(); - void RecalcVisualOverflow() override; const char* GetName() const override { return "LayoutSVGText"; } @@ -94,7 +93,7 @@ RootInlineBox* CreateRootInlineBox() override; - void InvalidatePositioningValues(LayoutInvalidationReasonForTracing); + void SubtreeStructureChanged(LayoutInvalidationReasonForTracing); bool needs_reordering_ : 1; bool needs_positioning_values_update_ : 1;
diff --git a/third_party/blink/renderer/core/layout/svg/svg_resources.cc b/third_party/blink/renderer/core/layout/svg/svg_resources.cc index b64f055..703d828 100644 --- a/third_party/blink/renderer/core/layout/svg/svg_resources.cc +++ b/third_party/blink/renderer/core/layout/svg/svg_resources.cc
@@ -31,6 +31,8 @@ #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/style/reference_clip_path_operation.h" #include "third_party/blink/renderer/core/style/style_svg_resource.h" +#include "third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.h" +#include "third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h" #include "third_party/blink/renderer/core/svg/svg_pattern_element.h" #include "third_party/blink/renderer/core/svg/svg_resource.h" #include "third_party/blink/renderer/core/svg/svg_tree_scope_resources.h" @@ -256,8 +258,8 @@ return 0; InvalidationModeMask invalidation_flags = SVGResourceClient::kBoundariesInvalidation; - if (LayoutSVGResourceFilter* filter = clipper_filter_masker_data_->filter) { - if (filter->RemoveClientFromCache(client)) + if (clipper_filter_masker_data_->filter) { + if (client.ClearFilterData()) invalidation_flags |= SVGResourceClient::kPaintInvalidation; } return invalidation_flags; @@ -669,9 +671,7 @@ LayoutSVGResourceContainer::MarkClientForInvalidation(*layout_object, invalidation_mask); - // Special case for filter invalidation. - if (invalidation_mask & SVGResourceClient::kSkipAncestorInvalidation) - return; + ClearFilterData(); bool needs_layout = invalidation_mask & SVGResourceClient::kLayoutInvalidation; @@ -680,8 +680,10 @@ } void SVGElementResourceClient::ResourceElementChanged() { - if (LayoutObject* layout_object = element_->GetLayoutObject()) + if (LayoutObject* layout_object = element_->GetLayoutObject()) { + ClearFilterData(); SVGResourcesCache::ResourceReferenceChanged(*layout_object); + } } void SVGElementResourceClient::ResourceDestroyed( @@ -695,8 +697,38 @@ resources->ResourceDestroyed(resource); } +void SVGElementResourceClient::FilterPrimitiveChanged( + SVGFilterPrimitiveStandardAttributes& primitive, + const QualifiedName& attribute) { + if (filter_data_ && filter_data_->state_ == FilterData::kReadyToPaint) { + SVGFilterGraphNodeMap* node_map = filter_data_->node_map; + if (FilterEffect* effect = node_map->EffectForElement(primitive)) { + if (!primitive.SetFilterEffectAttribute(effect, attribute)) + return; // No change + node_map->InvalidateDependentEffects(effect); + } + } + LayoutObject* layout_object = element_->GetLayoutObject(); + if (!layout_object) + return; + LayoutSVGResourceContainer::MarkClientForInvalidation( + *layout_object, SVGResourceClient::kPaintInvalidation); +} + +void SVGElementResourceClient::SetFilterData(FilterData* filter_data) { + filter_data_ = filter_data; +} + +bool SVGElementResourceClient::ClearFilterData() { + FilterData* filter_data = filter_data_.Release(); + if (filter_data) + filter_data->Dispose(); + return !!filter_data; +} + void SVGElementResourceClient::Trace(Visitor* visitor) { visitor->Trace(element_); + visitor->Trace(filter_data_); SVGResourceClient::Trace(visitor); }
diff --git a/third_party/blink/renderer/core/layout/svg/svg_resources.h b/third_party/blink/renderer/core/layout/svg/svg_resources.h index 740bbb9..a27e7f8 100644 --- a/third_party/blink/renderer/core/layout/svg/svg_resources.h +++ b/third_party/blink/renderer/core/layout/svg/svg_resources.h
@@ -32,6 +32,7 @@ namespace blink { class ComputedStyle; +class FilterData; class LayoutObject; class LayoutSVGResourceClipper; class LayoutSVGResourceFilter; @@ -202,10 +203,18 @@ void ResourceElementChanged() override; void ResourceDestroyed(LayoutSVGResourceContainer*) override; + void FilterPrimitiveChanged(SVGFilterPrimitiveStandardAttributes& primitive, + const QualifiedName& attribute) override; + + void SetFilterData(FilterData*); + bool ClearFilterData(); + FilterData* GetFilterData() const { return filter_data_; } + void Trace(Visitor*) override; private: Member<SVGElement> element_; + Member<FilterData> filter_data_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/page/chrome_client.h b/third_party/blink/renderer/core/page/chrome_client.h index 8e520b6..4ae4efd8 100644 --- a/third_party/blink/renderer/core/page/chrome_client.h +++ b/third_party/blink/renderer/core/page/chrome_client.h
@@ -355,6 +355,9 @@ virtual void FullscreenElementChanged(Element* old_element, Element* new_element) {} + virtual void AnimateDoubleTapZoom(const gfx::Point& point, + const gfx::Rect& rect) {} + virtual void ClearLayerSelection(LocalFrame*) {} virtual void UpdateLayerSelection(LocalFrame*, const cc::LayerSelection&) {}
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.cc b/third_party/blink/renderer/core/page/chrome_client_impl.cc index ea88d33e..3f256bb 100644 --- a/third_party/blink/renderer/core/page/chrome_client_impl.cc +++ b/third_party/blink/renderer/core/page/chrome_client_impl.cc
@@ -821,6 +821,11 @@ web_view_->FullscreenElementChanged(old_element, new_element); } +void ChromeClientImpl::AnimateDoubleTapZoom(const gfx::Point& point, + const gfx::Rect& rect) { + web_view_->AnimateDoubleTapZoom(point, WebRect(rect)); +} + void ChromeClientImpl::ClearLayerSelection(LocalFrame* frame) { WebFrameWidgetBase* widget = WebLocalFrameImpl::FromFrame(frame)->LocalRootFrameWidget();
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.h b/third_party/blink/renderer/core/page/chrome_client_impl.h index af5642b..494d1b88 100644 --- a/third_party/blink/renderer/core/page/chrome_client_impl.h +++ b/third_party/blink/renderer/core/page/chrome_client_impl.h
@@ -183,6 +183,9 @@ void FullscreenElementChanged(Element* old_element, Element* new_element) override; + void AnimateDoubleTapZoom(const gfx::Point& point, + const gfx::Rect& rect) override; + void ClearLayerSelection(LocalFrame*) override; void UpdateLayerSelection(LocalFrame*, const cc::LayerSelection&) override;
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc index 70905ed7..8ff83ef 100644 --- a/third_party/blink/renderer/core/page/page.cc +++ b/third_party/blink/renderer/core/page/page.cc
@@ -30,6 +30,7 @@ #include "third_party/blink/renderer/core/css/media_feature_overrides.h" #include "third_party/blink/renderer/core/css/style_change_reason.h" #include "third_party/blink/renderer/core/css/style_engine.h" +#include "third_party/blink/renderer/core/css/vision_deficiency.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/dom/visited_link_state.h" #include "third_party/blink/renderer/core/editing/drag_caret.h" @@ -799,6 +800,11 @@ } break; } + case SettingsDelegate::kVisionDeficiencyChange: { + if (auto* main_local_frame = DynamicTo<LocalFrame>(MainFrame())) + main_local_frame->GetDocument()->VisionDeficiencyChanged(); + break; + } } } @@ -1069,6 +1075,13 @@ SettingsChanged(SettingsDelegate::kColorSchemeChange); } +void Page::SetVisionDeficiency(VisionDeficiency new_vision_deficiency) { + if (new_vision_deficiency != vision_deficiency_) { + vision_deficiency_ = new_vision_deficiency; + SettingsChanged(SettingsDelegate::kVisionDeficiencyChange); + } +} + Page::PageClients::PageClients() : chrome_client(nullptr) {} template class CORE_TEMPLATE_EXPORT Supplement<Page>;
diff --git a/third_party/blink/renderer/core/page/page.h b/third_party/blink/renderer/core/page/page.h index 7f5b14a..ee101e42 100644 --- a/third_party/blink/renderer/core/page/page.h +++ b/third_party/blink/renderer/core/page/page.h
@@ -31,6 +31,7 @@ #include "third_party/blink/public/platform/web_text_autosizer_page_info.h" #include "third_party/blink/public/web/web_window_features.h" #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/css/vision_deficiency.h" #include "third_party/blink/renderer/core/frame/deprecation.h" #include "third_party/blink/renderer/core/frame/hosts_using_features.h" #include "third_party/blink/renderer/core/frame/settings_delegate.h" @@ -342,6 +343,9 @@ } void ClearMediaFeatureOverrides(); + void SetVisionDeficiency(VisionDeficiency new_vision_deficiency); + VisionDeficiency GetVisionDeficiency() const { return vision_deficiency_; } + WebScopedVirtualTimePauser& HistoryNavigationVirtualTimePauser() { return history_navigation_virtual_time_pauser_; } @@ -454,9 +458,12 @@ std::unique_ptr<PageScheduler> page_scheduler_; - // Overrides for various media features set from the devtools. + // Overrides for various media features, set from DevTools. std::unique_ptr<MediaFeatureOverrides> media_feature_overrides_; + // Emulated vision deficiency, set from DevTools. + VisionDeficiency vision_deficiency_ = VisionDeficiency::kNoVisionDeficiency; + int32_t autoplay_flags_; // Accessed by frames to determine whether to expose the PortalHost object.
diff --git a/third_party/blink/renderer/core/paint/svg_filter_painter.cc b/third_party/blink/renderer/core/paint/svg_filter_painter.cc index 5ee6960..0917fbf 100644 --- a/third_party/blink/renderer/core/paint/svg_filter_painter.cc +++ b/third_party/blink/renderer/core/paint/svg_filter_painter.cc
@@ -87,7 +87,7 @@ filter_.ClearInvalidationMask(); SVGElementResourceClient* client = SVGResources::GetClient(object); - if (FilterData* filter_data = filter_.GetFilterDataForClient(client)) { + if (FilterData* filter_data = client->GetFilterData()) { // If the filterData already exists we do not need to record the content // to be filtered. This can occur if the content was previously recorded // or we are in a cycle. @@ -117,7 +117,7 @@ DCHECK_EQ(filter_data->state_, FilterData::kInitial); // TODO(pdr): Can this be moved out of painter? - filter_.SetFilterDataForClient(client, filter_data); + client->SetFilterData(filter_data); filter_data->state_ = FilterData::kRecordingContent; return recording_context.BeginContent(); } @@ -127,7 +127,7 @@ const DisplayItemClient& display_item_client, SVGFilterRecordingContext& recording_context) { SVGElementResourceClient* client = SVGResources::GetClient(object); - FilterData* filter_data = filter_.GetFilterDataForClient(client); + FilterData* filter_data = client->GetFilterData(); if (!filter_data) { // Our state was torn down while we were being painted (selection style for // <text> can have this effect), or it was never created (invalid filter.)
diff --git a/third_party/blink/renderer/core/svg/svg_element.cc b/third_party/blink/renderer/core/svg/svg_element.cc index be5a681..c2b425c 100644 --- a/third_party/blink/renderer/core/svg/svg_element.cc +++ b/third_party/blink/renderer/core/svg/svg_element.cc
@@ -620,6 +620,12 @@ return; } + // SVGElement and HTMLElement are handling "nonce" the same way. + if (params.name == html_names::kNonceAttr) { + if (params.new_value != g_empty_atom) + setNonce(params.new_value); + } + const AtomicString& event_name = HTMLElement::EventNameForAttributeName(params.name); if (!event_name.IsNull()) {
diff --git a/third_party/blink/renderer/core/svg/svg_filter_element.cc b/third_party/blink/renderer/core/svg/svg_filter_element.cc index 7e6bc33..510b134 100644 --- a/third_party/blink/renderer/core/svg/svg_filter_element.cc +++ b/third_party/blink/renderer/core/svg/svg_filter_element.cc
@@ -113,18 +113,12 @@ void SVGFilterElement::PrimitiveAttributeChanged( SVGFilterPrimitiveStandardAttributes& primitive, const QualifiedName& attribute) { - if (LayoutObject* layout_object = GetLayoutObject()) { - ToLayoutSVGResourceFilter(layout_object) - ->PrimitiveAttributeChanged(primitive, attribute); - } else if (LocalSVGResource* resource = AssociatedResource()) { - resource->NotifyContentChanged(SVGResourceClient::kPaintInvalidation); - } + if (LocalSVGResource* resource = AssociatedResource()) + resource->NotifyFilterPrimitiveChanged(primitive, attribute); } void SVGFilterElement::InvalidateFilterChain() { - if (LayoutObject* layout_object = GetLayoutObject()) { - ToLayoutSVGResourceFilter(layout_object)->RemoveAllClientsFromCache(); - } else if (LocalSVGResource* resource = AssociatedResource()) { + if (LocalSVGResource* resource = AssociatedResource()) { resource->NotifyContentChanged(SVGResourceClient::kLayoutInvalidation | SVGResourceClient::kBoundariesInvalidation); }
diff --git a/third_party/blink/renderer/core/svg/svg_resource.cc b/third_party/blink/renderer/core/svg/svg_resource.cc index 9421f73..9cf40b6 100644 --- a/third_party/blink/renderer/core/svg/svg_resource.cc +++ b/third_party/blink/renderer/core/svg/svg_resource.cc
@@ -81,6 +81,16 @@ client->ResourceContentChanged(invalidation_mask); } +void LocalSVGResource::NotifyFilterPrimitiveChanged( + SVGFilterPrimitiveStandardAttributes& primitive, + const QualifiedName& attribute) { + HeapVector<Member<SVGResourceClient>> clients; + CopyToVector(clients_, clients); + + for (SVGResourceClient* client : clients) + client->FilterPrimitiveChanged(primitive, attribute); +} + void LocalSVGResource::NotifyResourceAttached( LayoutSVGResourceContainer& attached_resource) { // Checking the element here because @@ -129,7 +139,22 @@ options.initiator_info.name = fetch_initiator_type_names::kCSS; FetchParameters params(ResourceRequest(url_), options); params.MutableResourceRequest().SetMode( - network::mojom::RequestMode::kSameOrigin); + network::mojom::blink::RequestMode::kSameOrigin); + resource_document_ = + DocumentResource::FetchSVGDocument(params, document.Fetcher(), this); + target_ = ResolveTarget(); +} + +void ExternalSVGResource::LoadWithoutCSP(const Document& document) { + if (resource_document_) + return; + ResourceLoaderOptions options; + options.initiator_info.name = fetch_initiator_type_names::kCSS; + FetchParameters params(ResourceRequest(url_), options); + params.SetContentSecurityCheck( + network::mojom::blink::CSPDisposition::DO_NOT_CHECK); + params.MutableResourceRequest().SetMode( + network::mojom::blink::RequestMode::kSameOrigin); resource_document_ = DocumentResource::FetchSVGDocument(params, document.Fetcher(), this); target_ = ResolveTarget();
diff --git a/third_party/blink/renderer/core/svg/svg_resource.h b/third_party/blink/renderer/core/svg/svg_resource.h index f71d94de..aab5fd2 100644 --- a/third_party/blink/renderer/core/svg/svg_resource.h +++ b/third_party/blink/renderer/core/svg/svg_resource.h
@@ -64,6 +64,7 @@ virtual ~SVGResource(); virtual void Load(const Document&) {} + virtual void LoadWithoutCSP(const Document&) {} Element* Target() const { return target_; } LayoutSVGResourceContainer* ResourceContainer() const; @@ -93,6 +94,9 @@ void Unregister(); void NotifyContentChanged(InvalidationModeMask); + void NotifyFilterPrimitiveChanged( + SVGFilterPrimitiveStandardAttributes& primitive, + const QualifiedName& attribute); void NotifyResourceAttached(LayoutSVGResourceContainer&); void NotifyResourceDestroyed(LayoutSVGResourceContainer&); @@ -114,6 +118,7 @@ explicit ExternalSVGResource(const KURL&); void Load(const Document&) override; + void LoadWithoutCSP(const Document&) override; void Trace(Visitor*) override;
diff --git a/third_party/blink/renderer/core/svg/svg_resource_client.h b/third_party/blink/renderer/core/svg/svg_resource_client.h index 60ac325..1b5a587 100644 --- a/third_party/blink/renderer/core/svg/svg_resource_client.h +++ b/third_party/blink/renderer/core/svg/svg_resource_client.h
@@ -11,6 +11,8 @@ namespace blink { class LayoutSVGResourceContainer; +class QualifiedName; +class SVGFilterPrimitiveStandardAttributes; typedef unsigned InvalidationModeMask; @@ -24,12 +26,17 @@ kLayoutInvalidation = 1 << 0, kBoundariesInvalidation = 1 << 1, kPaintInvalidation = 1 << 2, - kSkipAncestorInvalidation = 1 << 3, }; virtual void ResourceContentChanged(InvalidationModeMask) = 0; virtual void ResourceElementChanged() = 0; virtual void ResourceDestroyed(LayoutSVGResourceContainer*) {} + virtual void FilterPrimitiveChanged( + SVGFilterPrimitiveStandardAttributes& primitive, + const QualifiedName& attribute) { + ResourceContentChanged(kPaintInvalidation); + } + protected: SVGResourceClient() = default; };
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index 6e2672e8..2191278 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -678,6 +678,8 @@ "fonts/shaping/shape_result_view.h", "fonts/shaping/shaping_line_breaker.cc", "fonts/shaping/shaping_line_breaker.h", + "fonts/shaping/stretchy_operator_shaper.cc", + "fonts/shaping/stretchy_operator_shaper.h", "fonts/simple_font_data.cc", "fonts/simple_font_data.h", "fonts/skia/font_cache_skia.cc", @@ -1777,6 +1779,7 @@ "fonts/shaping/shape_result_test.cc", "fonts/shaping/shape_result_view_test.cc", "fonts/shaping/shaping_line_breaker_test.cc", + "fonts/shaping/stretchy_operator_shaper_test.cc", "fonts/small_caps_iterator_test.cc", "fonts/symbols_iterator_test.cc", "fonts/typesetting_features_test.cc",
diff --git a/third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h b/third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h index 0799e41..af3cc0599 100644 --- a/third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h +++ b/third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h
@@ -8,6 +8,7 @@ #include "base/optional.h" #include "third_party/blink/renderer/platform/fonts/glyph.h" #include "third_party/blink/renderer/platform/platform_export.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" namespace blink { @@ -28,6 +29,15 @@ float full_advance; bool is_extender; }; + + // https://mathml-refresh.github.io/mathml-core/#the-glyphassembly-table + struct AssemblyParameters { + float connector_overlap{0}; + unsigned repetition_count{0}; + unsigned glyph_count{0}; + float stretch_size{0}; + Vector<GlyphPartRecord> parts; + }; }; } // namespace blink
diff --git a/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support_test.cc b/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support_test.cc index af881c7..8852fc0 100644 --- a/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support_test.cc +++ b/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support_test.cc
@@ -297,7 +297,8 @@ auto over_brace = math.PrimaryFont()->GlyphForCharacter(kOverBraceCodePoint); // Calculate glyph indices from the last unicode character in the font. - // TODO(fwang): Find a better way to access these glyph indices. + // TODO(https://crbug.com/1057596): Find a better way to access these glyph + // indices. auto v0 = math.PrimaryFont()->GlyphForCharacter( kArabicMathOperatorHahWithDalCodePoint) + 1;
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc b/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc index 3a73c9a9..f801778 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc
@@ -1450,6 +1450,96 @@ return result; } +scoped_refptr<ShapeResult> ShapeResult::CreateForStretchyMathOperator( + const Font* font, + TextDirection direction, + OpenTypeMathStretchData::StretchAxis stretch_axis, + Glyph glyph_variant, + float stretch_size) { + bool is_horizontal_assembly = + stretch_axis == OpenTypeMathStretchData::StretchAxis::Horizontal; + unsigned start_index = 0; + unsigned num_characters = 1; + scoped_refptr<ShapeResult> result = + ShapeResult::Create(font, start_index, num_characters, direction); + + hb_direction_t hb_direction = + is_horizontal_assembly ? HB_DIRECTION_LTR : HB_DIRECTION_TTB; + unsigned glyph_index = 0; + scoped_refptr<ShapeResult::RunInfo> run = RunInfo::Create( + font->PrimaryFont(), hb_direction, CanvasRotationInVertical::kRegular, + HB_SCRIPT_COMMON, start_index, 1 /* num_glyph */, num_characters); + run->glyph_data_[glyph_index] = {glyph_variant, 0 /* character index */, + true /* IsSafeToBreakBefore */, + stretch_size}; + run->width_ = std::max(0.0f, stretch_size); + + result->width_ = run->width_; + result->num_glyphs_ = run->NumGlyphs(); + result->runs_.push_back(std::move(run)); + + return result; +} + +scoped_refptr<ShapeResult> ShapeResult::CreateForStretchyMathOperator( + const Font* font, + TextDirection direction, + OpenTypeMathStretchData::StretchAxis stretch_axis, + const OpenTypeMathStretchData::AssemblyParameters& assembly_parameters) { + DCHECK(!assembly_parameters.parts.IsEmpty()); + DCHECK_LE(assembly_parameters.glyph_count, HarfBuzzRunGlyphData::kMaxGlyphs); + + bool is_horizontal_assembly = + stretch_axis == OpenTypeMathStretchData::StretchAxis::Horizontal; + unsigned start_index = 0; + unsigned num_characters = 1; + scoped_refptr<ShapeResult> result = + ShapeResult::Create(font, start_index, num_characters, direction); + + hb_direction_t hb_direction = + is_horizontal_assembly ? HB_DIRECTION_LTR : HB_DIRECTION_TTB; + scoped_refptr<ShapeResult::RunInfo> run = RunInfo::Create( + font->PrimaryFont(), hb_direction, CanvasRotationInVertical::kRegular, + HB_SCRIPT_COMMON, start_index, assembly_parameters.glyph_count, + num_characters); + + float overlap = assembly_parameters.connector_overlap; + unsigned part_index = 0; + for (const auto& part : assembly_parameters.parts) { + unsigned repetition_count = + part.is_extender ? assembly_parameters.repetition_count : 1; + if (!repetition_count) + continue; + DCHECK(part_index < assembly_parameters.glyph_count); + for (unsigned repetition_index = 0; repetition_index < repetition_count; + repetition_index++) { + unsigned glyph_index = + is_horizontal_assembly + ? part_index + : assembly_parameters.glyph_count - 1 - part_index; + float full_advance = glyph_index == assembly_parameters.glyph_count - 1 + ? part.full_advance + : part.full_advance - overlap; + run->glyph_data_[glyph_index] = {part.glyph, 0 /* character index */, + !glyph_index /* IsSafeToBreakBefore */, + full_advance}; + if (!is_horizontal_assembly) { + GlyphOffset glyph_offset( + 0, -assembly_parameters.stretch_size + part.full_advance); + run->glyph_data_.SetOffsetAt(glyph_index, glyph_offset); + result->has_vertical_offsets_ |= (glyph_offset.Height() != 0); + } + part_index++; + } + } + run->width_ = std::max(0.0f, assembly_parameters.stretch_size); + + result->width_ = run->width_; + result->num_glyphs_ = run->NumGlyphs(); + result->runs_.push_back(std::move(run)); + return result; +} + void ShapeResult::ToString(StringBuilder* output) const { output->Append("#chars="); output->AppendNumber(num_characters_);
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shape_result.h b/third_party/blink/renderer/platform/fonts/shaping/shape_result.h index eeb7e99..d63fdd6 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/shape_result.h +++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result.h
@@ -35,6 +35,7 @@ #include "base/containers/span.h" #include "third_party/blink/renderer/platform/fonts/canvas_rotation_in_vertical.h" #include "third_party/blink/renderer/platform/fonts/glyph.h" +#include "third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h" #include "third_party/blink/renderer/platform/fonts/simple_font_data.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/geometry/layout_unit.h" @@ -142,6 +143,17 @@ unsigned start_index, unsigned length, float width); + static scoped_refptr<ShapeResult> CreateForStretchyMathOperator( + const Font*, + TextDirection, + OpenTypeMathStretchData::StretchAxis, + Glyph, + float stretch_size); + static scoped_refptr<ShapeResult> CreateForStretchyMathOperator( + const Font*, + TextDirection, + OpenTypeMathStretchData::StretchAxis, + const OpenTypeMathStretchData::AssemblyParameters&); ~ShapeResult(); // Returns a mutable unique instance. If |this| has more than 1 ref count, @@ -495,6 +507,7 @@ friend class ShapeResultBloberizer; friend class ShapeResultView; friend class ShapeResultTest; + friend class StretchyOperatorShaper; template <bool has_non_zero_glyph_offsets> float ForEachGlyphImpl(float initial_advance,
diff --git a/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.cc b/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.cc new file mode 100644 index 0000000..99c80b3 --- /dev/null +++ b/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.cc
@@ -0,0 +1,223 @@ +// 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 "third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.h" + +#include <hb-ot.h> +#include <hb.h> +#include <unicode/uchar.h> + +#include "third_party/blink/renderer/platform/fonts/canvas_rotation_in_vertical.h" +#include "third_party/blink/renderer/platform/fonts/font.h" +#include "third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.h" +#include "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.h" +#include "third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h" +#include "third_party/blink/renderer/platform/geometry/float_rect.h" +#include "third_party/blink/renderer/platform/wtf/text/unicode.h" +#include "ui/gfx/skia_util.h" + +namespace blink { + +namespace { + +// HarfBuzz' hb_position_t is a 16.16 fixed-point value. +inline float HarfBuzzUnitsToFloat(hb_position_t value) { + static const float kFloatToHbRatio = 1.0f / (1 << 16); + return kFloatToHbRatio * value; +} + +inline float GetGlyphStretchSize( + FloatRect bounds, + OpenTypeMathStretchData::StretchAxis stretch_axis) { + return stretch_axis == OpenTypeMathStretchData::StretchAxis::Horizontal + ? bounds.Width() + : bounds.Height(); +} + +inline StretchyOperatorShaper::Metrics ToMetrics(FloatRect bounds) { + return {bounds.Width(), -bounds.Y(), bounds.MaxY()}; +} + +base::Optional<OpenTypeMathStretchData::AssemblyParameters> +GetAssemblyParameters(const HarfBuzzFace* harfbuzz_face, + Glyph base_glyph, + OpenTypeMathStretchData::StretchAxis stretch_axis, + float target_size) { + Vector<OpenTypeMathStretchData::GlyphPartRecord> parts = + OpenTypeMathSupport::GetGlyphPartRecords(harfbuzz_face, base_glyph, + stretch_axis); + if (parts.IsEmpty()) + return base::nullopt; + + hb_font_t* hb_font = + harfbuzz_face->GetScaledFont(nullptr, HarfBuzzFace::NoVerticalLayout); + + auto hb_stretch_axis = + stretch_axis == OpenTypeMathStretchData::StretchAxis::Horizontal + ? HB_DIRECTION_LTR + : HB_DIRECTION_BTT; + + // Go over the assembly parts and determine parameters used below. + // https://mathml-refresh.github.io/mathml-core/#the-glyphassembly-table + float min_connector_overlap = HarfBuzzUnitsToFloat( + hb_ot_math_get_min_connector_overlap(hb_font, hb_stretch_axis)); + float max_connector_overlap = std::numeric_limits<float>::max(); + float non_extender_advance_sum = 0, extender_advance_sum = 0; + unsigned non_extender_count = 0, extender_count = 0; + + for (auto& part : parts) { + // Calculate the count and advance sums of extender and non-extender glyphs. + if (part.is_extender) { + extender_count++; + extender_advance_sum += part.full_advance; + } else { + non_extender_count++; + non_extender_advance_sum += part.full_advance; + } + + // Take into account start connector length for all but the first glyph. + if (part.is_extender || &part != &parts.front()) { + max_connector_overlap = + std::min(max_connector_overlap, part.start_connector_length); + } + + // Take into account end connector length for all but the last glyph. + if (part.is_extender || &part != &parts.back()) { + max_connector_overlap = + std::min(max_connector_overlap, part.end_connector_length); + } + } + + // Check validity conditions indicated in MathML core. + float extender_non_overlapping_advance_sum = + extender_advance_sum - min_connector_overlap * extender_count; + if (extender_count == 0 || max_connector_overlap < min_connector_overlap || + extender_non_overlapping_advance_sum <= 0) + return base::nullopt; + + // Calculate the minimal number of repetitions needed to obtain an assembly + // size of size at least target size (r_min in MathML Core). + unsigned repetition_count = std::max<float>( + std::ceil((target_size - non_extender_advance_sum + + min_connector_overlap * (non_extender_count - 1)) / + extender_non_overlapping_advance_sum), + 0); + + // Calculate the number of glyphs, limiting repetition_count to ensure the + // assembly does not have more than HarfBuzzRunGlyphData::kMaxGlyphs. + DCHECK_LE(non_extender_count, HarfBuzzRunGlyphData::kMaxGlyphs); + repetition_count = std::min<unsigned>( + repetition_count, + (HarfBuzzRunGlyphData::kMaxGlyphs - non_extender_count) / extender_count); + unsigned glyph_count = non_extender_count + repetition_count * extender_count; + DCHECK_LE(glyph_count, HarfBuzzRunGlyphData::kMaxGlyphs); + + // Calculate the maximum overlap (called o_max in MathML Core) and the number + // of glyph in such an assembly (called N in MathML Core). + float connector_overlap = max_connector_overlap; + if (glyph_count > 1) { + float max_connector_overlap_theorical = + (non_extender_advance_sum + repetition_count * extender_advance_sum - + target_size) / + (glyph_count - 1); + connector_overlap = + std::max(min_connector_overlap, + std::min(connector_overlap, max_connector_overlap_theorical)); + } + + // Calculate the assembly size (called AssemblySize(o, r) in MathML Core). + float stretch_size = non_extender_advance_sum + + repetition_count * extender_advance_sum - + connector_overlap * (glyph_count - 1); + + return base::Optional<OpenTypeMathStretchData::AssemblyParameters>( + {connector_overlap, repetition_count, glyph_count, stretch_size, + std::move(parts)}); +} + +} // namespace + +StretchyOperatorShaper::Metrics StretchyOperatorShaper::GetMetrics( + const Font* font, + float target_size) const { + const SimpleFontData* primary_font = font->PrimaryFont(); + const HarfBuzzFace* harfbuzz_face = + primary_font->PlatformData().GetHarfBuzzFace(); + Glyph base_glyph = primary_font->GlyphForCharacter(stretchy_character_); + + FloatRect bounds; + + // Try different glyph variants. + for (auto& variant : OpenTypeMathSupport::GetGlyphVariantRecords( + harfbuzz_face, base_glyph, stretch_axis_)) { + bounds = primary_font->BoundsForGlyph(variant); + if (GetGlyphStretchSize(bounds, stretch_axis_) >= target_size) + return ToMetrics(bounds); + } + + // Try a glyph assembly. + auto params = GetAssemblyParameters(harfbuzz_face, base_glyph, stretch_axis_, + target_size); + if (!params) + return ToMetrics(bounds); + + bounds = stretch_axis_ == OpenTypeMathStretchData::StretchAxis::Horizontal + ? FloatRect(0, 0, params->stretch_size, 0) + : FloatRect(0, -params->stretch_size, 0, params->stretch_size); + + for (auto& part : params->parts) { + // Include dimension of the part, orthogonal to the stretch axis. + auto glyph_bounds = primary_font->BoundsForGlyph(part.glyph); + if (stretch_axis_ == OpenTypeMathStretchData::StretchAxis::Horizontal) { + glyph_bounds.SetX(0); + glyph_bounds.SetWidth(0); + } else { + glyph_bounds.SetY(0); + glyph_bounds.SetHeight(0); + } + bounds.UniteEvenIfEmpty(glyph_bounds); + } + + return ToMetrics(bounds); +} + +scoped_refptr<ShapeResult> StretchyOperatorShaper::Shape( + const Font* font, + float target_size) const { + const SimpleFontData* primary_font = font->PrimaryFont(); + const HarfBuzzFace* harfbuzz_face = + primary_font->PlatformData().GetHarfBuzzFace(); + Glyph base_glyph = primary_font->GlyphForCharacter(stretchy_character_); + + Glyph glyph_variant; + float glyph_variant_stretch_size; + TextDirection direction = TextDirection::kLtr; + + // Try different glyph variants. + for (auto& variant : OpenTypeMathSupport::GetGlyphVariantRecords( + harfbuzz_face, base_glyph, stretch_axis_)) { + glyph_variant = variant; + auto bounds = primary_font->BoundsForGlyph(glyph_variant); + glyph_variant_stretch_size = GetGlyphStretchSize(bounds, stretch_axis_); + if (glyph_variant_stretch_size >= target_size) { + return ShapeResult::CreateForStretchyMathOperator( + font, direction, stretch_axis_, glyph_variant, + glyph_variant_stretch_size); + } + } + + // Try a glyph assembly. + auto params = GetAssemblyParameters(harfbuzz_face, base_glyph, stretch_axis_, + target_size); + if (!params) { + return ShapeResult::CreateForStretchyMathOperator( + font, direction, stretch_axis_, glyph_variant, + glyph_variant_stretch_size); + } + + return ShapeResult::CreateForStretchyMathOperator( + font, direction, stretch_axis_, std::move(*params)); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.h b/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.h new file mode 100644 index 0000000..4df0eda --- /dev/null +++ b/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.h
@@ -0,0 +1,59 @@ +// 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_PLATFORM_FONTS_SHAPING_STRETCHY_OPERATOR_SHAPER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_STRETCHY_OPERATOR_SHAPER_H_ + +#include <base/memory/scoped_refptr.h> +#include <unicode/uchar.h> +#include "third_party/blink/renderer/platform/fonts/glyph.h" +#include "third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.h" +#include "third_party/blink/renderer/platform/text/text_direction.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" + +namespace blink { + +class Font; +class ShapeResult; +class StretchyOperatorShaper; + +// TODO(https://crbug.com/1057589): Add a TextDirection parameter, so that it's +// possible to perform glyph-level (rtlm feature) or character-level mirroring +// before stretching. +// https://mathml-refresh.github.io/mathml-core/#algorithms-for-glyph-stretching +class PLATFORM_EXPORT StretchyOperatorShaper final { + DISALLOW_NEW(); + + public: + StretchyOperatorShaper(UChar stretchy_character, + OpenTypeMathStretchData::StretchAxis stretch_axis) + : stretchy_character_(stretchy_character), stretch_axis_(stretch_axis) {} + + // Returns the metrics of the stretched operator for layout purpose. + // May be called multiple times; font and direction may vary between calls. + // https://mathml-refresh.github.io/mathml-core/#dfn-box-metrics-of-a-stretchy-glyph + struct Metrics { + float advance; + float ascent; + float descent; + // TODO(https://crbug.com/1057592): Add italic correction. + }; + Metrics GetMetrics(const Font*, float target_size) const; + + // Shape the stretched operator. The coordinates of the glyph(s) use the same + // origin as the rectangle returned by GetMetrics. + // May be called multiple times; font and direction may vary between calls. + // https://mathml-refresh.github.io/mathml-core/#dfn-shape-a-stretchy-glyph + scoped_refptr<ShapeResult> Shape(const Font*, float target_size) const; + + ~StretchyOperatorShaper() = default; + + private: + const UChar stretchy_character_; + const OpenTypeMathStretchData::StretchAxis stretch_axis_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_STRETCHY_OPERATOR_SHAPER_H_
diff --git a/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper_test.cc b/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper_test.cc new file mode 100644 index 0000000..87b30e6 --- /dev/null +++ b/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper_test.cc
@@ -0,0 +1,265 @@ +// 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 "third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.h" +#include "base/memory/scoped_refptr.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/fonts/font.h" +#include "third_party/blink/renderer/platform/fonts/opentype/open_type_types.h" +#include "third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h" +#include "third_party/blink/renderer/platform/fonts/shaping/shape_result_test_info.h" +#include "third_party/blink/renderer/platform/testing/font_test_helpers.h" +#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" + +namespace blink { + +namespace { + +const UChar32 kLeftBraceCodePoint = '{'; +const UChar32 kOverBraceCodePoint = 0x23DE; +const UChar32 kArabicMathOperatorHahWithDalCodePoint = 0x1EEF1; +float kSizeError = .1; + +ShapeResultTestInfo* TestInfo(const scoped_refptr<ShapeResult>& result) { + return static_cast<ShapeResultTestInfo*>(result.get()); +} + +} // namespace + +class StretchyOperatorShaperTest : public testing::Test { + protected: + void SetUp() override { + font_description.SetComputedSize(10.0); + font = Font(font_description); + font.Update(nullptr); + } + + void TearDown() override {} + + Font CreateMathFont(const String& name, float size = 1000) { + FontDescription::VariantLigatures ligatures; + return blink::test::CreateTestFont( + "MathTestFont", + blink::test::BlinkWebTestsFontsTestDataPath(String("math/") + name), + size, &ligatures); + } + + FontDescription font_description; + Font font; +}; + +// See createStretchy() in +// third_party/blink/web_tests/external/wpt/mathml/tools/operator-dictionary.py +TEST_F(StretchyOperatorShaperTest, GlyphVariants) { + Font math = CreateMathFont("operators.woff"); + + StretchyOperatorShaper vertical_shaper( + kLeftBraceCodePoint, OpenTypeMathStretchData::StretchAxis::Vertical); + StretchyOperatorShaper horizontal_shaper( + kOverBraceCodePoint, OpenTypeMathStretchData::StretchAxis::Horizontal); + + auto left_brace = math.PrimaryFont()->GlyphForCharacter(kLeftBraceCodePoint); + auto over_brace = math.PrimaryFont()->GlyphForCharacter(kOverBraceCodePoint); + + // Calculate glyph indices from the last unicode character in the font. + // TODO(https://crbug.com/1057596): Find a better way to access these glyph + // indices. + auto v0 = math.PrimaryFont()->GlyphForCharacter( + kArabicMathOperatorHahWithDalCodePoint) + + 1; + auto h0 = v0 + 1; + auto v1 = h0 + 1; + auto h1 = v1 + 1; + auto v2 = h1 + 1; + auto h2 = v2 + 1; + + // Stretch operators to target sizes (in font units) 125, 250, 375, 500, 625, + // 750, 875, 1000, 1125, ..., 3750, 3875, 4000. + // + // Shaper tries glyphs over_brace/left_brace, h0/v0, h1/v1, h2/v2, h3/v3 of + // respective sizes 1000, 1000, 2000, 3000 and 4000. It returns the smallest + // glyph larger than the target size. + const unsigned size_count = 4; + const unsigned subdivision = 8; + for (unsigned i = 0; i < size_count; i++) { + for (unsigned j = 1; j <= subdivision; j++) { + // Due to floating-point errors, the actual metrics of the size variants + // might actually be slightly smaller than expected. Reduce the + // target_size by kSizeError to ensure that the shaper picks the desired + // size variant. + float target_size = i * 1000 + (j * 1000 / subdivision) - kSizeError; + + // Metrics of horizontal size variants. + { + auto metrics = horizontal_shaper.GetMetrics(&math, target_size); + EXPECT_NEAR(metrics.advance, (i + 1) * 1000, kSizeError); + EXPECT_NEAR(metrics.ascent, 1000, kSizeError); + EXPECT_FLOAT_EQ(metrics.descent, 0); + } + + // Metrics of vertical size variants. + + { + auto metrics = vertical_shaper.GetMetrics(&math, target_size); + EXPECT_NEAR(metrics.advance, 1000, kSizeError); + EXPECT_NEAR(metrics.ascent, (i + 1) * 1000, kSizeError); + EXPECT_FLOAT_EQ(metrics.descent, 0); + } + + // Shaping of horizontal size variants. + { + scoped_refptr<ShapeResult> result = + horizontal_shaper.Shape(&math, target_size); + EXPECT_EQ(TestInfo(result)->NumberOfRunsForTesting(), 1u); + EXPECT_EQ(TestInfo(result)->RunInfoForTesting(0).NumGlyphs(), 1u); + Glyph expected_variant = i ? h0 + 2 * i : over_brace; + EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, 0), expected_variant); + EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, 0), (i + 1) * 1000, + kSizeError); + } + + // Shaping of vertical size variants. + { + scoped_refptr<ShapeResult> result = + vertical_shaper.Shape(&math, target_size); + EXPECT_EQ(TestInfo(result)->NumberOfRunsForTesting(), 1u); + EXPECT_EQ(TestInfo(result)->RunInfoForTesting(0).NumGlyphs(), 1u); + Glyph expected_variant = i ? v0 + 2 * i : left_brace; + EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, 0), expected_variant); + EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, 0), (i + 1) * 1000, + kSizeError); + } + } + } + + // Stretch an operator to target sizes (in font units) much larger than 4000. + // + // This will force an assembly with the following parts: + // _____________________________________________________________ + // Part | MaxStartOverlap | MaxEndOverlap | Advance | Extender | + // h2/v2 | 0 | 1000 | 3000 | false | + // h1/v1 | 1000 | 1000 | 2000 | true | + // + // For an assembly made of one non-extender glyph h2/v2 and repetition_count + // copies of extenders h1/v1, the size is + // advance(h2/v2) + repetition_count * (advance(h1/v1) - overlap). + // + // For repetition_count = k and overlap = 750, the size is X = 1250k + 3000. + // + // Since the font min overlap is 500, for repetition_count = k - 1 the size + // is at most Y = 1500k + 1500. + // + // Since the max overlap of parts is 1000, for repetition_count = k + 1 the + // size is at least Z = 1000k + 4000. + // + // { X - 4000 = 1250k - 1000 >= 250 >> kSizeError for k >= 1. + // { X - Y = 1500 - 250k >= 250 >> kSizeError for k <= 5. + // Hence setting the target size to 1250k + 3000 will ensure an assembly of + // k + 1 glyphs and overlap close to 750 for 1 <= k <= 5. + // + // Additionally, X - Z = 250k - 1000 = 250 >> kSizeError for k = 5 so this + // case also verifies that the minimal number of repetitions is actually used. + // + for (unsigned repetition_count = 1; repetition_count <= 5; + repetition_count++) { + // It is not necessary to decrease the target_size by kSizeError here. The + // shaper can just increase overlap by kSizeError / repetition_count to + // reduce the actual size of the assembly. + float overlap = 750; + float target_size = 3000 + repetition_count * (2000 - overlap); + + // Metrics of horizontal assembly. + { + auto metrics = horizontal_shaper.GetMetrics(&math, target_size); + EXPECT_NEAR(metrics.advance, target_size, kSizeError); + EXPECT_NEAR(metrics.ascent, 1000, kSizeError); + EXPECT_FLOAT_EQ(metrics.descent, 0); + } + + // Metrics of vertical assembly. + { + auto metrics = vertical_shaper.GetMetrics(&math, target_size); + EXPECT_NEAR(metrics.advance, 1000, kSizeError); + EXPECT_NEAR(metrics.ascent, target_size, kSizeError); + EXPECT_FLOAT_EQ(metrics.descent, 0); + } + + // Shaping of horizontal assembly. + // From left to right: h2, h1, h1, h1, ... + { + scoped_refptr<ShapeResult> result = + horizontal_shaper.Shape(&math, target_size); + + EXPECT_EQ(TestInfo(result)->NumberOfRunsForTesting(), 1u); + EXPECT_EQ(TestInfo(result)->RunInfoForTesting(0).NumGlyphs(), + repetition_count + 1); + EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, 0), h2); + EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, 0), 3000 - overlap, + kSizeError); + for (unsigned i = 0; i < repetition_count - 1; i++) { + EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, i + 1), h1); + EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, i + 1), + 2000 - overlap, kSizeError); + } + EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, repetition_count), h1); + EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, repetition_count), + 2000, kSizeError); + } + + // Shaping of vertical assembly. + // From bottom to top: v2, v1, v1, v1, ... + { + scoped_refptr<ShapeResult> result = + vertical_shaper.Shape(&math, target_size); + + EXPECT_EQ(TestInfo(result)->NumberOfRunsForTesting(), 1u); + EXPECT_EQ(TestInfo(result)->RunInfoForTesting(0).NumGlyphs(), + repetition_count + 1); + for (unsigned i = 0; i < repetition_count; i++) { + EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, i), v1); + EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, i), 2000 - overlap, + kSizeError); + } + EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, repetition_count), v2); + EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, repetition_count), + 3000, kSizeError); + } + } + + // Stretch an operator to edge target size values. + // + // These tests verify that it does not cause any assertion or crashes. + { + // Zero. + float target_size = 0; + horizontal_shaper.Shape(&math, target_size); + vertical_shaper.Shape(&math, target_size); + + // Negative. + target_size = -5500; + horizontal_shaper.Shape(&math, target_size); + vertical_shaper.Shape(&math, target_size); + + // Max limit. + target_size = std::numeric_limits<float>::max(); + horizontal_shaper.Shape(&math, target_size); + vertical_shaper.Shape(&math, target_size); + + // Min limit. + target_size = std::numeric_limits<float>::min(); + horizontal_shaper.Shape(&math, target_size); + vertical_shaper.Shape(&math, target_size); + + // More than the max number of glyphs. + // The size of an assembly with one non-extender v2/h2 and k - 1 extenders + // h1/v1 and minimal overlap 500 is Y = 1500k + 1500. + // So target_size - Y >= 250 >> kSizeError if the assembly does not have + // more than the max number of glyphs. + target_size = 1500 * HarfBuzzRunGlyphData::kMaxGlyphs + 1750; + horizontal_shaper.Shape(&math, target_size); + vertical_shaper.Shape(&math, target_size); + } +} + +} // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h b/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h index 0ebd9664..c6ee2e6c 100644 --- a/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h +++ b/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h
@@ -118,9 +118,6 @@ template <WTF::WeakHandlingFlag WeakHandling = WTF::kNoWeakHandling> static void Trace(Visitor* visitor, void* self) { - if (visitor->ConcurrentTracingBailOut({self, &Trace})) - return; - static_assert(WTF::IsTraceableInCollectionTrait<Traits>::value || WTF::IsWeak<ValueType>::value, "T should not be traced");
diff --git a/third_party/blink/renderer/platform/heap/heap.cc b/third_party/blink/renderer/platform/heap/heap.cc index 7fe59a2..09ffccc 100644 --- a/third_party/blink/renderer/platform/heap/heap.cc +++ b/third_party/blink/renderer/platform/heap/heap.cc
@@ -261,39 +261,6 @@ } } -void ThreadHeap::InvokeEphemeronCallbacks(MarkingVisitor* visitor) { - // Mark any strong pointers that have now become reachable in ephemeron maps. - ThreadHeapStatsCollector::Scope stats_scope( - stats_collector(), - ThreadHeapStatsCollector::kMarkInvokeEphemeronCallbacks); - - // We first reiterate over known callbacks from previous iterations. - for (auto& tuple : ephemeron_callbacks_) - tuple.value(visitor, tuple.key); - - DCHECK_EQ(WorklistTaskId::MutatorThread, visitor->task_id()); - - // Then we iterate over the new callbacks found by the marking visitor. - // Callbacks found by the concurrent marking will be flushed eventually - // and then invoked by the mutator thread (in the atomic pause at latest). - while ( - !weak_table_worklist_->IsLocalViewEmpty(WorklistTaskId::MutatorThread)) { - // Read ephemeron callbacks from worklist to ephemeron_callbacks_ hashmap. - WeakTableWorklist::View ephemerons_worklist(weak_table_worklist_.get(), - WorklistTaskId::MutatorThread); - WeakTableItem item; - while (ephemerons_worklist.Pop(&item)) { - auto result = - ephemeron_callbacks_.insert(item.base_object_payload, item.callback); - DCHECK(result.is_new_entry || - result.stored_value->value == item.callback); - if (result.is_new_entry) { - item.callback(visitor, item.base_object_payload); - } - } - } -} - namespace { template <typename Worklist, typename Callback> @@ -319,6 +286,45 @@ } // namespace +bool ThreadHeap::InvokeEphemeronCallbacks(MarkingVisitor* visitor, + base::TimeTicks deadline) { + // Mark any strong pointers that have now become reachable in ephemeron maps. + ThreadHeapStatsCollector::Scope stats_scope( + stats_collector(), + ThreadHeapStatsCollector::kMarkInvokeEphemeronCallbacks); + + // We first reiterate over known callbacks from previous iterations. + constexpr size_t kDeadlineCheckInterval = 250; + size_t processed_callback_count = 0; + for (auto& tuple : ephemeron_callbacks_) { + tuple.value(visitor, tuple.key); + if (++processed_callback_count == kDeadlineCheckInterval) { + if (deadline <= base::TimeTicks::Now()) { + return false; + } + processed_callback_count = 0; + } + } + + DCHECK_EQ(WorklistTaskId::MutatorThread, visitor->task_id()); + + // Then we iterate over the new callbacks found by the marking visitor. + // Callbacks found by the concurrent marking will be flushed eventually + // and then invoked by the mutator thread (in the atomic pause at latest). + return DrainWorklistWithDeadline( + deadline, weak_table_worklist_.get(), + [this, visitor](const WeakTableItem& item) { + auto result = ephemeron_callbacks_.insert(item.base_object_payload, + item.callback); + DCHECK(result.is_new_entry || + result.stored_value->value == item.callback); + if (result.is_new_entry) { + item.callback(visitor, item.base_object_payload); + } + }, + WorklistTaskId::MutatorThread); +} + bool ThreadHeap::AdvanceMarking(MarkingVisitor* visitor, base::TimeTicks deadline) { DCHECK_EQ(WorklistTaskId::MutatorThread, visitor->task_id()); @@ -390,7 +396,9 @@ break; } - InvokeEphemeronCallbacks(visitor); + finished = InvokeEphemeronCallbacks(visitor, deadline); + if (!finished) + break; // Rerun loop if ephemeron processing queued more objects for tracing. } while (!marking_worklist_->IsLocalViewEmpty(WorklistTaskId::MutatorThread));
diff --git a/third_party/blink/renderer/platform/heap/heap.h b/third_party/blink/renderer/platform/heap/heap.h index 4debc48..5cd67b8 100644 --- a/third_party/blink/renderer/platform/heap/heap.h +++ b/third_party/blink/renderer/platform/heap/heap.h
@@ -404,7 +404,7 @@ void DestroyMarkingWorklists(BlinkGC::StackState); void DestroyCompactionWorklists(); - void InvokeEphemeronCallbacks(MarkingVisitor*); + bool InvokeEphemeronCallbacks(MarkingVisitor*, base::TimeTicks); bool FlushV8References(base::TimeTicks);
diff --git a/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc b/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc index 6b28c4858..449d18c4 100644 --- a/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc +++ b/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
@@ -173,7 +173,7 @@ RevalidationStartForbiddenScope revalidation_start_forbidden_scope(this); RawResourceClient* client = static_cast<RawResourceClient*>(c); for (const auto& redirect : RedirectChain()) { - client->RedirectReceived(this, redirect.request_, + client->RedirectReceived(this, ResourceRequest(redirect.request_), redirect.redirect_response_); if (!HasClient(c)) return;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource.cc b/third_party/blink/renderer/platform/loader/fetch/resource.cc index 4a887fa..2f7d7eb 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource.cc
@@ -472,7 +472,7 @@ return CurrentAge(response, response_timestamp) <= max_life; } -const ResourceRequest& Resource::LastResourceRequest() const { +const ResourceRequestHead& Resource::LastResourceRequest() const { if (!redirect_chain_.size()) return GetResourceRequest(); return redirect_chain_.back().request_; @@ -1067,8 +1067,7 @@ GetResourceRequest().CacheControlContainsNoStore(); } -static bool ShouldRevalidateStaleResponse(const ResourceRequest& request, - const ResourceResponse& response, +static bool ShouldRevalidateStaleResponse(const ResourceResponse& response, base::Time response_timestamp) { base::TimeDelta staleness = response.CacheControlStaleWhileRevalidate(); if (staleness.is_zero()) @@ -1082,15 +1081,14 @@ for (auto& redirect : redirect_chain_) { // Use |response_timestamp_| since we don't store the timestamp // of each redirect response. - if (blink::ShouldRevalidateStaleResponse(redirect.request_, - redirect.redirect_response_, + if (blink::ShouldRevalidateStaleResponse(redirect.redirect_response_, response_timestamp_)) { return true; } } - return blink::ShouldRevalidateStaleResponse( - GetResourceRequest(), GetResponse(), response_timestamp_); + return blink::ShouldRevalidateStaleResponse(GetResponse(), + response_timestamp_); } bool Resource::StaleRevalidationRequested() const {
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource.h b/third_party/blink/renderer/platform/loader/fetch/resource.h index e10f36b..ffb2d1e 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource.h
@@ -179,7 +179,7 @@ const ResourceRequest& GetResourceRequest() const { return resource_request_; } - const ResourceRequest& LastResourceRequest() const; + const ResourceRequestHead& LastResourceRequest() const; const ResourceResponse* LastResourceResponse() const; virtual void SetRevalidatingRequest(const ResourceRequest&); @@ -466,13 +466,11 @@ DISALLOW_NEW(); public: - explicit RedirectPair(const ResourceRequest& request, + explicit RedirectPair(const ResourceRequestHead& request, const ResourceResponse& redirect_response) - : redirect_response_(redirect_response) { - request_.CopyFrom(request); - } + : request_(request), redirect_response_(redirect_response) {} - ResourceRequest request_; + ResourceRequestHead request_; ResourceResponse redirect_response_; }; const Vector<RedirectPair>& RedirectChain() const { return redirect_chain_; }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc index cc3431e..e95156fc 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -2030,10 +2030,11 @@ ResourceLoaderOptions options = resource->Options(); options.initiator_info.name = initiator_name; FetchParameters params(std::move(resource_request), options); - Context().CanRequest(resource->GetType(), resource->LastResourceRequest(), - resource->LastResourceRequest().Url(), params.Options(), + ResourceRequest last_resource_request(resource->LastResourceRequest()); + Context().CanRequest(resource->GetType(), last_resource_request, + last_resource_request.Url(), params.Options(), ReportingDisposition::kReport, - resource->LastResourceRequest().GetRedirectStatus()); + last_resource_request.GetRedirectStatus()); DidLoadResourceFromMemoryCache(resource->InspectorId(), resource, params.GetResourceRequest(), false /* is_static_data */);
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc index 4edab9bad..9db847ab 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -804,18 +804,19 @@ redirect_response_with_type ? *redirect_response_with_type : redirect_response; - // The following two calls may rewrite the new_request.Url() to + // The following two calls may rewrite the new_request->Url() to // something else not for rejecting redirect but for other reasons. // E.g. WebFrameTestClient::WillSendRequest() and // RenderFrameImpl::WillSendRequest(). We should reflect the - // rewriting but currently we cannot. So, compare new_request.Url() and + // rewriting but currently we cannot. So, compare new_request->Url() and // new_url after calling them, and return false to make the redirect fail on // mismatch. WebScopedVirtualTimePauser unused_virtual_time_pauser; + // TODO(yoichio): Have PrepareRequest use ResourceRequestHead. Context().PrepareRequest(*new_request, resource_->Options().initiator_info, - unused_virtual_time_pauser, - resource_->GetType()); + unused_virtual_time_pauser, resource_->GetType()); + DCHECK(!new_request->HttpBody()); if (auto* observer = fetcher_->GetResourceLoadObserver()) { observer->WillSendRequest(resource_->InspectorId(), *new_request, redirect_response_to_pass, resource_->GetType(), @@ -957,8 +958,10 @@ kEnableCorsHandlingByResourceFetcher && request_mode == network::mojom::RequestMode::kCors && response.WasFallbackRequiredByServiceWorker()) { + DCHECK(resource_->RedirectChain().IsEmpty()); ResourceRequest last_request; - last_request.CopyFrom(resource_->LastResourceRequest()); + last_request.CopyHeadFrom(resource_->GetResourceRequest()); + last_request.SetHttpBody(resource_->GetResourceRequest().HttpBody()); DCHECK(!last_request.GetSkipServiceWorker()); // This code handles the case when a controlling service worker doesn't // handle a cross origin request.
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc index a7b4142a..6428325 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
@@ -117,7 +117,7 @@ this->ResourceRequestHead::operator=(src); } -std::unique_ptr<ResourceRequest> ResourceRequest::CreateRedirectRequest( +std::unique_ptr<ResourceRequest> ResourceRequestHead::CreateRedirectRequest( const KURL& new_url, const AtomicString& new_method, const net::SiteForCookies& new_site_for_cookies,
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.h b/third_party/blink/renderer/platform/loader/fetch/resource_request.h index be58e01..d1135ec 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_request.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.h
@@ -67,13 +67,24 @@ ResourceRequestHead(); explicit ResourceRequestHead(const KURL&); - explicit ResourceRequestHead(const ResourceRequestHead&); + ResourceRequestHead(const ResourceRequestHead&); ResourceRequestHead& operator=(const ResourceRequestHead&); - explicit ResourceRequestHead(ResourceRequestHead&&); + ResourceRequestHead(ResourceRequestHead&&); ResourceRequestHead& operator=(ResourceRequestHead&&); ~ResourceRequestHead(); + // Constructs a new ResourceRequest for a redirect from this instance. + // Since body for a redirect request is kept and handled in the network + // service, the returned instance here in blink side doesn't contain body. + std::unique_ptr<ResourceRequest> CreateRedirectRequest( + const KURL& new_url, + const AtomicString& new_method, + const net::SiteForCookies& new_site_for_cookies, + const String& new_referrer, + network::mojom::ReferrerPolicy new_referrer_policy, + bool skip_service_worker) const; + bool IsNull() const; const KURL& Url() const; @@ -559,15 +570,6 @@ void CopyFrom(const ResourceRequest&); void CopyHeadFrom(const ResourceRequestHead&); - // Constructs a new ResourceRequest for a redirect from this instance. - std::unique_ptr<ResourceRequest> CreateRedirectRequest( - const KURL& new_url, - const AtomicString& new_method, - const net::SiteForCookies& new_site_for_cookies, - const String& new_referrer, - network::mojom::ReferrerPolicy new_referrer_policy, - bool skip_service_worker) const; - EncodedFormData* HttpBody() const; void SetHttpBody(scoped_refptr<EncodedFormData>);
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h index a430593..cfc8b6e 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h
@@ -37,11 +37,13 @@ } mojo::PendingRemote<Interface> BindNewPipeAndPassRemote( scoped_refptr<base::SequencedTaskRunner> task_runner) WARN_UNUSED_RESULT { + DCHECK(task_runner); return wrapper_->receiver().BindNewPipeAndPassRemote( std::move(task_runner)); } void Bind(mojo::PendingReceiver<Interface> pending_receiver, scoped_refptr<base::SequencedTaskRunner> task_runner) { + DCHECK(task_runner); wrapper_->receiver().Bind(std::move(pending_receiver), std::move(task_runner)); }
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set.h b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set.h index 3b84521f..26920f9 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set.h +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set.h
@@ -31,6 +31,7 @@ mojo::ReceiverId Add(ImplPointerType impl, mojo::PendingReceiver<Interface> receiver, scoped_refptr<base::SequencedTaskRunner> task_runner) { + DCHECK(task_runner); return wrapper_->receiver_set().Add(std::move(impl), std::move(receiver)); } void Clear() { wrapper_->receiver_set().Clear(); }
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_remote.h b/third_party/blink/renderer/platform/mojo/heap_mojo_remote.h index 4457f95..a3ee535 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_remote.h +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_remote.h
@@ -38,11 +38,13 @@ } mojo::PendingReceiver<Interface> BindNewPipeAndPassReceiver( scoped_refptr<base::SequencedTaskRunner> task_runner) WARN_UNUSED_RESULT { + DCHECK(task_runner); return wrapper_->remote().BindNewPipeAndPassReceiver( std::move(task_runner)); } void Bind(mojo::PendingRemote<Interface> pending_remote, scoped_refptr<base::SequencedTaskRunner> task_runner) { + DCHECK(task_runner); wrapper_->remote().Bind(std::move(pending_remote), std::move(task_runner)); }
diff --git a/third_party/blink/renderer/platform/wtf/hash_table.h b/third_party/blink/renderer/platform/wtf/hash_table.h index 7b3a156d..b6055474 100644 --- a/third_party/blink/renderer/platform/wtf/hash_table.h +++ b/third_party/blink/renderer/platform/wtf/hash_table.h
@@ -2140,15 +2140,6 @@ std::enable_if_t<A::kIsGarbageCollected> HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>:: Trace(VisitorDispatcher visitor) { - // bail out for concurrent marking - if (visitor->ConcurrentTracingBailOut( - {this, [](blink::Visitor* visitor, void* object) { - reinterpret_cast<HashTable<Key, Value, Extractor, HashFunctions, - Traits, KeyTraits, Allocator>*>(object) - ->Trace(visitor); - }})) - return; - static_assert(WTF::IsWeak<ValueType>::value || IsTraceableInCollectionTrait<Traits>::value, "Value should not be traced");
diff --git a/third_party/blink/renderer/platform/wtf/linked_hash_set.h b/third_party/blink/renderer/platform/wtf/linked_hash_set.h index 5bf2569e..1be1dbc 100644 --- a/third_party/blink/renderer/platform/wtf/linked_hash_set.h +++ b/third_party/blink/renderer/platform/wtf/linked_hash_set.h
@@ -355,14 +355,6 @@ template <typename VisitorDispatcher> void Trace(VisitorDispatcher visitor) { - if (visitor->ConcurrentTracingBailOut( - {this, [](blink::Visitor* visitor, void* object) { - reinterpret_cast<LinkedHashSet<ValueArg, HashFunctions, - TraitsArg, Allocator>*>(object) - ->Trace(visitor); - }})) - return; - impl_.Trace(visitor); // Should the underlying table be moved by GC, register a callback // that fixes up the interior pointers that the (Heap)LinkedHashSet keeps.
diff --git a/third_party/blink/renderer/platform/wtf/list_hash_set.h b/third_party/blink/renderer/platform/wtf/list_hash_set.h index 2fc5e5e..7329cfa 100644 --- a/third_party/blink/renderer/platform/wtf/list_hash_set.h +++ b/third_party/blink/renderer/platform/wtf/list_hash_set.h
@@ -516,13 +516,6 @@ template <typename VisitorDispatcher, typename A = NodeAllocator> std::enable_if_t<A::kIsGarbageCollected> Trace(VisitorDispatcher visitor) { - if (visitor->ConcurrentTracingBailOut( - {this, [](blink::Visitor* visitor, void* object) { - reinterpret_cast<ListHashSetNode<ValueArg, AllocatorArg>*>( - object) - ->Trace(visitor); - }})) - return; // The conservative stack scan can find nodes that have been removed // from the set and destructed. We don't need to trace these, and it // would be wrong to do so, because the class will not expect the trace @@ -1206,13 +1199,6 @@ template <typename VisitorDispatcher, typename A> std::enable_if_t<A::kIsGarbageCollected> ListHashSet<T, inlineCapacity, U, V>::Trace(VisitorDispatcher visitor) { - if (visitor->ConcurrentTracingBailOut( - {this, [](blink::Visitor* visitor, void* object) { - reinterpret_cast<ListHashSet<T, inlineCapacity, U, V>*>(object) - ->Trace(visitor); - }})) - return; - static_assert(!IsWeak<T>::value, "HeapListHashSet does not support weakness, consider using " "HeapLinkedHashSet instead.");
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 410ca88b..e35a693 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -56,8 +56,6 @@ crbug.com/906791 external/wpt/fullscreen/api/element-ready-check-allowed-cross-origin-manual.sub.html [ Timeout ] crbug.com/860713 external/wpt/bluetooth/requestDevice/cross-origin-iframe.sub.https.html [ Failure Timeout ] crbug.com/860713 external/wpt/bluetooth/requestDevice/request-from-sandboxed-iframe.https.html [ Failure Timeout ] -crbug.com/860713 virtual/web-bluetooth-new-permissions-backend/external/wpt/bluetooth/requestDevice/cross-origin-iframe.sub.https.html [ Failure Timeout ] -crbug.com/860713 virtual/web-bluetooth-new-permissions-backend/external/wpt/bluetooth/requestDevice/request-from-sandboxed-iframe.https.html [ Failure Timeout ] # The following tests would pass with User Activation Delegation. crbug.com/928838 external/wpt/html/user-activation/activation-transfer-with-click.tentative.html [ Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 4aab5a1..6770420 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -731,10 +731,5 @@ "prefix": "storage-access-api", "bases": [ "external/wpt/storage-access-api" ], "args": [ "--enable-features=StorageAccessAPI" ] - }, - { - "prefix": "web-bluetooth-new-permissions-backend", - "bases": ["bluetooth", "external/wpt/bluetooth"], - "args": ["--enable-features=WebBluetoothNewPermissionsBackend"] } ]
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/nonce-hiding/nonces-expected.txt b/third_party/blink/web_tests/external/wpt/content-security-policy/nonce-hiding/nonces-expected.txt deleted file mode 100644 index b9c30eda2..0000000 --- a/third_party/blink/web_tests/external/wpt/content-security-policy/nonce-hiding/nonces-expected.txt +++ /dev/null
@@ -1,15 +0,0 @@ -This is a testharness.js-based test. -PASS Basic nonce tests for meh in HTML namespace -PASS Ensure that removal of content attribute does not affect IDL attribute for meh in HTML namespace -PASS Basic nonce tests for div in HTML namespace -PASS Ensure that removal of content attribute does not affect IDL attribute for div in HTML namespace -PASS Basic nonce tests for script in HTML namespace -PASS Ensure that removal of content attribute does not affect IDL attribute for script in HTML namespace -FAIL Basic nonce tests for meh in SVG namespace assert_equals: IDL attribute is modified after content attribute set expected "x" but got "" -FAIL Ensure that removal of content attribute does not affect IDL attribute for meh in SVG namespace assert_equals: IDL attribute is modified after content attribute set expected "x" but got "" -FAIL Basic nonce tests for svg in SVG namespace assert_equals: IDL attribute is modified after content attribute set expected "x" but got "" -FAIL Ensure that removal of content attribute does not affect IDL attribute for svg in SVG namespace assert_equals: IDL attribute is modified after content attribute set expected "x" but got "" -FAIL Basic nonce tests for script in SVG namespace assert_equals: IDL attribute is modified after content attribute set expected "x" but got "" -FAIL Ensure that removal of content attribute does not affect IDL attribute for script in SVG namespace assert_equals: IDL attribute is modified after content attribute set expected "x" but got "" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/nonce-hiding/svgscript-nonces-hidden-expected.txt b/third_party/blink/web_tests/external/wpt/content-security-policy/nonce-hiding/svgscript-nonces-hidden-expected.txt deleted file mode 100644 index 05dc387..0000000 --- a/third_party/blink/web_tests/external/wpt/content-security-policy/nonce-hiding/svgscript-nonces-hidden-expected.txt +++ /dev/null
@@ -1,12 +0,0 @@ -This is a testharness.js-based test. -PASS Reading 'nonce' content attribute and IDL attribute. -PASS Cloned node retains nonce. -PASS Cloned node retains nonce when inserted. -FAIL Writing 'nonce' content attribute. assert_equals: expected "foo" but got "abc" -PASS Writing 'nonce' IDL attribute. -PASS Document-written script executes. -PASS Document-written script's nonce value. -PASS createElement.nonce. -PASS createElement.setAttribute. -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/nonce-hiding/svgscript-nonces-hidden-meta.sub-expected.txt b/third_party/blink/web_tests/external/wpt/content-security-policy/nonce-hiding/svgscript-nonces-hidden-meta.sub-expected.txt deleted file mode 100644 index 05dc387..0000000 --- a/third_party/blink/web_tests/external/wpt/content-security-policy/nonce-hiding/svgscript-nonces-hidden-meta.sub-expected.txt +++ /dev/null
@@ -1,12 +0,0 @@ -This is a testharness.js-based test. -PASS Reading 'nonce' content attribute and IDL attribute. -PASS Cloned node retains nonce. -PASS Cloned node retains nonce when inserted. -FAIL Writing 'nonce' content attribute. assert_equals: expected "foo" but got "abc" -PASS Writing 'nonce' IDL attribute. -PASS Document-written script executes. -PASS Document-written script's nonce value. -PASS createElement.nonce. -PASS createElement.setAttribute. -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/dedicated-worker-cache-storage.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/dedicated-worker-cache-storage.https.html index 2559de8..dced705 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/dedicated-worker-cache-storage.https.html +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/dedicated-worker-cache-storage.https.html
@@ -5,6 +5,7 @@ <script src="/resources/testharnessreport.js"></script> <script src="/common/get-host-info.sub.js"></script> <script> +// See also: ./shared-worker-cache-storage.https.html function remote(path) { const REMOTE_ORIGIN = get_host_info().HTTPS_REMOTE_ORIGIN; @@ -12,11 +13,11 @@ } const iframe_path = "./resources/iframe.html?pipe="; -const dedicated_worker_path = "./dedicated-worker.js?pipe="; +const dedicated_worker_path = "./universal-worker.js?pipe="; const ressource_path = "/images/blue.png?pipe="; const coep_header= { - "coep-none" : "|header(Cross-Origin-Embedder-Policy,none)", + "coep-none" : "", "coep-require-corp" : "|header(Cross-Origin-Embedder-Policy,require-corp)", } @@ -107,7 +108,7 @@ iframe.contentWindow.postMessage(iframe_eval); const {data} = await iframe_response; - assert_equals(data == "success", loaded); + assert_equals(data === "success", loaded); }, `${iframe_coep} ${worker_coep} ${response_corp}`) }
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/dedicated-worker.js b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/universal-worker.js similarity index 100% rename from third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/dedicated-worker.js rename to third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/universal-worker.js
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/service-worker-cache-storage.https-expected.txt b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/service-worker-cache-storage.https-expected.txt new file mode 100644 index 0000000..10fe541 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/service-worker-cache-storage.https-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +PASS A ServiceWorker with coep-none use CacheStorage to get a corp-undefined response. +PASS A ServiceWorker with coep-none use CacheStorage to get a corp-cross-origin response. +FAIL A ServiceWorker with coep-require-corp use CacheStorage to get a corp-undefined response. assert_equals: expected false but got true +PASS A ServiceWorker with coep-require-corp use CacheStorage to get a corp-cross-origin response. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/service-worker-cache-storage.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/service-worker-cache-storage.https.html new file mode 100644 index 0000000..873f06c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/service-worker-cache-storage.https.html
@@ -0,0 +1,117 @@ +<!doctype html> +<html> +<title> Check enforcement of COEP in a ServiceWorker using CacheStorage. </title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> +<script> +// See also: ./dedicated-worker-cache-storage.https.html + +function remote(path) { + const REMOTE_ORIGIN = get_host_info().HTTPS_REMOTE_ORIGIN; + return new URL(path, REMOTE_ORIGIN); +} + +const iframe_path = "./resources/iframe.html?pipe="; +const service_worker_path = "./resources/universal-worker.js?pipe="; +const ressource_path = "/images/blue.png?pipe="; + +const coep_header= { + "coep-none" : "", + "coep-require-corp" : "|header(Cross-Origin-Embedder-Policy,require-corp)", +} + +const corp_header = { + "corp-undefined" : "", + "corp-cross-origin" : "|header(Cross-Origin-Resource-Policy,cross-origin)", +} + +// Send a message to the |worker| and wait for its response. +function executeCommandInServiceWorker(worker, command) { + const channel = new MessageChannel(); + const response = new Promise(resolve => channel.port1.onmessage = resolve); + worker.postMessage(command, [ channel.port2 ]); + return response; +} + +// Check enforcement of COEP in a ServiceWorker using CacheStorage. +// +// 1) Fetch a response from a document with COEP:none. Store it in the +// CacheStorage. The response is cross-origin without any CORS header. +// 2) From a ServiceWorker, retrieve the response from the CacheStorage. +// +// Test parameters: +// - |worker_coep| the COEP header of the ServiceWorker's script response. +// - |response_corp| the CORP header of the response. +// +// Test expectations: +// |loaded| is true whenever the worker is able to fetch the response from +// the CacheStorage. According to the specification: +// https://mikewest.github.io/corpp/#initialize-embedder-policy-for-global +// it must be false when: +// - |worker_coep| is 'coep-require-corp' and +// - |response-corp| is 'corp-undefined'. +function check( + // Test parameters: + worker_coep, + response_corp, + + // Test expectations: + loaded) { + + promise_test(async (t) => { + // 1) Fetch a response from a document with COEP:none. Store it in the + // CacheStorage. The response is cross-origin without any CORS header. + const resource_path = ressource_path + corp_header[response_corp]; + const resource_url = remote(resource_path); + const fetch_request = new Request(resource_url, {mode: 'no-cors'}); + const cache = await caches.open('v1'); + const fetch_response = await fetch(fetch_request); + await cache.put(fetch_request, fetch_response); + + // 2) Start a ServiceWorker. + const SCOPE= new URL(location.href).pathname; + const service_worker_allowed = `|header(service-worker-allowed,${SCOPE})`; + const SCRIPT = + service_worker_path + + coep_header[worker_coep] + + service_worker_allowed; + + const reg = await service_worker_unregister_and_register(t, SCRIPT, SCOPE); + add_completion_callback(() => reg.unregister()); + + // Start talking to the ServiceWorker, no matter its state. + const worker = reg.installing || reg.waiting || reg.active; + + // 3) From the service worker, try to retrieve the response from the + // CacheStorage. + const response = executeCommandInServiceWorker(worker, ` + (async function() { + const cache = await caches.open('v1'); + const request = new Request('${resource_url}', { + mode: 'no-cors' + }); + try { + const response = await cache.match(request); + message.ports[0].postMessage('success'); + } catch(error) { + message.ports[0].postMessage('error'); + } + })() + `); + const {data} = await response; + assert_equals(data === "success", loaded); + }, `A ServiceWorker with ${worker_coep} use CacheStorage to get a ${response_corp} response.`) +} + +// ------------------------------------------------------ +// worker_coep , response_corp , loaded +// ------------------------------------------------------ +check("coep-none" , "corp-undefined" , true); +check("coep-none" , "corp-cross-origin" , true); +check("coep-require-corp" , "corp-undefined" , false); +check("coep-require-corp" , "corp-cross-origin" , true); + +</script> +</html>
diff --git a/third_party/blink/web_tests/http/tests/devtools/startup/console-exception-while-no-inspector-expected.txt b/third_party/blink/web_tests/http/tests/devtools/startup/console-exception-while-no-inspector-expected.txt deleted file mode 100644 index f5fd37d..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/startup/console-exception-while-no-inspector-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -Tests that console will NOT contain stack trace for exception thrown when inspector front-end was closed. Bug 109427. https://bugs.webkit.org/show_bug.cgi?id=109427 - -SUCCESS: message doesn't have stack trace -TEST COMPLETE. -
diff --git a/third_party/blink/web_tests/http/tests/devtools/startup/console-exception-while-no-inspector.js b/third_party/blink/web_tests/http/tests/devtools/startup/console-exception-while-no-inspector.js deleted file mode 100644 index 8f552294..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/startup/console-exception-while-no-inspector.js +++ /dev/null
@@ -1,20 +0,0 @@ -// 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. - -(async function() { - await TestRunner.setupStartupTest('resources/console-exception-while-no-inspector.html'); - TestRunner.addResult( - `Tests that console will NOT contain stack trace for exception thrown when inspector front-end was closed. Bug 109427. https://bugs.webkit.org/show_bug.cgi?id=109427\n`); - await TestRunner.waitForEvent(SDK.ConsoleModel.Events.MessageAdded, SDK.consoleModel); - - var message = SDK.consoleModel.messages()[0]; - var stack = message.stackTrace; - if (stack && stack.callFrames.length) - TestRunner.addResult('FAIL: found message with stack trace'); - else - TestRunner.addResult('SUCCESS: message doesn\'t have stack trace'); - - TestRunner.addResult('TEST COMPLETE.'); - TestRunner.completeTest(); -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/startup/pause-on-start-expected.txt b/third_party/blink/web_tests/http/tests/devtools/startup/pause-on-start-expected.txt deleted file mode 100644 index cca4143..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/startup/pause-on-start-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -Tests that tools pause on start. - -noop -
diff --git a/third_party/blink/web_tests/http/tests/devtools/startup/pause-on-start.js b/third_party/blink/web_tests/http/tests/devtools/startup/pause-on-start.js deleted file mode 100644 index 563a11aa..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/startup/pause-on-start.js +++ /dev/null
@@ -1,16 +0,0 @@ -// 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. - -(async function() { - Root.Runtime._queryParamsObject.set('panel', 'sources'); - await TestRunner.setupStartupTest('resources/pause-on-start.html'); - TestRunner.addResult( - `Tests that tools pause on start.\n`); - SDK.targetManager.addModelListener( - SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerPaused, (event) => { - const name = event.data.debuggerPausedDetails().callFrames[0].functionName; - TestRunner.addResult(name); - TestRunner.completeTest(); - }); -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/startup/resources/cached-resource-metadata.html b/third_party/blink/web_tests/http/tests/devtools/startup/resources/cached-resource-metadata.html deleted file mode 100644 index 4e97a32..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/startup/resources/cached-resource-metadata.html +++ /dev/null
@@ -1,24 +0,0 @@ -<html> -<head> -<script> -function addScript() -{ - var fulfill; - var promise = new Promise(x => fulfill = x); - var script = document.createElement("script"); - script.type = "text/javascript"; - script.src = "../../resource-tree/resources/script-with-constant-last-modified.php"; - script.onload = fulfill; - document.body.appendChild(script); - return promise; -} - -function addScriptAndRunTest() -{ - addScript().then(() => testRunner.inspectSecondaryWindow()); -} -</script> -</head> -<body onload="addScriptAndRunTest()"> -</body> -</html>
diff --git a/third_party/blink/web_tests/http/tests/devtools/startup/resources/console-exception-while-no-inspector.html b/third_party/blink/web_tests/http/tests/devtools/startup/resources/console-exception-while-no-inspector.html deleted file mode 100644 index bd3e16c..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/startup/resources/console-exception-while-no-inspector.html +++ /dev/null
@@ -1,39 +0,0 @@ -<html> -<head> -<script> -function throwException() { - throw 2013; -} - -function baz() -{ - throwException(); -} - -function bar(callback) -{ - callback() -} - -function foo() -{ - bar(baz.bind(this)); -} - - -function handleLoaded() -{ - setTimeout(showInspectorAndRunTest, 0); - foo(); -} - - -function showInspectorAndRunTest() -{ - testRunner.inspectSecondaryWindow(); -} -</script> -</head> -<body onload="handleLoaded()"> -</body> -</html>
diff --git a/third_party/blink/web_tests/http/tests/devtools/startup/resources/pause-on-start.html b/third_party/blink/web_tests/http/tests/devtools/startup/resources/pause-on-start.html deleted file mode 100644 index a7d689dc..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/startup/resources/pause-on-start.html +++ /dev/null
@@ -1,9 +0,0 @@ -<script> -function onload() { - testRunner.inspectSecondaryWindow(); - setInterval(noop, 10); -} - -function noop() {} -</script> -<body onload="onload()"></body>
diff --git a/third_party/blink/web_tests/http/tests/devtools/startup/resources/shadow-dom-rules.html b/third_party/blink/web_tests/http/tests/devtools/startup/resources/shadow-dom-rules.html deleted file mode 100644 index 7d51298..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/startup/resources/shadow-dom-rules.html +++ /dev/null
@@ -1,22 +0,0 @@ -<html> -<head> -<script> - -function createShadowRoot() -{ - var template = document.querySelector('#tmpl'); - var root = document.querySelector('#host').createShadowRoot(); - root.appendChild(template.content.cloneNode(true)); - testRunner.inspectSecondaryWindow(); -} -</script> -</head> - -<body onload="createShadowRoot()"> -<div id="host"></div> -<template id="tmpl"> - <style> .red { color: red; } </style> - <div id="inner" class="red">hi!</div> -</template> -</body> -</html>
diff --git a/third_party/blink/web_tests/http/tests/devtools/startup/resources/style.css b/third_party/blink/web_tests/http/tests/devtools/startup/resources/style.css deleted file mode 100644 index eba2cb6b..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/startup/resources/style.css +++ /dev/null
@@ -1,3 +0,0 @@ -#testDiv { - color: red; -} \ No newline at end of file
diff --git a/third_party/blink/web_tests/http/tests/devtools/startup/shadow-dom-rules-expected.txt b/third_party/blink/web_tests/http/tests/devtools/startup/shadow-dom-rules-expected.txt deleted file mode 100644 index d1e9c2a..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/startup/shadow-dom-rules-expected.txt +++ /dev/null
@@ -1,18 +0,0 @@ -This test checks that style sheets hosted inside shadow roots could be inspected. - - -Running: testInit - -Running: testDumpStyles -[expanded] -element.style { () - -[expanded] -.red { (<style>) - color: red; - -[expanded] -div { (user agent stylesheet) - display: block; - -
diff --git a/third_party/blink/web_tests/http/tests/devtools/startup/shadow-dom-rules.js b/third_party/blink/web_tests/http/tests/devtools/startup/shadow-dom-rules.js deleted file mode 100644 index 3f7539d..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/startup/shadow-dom-rules.js +++ /dev/null
@@ -1,20 +0,0 @@ -// 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. - -(async function() { - await TestRunner.setupStartupTest('resources/shadow-dom-rules.html'); - TestRunner.addResult(`This test checks that style sheets hosted inside shadow roots could be inspected.\n`); - await TestRunner.loadModule('elements_test_runner'); - - TestRunner.runTestSuite([ - function testInit(next) { - ElementsTestRunner.selectNodeAndWaitForStyles('inner', next); - }, - - async function testDumpStyles(next) { - await ElementsTestRunner.dumpSelectedElementStyles(true); - next(); - } - ]); -})();
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/cross-origin-isolation/coep-load-error-reporting-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/network/cross-origin-isolation/coep-load-error-reporting-expected.txt new file mode 100644 index 0000000..d22db3a --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/cross-origin-isolation/coep-load-error-reporting-expected.txt
@@ -0,0 +1,12 @@ +Tests that cross-origin embedder policy (COEP) related blocking is reported correctly. +https://devtools.test:8443/inspector-protocol/network/cross-origin-isolation/resources/coep-page-with-resources.php: *loading finished* +https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-origin-after-defaulted-to-same-origin-by-coep +https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?corp=cross-origin: *loading finished* +https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?corp=same-site: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-site +https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?corp=same-origin: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-origin +https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php: net::ERR_BLOCKED_BY_RESPONSE coep-frame-resource-needs-coep-header +https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?coep: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-origin-after-defaulted-to-same-origin-by-coep +https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?coep&corp=same-site: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-site +https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?coep&corp=same-origin: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-origin +https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php&coop: net::ERR_BLOCKED_BY_RESPONSE coep-frame-resource-needs-coep-header +
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/cross-origin-isolation/coep-load-error-reporting.js b/third_party/blink/web_tests/http/tests/inspector-protocol/network/cross-origin-isolation/coep-load-error-reporting.js new file mode 100644 index 0000000..1facafa --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/cross-origin-isolation/coep-load-error-reporting.js
@@ -0,0 +1,54 @@ +(async function(testRunner) { + const {page, session, dp} = await testRunner.startBlank( + `Tests that cross-origin embedder policy (COEP) related blocking is reported correctly.`); + + await session.protocol.Network.clearBrowserCache(); + await session.protocol.Network.setCacheDisabled({cacheDisabled: true}); + await dp.Target.setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true, flatten: true}); + + let numberOfMessages = 0; + const expectedNumberOfMessages = 21; + const resources = new Map(); + + function record(requestId, info) { + resources.set(requestId, {...resources.get(requestId), ...info}); + + if (++numberOfMessages === expectedNumberOfMessages) { + function compareInfo(a, b) { + return a.requestWillBeSent?.request?.url < b.requestWillBeSent?.request?.url; + } + const entries = Array.from(resources.values()).sort(compareInfo); + for (const entry of entries) { + if (entry.loadingFailed) { + testRunner.log(`${entry.requestWillBeSent.request?.url}: ${entry.loadingFailed.errorText} ${entry.loadingFailed.blockedReason}`); + } + if (entry.loadingFinished) { + testRunner.log(`${entry.requestWillBeSent.request?.url}: *loading finished*`); + } + } + testRunner.completeTest(); + } + } + + async function initalizeTarget(dp) { + dp.Network.onLoadingFailed(event => record(event.params.requestId, {loadingFailed: event.params})), + dp.Network.onLoadingFinished(event => record(event.params.requestId, {loadingFinished: event.params})), + dp.Network.onRequestWillBeSent(event => record(event.params.requestId, {requestWillBeSent: event.params})), + await Promise.all([ + dp.Network.enable(), + dp.Page.enable() + ]); + } + + await initalizeTarget(dp); + + dp.Target.onAttachedToTarget(async e => { + const dp = session.createChild(e.params.sessionId).protocol; + await initalizeTarget(dp); + }); + + page.navigate('https://devtools.test:8443/inspector-protocol/network/cross-origin-isolation/resources/coep-page-with-resources.php'); + + // `record` above makes sure to complete the test. +}) +
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/cross-origin-isolation/resources/coep-page-with-resources.php b/third_party/blink/web_tests/http/tests/inspector-protocol/network/cross-origin-isolation/resources/coep-page-with-resources.php new file mode 100644 index 0000000..275a50bd --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/cross-origin-isolation/resources/coep-page-with-resources.php
@@ -0,0 +1,49 @@ +<?php + +header("Cross-Origin-Embedder-Policy: require-corp"); + +?> + +<!DOCTYPE html> +<html lang="en"> + <head> + <title>Page with Cross-Origin-Embedder-Policy</title> + <meta charset="utf-8"> + </head> + <body> + <div> + This is a COEP page embedding resources. + </div> + None/None<br/> + <iframe src="https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php"> + </iframe><br/> + COEP/None<br/> + <iframe src="https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?coep"> + </iframe><br/> + COEP/Same-Site<br/> + <iframe src="https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?coep&corp=same-site"> + </iframe><br/> + COEP/Same-Origin<br/> + <iframe src="https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?coep&corp=same-origin"> + </iframe><br/> + COEP/Cross-Origin<br/> + <iframe src="https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?coep&corp=cross-origin"> + </iframe><br/> + Script CORP None <span id="script-corp-none">not loaded</span> + <script src="https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php" defer> + </script><br/> + Script CORP cross origin <span id="script-corp-cross-origin">not loaded</span> + <script src="https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?corp=cross-origin" defer> + </script> <br/> + Script CORP same site <span id="script-corp-same-site">not loaded</span> + <script src="https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?corp=same-site" defer> + </script><br/> + Script CORP same origin <span id="script-corp-same-origin">not loaded</span> + <script src="https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?corp=same-origin" defer> + </script><br/> + Sandboxed COOP iframe<br/> + <iframe src="https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php&coop"> + </iframe><br/> + </body> +</html> +
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php b/third_party/blink/web_tests/http/tests/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php new file mode 100644 index 0000000..39e1604 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php
@@ -0,0 +1,18 @@ +<?php + +if (isset($_GET['corp'])) { + header("Cross-Origin-Resource-Policy: " . $_GET['corp']); +} + +if (isset($_GET['coop'])) { + header("Cross-Origin-Opener-Policy: same-origin"); +} + + +if (isset($_GET['coep'])) { + header("Cross-Origin-Embedder-Policy: require-corp"); +} + +echo "This is some content"; + +?>
diff --git a/third_party/blink/web_tests/inspector-protocol/emulation/set-vision-deficiency-expected.txt b/third_party/blink/web_tests/inspector-protocol/emulation/set-vision-deficiency-expected.txt new file mode 100644 index 0000000..1699891 --- /dev/null +++ b/third_party/blink/web_tests/inspector-protocol/emulation/set-vision-deficiency-expected.txt
@@ -0,0 +1,42 @@ +Tests that vision deficiencies can be emulated. +<p>Emulating none: +<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAFRJREFUWIXt18ENACAMw8DA5N0chnCQePgGiKz+ujI5aZru3K6uPWAgZSBlIGUgZSBlIGUgZSBlILWS030iyr6/oIGUgZSBlIGUgZSBlIGUgZSB1AXNwwVLtuf+dAAAAABJRU5ErkJggg=="> +<p>Emulating achromatomaly: +<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAGFJREFUWIXt10ENwCAUBFFAATbQxBErtVNdyAARs016mCdgM/m3X8capwTtdybnSouufcBAykDKQMpAykDKQMpAykDKQKr2/kR/krTfX9BAykDKQMpAykDKQMpAykDKQOoCayUFlTeCp/sAAAAASUVORK5CYII="> +<p>Emulating achromatopsia: +<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAFpJREFUWIXt10ENADEMxMD2eARR2IfQFYS3Uh8eACsrv+zu/lfQzCTn1hddu8BAykDKQMpAykDKQMpAykDKQGpXVfQnSXv+ggZSBlIGUgZSBlIGUgZSBlIGUgcPVwX7L3bHewAAAABJRU5ErkJggg=="> +<p>Emulating blurredVision: +<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAehJREFUWIXtl81u4jAURo8TN7RpASXqohKLvsG89DzXLJFm1ZZCyb89i5tAWtAQYlfqIp90FWEl1yfX186H4tdvy3wN8Qvc7CGoQVnA8n8psAqMhiqGfQrbFWye4X0FWSrjRst9qAv5zkuzWEPyBx7+QrQDXbZwAwBRUEdQPsDuSYbKOeQJFAtQZhTUZ8C7F4FbrGG2EUBlhgHaQACLhQzlCURbCAtZicOLjqueAN7spXK3G5i9jQCcyfz5TlokLI9tMp6rBxjUkjQsBU4X1wEC1GUPrOn18KUcQwCV4WwM6kF6z1hvVfsMeJA9E5d07hk/lesUeMv0TZoAXTUBumoCdFXvHFRf4pKuvX+cNDbgJIDBn7qT8AusMRqaSKKO2rmvdDPd80aDDb1CaqpY/Fy+FKZRdmspOaq4B9pV0xUwS8VsAkRLN8OapWJYmxmYEB/9qXlfCUue+LH8WQplfKyiozSbZ3nr7bb1dM0AuB6kCWVZy7nAfTxCdS9jHjaNVDBLxKh2Nl0NBOwmN1qcdRVDed/7s+ReQcXtqyWor1ja0xSHpe5OBKPbHnTfKIqwsIddqxgJ2F39n4cK1bREri5YHa+2/9s5q/UM6FdfvsU/Tz/ezUyArpoAXTUBumoCdNUE6KoJ0FX/AAow6PKlz4YvAAAAAElFTkSuQmCC"> +<p>Emulating none: +<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAFRJREFUWIXt18ENACAMw8DA5N0chnCQePgGiKz+ujI5aZru3K6uPWAgZSBlIGUgZSBlIGUgZSBlILWS030iyr6/oIGUgZSBlIGUgZSBlIGUgZSB1AXNwwVLtuf+dAAAAABJRU5ErkJggg=="> +<p>Emulating deuteranomaly: +<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAGFJREFUWIXt1zENwDAQBMG3IaQ0uWAzHGNwHxoOiL1IKXYAnFbffRv3dSromSs5Vz269gEDKQMpAykDKQMpAykDKQMpA6lWtaM/SdrvL2ggZSBlIGUgZSBlIGUgZSBlIPUCZwcGA/y3590AAAAASUVORK5CYII="> +<p>Emulating deuteranopia: +<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAF9JREFUWIXt17ENwCAQBMGHYohdqKuhEsduBorYQyLYKeC0+uzbM8aqoO9/k3PVo2sHGEgZSBlIGUgZSBlIGUgZSBlItaoZ/UnSrr+ggZSBlIGUgZSBlIGUgZSBlIHUBmSnBbHzufJtAAAAAElFTkSuQmCC"> +<p>Emulating none: +<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAFRJREFUWIXt18ENACAMw8DA5N0chnCQePgGiKz+ujI5aZru3K6uPWAgZSBlIGUgZSBlIGUgZSBlILWS030iyr6/oIGUgZSBlIGUgZSBlIGUgZSB1AXNwwVLtuf+dAAAAABJRU5ErkJggg=="> +<p>Emulating protanomaly: +<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAGFJREFUWIXt1zENwDAQBMG3EaQzsqA0GENwHRQOiL1IKXYAnFbffRv3dSromSs5Vz269gEDKQMpAykDKQMpAykDKQMpA6lWtaM/SdrvL2ggZSBlIGUgZSBlIGUgZSBlIPUC9+8GC+XyxMUAAAAASUVORK5CYII="> +<p>Emulating protanopia: +<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAF9JREFUWIXt10ENwCAQBdEFI5VBahcnnEhVURHzm/QwT8DPZG/bxn2dCnr2TM5Vj659wEDKQMpAykDKQMpAykDKQMpAqlWt6E+S9vsLGkgZSBlIGUgZSBlIGUgZSBlIvZuvBc8DKP+1AAAAAElFTkSuQmCC"> +<p>Emulating tritanomaly: +<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAFxJREFUWIXt18EJACEQBEEVczA78zQhoxA0iJ6De3QFMDT729rnuCXo7JWcKy269gEDKQMpAykDKQMpAykDKQMpA6me/iHSfn9BAykDKQMpAykDKQMpAykDKQOpB4zjBwAkamC5AAAAAElFTkSuQmCC"> +<p>Emulating tritanopia: +<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAF5JREFUWIXt17ENwCAQBEGwEC0RuQBaoP8qnJgi9pAIdgo4rT772sf7l6BvzeRceaJrBxhIGUgZSBlIGUgZSBlIGUgZSLX0D5F2/QUNpAykDKQMpAykDKQMpAykDKQ2h2YFBXR3unwAAAAASUVORK5CYII="> +<p>Emulating tritanopia: +<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAF5JREFUWIXt17ENwCAQBEGwEC0RuQBaoP8qnJgi9pAIdgo4rT772sf7l6BvzeRceaJrBxhIGUgZSBlIGUgZSBlIGUgZSLX0D5F2/QUNpAykDKQMpAykDKQMpAykDKQ2h2YFBXR3unwAAAAASUVORK5CYII="> +<p>Emulating some-invalid-deficiency: +{ + "code": -32602, + "message": "Unknown vision deficiency type" +} +<p>Emulating : +{ + "code": -32602, + "message": "Unknown vision deficiency type" +} +<p>Navigating… +<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAF5JREFUWIXt17ENwCAQBEGwEC0RuQBaoP8qnJgi9pAIdgo4rT772sf7l6BvzeRceaJrBxhIGUgZSBlIGUgZSBlIGUgZSLX0D5F2/QUNpAykDKQMpAykDKQMpAykDKQ2h2YFBXR3unwAAAAASUVORK5CYII="> +<p>Emulating achromatopsia: +<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAFpJREFUWIXt10ENADEMxMD2eARR2IfQFYS3Uh8eACsrv+zu/lfQzCTn1hddu8BAykDKQMpAykDKQMpAykDKQGpXVfQnSXv+ggZSBlIGUgZSBlIGUgZSBlIGUgcPVwX7L3bHewAAAABJRU5ErkJggg=="> +
diff --git a/third_party/blink/web_tests/inspector-protocol/emulation/set-vision-deficiency.js b/third_party/blink/web_tests/inspector-protocol/emulation/set-vision-deficiency.js new file mode 100644 index 0000000..6adc8ca2 --- /dev/null +++ b/third_party/blink/web_tests/inspector-protocol/emulation/set-vision-deficiency.js
@@ -0,0 +1,59 @@ +(async function(testRunner) { + const {page, session, dp} = await testRunner.startBlank( + 'Tests that vision deficiencies can be emulated.'); + // Note: the output log for this test can be viewed as HTML to + // simplify review. + + await session.navigate('../resources/vision-deficiency.html'); + + async function logScreenshotData() { + const response = await dp.Page.captureScreenshot({ + clip: { + x: 0, + y: 0, + width: 40, + height: 40, + scale: 1, + }, + }); + const imageData = response.result.data; + testRunner.log(`<img src="data:image/png;base64,${imageData}">`); + } + + async function setEmulatedVisionDeficiency(id) { + testRunner.log(`<p>Emulating ${id}: `); + const response = await dp.Emulation.setEmulatedVisionDeficiency({ + type: id, + }); + if (response.error) { + testRunner.log(JSON.stringify(response.error, null, 2)); + return; + } + await logScreenshotData(); + } + + await setEmulatedVisionDeficiency('none'); + await setEmulatedVisionDeficiency('achromatomaly'); + await setEmulatedVisionDeficiency('achromatopsia'); + await setEmulatedVisionDeficiency('blurredVision'); + await setEmulatedVisionDeficiency('none'); + await setEmulatedVisionDeficiency('deuteranomaly'); + await setEmulatedVisionDeficiency('deuteranopia'); + await setEmulatedVisionDeficiency('none'); + await setEmulatedVisionDeficiency('protanomaly'); + await setEmulatedVisionDeficiency('protanopia'); + await setEmulatedVisionDeficiency('tritanomaly'); + await setEmulatedVisionDeficiency('tritanopia'); + // Test setting the already-active vision deficiency. + await setEmulatedVisionDeficiency('tritanopia'); + // Test setting unknown vision deficiencies. + await setEmulatedVisionDeficiency('some-invalid-deficiency'); + await setEmulatedVisionDeficiency(''); + + testRunner.log(`<p>Navigating…`); + await session.navigate('../resources/vision-deficiency.html'); + await logScreenshotData(); + await setEmulatedVisionDeficiency('achromatopsia'); + + testRunner.completeTest(); +});
diff --git a/third_party/blink/web_tests/inspector-protocol/resources/vision-deficiency.css b/third_party/blink/web_tests/inspector-protocol/resources/vision-deficiency.css new file mode 100644 index 0000000..17733910 --- /dev/null +++ b/third_party/blink/web_tests/inspector-protocol/resources/vision-deficiency.css
@@ -0,0 +1,12 @@ +html { + background: blue; +} +html, body { + margin: 0; + padding: 0; +} +div { + width: 20px; + height: 20px; + background: green; +}
diff --git a/third_party/blink/web_tests/inspector-protocol/resources/vision-deficiency.html b/third_party/blink/web_tests/inspector-protocol/resources/vision-deficiency.html new file mode 100644 index 0000000..3273a67 --- /dev/null +++ b/third_party/blink/web_tests/inspector-protocol/resources/vision-deficiency.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<!-- +Note: These tests should pass even when the document's CSP disallows + data: URLs. +--> +<meta http-equiv="Content-Security-Policy" content="default-src 'self'"> +<link rel="stylesheet" href="vision-deficiency.css"> +<div></div>
diff --git a/third_party/blink/web_tests/virtual/web-bluetooth-new-permissions-backend/README.md b/third_party/blink/web_tests/virtual/web-bluetooth-new-permissions-backend/README.md deleted file mode 100644 index dd5209b..0000000 --- a/third_party/blink/web_tests/virtual/web-bluetooth-new-permissions-backend/README.md +++ /dev/null
@@ -1,15 +0,0 @@ -# Web Bluetooth New Permissions Backend - -This virtual test suite runs content_shell with -`--enable-features=WebBluetoothNewPermissionsBackend`. This flag enables the -Web Bluetooth tests to use the -[`FakeBluetoothDelegate`](https://source.chromium.org/chromium/chromium/src/+/master:content/shell/browser/web_test/fake_bluetooth_delegate.h) -interface for granting and checking permissions. This class emulates the -behavior of the new Web Bluetooth permissions backend based on -[`ChooserContextBase`](https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/permissions/chooser_context_base.h). - -The new permissions backend is implemented as part of the [Web Bluetooth -Persistent Permissions project](https://docs.google.com/document/d/1h3uAVXJARHrNWaNACUPiQhLt7XI-fFFQoARSs1WgMDM). - -TODO(https://crbug.com/589228): Remove this virtual test suite when the -`WebBluetoothNewPermissionsBackend` flag is enabled by default. \ No newline at end of file
diff --git a/third_party/blink/web_tests/virtual/web-bluetooth-new-permissions-backend/bluetooth/README.txt b/third_party/blink/web_tests/virtual/web-bluetooth-new-permissions-backend/bluetooth/README.txt deleted file mode 100644 index a43806c..0000000 --- a/third_party/blink/web_tests/virtual/web-bluetooth-new-permissions-backend/bluetooth/README.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This directory includes Web Bluetooth tests that use the [out of date Web -Bluetooth test API](https://webbluetoothcg.github.io/web-bluetooth/tests.html) -as well as some tests using the [redesigned test -API](https://docs.google.com/document/d/1Nhv_oVDCodd1pEH_jj9k8gF4rPGb_84VYaZ9IG8M_WY). \ No newline at end of file
diff --git a/third_party/blink/web_tests/virtual/web-bluetooth-new-permissions-backend/external/wpt/bluetooth/README.txt b/third_party/blink/web_tests/virtual/web-bluetooth-new-permissions-backend/external/wpt/bluetooth/README.txt deleted file mode 100644 index c49c2d09..0000000 --- a/third_party/blink/web_tests/virtual/web-bluetooth-new-permissions-backend/external/wpt/bluetooth/README.txt +++ /dev/null
@@ -1,5 +0,0 @@ -This directory includes Web Bluetooth tests that use the [redesigned Web -Bluetooth test -API](https://docs.google.com/document/d/1Nhv_oVDCodd1pEH_jj9k8gF4rPGb_84VYaZ9IG8M_WY) -and are available in -[web-platform-tests/wpt](https://github.com/web-platform-tests/wpt). \ No newline at end of file
diff --git a/third_party/closure_compiler/externs/webview_tag.js b/third_party/closure_compiler/externs/webview_tag.js index 2e890874..cbf2d20 100644 --- a/third_party/closure_compiler/externs/webview_tag.js +++ b/third_party/closure_compiler/externs/webview_tag.js
@@ -226,6 +226,53 @@ WebView.prototype.request; /** + * @constructor + * @see https://developer.chrome.com/apps/tags/webview#type-ContextMenus + */ +function ContextMenus() {} +ContextMenus.prototype.onShow; +ContextMenus.prototype.onShow.addListener = function() {}; + +/** + * @type {ContextMenus} + * @see https://developer.chrome.com/apps/tags/webview#property-contextMenus + */ +WebView.prototype.contextMenus; + +/** + * @typedef{{ + * code: ?string, + * files: ?Array<string> + * }} + * @see https://developer.chrome.com/apps/tags/webview#type-InjectionItems + */ +var InjectionItems; + +/** + * Details of the content script to inject. + * @typedef{{ + * name: string, + * matches: Array<string>, + * exclude_matches: ?Array<string>, + * match_about_blank: ?boolean, + * css: ?InjectionItems, + * js: ?InjectionItems, + * run_at: ?string, + * all_frames: ?boolean, + * include_globs: ?Array<string>, + * exclude_globs: ?Array<string>, + * }} + * @see https://developer.chrome.com/apps/tags/webview#type-ContentScriptDetails + */ +var ContentScriptDetails; + +/** + * @param {Array<ContentScriptDetails>} contentScriptList + * @see https://developer.chrome.com/apps/tags/webview#method-addContentScripts + */ +WebView.prototype.addContentScripts = function(contentScriptList) {}; + +/** * @see https://developer.chrome.com/apps/tags/webview#method-back */ WebView.prototype.back = function() {}; @@ -319,6 +366,12 @@ WebView.prototype.reload = function() {}; /** + * @param {Array<string>} contentScriptList + * @see https://developer.chrome.com/apps/tags/webview#method-removeContentScripts + */ +WebView.prototype.removeContentScripts = function(contentScriptList) {}; + +/** * @param {string} userAgent * @see https://developer.chrome.com/apps/tags/webview#method-setUserAgentOverride */ @@ -332,6 +385,14 @@ WebView.prototype.setZoom = function(zoomFactor, opt_callback) {}; /** + * @param {string} zoomMode Allowed values: "per-origin", "per-view", "disabled" + * @see https://developer.chrome.com/apps/tags/webview#type-ZoomMode + * @param {Function=} opt_callback + * @see https://developer.chrome.com/apps/tags/webview#method-setZoomMode + */ +WebView.prototype.setZoomMode = function(zoomMode, opt_callback) {}; + +/** * @see https://developer.chrome.com/apps/tags/webview#method-stop */ WebView.prototype.stop = function() {};
diff --git a/tools/clang/blink_gc_plugin/tests/finalize_after_dispatch.cpp b/tools/clang/blink_gc_plugin/tests/finalize_after_dispatch.cpp index 14166a78..c7e932e 100644 --- a/tools/clang/blink_gc_plugin/tests/finalize_after_dispatch.cpp +++ b/tools/clang/blink_gc_plugin/tests/finalize_after_dispatch.cpp
@@ -23,9 +23,7 @@ } } -void A::TraceAfterDispatch(Visitor* visitor) -{ -} +void A::TraceAfterDispatch(Visitor* visitor) const {} void A::FinalizeGarbageCollectedObject() { @@ -42,22 +40,18 @@ } } -void B::TraceAfterDispatch(Visitor* visitor) -{ - visitor->Trace(m_a); - A::TraceAfterDispatch(visitor); +void B::TraceAfterDispatch(Visitor* visitor) const { + visitor->Trace(m_a); + A::TraceAfterDispatch(visitor); } -void C::TraceAfterDispatch(Visitor* visitor) -{ - visitor->Trace(m_a); - A::TraceAfterDispatch(visitor); +void C::TraceAfterDispatch(Visitor* visitor) const { + visitor->Trace(m_a); + A::TraceAfterDispatch(visitor); } -void D::TraceAfterDispatch(Visitor* visitor) -{ - visitor->Trace(m_a); - Abstract::TraceAfterDispatch(visitor); +void D::TraceAfterDispatch(Visitor* visitor) const { + visitor->Trace(m_a); + Abstract::TraceAfterDispatch(visitor); } - }
diff --git a/tools/clang/blink_gc_plugin/tests/finalize_after_dispatch.h b/tools/clang/blink_gc_plugin/tests/finalize_after_dispatch.h index f256bd03..9a67d8c 100644 --- a/tools/clang/blink_gc_plugin/tests/finalize_after_dispatch.h +++ b/tools/clang/blink_gc_plugin/tests/finalize_after_dispatch.h
@@ -19,14 +19,14 @@ class NeedsFinalizedBase : public GarbageCollected<NeedsFinalizedBase> { public: void Trace(Visitor*) { }; - void TraceAfterDispatch(Visitor*) { }; + void TraceAfterDispatch(Visitor*) const {}; void FinalizeGarbageCollectedObject() { }; }; class A : GarbageCollected<A> { public: void Trace(Visitor*); - void TraceAfterDispatch(Visitor*); + void TraceAfterDispatch(Visitor*) const; void FinalizeGarbageCollectedObject(); protected: @@ -41,16 +41,18 @@ public: B() : A(TB) { } ~B() { } - void TraceAfterDispatch(Visitor*); -private: + void TraceAfterDispatch(Visitor*) const; + + private: Member<A> m_a; }; class C : public A { public: C() : A(TC) { } - void TraceAfterDispatch(Visitor*); -private: + void TraceAfterDispatch(Visitor*) const; + + private: Member<A> m_a; }; @@ -63,8 +65,9 @@ class D : public Abstract { public: D() : Abstract(TD) { } - void TraceAfterDispatch(Visitor*); -private: + void TraceAfterDispatch(Visitor*) const; + + private: Member<A> m_a; };
diff --git a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch.cpp b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch.cpp index 4c62354..80f382b 100644 --- a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch.cpp +++ b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch.cpp
@@ -23,28 +23,22 @@ } } -void A::TraceAfterDispatch(Visitor* visitor) -{ +void A::TraceAfterDispatch(Visitor* visitor) const {} + +void B::TraceAfterDispatch(Visitor* visitor) const { + visitor->Trace(m_a); + // Missing A::TraceAfterDispatch(visitor); + // Also check that calling Trace does not count. + A::Trace(visitor); } -void B::TraceAfterDispatch(Visitor* visitor) -{ - visitor->Trace(m_a); - // Missing A::TraceAfterDispatch(visitor); - // Also check that calling Trace does not count. - A::Trace(visitor); +void C::TraceAfterDispatch(Visitor* visitor) const { + // Missing visitor->Trace(m_a); + A::TraceAfterDispatch(visitor); } -void C::TraceAfterDispatch(Visitor* visitor) -{ - // Missing visitor->Trace(m_a); - A::TraceAfterDispatch(visitor); +void D::TraceAfterDispatch(Visitor* visitor) const { + visitor->Trace(m_a); + Abstract::TraceAfterDispatch(visitor); } - -void D::TraceAfterDispatch(Visitor* visitor) -{ - visitor->Trace(m_a); - Abstract::TraceAfterDispatch(visitor); -} - }
diff --git a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch.h b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch.h index 0a5a7c7..b72e618 100644 --- a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch.h +++ b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch.h
@@ -12,8 +12,9 @@ class A : public GarbageCollected<A> { public: void Trace(Visitor*); - void TraceAfterDispatch(Visitor*); -protected: + void TraceAfterDispatch(Visitor*) const; + + protected: enum Type { TB, TC, TD }; A(Type type) : m_type(type) { } private: @@ -23,16 +24,18 @@ class B : public A { public: B() : A(TB) { } - void TraceAfterDispatch(Visitor*); -private: + void TraceAfterDispatch(Visitor*) const; + + private: Member<A> m_a; }; class C : public A { public: C() : A(TC) { } - void TraceAfterDispatch(Visitor*); -private: + void TraceAfterDispatch(Visitor*) const; + + private: Member<A> m_a; }; @@ -45,8 +48,9 @@ class D : public Abstract { public: D() : Abstract(TD) { } - void TraceAfterDispatch(Visitor*); -private: + void TraceAfterDispatch(Visitor*) const; + + private: Member<A> m_a; };
diff --git a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch.txt b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch.txt index 4873999..7e25b03 100644 --- a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch.txt +++ b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch.txt
@@ -2,10 +2,10 @@ void A::Trace(Visitor* visitor) ^ trace_after_dispatch.cpp:30:1: warning: [blink-gc] Base class 'A' of derived class 'B' requires tracing. -void B::TraceAfterDispatch(Visitor* visitor) +void B::TraceAfterDispatch(Visitor* visitor) const ^ trace_after_dispatch.cpp:38:1: warning: [blink-gc] Class 'C' has untraced fields that require tracing. -void C::TraceAfterDispatch(Visitor* visitor) +void C::TraceAfterDispatch(Visitor* visitor) const ^ ./trace_after_dispatch.h:36:5: note: [blink-gc] Untraced field 'm_a' declared here: Member<A> m_a;
diff --git a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl.cpp b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl.cpp index c8cd1df..337ee8a38 100644 --- a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl.cpp +++ b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl.cpp
@@ -29,13 +29,13 @@ } } -void TraceAfterDispatchExternBase::TraceAfterDispatch(Visitor* visitor) { +void TraceAfterDispatchExternBase::TraceAfterDispatch(Visitor* visitor) const { visitor->Trace(x_base_); } -void TraceAfterDispatchExternDerived::TraceAfterDispatch(Visitor* visitor) { +void TraceAfterDispatchExternDerived::TraceAfterDispatch( + Visitor* visitor) const { visitor->Trace(x_derived_); TraceAfterDispatchExternBase::TraceAfterDispatch(visitor); } - }
diff --git a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl.h b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl.h index 967793f..d86f072a 100644 --- a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl.h +++ b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl.h
@@ -25,7 +25,7 @@ void Trace(Visitor*); - void TraceAfterDispatch(Visitor* visitor) { visitor->Trace(x_base_); } + void TraceAfterDispatch(Visitor* visitor) const { visitor->Trace(x_base_); } private: ClassTag tag_; @@ -36,7 +36,7 @@ public: TraceAfterDispatchInlinedDerived() : TraceAfterDispatchInlinedBase(DERIVED) {} - void TraceAfterDispatch(Visitor* visitor) { + void TraceAfterDispatch(Visitor* visitor) const { visitor->Trace(x_derived_); TraceAfterDispatchInlinedBase::TraceAfterDispatch(visitor); } @@ -52,7 +52,7 @@ void Trace(Visitor* visitor); - void TraceAfterDispatch(Visitor* visitor); + void TraceAfterDispatch(Visitor* visitor) const; private: ClassTag tag_; @@ -63,7 +63,7 @@ public: TraceAfterDispatchExternDerived() : TraceAfterDispatchExternBase(DERIVED) {} - void TraceAfterDispatch(Visitor* visitor); + void TraceAfterDispatch(Visitor* visitor) const; private: Member<X> x_derived_;
diff --git a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.cpp b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.cpp index 76dc9761..9d9e01305 100644 --- a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.cpp +++ b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.cpp
@@ -31,12 +31,12 @@ } } -void TraceAfterDispatchExternBase::TraceAfterDispatch(Visitor* visitor) { +void TraceAfterDispatchExternBase::TraceAfterDispatch(Visitor* visitor) const { // No Trace call. } -void TraceAfterDispatchExternDerived::TraceAfterDispatch(Visitor* visitor) { +void TraceAfterDispatchExternDerived::TraceAfterDispatch( + Visitor* visitor) const { // Ditto. } - }
diff --git a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.h b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.h index 00c7986..35b34b9 100644 --- a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.h +++ b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.h
@@ -25,7 +25,7 @@ void Trace(Visitor*); - void TraceAfterDispatch(Visitor* visitor) { + void TraceAfterDispatch(Visitor* visitor) const { // No Trace call; should get a warning. } @@ -38,7 +38,7 @@ public: TraceAfterDispatchInlinedDerived() : TraceAfterDispatchInlinedBase(DERIVED) {} - void TraceAfterDispatch(Visitor* visitor) { + void TraceAfterDispatch(Visitor* visitor) const { // No Trace call (for member and base class). } @@ -53,7 +53,7 @@ void Trace(Visitor* visitor); - void TraceAfterDispatch(Visitor* visitor); + void TraceAfterDispatch(Visitor* visitor) const; private: ClassTag tag_; @@ -64,7 +64,7 @@ public: TraceAfterDispatchExternDerived() : TraceAfterDispatchExternBase(DERIVED) {} - void TraceAfterDispatch(Visitor* visitor); + void TraceAfterDispatch(Visitor* visitor) const; private: Member<X> x_derived_;
diff --git a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.txt b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.txt index 85f57af..dbe1329 100644 --- a/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.txt +++ b/tools/clang/blink_gc_plugin/tests/trace_after_dispatch_impl_error.txt
@@ -6,26 +6,26 @@ ^ In file included from trace_after_dispatch_impl_error.cpp:5: ./trace_after_dispatch_impl_error.h:28:3: warning: [blink-gc] Class 'TraceAfterDispatchInlinedBase' has untraced fields that require tracing. - void TraceAfterDispatch(Visitor* visitor) { + void TraceAfterDispatch(Visitor* visitor) const { ^ ./trace_after_dispatch_impl_error.h:34:3: note: [blink-gc] Untraced field 'x_base_' declared here: Member<X> x_base_; ^ ./trace_after_dispatch_impl_error.h:41:3: warning: [blink-gc] Base class 'TraceAfterDispatchInlinedBase' of derived class 'TraceAfterDispatchInlinedDerived' requires tracing. - void TraceAfterDispatch(Visitor* visitor) { + void TraceAfterDispatch(Visitor* visitor) const { ^ ./trace_after_dispatch_impl_error.h:41:3: warning: [blink-gc] Class 'TraceAfterDispatchInlinedDerived' has untraced fields that require tracing. ./trace_after_dispatch_impl_error.h:46:3: note: [blink-gc] Untraced field 'x_derived_' declared here: Member<X> x_derived_; ^ trace_after_dispatch_impl_error.cpp:34:1: warning: [blink-gc] Class 'TraceAfterDispatchExternBase' has untraced fields that require tracing. -void TraceAfterDispatchExternBase::TraceAfterDispatch(Visitor* visitor) { +void TraceAfterDispatchExternBase::TraceAfterDispatch(Visitor* visitor) const { ^ ./trace_after_dispatch_impl_error.h:60:3: note: [blink-gc] Untraced field 'x_base_' declared here: Member<X> x_base_; ^ trace_after_dispatch_impl_error.cpp:38:1: warning: [blink-gc] Base class 'TraceAfterDispatchExternBase' of derived class 'TraceAfterDispatchExternDerived' requires tracing. -void TraceAfterDispatchExternDerived::TraceAfterDispatch(Visitor* visitor) { +void TraceAfterDispatchExternDerived::TraceAfterDispatch(Visitor* visitor) const { ^ trace_after_dispatch_impl_error.cpp:38:1: warning: [blink-gc] Class 'TraceAfterDispatchExternDerived' has untraced fields that require tracing. ./trace_after_dispatch_impl_error.h:70:3: note: [blink-gc] Untraced field 'x_derived_' declared here:
diff --git a/tools/clang/blink_gc_plugin/tests/trace_wrapper.h b/tools/clang/blink_gc_plugin/tests/trace_wrapper.h index 898eb63e..c09c03f 100644 --- a/tools/clang/blink_gc_plugin/tests/trace_wrapper.h +++ b/tools/clang/blink_gc_plugin/tests/trace_wrapper.h
@@ -26,12 +26,12 @@ class B : public GarbageCollected<B> { public: void Trace(Visitor* visitor); - void TraceAfterDispatch(Visitor*) {} + void TraceAfterDispatch(Visitor*) const {} }; class C : public B { public: - void TraceAfterDispatch(Visitor*) { + void TraceAfterDispatch(Visitor*) const { // Missing visitor->Trace(str_); }
diff --git a/tools/clang/blink_gc_plugin/tests/trace_wrapper.txt b/tools/clang/blink_gc_plugin/tests/trace_wrapper.txt index e6c1076..b5a2b72 100644 --- a/tools/clang/blink_gc_plugin/tests/trace_wrapper.txt +++ b/tools/clang/blink_gc_plugin/tests/trace_wrapper.txt
@@ -6,7 +6,7 @@ TraceWrapperV8Reference<v8::String> str_; ^ ./trace_wrapper.h:34:3: warning: [blink-gc] Base class 'B' of derived class 'C' requires tracing. - void TraceAfterDispatch(Visitor*) { + void TraceAfterDispatch(Visitor*) const { ^ ./trace_wrapper.h:34:3: warning: [blink-gc] Class 'C' has untraced fields that require tracing. ./trace_wrapper.h:39:3: note: [blink-gc] Untraced field 'str_' declared here:
diff --git a/tools/clang/blink_gc_plugin/tests/virtual_and_trace_after_dispatch.cpp b/tools/clang/blink_gc_plugin/tests/virtual_and_trace_after_dispatch.cpp index b284ddf..87719d99 100644 --- a/tools/clang/blink_gc_plugin/tests/virtual_and_trace_after_dispatch.cpp +++ b/tools/clang/blink_gc_plugin/tests/virtual_and_trace_after_dispatch.cpp
@@ -17,14 +17,10 @@ } } -void A::TraceAfterDispatch(Visitor* visitor) -{ -} +void A::TraceAfterDispatch(Visitor* visitor) const {} -void B::TraceAfterDispatch(Visitor* visitor) -{ - visitor->Trace(m_a); - A::TraceAfterDispatch(visitor); +void B::TraceAfterDispatch(Visitor* visitor) const { + visitor->Trace(m_a); + A::TraceAfterDispatch(visitor); } - }
diff --git a/tools/clang/blink_gc_plugin/tests/virtual_and_trace_after_dispatch.h b/tools/clang/blink_gc_plugin/tests/virtual_and_trace_after_dispatch.h index c6a7c959..9017e86 100644 --- a/tools/clang/blink_gc_plugin/tests/virtual_and_trace_after_dispatch.h +++ b/tools/clang/blink_gc_plugin/tests/virtual_and_trace_after_dispatch.h
@@ -12,8 +12,9 @@ class A : public GarbageCollected<A> { public: void Trace(Visitor*); - void TraceAfterDispatch(Visitor*); -protected: + void TraceAfterDispatch(Visitor*) const; + + protected: enum Type { TB }; A(Type type) : m_type(type) { } private: @@ -23,7 +24,7 @@ class B : public A { public: B() : A(TB) { } - void TraceAfterDispatch(Visitor*); + void TraceAfterDispatch(Visitor*) const; virtual void foo() { } private: Member<A> m_a;
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec index 79ce436..fe26a76 100644 --- a/tools/gritsettings/resource_ids.spec +++ b/tools/gritsettings/resource_ids.spec
@@ -200,6 +200,9 @@ "chrome/browser/resources/bluetooth_internals/resources.grd": { "includes": [2020], }, + "chrome/browser/resources/gaia_auth_host/gaia_auth_host_resources.grd": { + "includes": [2030], + }, "chrome/browser/resources/invalidations/invalidations_resources.grd": { "includes": [2040], },
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 02cc9c86..f53f57b0 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -37434,6 +37434,8 @@ <int value="-1776351704" label="DesktopPWAsOmniboxInstall:disabled"/> <int value="-1774818943" label="VrWebInputEditing:enabled"/> <int value="-1772942854" label="LongPressBackForHistory:enabled"/> + <int value="-1772905637" + label="RunVideoCaptureServiceInBrowserProcess:enabled"/> <int value="-1772172557" label="enable-osk-overscroll"/> <int value="-1768672408" label="ChromeDuplex:disabled"/> <int value="-1768308156" label="OmniboxDedupeGoogleDriveURLs:enabled"/> @@ -38897,6 +38899,8 @@ <int value="-20438829" label="SyncUSSAutofillProfile:enabled"/> <int value="-20329017" label="EduCoexistence:disabled"/> <int value="-20267582" label="ResourceLoadingHints:disabled"/> + <int value="-19498390" + label="RunVideoCaptureServiceInBrowserProcess:disabled"/> <int value="-18464041" label="AutofillPrefilledFields:disabled"/> <int value="-17698200" label="DoubleTapToZoomInTabletMode:disabled"/> <int value="-17373827" label="SharingDeviceExpiration:enabled"/>
diff --git a/tools/perf/core/minidump_unittest.py b/tools/perf/core/minidump_unittest.py index ccaa19ff..8562d8d2 100644 --- a/tools/perf/core/minidump_unittest.py +++ b/tools/perf/core/minidump_unittest.py
@@ -20,7 +20,8 @@ # still read-only, so skip the test in that case. # TODO(crbug.com/1038043): Test is failing on chromeos-betty-chrome. # TODO(crbug.com/1056235): Re-enable on Linux once the crashes are fixed. - @decorators.Disabled('chromeos-local', 'chromeos-board-betty', 'linux') + @decorators.Disabled('chromeos-local', 'chromeos-board-betty', + 'chromeos-amd64-generic-rel', 'linux') def testSymbolizeMinidump(self): # Wait for the browser to restart fully before crashing self._LoadPageThenWait('var sam = "car";', 'sam') @@ -64,7 +65,8 @@ # still read-only, so skip the test in that case. # TODO(crbug.com/1038043): Test is failing on chromeos-betty-chrome. # TODO(crbug.com/1056235): Re-enable on Linux once the crashes are fixed. - @decorators.Disabled('chromeos-local', 'chromeos-board-betty', 'linux') + @decorators.Disabled('chromeos-local', 'chromeos-board-betty', + 'chromeos-amd64-generic-rel', 'linux') def testMultipleCrashMinidumps(self): # Wait for the browser to restart fully before crashing self._LoadPageThenWait('var cat = "dog";', 'cat')
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn index 715a7ff..5fc8dcd 100644 --- a/ui/android/BUILD.gn +++ b/ui/android/BUILD.gn
@@ -335,7 +335,7 @@ "//base:jni_java", "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/android_deps:androidx_annotation_annotation_java", - "//third_party/android_deps:com_android_support_asynclayoutinflater_java", + "//third_party/android_deps:androidx_asynclayoutinflater_asynclayoutinflater_java", "//third_party/android_deps:com_android_support_recyclerview_v7_java", "//ui/base/mojom:cursor_type_java", ]
diff --git a/ui/android/java/src/org/chromium/ui/AsyncViewStub.java b/ui/android/java/src/org/chromium/ui/AsyncViewStub.java index a1d864e..f17f90530 100644 --- a/ui/android/java/src/org/chromium/ui/AsyncViewStub.java +++ b/ui/android/java/src/org/chromium/ui/AsyncViewStub.java
@@ -8,7 +8,6 @@ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; -import android.support.v4.view.AsyncLayoutInflater; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; @@ -16,6 +15,7 @@ import android.view.ViewParent; import androidx.annotation.NonNull; +import androidx.asynclayoutinflater.view.AsyncLayoutInflater; import org.chromium.base.Callback; import org.chromium.base.ObserverList;
diff --git a/ui/android/junit/src/org/chromium/ui/shadows/ShadowAsyncLayoutInflater.java b/ui/android/junit/src/org/chromium/ui/shadows/ShadowAsyncLayoutInflater.java index 352dfce..1778a82 100644 --- a/ui/android/junit/src/org/chromium/ui/shadows/ShadowAsyncLayoutInflater.java +++ b/ui/android/junit/src/org/chromium/ui/shadows/ShadowAsyncLayoutInflater.java
@@ -5,7 +5,6 @@ package org.chromium.ui.shadows; import android.content.Context; -import android.support.v4.view.AsyncLayoutInflater; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -13,6 +12,7 @@ import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.asynclayoutinflater.view.AsyncLayoutInflater; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements;
diff --git a/ui/events/blink/BUILD.gn b/ui/events/blink/BUILD.gn index 2b8760e..b4c7d56 100644 --- a/ui/events/blink/BUILD.gn +++ b/ui/events/blink/BUILD.gn
@@ -72,6 +72,7 @@ deps = [ "//cc:cc", + "//services/tracing/public/cpp:cpp", "//third_party/blink/public:blink_headers", "//third_party/one_euro_filter", "//ui/base:base",
diff --git a/ui/events/blink/DEPS b/ui/events/blink/DEPS index 2f904b2..0a508d0 100644 --- a/ui/events/blink/DEPS +++ b/ui/events/blink/DEPS
@@ -21,4 +21,6 @@ "+ui/gfx/geometry", "+third_party/one_euro_filter/src/one_euro_filter.h", + + "+services/tracing/public/cpp", ]
diff --git a/ui/events/blink/input_handler_proxy.cc b/ui/events/blink/input_handler_proxy.cc index 0956f07..0ba5c5b1 100644 --- a/ui/events/blink/input_handler_proxy.cc +++ b/ui/events/blink/input_handler_proxy.cc
@@ -22,6 +22,8 @@ #include "base/trace_event/trace_event.h" #include "build/build_config.h" #include "cc/input/main_thread_scrolling_reason.h" +#include "services/tracing/public/cpp/perfetto/flow_event_utils.h" +#include "services/tracing/public/cpp/perfetto/macros.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/common/input/web_mouse_wheel_event.h" #include "third_party/blink/public/common/input/web_touch_event.h" @@ -43,6 +45,8 @@ using blink::WebMouseWheelEvent; using blink::WebTouchEvent; using blink::WebTouchPoint; +using perfetto::protos::pbzero::ChromeLatencyInfo; +using perfetto::protos::pbzero::TrackEvent; namespace { @@ -241,10 +245,15 @@ EventDispositionCallback callback) { DCHECK(input_handler_); - TRACE_EVENT_WITH_FLOW1("input,benchmark", "LatencyInfo.Flow", - TRACE_ID_GLOBAL(latency_info.trace_id()), - TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, - "step", "HandleInputEventImpl"); + TRACE_EVENT("input,benchmark", "LatencyInfo.Flow", + [&latency_info](perfetto::EventContext ctx) { + ChromeLatencyInfo* info = + ctx.event()->set_chrome_latency_info(); + info->set_trace_id(latency_info.trace_id()); + info->set_step(ChromeLatencyInfo::STEP_HANDLE_INPUT_EVENT_IMPL); + tracing::FillFlowEvent(ctx, TrackEvent::LegacyEvent::FLOW_INOUT, + latency_info.trace_id()); + }); std::unique_ptr<EventWithCallback> event_with_callback = std::make_unique<EventWithCallback>(std::move(event), latency_info,
diff --git a/ui/latency/BUILD.gn b/ui/latency/BUILD.gn index 13978ba..0e3639e5 100644 --- a/ui/latency/BUILD.gn +++ b/ui/latency/BUILD.gn
@@ -18,6 +18,7 @@ deps = [ "//base", + "//services/tracing/public/cpp:cpp", "//ui/gfx", ]
diff --git a/ui/latency/DEPS b/ui/latency/DEPS index 40d9b9f..2a39e69c 100644 --- a/ui/latency/DEPS +++ b/ui/latency/DEPS
@@ -1,5 +1,7 @@ include_rules = [ "+services/metrics/public/cpp", + "+services/tracing/public/cpp", + "+third_party/perfetto/protos/perfetto/trace/track_event", "+ui/gfx", ]
diff --git a/ui/latency/latency_info.cc b/ui/latency/latency_info.cc index 6dca0cd..90c77e1 100644 --- a/ui/latency/latency_info.cc +++ b/ui/latency/latency_info.cc
@@ -15,9 +15,14 @@ #include "base/macros.h" #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event.h" +#include "services/tracing/public/cpp/perfetto/flow_event_utils.h" +#include "services/tracing/public/cpp/perfetto/macros.h" namespace { +using perfetto::protos::pbzero::ChromeLatencyInfo; +using perfetto::protos::pbzero::TrackEvent; + const size_t kMaxLatencyInfoNumber = 100; const char* GetComponentName(ui::LatencyComponentType type) { @@ -148,14 +153,20 @@ void LatencyInfo::TraceIntermediateFlowEvents( const std::vector<LatencyInfo>& latency_info, - const char* event_name) { + perfetto::protos::pbzero::ChromeLatencyInfo::Step step) { for (auto& latency : latency_info) { if (latency.trace_id() == -1) continue; - TRACE_EVENT_WITH_FLOW1("input,benchmark", "LatencyInfo.Flow", - TRACE_ID_GLOBAL(latency.trace_id()), - TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, - "step", event_name); + + TRACE_EVENT( + "input,benchmark", "LatencyInfo.Flow", + [&latency, &step](perfetto::EventContext ctx) { + ChromeLatencyInfo* info = ctx.event()->set_chrome_latency_info(); + info->set_step(step); + info->set_trace_id(latency.trace_id()); + tracing::FillFlowEvent(ctx, TrackEvent::LegacyEvent::FLOW_INOUT, + latency.trace_id()); + }); } } @@ -260,9 +271,14 @@ TRACE_ID_GLOBAL(trace_id_), ts); } - TRACE_EVENT_WITH_FLOW1("input,benchmark", "LatencyInfo.Flow", - TRACE_ID_GLOBAL(trace_id_), - TRACE_EVENT_FLAG_FLOW_OUT, "trace_id", trace_id_); + TRACE_EVENT("input,benchmark", "LatencyInfo.Flow", + [this](perfetto::EventContext ctx) { + ChromeLatencyInfo* info = + ctx.event()->set_chrome_latency_info(); + info->set_trace_id(trace_id_); + tracing::FillFlowEvent(ctx, TrackEvent::LegacyEvent::FLOW_OUT, + trace_id_); + }); } auto it = latency_components_.find(component); @@ -293,8 +309,14 @@ "data", AsTraceableData()); } - TRACE_EVENT_WITH_FLOW0("input,benchmark", "LatencyInfo.Flow", - TRACE_ID_GLOBAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN); + TRACE_EVENT("input,benchmark", "LatencyInfo.Flow", + [this](perfetto::EventContext ctx) { + ChromeLatencyInfo* info = + ctx.event()->set_chrome_latency_info(); + info->set_trace_id(trace_id_); + tracing::FillFlowEvent(ctx, TrackEvent::LegacyEvent::FLOW_IN, + trace_id_); + }); } void LatencyInfo::CoalesceScrollUpdateWith(const LatencyInfo& other) {
diff --git a/ui/latency/latency_info.h b/ui/latency/latency_info.h index 24322a0d..fb1a15a 100644 --- a/ui/latency/latency_info.h +++ b/ui/latency/latency_info.h
@@ -16,6 +16,7 @@ #include "base/containers/flat_map.h" #include "base/time/time.h" #include "services/metrics/public/cpp/ukm_source_id.h" +#include "third_party/perfetto/protos/perfetto/trace/track_event/chrome_latency_info.pbzero.h" #include "ui/gfx/geometry/point_f.h" #if !defined(OS_IOS) @@ -128,7 +129,7 @@ // Adds trace flow events only to LatencyInfos that are being traced. static void TraceIntermediateFlowEvents( const std::vector<LatencyInfo>& latency_info, - const char* trace_name); + perfetto::protos::pbzero::ChromeLatencyInfo::Step step); // Copy timestamp with type |type| from |other| into |this|. void CopyLatencyFrom(const LatencyInfo& other, LatencyComponentType type);
diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn index 054cd18..ac9538b 100644 --- a/ui/ozone/platform/wayland/BUILD.gn +++ b/ui/ozone/platform/wayland/BUILD.gn
@@ -22,6 +22,8 @@ "common/wayland_util.h", "gpu/drm_render_node_path_finder.cc", "gpu/drm_render_node_path_finder.h", + "gpu/gl_surface_egl_readback_wayland.cc", + "gpu/gl_surface_egl_readback_wayland.h", "gpu/gl_surface_wayland.cc", "gpu/gl_surface_wayland.h", "gpu/wayland_buffer_manager_gpu.cc",
diff --git a/ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.cc b/ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.cc new file mode 100644 index 0000000..700cb969 --- /dev/null +++ b/ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.cc
@@ -0,0 +1,178 @@ +// 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/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.h" + +#include "base/memory/shared_memory_mapping.h" +#include "base/memory/unsafe_shared_memory_region.h" +#include "base/numerics/checked_math.h" +#include "ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h" + +namespace ui { + +namespace { + +constexpr size_t kMaxBuffers = 2; + +constexpr size_t kBytesPerPixelBGRA = 4; + +} // namespace + +GLSurfaceEglReadbackWayland::PixelBuffer::PixelBuffer( + base::WritableSharedMemoryMapping shm_mapping, + uint32_t buffer_id) + : shm_mapping_(std::move(shm_mapping)), buffer_id_(buffer_id) {} + +GLSurfaceEglReadbackWayland::PixelBuffer::~PixelBuffer() = default; + +GLSurfaceEglReadbackWayland::GLSurfaceEglReadbackWayland( + gfx::AcceleratedWidget widget, + WaylandBufferManagerGpu* buffer_manager) + : PbufferGLSurfaceEGL(gfx::Size(1, 1)), + widget_(widget), + buffer_manager_(buffer_manager) { + buffer_manager_->RegisterSurface(widget_, this); +} + +void GLSurfaceEglReadbackWayland::Destroy() { + DestroyBuffers(); + buffer_manager_->UnregisterSurface(widget_); + + PbufferGLSurfaceEGL::Destroy(); +} + +bool GLSurfaceEglReadbackWayland::Resize(const gfx::Size& size, + float scale_factor, + const gfx::ColorSpace& color_space, + bool has_alpha) { + DestroyBuffers(); + + pending_frames_ = 0; + + if (!PbufferGLSurfaceEGL::Resize(size, scale_factor, color_space, has_alpha)) + return false; + + for (size_t i = 0; i < kMaxBuffers; ++i) { + base::CheckedNumeric<size_t> checked_length(size.width()); + checked_length *= size.height(); + checked_length *= kBytesPerPixelBGRA; + if (!checked_length.IsValid()) + return false; + + base::UnsafeSharedMemoryRegion shm_region = + base::UnsafeSharedMemoryRegion::Create(checked_length.ValueOrDie()); + if (!shm_region.IsValid()) + return false; + + auto shm_mapping = shm_region.Map(); + if (!shm_mapping.IsValid()) + return false; + + base::subtle::PlatformSharedMemoryRegion platform_shm = + base::UnsafeSharedMemoryRegion::TakeHandleForSerialization( + std::move(shm_region)); + base::subtle::ScopedFDPair fd_pair = platform_shm.PassPlatformHandle(); + + auto buffer_id = buffer_manager_->AllocateBufferID(); + available_buffers_.push_back( + std::make_unique<PixelBuffer>(std::move(shm_mapping), buffer_id)); + + buffer_manager_->CreateShmBasedBuffer( + std::move(fd_pair.fd), checked_length.ValueOrDie(), size, buffer_id); + } + + return true; +} + +bool GLSurfaceEglReadbackWayland::IsOffscreen() { + return false; +} + +bool GLSurfaceEglReadbackWayland::SupportsAsyncSwap() { + return true; +} + +gfx::SwapResult GLSurfaceEglReadbackWayland::SwapBuffers( + PresentationCallback callback) { + NOTREACHED(); + return gfx::SwapResult::SWAP_FAILED; +} + +void GLSurfaceEglReadbackWayland::SwapBuffersAsync( + SwapCompletionCallback completion_callback, + PresentationCallback presentation_callback) { + DCHECK(pending_frames_ < kMaxBuffers); + + // Increase pending frames number. + ++pending_frames_; + + completion_callbacks_.push_back(std::move(completion_callback)); + presentation_callbacks_.push_back(std::move(presentation_callback)); + + DCHECK(!available_buffers_.empty()); + in_flight_pixel_buffers_.push_back(std::move(available_buffers_.front())); + auto* next_buffer = in_flight_pixel_buffers_.back().get(); + available_buffers_.erase(available_buffers_.begin()); + + const gfx::Size size = GetSize(); + CHECK(next_buffer->shm_mapping_.memory()); + glReadPixels(0, 0, size.width(), size.height(), GL_BGRA, GL_UNSIGNED_BYTE, + next_buffer->shm_mapping_.memory()); + + buffer_manager_->CommitBuffer(widget_, next_buffer->buffer_id_, + {{0, 0}, size}); +} + +gfx::SurfaceOrigin GLSurfaceEglReadbackWayland::GetOrigin() const { + // GLSurfaceEglReadbackWayland's y-axis is flipped compare to GL - (0,0) is at + // top left corner. + return gfx::SurfaceOrigin::kTopLeft; +} + +GLSurfaceEglReadbackWayland::~GLSurfaceEglReadbackWayland() { + Destroy(); +} + +void GLSurfaceEglReadbackWayland::OnSubmission( + uint32_t buffer_id, + const gfx::SwapResult& swap_result) { + --pending_frames_; + + if (in_flight_pixel_buffers_.front()) { + if (displayed_buffer_) + available_buffers_.push_back(std::move(displayed_buffer_)); + displayed_buffer_ = std::move(in_flight_pixel_buffers_.front()); + DCHECK_EQ(displayed_buffer_->buffer_id_, buffer_id); + } + + in_flight_pixel_buffers_.pop_front(); + + DCHECK(!completion_callbacks_.empty()); + std::move(completion_callbacks_.front()).Run(swap_result, nullptr); + completion_callbacks_.erase(completion_callbacks_.begin()); +} + +void GLSurfaceEglReadbackWayland::OnPresentation( + uint32_t buffer_id, + const gfx::PresentationFeedback& feedback) { + DCHECK(!presentation_callbacks_.empty()); + std::move(presentation_callbacks_.front()).Run(feedback); + presentation_callbacks_.erase(presentation_callbacks_.begin()); +} + +void GLSurfaceEglReadbackWayland::DestroyBuffers() { + for (const auto& pixel_buffer : available_buffers_) + buffer_manager_->DestroyBuffer(widget_, pixel_buffer->buffer_id_); + for (const auto& pixel_buffer : in_flight_pixel_buffers_) + buffer_manager_->DestroyBuffer(widget_, pixel_buffer->buffer_id_); + + if (displayed_buffer_) + buffer_manager_->DestroyBuffer(widget_, displayed_buffer_->buffer_id_); + + available_buffers_.clear(); + in_flight_pixel_buffers_.clear(); + displayed_buffer_.reset(); +} + +} // namespace ui
diff --git a/ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.h b/ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.h new file mode 100644 index 0000000..de83a75 --- /dev/null +++ b/ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.h
@@ -0,0 +1,95 @@ +// 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_OZONE_PLATFORM_WAYLAND_GPU_GL_SURFACE_EGL_READBACK_WAYLAND_H_ +#define UI_OZONE_PLATFORM_WAYLAND_GPU_GL_SURFACE_EGL_READBACK_WAYLAND_H_ + +#include "base/containers/circular_deque.h" +#include "base/containers/flat_map.h" +#include "base/memory/shared_memory_mapping.h" +#include "ui/ozone/common/gl_surface_egl_readback.h" +#include "ui/ozone/platform/wayland/gpu/wayland_surface_gpu.h" + +namespace ui { + +class WaylandBufferManagerGpu; + +// GLSurface implementation that copies pixels from readback to shared memory +// and let Wayland compositor to present them. +class GLSurfaceEglReadbackWayland : public gl::PbufferGLSurfaceEGL, + public WaylandSurfaceGpu { + public: + GLSurfaceEglReadbackWayland(gfx::AcceleratedWidget widget, + WaylandBufferManagerGpu* buffer_manager); + GLSurfaceEglReadbackWayland(const GLSurfaceEglReadbackWayland&) = delete; + GLSurfaceEglReadbackWayland& operator=(const GLSurfaceEglReadbackWayland&) = + delete; + + // gl::GLSurface: + void Destroy() override; + bool Resize(const gfx::Size& size, + float scale_factor, + const gfx::ColorSpace& color_space, + bool has_alpha) override; + bool IsOffscreen() override; + gfx::SwapResult SwapBuffers(PresentationCallback callback) override; + bool SupportsAsyncSwap() override; + void SwapBuffersAsync(SwapCompletionCallback completion_callback, + PresentationCallback presentation_callback) override; + gfx::SurfaceOrigin GetOrigin() const override; + + private: + struct PixelBuffer { + PixelBuffer(base::WritableSharedMemoryMapping shm_mapping, + uint32_t buffer_id); + ~PixelBuffer(); + PixelBuffer(const PixelBuffer&) = delete; + PixelBuffer& operator=(const PixelBuffer&) = delete; + + // Shared memory mapping that readback pixels are written to so that Wayland + // is able to turn them in light. + base::WritableSharedMemoryMapping shm_mapping_; + + // The buffer id that corresponds to the |wl_buffer| created on the browser + // process side. + uint32_t buffer_id_ = 0; + }; + + ~GLSurfaceEglReadbackWayland() override; + + // WaylandSurfaceGpu: + void OnSubmission(uint32_t buffer_id, + const gfx::SwapResult& swap_result) override; + void OnPresentation(uint32_t buffer_id, + const gfx::PresentationFeedback& feedback) override; + + void DestroyBuffers(); + + // Widget of the window that this readback writes pixels to. + const gfx::AcceleratedWidget widget_; + + WaylandBufferManagerGpu* const buffer_manager_; + + // Size of the buffer. + gfx::Size size_; + + // Available pixel buffers based on shared memory. + std::vector<std::unique_ptr<PixelBuffer>> available_buffers_; + + // Displayed buffer that will become available after another buffer is + // submitted. + std::unique_ptr<PixelBuffer> displayed_buffer_; + + // Submitted buffers waiting to be displayed. + base::circular_deque<std::unique_ptr<PixelBuffer>> in_flight_pixel_buffers_; + + std::vector<SwapCompletionCallback> completion_callbacks_; + std::vector<PresentationCallback> presentation_callbacks_; + + size_t pending_frames_ = 0; +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_WAYLAND_GPU_GL_SURFACE_EGL_READBACK_WAYLAND_H_
diff --git a/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc b/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc index 9e11755..8611c123 100644 --- a/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc +++ b/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc
@@ -11,6 +11,7 @@ #include "ui/ozone/common/egl_util.h" #include "ui/ozone/common/gl_ozone_egl.h" #include "ui/ozone/platform/wayland/common/wayland_object.h" +#include "ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.h" #include "ui/ozone/platform/wayland/gpu/gl_surface_wayland.h" #include "ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h" #include "ui/ozone/platform/wayland/gpu/wayland_canvas_surface.h" @@ -77,10 +78,11 @@ scoped_refptr<gl::GLSurface> GLOzoneEGLWayland::CreateSurfacelessViewGLSurface( gfx::AcceleratedWidget window) { - // Only EGLGLES2 is supported with surfaceless view gl. - if (gl::GetGLImplementation() != gl::kGLImplementationEGLGLES2) - return nullptr; - + if (gl::GetGLImplementation() == gl::kGLImplementationSwiftShaderGL) { + return gl::InitializeGLSurface( + base::MakeRefCounted<GLSurfaceEglReadbackWayland>(window, + buffer_manager_)); + } else { #if defined(WAYLAND_GBM) // If there is a gbm device available, use surfaceless gl surface. if (!buffer_manager_->gbm_device()) @@ -90,6 +92,7 @@ #else return nullptr; #endif + } } scoped_refptr<gl::GLSurface> GLOzoneEGLWayland::CreateOffscreenGLSurface(