diff --git a/BUILD.gn b/BUILD.gn index 46462a3..86c82ac 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -81,8 +81,6 @@ "//services/service_manager/public/cpp", "//skia:skia_unittests", "//sql:sql_unittests", - "//third_party/angle/src/tests:angle_end2end_tests", - "//third_party/angle/src/tests:angle_white_box_tests", "//third_party/flatbuffers:flatbuffers_unittests", "//third_party/liburlpattern:liburlpattern_unittests", "//tools/binary_size:binary_size_trybot_py", @@ -192,6 +190,7 @@ "//mojo:mojo_unittests", "//net:net_perftests", "//storage:storage_unittests", + "//third_party/angle/src/tests:angle_end2end_tests", "//third_party/angle/src/tests:angle_unittests", "//third_party/blink/common:blink_common_unittests", "//third_party/blink/renderer/controller:blink_unittests", @@ -242,6 +241,7 @@ "//google_apis/gcm:mcs_probe", "//media/capture:capture_unittests", "//media/cast:cast_unittests", + "//third_party/angle/src/tests:angle_white_box_tests", "//third_party/catapult/telemetry:bitmaptools($host_toolchain)", ] } else if (is_ios) {
diff --git a/DEPS b/DEPS index 2ede054..fd61281 100644 --- a/DEPS +++ b/DEPS
@@ -203,7 +203,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': '43ed322b6a782285f8fcfbaadd3926c371c3a60b', + 'v8_revision': '724907341fdd1a17fced5758d13d736c3c19cc6b', # 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. @@ -211,7 +211,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': 'de32c3d2de006a2c8d2acfa829634fcf2d1564ab', + 'angle_revision': '7f0e7d0d262aa0ee71c862846c72f737cbbfca04', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -219,7 +219,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '84c7d11419c50573f3025beb6898391588a13321', + 'pdfium_revision': 'a3806cb359231cd0f4286a0982255ff3d2077b71', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -274,7 +274,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': 'd08c5531762807570b5a929d3496eae8632bf2b5', + 'devtools_frontend_revision': 'a60056fee789b9256679a8d1e60f00650303f9af', # 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. @@ -314,7 +314,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': 'ea26a8ce553fe2efa94830f3d7326072487bde3f', + 'dawn_revision': '2bd95f1cf45451119b6644e41919b7bef443d912', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -353,7 +353,7 @@ 'ukey2_revision': '0275885d8e6038c39b8a8ca55e75d1d4d1727f47', # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'tint_revision': '1d9935cf37fdd1b9eb18f3e41d6142a345bba4a6', + 'tint_revision': '987376cd21a8785c3e0b66bd6ba2052219400ab3', # TODO(crbug.com/941824): The values below need to be kept in sync # between //DEPS and //buildtools/DEPS, so if you're updating one, @@ -893,7 +893,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '82b992a1656d7d1cd0ee3cbea8ff609ffdfed380', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '59b0ce20d3e5a64cc0b233ea199f254b136ef7f2', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1556,7 +1556,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/linux-amd64', - 'version': 'SydJmfq0VW7jq5fTDGtIQ-7WoB0vNc-LJAi3Xd4fKvQC', + 'version': '_LOGbVhF_buvk7XI34hbaIYtgbUAkuiM0-VxgWcpwk4C', }, ], 'dep_type': 'cipd', @@ -1566,7 +1566,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/windows-amd64', - 'version': 'mvme2We4n3wONUhzQu6ATl9Ow4Fb4li6ET-Yhv7Ph3EC', + 'version': '4r6X5OSxy-ZDOlqtn41HMmKG2qlEfMNdLwpzyufLFzcC', }, ], 'dep_type': 'cipd', @@ -1576,7 +1576,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/mac-amd64', - 'version': 'oxKWG6EzN6FHwQ-4J6gUYMHuNuHyARpVl4EvirOsXSgC', + 'version': 'GMDKIbJ4mwbVXaPYncGej4OyIS1ZjiCVhESk0xO0fVMC', }, ], 'dep_type': 'cipd', @@ -1590,7 +1590,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@6f7379c80b03c2f1aac2182807e684f7694accbd', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@aa6859ae90565a98ff34356f00dac4291b91ed57', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java index 1602f4b..6acecc8 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java
@@ -490,6 +490,11 @@ return mDisabled; } + @Override + public boolean isAwGCurrentAutofillService() { + return sIsAwGCurrentAutofillService; + } + public boolean isQuerySucceed() { return mQuerySucceed; } @@ -584,6 +589,7 @@ private static final int TOTAL_CONTROLS = 1; // text1 public static final int NO_FORM_SUBMISSION = -1; + public static final int NO_RECORD = -1; private int mCnt; private AwAutofillTest mTest; @@ -596,8 +602,16 @@ private MetricsUtils.HistogramDelta mUserChangedNonAutofilledField; private MetricsUtils.HistogramDelta mAutofillWebViewCreatedByActivityContext; private MetricsUtils.HistogramDelta mAutofillWebViewCreatedByAppContext; + private MetricsUtils.HistogramDelta mAutofillHasInvalidServerPrediction; + private MetricsUtils.HistogramDelta mAutofillHasValidServerPrediction; + private MetricsUtils.HistogramDelta mAwGIsCurrentService; + private MetricsUtils.HistogramDelta mAwGIsNotCurrentService; private volatile Integer mSourceValue; + private volatile Integer mServerPredictionAvailabilityValue; + private volatile Integer mAwGSuggestionAvailabilityValue; private HashMap<MetricsUtils.HistogramDelta, Integer> mSubmissionSourceDelta; + private HashMap<MetricsUtils.HistogramDelta, Integer> mServerPredictionAvailablityDelta; + private HashMap<MetricsUtils.HistogramDelta, Integer> mAwGSuggestionAvailablityDelta; private volatile Integer mHistogramSimpleCount; public AwAutofillSessionUMATestHelper(AwAutofillTest test, TestWebServer webServer) { @@ -608,25 +622,44 @@ public int getSessionValue() { TestThreadUtils.runOnUiThreadBlocking( - () -> { mSessionValue = getUMAEnumerateValue(mSessionDelta); }); + () -> { mSessionValue = getUMAEnumerateValue(mSessionDelta, null); }); return mSessionValue; } public int getSubmissionSourceValue() { - TestThreadUtils.runOnUiThreadBlocking( - () -> { mSourceValue = getUMAEnumerateValue(mSubmissionSourceDelta); }); + TestThreadUtils.runOnUiThreadBlocking(() -> { + mSourceValue = getUMAEnumerateValue(mSubmissionSourceDelta, NO_FORM_SUBMISSION); + }); return mSourceValue; } - private int getUMAEnumerateValue(HashMap<MetricsUtils.HistogramDelta, Integer> deltas) { - int value = NO_FORM_SUBMISSION; + public int getServerPredictionAvailabilityValue() { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mServerPredictionAvailabilityValue = + getUMAEnumerateValue(mServerPredictionAvailablityDelta, null); + }); + return mServerPredictionAvailabilityValue; + } + + public int getAwGSuggestionAvailabilityValue() { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mAwGSuggestionAvailabilityValue = + getUMAEnumerateValue(mAwGSuggestionAvailablityDelta, NO_RECORD); + }); + return mAwGSuggestionAvailabilityValue; + } + + private int getUMAEnumerateValue( + HashMap<MetricsUtils.HistogramDelta, Integer> deltas, Integer defaultValue) { + Integer value = null; for (MetricsUtils.HistogramDelta delta : deltas.keySet()) { if (delta.getDelta() != 0) { - assertEquals(NO_FORM_SUBMISSION, value); + assertNull(value); value = deltas.get(delta); } } - return value; + if (defaultValue == null) assertNotNull(value); + return value != null ? value : defaultValue; } public void triggerAutofill() throws Throwable { @@ -639,6 +672,27 @@ AUTOFILL_VALUE_CHANGED}); } + public void simulateServerPredictionBeforeTriggeringAutofill(int serverType) + throws Throwable { + final String url = mWebServer.setResponse(FILE, DATA, null); + mTest.loadUrlSync(url); + simulateServerPrediction(serverType); + mTest.executeJavaScriptAndWaitForResult("document.getElementById('text1').select();"); + mTest.dispatchDownAndUpKeyEvents(KeyEvent.KEYCODE_A); + mCnt += mTest.waitForCallbackAndVerifyTypes(mCnt, + new Integer[] {AUTOFILL_CANCEL, AUTOFILL_VIEW_ENTERED, AUTOFILL_SESSION_STARTED, + AUTOFILL_VALUE_CHANGED}); + } + + public void simulateServerPrediction(int serverType) throws Throwable { + TestThreadUtils.runOnUiThreadBlocking( + () + -> AutofillProviderTestHelper + .simulateMainFrameAutofillServerResponseForTesting( + mTest.mAwContents.getWebContents(), + new String[] {"text1"}, new int[] {serverType})); + } + public void simulateUserSelectSuggestion() throws Throwable { // Simulate user select suggestion TestViewStructure viewStructure = mTest.mTestValues.testViewStructure; @@ -701,6 +755,23 @@ AutofillProviderUMA.UMA_AUTOFILL_SUBMISSION_SOURCE, i), i); } + mServerPredictionAvailablityDelta = + new HashMap<MetricsUtils.HistogramDelta, Integer>(); + for (int i = 0; i < AutofillProviderUMA.SERVER_PREDICTION_AVAILABLE_COUNT; i++) { + mServerPredictionAvailablityDelta.put( + new MetricsUtils.HistogramDelta( + AutofillProviderUMA.UMA_AUTOFILL_SERVER_PREDICTION_AVAILABILITY, + i), + i); + } + mAwGSuggestionAvailablityDelta = + new HashMap<MetricsUtils.HistogramDelta, Integer>(); + for (int i = 0; i < AutofillProviderUMA.AWG_SUGGSTION_AVAILABLE_COUNT; i++) { + mAwGSuggestionAvailablityDelta.put( + new MetricsUtils.HistogramDelta( + AutofillProviderUMA.UMA_AUTOFILL_AWG_SUGGSTION_AVAILABILITY, i), + i); + } mAutofillWebViewViewEnabled = new MetricsUtils.HistogramDelta( AutofillProviderUMA.UMA_AUTOFILL_ENABLED, 1 /*true*/); mAutofillWebViewViewDisabled = new MetricsUtils.HistogramDelta( @@ -713,7 +784,15 @@ AutofillProviderUMA.UMA_AUTOFILL_USER_CHANGED_AUTOFILLED_FIELD, 1 /*true*/); mUserChangedNonAutofilledField = new MetricsUtils.HistogramDelta( AutofillProviderUMA.UMA_AUTOFILL_USER_CHANGED_AUTOFILLED_FIELD, - 0 /*falsTe*/); + 0 /*false*/); + mAutofillHasInvalidServerPrediction = new MetricsUtils.HistogramDelta( + AutofillProviderUMA.UMA_AUTOFILL_VALID_SERVER_PREDICTION, 0 /*false*/); + mAutofillHasValidServerPrediction = new MetricsUtils.HistogramDelta( + AutofillProviderUMA.UMA_AUTOFILL_VALID_SERVER_PREDICTION, 1 /*true*/); + mAwGIsNotCurrentService = new MetricsUtils.HistogramDelta( + AutofillProviderUMA.UMA_AUTOFILL_AWG_IS_CURRENT_SERVICE, 0 /*false*/); + mAwGIsCurrentService = new MetricsUtils.HistogramDelta( + AutofillProviderUMA.UMA_AUTOFILL_AWG_IS_CURRENT_SERVICE, 1 /*true*/); }); } @@ -739,6 +818,20 @@ }); } + public void verifyAwGIsCurrentService(boolean current) { + TestThreadUtils.runOnUiThreadBlocking(() -> { + assertEquals(current ? 0 : 1, mAwGIsNotCurrentService.getDelta()); + assertEquals(current ? 1 : 0, mAwGIsCurrentService.getDelta()); + }); + } + + public void verifyServerPredictionValid(boolean valid) { + TestThreadUtils.runOnUiThreadBlocking(() -> { + assertEquals(valid ? 0 : 1, mAutofillHasInvalidServerPrediction.getDelta()); + assertEquals(valid ? 1 : 0, mAutofillHasValidServerPrediction.getDelta()); + }); + } + public void verifyUserChangedAutofilledField() { TestThreadUtils.runOnUiThreadBlocking(() -> { assertEquals(0, mUserChangedNonAutofilledField.getDelta()); @@ -770,6 +863,8 @@ } } + private static boolean sIsAwGCurrentAutofillService = true; + @Rule public AwActivityTestRule mRule = new AwActivityTestRule(); @@ -805,6 +900,13 @@ AwActivityTestRule.enableJavaScriptOnUiThread(mAwContents); } + public void setUpAwGNotCurrent() throws Exception { + sIsAwGCurrentAutofillService = false; + mWebServer.shutdown(); + // Initialize everything again. + setUp(); + } + @After public void tearDown() { mWebServer.shutdown(); @@ -1637,6 +1739,8 @@ mUMATestHelper.getSessionValue()); assertEquals( AutofillProviderUMA.FORM_SUBMISSION, mUMATestHelper.getSubmissionSourceValue()); + assertEquals(AutofillProviderUMA.AWG_HAS_SUGGESTION_AUTOFILLED, + mUMATestHelper.getAwGSuggestionAvailabilityValue()); } @Test @@ -1653,6 +1757,8 @@ mUMATestHelper.getSessionValue()); assertEquals(AwAutofillSessionUMATestHelper.NO_FORM_SUBMISSION, mUMATestHelper.getSubmissionSourceValue()); + assertEquals(AwAutofillSessionUMATestHelper.NO_RECORD, + mUMATestHelper.getAwGSuggestionAvailabilityValue()); } @Test @@ -1674,6 +1780,8 @@ assertEquals(count + 1, mUMATestHelper.getHistogramSampleCount( AutofillProviderUMA.UMA_AUTOFILL_SUGGESTION_TIME)); + assertEquals(AwAutofillSessionUMATestHelper.NO_RECORD, + mUMATestHelper.getAwGSuggestionAvailabilityValue()); } @Test @@ -1689,6 +1797,8 @@ mUMATestHelper.getSessionValue()); assertEquals( AutofillProviderUMA.FORM_SUBMISSION, mUMATestHelper.getSubmissionSourceValue()); + assertEquals(AutofillProviderUMA.AWG_HAS_SUGGESTION_NO_AUTOFILL, + mUMATestHelper.getAwGSuggestionAvailabilityValue()); } @Test @@ -1704,6 +1814,8 @@ assertEquals(AwAutofillSessionUMATestHelper.NO_FORM_SUBMISSION, mUMATestHelper.getSubmissionSourceValue()); mUMATestHelper.verifyUserChangedNonAutofilledField(); + assertEquals(AwAutofillSessionUMATestHelper.NO_RECORD, + mUMATestHelper.getAwGSuggestionAvailabilityValue()); } @Test @@ -1719,6 +1831,8 @@ assertEquals( AutofillProviderUMA.FORM_SUBMISSION, mUMATestHelper.getSubmissionSourceValue()); mUMATestHelper.verifyUserChangedNonAutofilledField(); + assertEquals(AutofillProviderUMA.AWG_NO_SUGGESTION, + mUMATestHelper.getAwGSuggestionAvailabilityValue()); } @Test @@ -1735,6 +1849,8 @@ assertEquals( AutofillProviderUMA.FORM_SUBMISSION, mUMATestHelper.getSubmissionSourceValue()); mUMATestHelper.verifyUserDidntChangeForm(); + assertEquals(AutofillProviderUMA.AWG_HAS_SUGGESTION_AUTOFILLED, + mUMATestHelper.getAwGSuggestionAvailabilityValue()); } @Test @@ -1752,12 +1868,14 @@ assertEquals(AwAutofillSessionUMATestHelper.NO_FORM_SUBMISSION, mUMATestHelper.getSubmissionSourceValue()); mUMATestHelper.verifyUserDidntChangeForm(); + assertEquals(AwAutofillSessionUMATestHelper.NO_RECORD, + mUMATestHelper.getAwGSuggestionAvailabilityValue()); } @Test @SmallTest @Feature({"AndroidWebView"}) - public void testUMAUserSelectNotSuggestionUserNotChangeFormNoFormSubmitted() throws Throwable { + public void testUMAUserNotSelectSuggestionUserNotChangeFormNoFormSubmitted() throws Throwable { mUMATestHelper.triggerAutofill(); invokeOnProvideAutoFillVirtualStructure(); invokeOnInputUIShown(); @@ -1768,6 +1886,8 @@ assertEquals(AwAutofillSessionUMATestHelper.NO_FORM_SUBMISSION, mUMATestHelper.getSubmissionSourceValue()); mUMATestHelper.verifyUserDidntChangeForm(); + assertEquals(AwAutofillSessionUMATestHelper.NO_RECORD, + mUMATestHelper.getAwGSuggestionAvailabilityValue()); } @Test @@ -1784,6 +1904,8 @@ assertEquals( AutofillProviderUMA.FORM_SUBMISSION, mUMATestHelper.getSubmissionSourceValue()); mUMATestHelper.verifyUserDidntChangeForm(); + assertEquals(AutofillProviderUMA.AWG_HAS_SUGGESTION_NO_AUTOFILL, + mUMATestHelper.getAwGSuggestionAvailabilityValue()); } @Test @@ -1798,6 +1920,8 @@ assertEquals(AwAutofillSessionUMATestHelper.NO_FORM_SUBMISSION, mUMATestHelper.getSubmissionSourceValue()); mUMATestHelper.verifyUserDidntChangeForm(); + assertEquals(AwAutofillSessionUMATestHelper.NO_RECORD, + mUMATestHelper.getAwGSuggestionAvailabilityValue()); } @Test @@ -1812,6 +1936,8 @@ assertEquals( AutofillProviderUMA.FORM_SUBMISSION, mUMATestHelper.getSubmissionSourceValue()); mUMATestHelper.verifyUserDidntChangeForm(); + assertEquals(AutofillProviderUMA.AWG_NO_SUGGESTION, + mUMATestHelper.getAwGSuggestionAvailabilityValue()); } @Test @@ -1829,6 +1955,59 @@ @Test @SmallTest @Feature({"AndroidWebView"}) + @MinAndroidSdkLevel(Build.VERSION_CODES.P) + public void testUMAAwGIsCurrentService() throws Throwable { + mUMATestHelper.triggerAutofill(); + mUMATestHelper.verifyAwGIsCurrentService(/*current=*/true); + } + + @Test + @SmallTest + @Feature({"AndroidWebView"}) + @MinAndroidSdkLevel(Build.VERSION_CODES.P) + public void testUMAAwGIsNotCurrentService() throws Throwable { + setUpAwGNotCurrent(); + mUMATestHelper.triggerAutofill(); + mUMATestHelper.verifyAwGIsCurrentService(/*current=*/false); + } + + @Test + @SmallTest + @Feature({"AndroidWebView"}) + @CommandLineFlags.Add({"enable-features=AndroidAutofillQueryServerFieldTypes"}) + public void testUMANoServerPrediction() throws Throwable { + mUMATestHelper.triggerAutofill(); + mUMATestHelper.startNewSession(); + assertEquals(AutofillProviderUMA.SERVER_PREDICTION_NOT_AVAILABLE, + mUMATestHelper.getServerPredictionAvailabilityValue()); + } + + @Test + @SmallTest + @Feature({"AndroidWebView"}) + @CommandLineFlags.Add({"enable-features=AndroidAutofillQueryServerFieldTypes"}) + public void testUMAServerPredictionArriveBeforeSessionStart() throws Throwable { + mUMATestHelper.simulateServerPredictionBeforeTriggeringAutofill(/*USERNAME*/ 86); + assertEquals(AutofillProviderUMA.SERVER_PREDICTION_AVAILABLE_ON_SESSION_STARTS, + mUMATestHelper.getServerPredictionAvailabilityValue()); + mUMATestHelper.verifyServerPredictionValid(true); + } + + @Test + @SmallTest + @Feature({"AndroidWebView"}) + @CommandLineFlags.Add({"enable-features=AndroidAutofillQueryServerFieldTypes"}) + public void testUMAServerPredictionArriveAfterSessionStart() throws Throwable { + mUMATestHelper.triggerAutofill(); + mUMATestHelper.simulateServerPrediction(/*NO_SERVER_DATA*/ 0); + assertEquals(AutofillProviderUMA.SERVER_PREDICTION_AVAILABLE_AFTER_SESSION_STARTS, + mUMATestHelper.getServerPredictionAvailabilityValue()); + mUMATestHelper.verifyServerPredictionValid(false); + } + + @Test + @SmallTest + @Feature({"AndroidWebView"}) public void testUMAAutofillDisabled() throws Throwable { mTestAutofillManagerWrapper.setDisabled(); mUMATestHelper.triggerAutofill();
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 869928b..e75705e2 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -2249,6 +2249,7 @@ "system/session/logout_confirmation_controller_unittest.cc", "system/session/session_limit_notification_controller_unittest.cc", "system/status_area_widget_unittest.cc", + "system/time/time_tray_item_view_unittest.cc", "system/time/time_view_unittest.cc", "system/toast/toast_manager_unittest.cc", "system/tracing_notification_controller_unittest.cc",
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index a8cf9de..50a0573 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -933,6 +933,9 @@ <message name="IDS_ASH_STATUS_TRAY_DATE" desc="The date displayed on ash system bubble, Depending on launguage, please choose the best separator(eg ',') between abbreviated weekday and date"> <ph name="short_weekday">$1<ex>Fri</ex></ph>, <ph name="date">$2<ex>Aug 31, 2012</ex></ph> </message> + <message name="IDS_ASH_STATUS_TRAY_DATE_TIME" desc="The time displayed on ash system tray, Depending on launguage, please choose the best separator(eg ',') between abbreviated date and time"> + <ph name="date">$1<ex>Aug 31</ex></ph>, <ph name="time">$2<ex>03:00</ex></ph> + </message> <message name="IDS_ASH_STATUS_TRAY_REBOOT" desc="The accessible text for the reboot button."> Restart </message>
diff --git a/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_DATE_TIME.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_DATE_TIME.png.sha1 new file mode 100644 index 0000000..41a5ada1 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_DATE_TIME.png.sha1
@@ -0,0 +1 @@ +56b9ecb9b85721cdee47f52a37df3dcd4f6867a5 \ No newline at end of file
diff --git a/ash/ime/ime_mode_indicator_view.cc b/ash/ime/ime_mode_indicator_view.cc index a5a6d2ec..b6402b58 100644 --- a/ash/ime/ime_mode_indicator_view.cc +++ b/ash/ime/ime_mode_indicator_view.cc
@@ -14,6 +14,7 @@ #include "ui/views/bubble/bubble_frame_view.h" #include "ui/views/controls/label.h" #include "ui/views/layout/fill_layout.h" +#include "ui/views/metadata/metadata_impl_macros.h" #include "ui/wm/core/window_animations.h" namespace ash { @@ -29,8 +30,12 @@ class ModeIndicatorFrameView : public views::BubbleFrameView { public: + METADATA_HEADER(ModeIndicatorFrameView); + explicit ModeIndicatorFrameView() : views::BubbleFrameView(gfx::Insets(), gfx::Insets()) {} + ModeIndicatorFrameView(const ModeIndicatorFrameView&) = delete; + ModeIndicatorFrameView& operator=(const ModeIndicatorFrameView&) = delete; ~ModeIndicatorFrameView() override {} private: @@ -40,10 +45,11 @@ ->GetDisplayNearestPoint(rect.CenterPoint()) .bounds(); } - - DISALLOW_COPY_AND_ASSIGN(ModeIndicatorFrameView); }; +BEGIN_METADATA(ModeIndicatorFrameView, views::BubbleFrameView) +END_METADATA + } // namespace ImeModeIndicatorView::ImeModeIndicatorView(const gfx::Rect& cursor_bounds, @@ -84,10 +90,6 @@ return size; } -const char* ImeModeIndicatorView::GetClassName() const { - return "ImeModeIndicatorView"; -} - void ImeModeIndicatorView::Init() { SetLayoutManager(std::make_unique<views::FillLayout>()); AddChildView(label_view_); @@ -105,4 +107,7 @@ return frame; } +BEGIN_METADATA(ImeModeIndicatorView, views::BubbleDialogDelegateView) +END_METADATA + } // namespace ash
diff --git a/ash/ime/ime_mode_indicator_view.h b/ash/ime/ime_mode_indicator_view.h index e4b68c1..2208a09 100644 --- a/ash/ime/ime_mode_indicator_view.h +++ b/ash/ime/ime_mode_indicator_view.h
@@ -11,6 +11,7 @@ #include "base/timer/timer.h" #include "ui/gfx/geometry/rect.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" +#include "ui/views/metadata/metadata_header_macros.h" #include "ui/views/widget/widget.h" namespace views { @@ -23,9 +24,13 @@ // Dvorak) after switching IMEs with an accelerator (e.g. Ctrl-Space). class ASH_EXPORT ImeModeIndicatorView : public views::BubbleDialogDelegateView { public: + METADATA_HEADER(ImeModeIndicatorView); + // The cursor bounds is in the universal screen coordinates in DIP. ImeModeIndicatorView(const gfx::Rect& cursor_bounds, const base::string16& label); + ImeModeIndicatorView(const ImeModeIndicatorView&) = delete; + ImeModeIndicatorView& operator=(const ImeModeIndicatorView&) = delete; ~ImeModeIndicatorView() override; // Show the mode indicator then hide with fading animation. @@ -35,7 +40,6 @@ void OnBeforeBubbleWidgetInit(views::Widget::InitParams* params, views::Widget* widget) const override; gfx::Size CalculatePreferredSize() const override; - const char* GetClassName() const override; void Init() override; protected: @@ -47,8 +51,6 @@ gfx::Rect cursor_bounds_; views::Label* label_view_; base::OneShotTimer timer_; - - DISALLOW_COPY_AND_ASSIGN(ImeModeIndicatorView); }; } // namespace ash
diff --git a/ash/public/cpp/ash_features.cc b/ash/public/cpp/ash_features.cc index 769d3b0f..7dc4fd3 100644 --- a/ash/public/cpp/ash_features.cc +++ b/ash/public/cpp/ash_features.cc
@@ -143,6 +143,9 @@ const base::Feature kDragUnpinnedAppToPin{"DragUnpinnedAppToPin", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kScalableStatusArea{"ScalableStatusArea", + base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kKeyboardBasedDisplayArrangementInSettings{ "KeyboardBasedDisplayArrangementInSettings", base::FEATURE_ENABLED_BY_DEFAULT}; @@ -321,6 +324,10 @@ return base::FeatureList::IsEnabled(kDragUnpinnedAppToPin); } +bool IsScalableStatusAreaEnabled() { + return base::FeatureList::IsEnabled(kScalableStatusArea); +} + namespace { // The boolean flag indicating if "WebUITabStrip" feature is enabled in Chrome.
diff --git a/ash/public/cpp/ash_features.h b/ash/public/cpp/ash_features.h index d7ab211..2c477c3 100644 --- a/ash/public/cpp/ash_features.h +++ b/ash/public/cpp/ash_features.h
@@ -194,6 +194,9 @@ // Enables dragging an unpinned open app to pinned app side to pin. ASH_PUBLIC_EXPORT extern const base::Feature kDragUnpinnedAppToPin; +// Enables the system tray to show more information in larger screen. +ASH_PUBLIC_EXPORT extern const base::Feature kScalableStatusArea; + ASH_PUBLIC_EXPORT bool IsAllowAmbientEQEnabled(); ASH_PUBLIC_EXPORT bool IsAltTabLimitedToActiveDesk(); @@ -274,6 +277,8 @@ ASH_PUBLIC_EXPORT bool IsDragUnpinnedAppToPinEnabled(); +ASH_PUBLIC_EXPORT bool IsScalableStatusAreaEnabled(); + // These two functions are supposed to be temporary functions to set or get // whether "WebUITabStrip" feature is enabled from Chrome. ASH_PUBLIC_EXPORT void SetWebUITabStripEnabled(bool enabled);
diff --git a/ash/system/time/time_tray_item_view.cc b/ash/system/time/time_tray_item_view.cc index 2f77e16..1567031 100644 --- a/ash/system/time/time_tray_item_view.cc +++ b/ash/system/time/time_tray_item_view.cc
@@ -4,6 +4,7 @@ #include "ash/system/time/time_tray_item_view.h" +#include "ash/public/cpp/ash_features.h" #include "ash/session/session_controller_impl.h" #include "ash/shelf/shelf.h" #include "ash/shell.h" @@ -16,14 +17,18 @@ namespace tray { -TimeTrayItemView::TimeTrayItemView(Shelf* shelf) - : TrayItemView(shelf), session_observer_(this) { +TimeTrayItemView::TimeTrayItemView(Shelf* shelf, UnifiedSystemTrayModel* model) + : TrayItemView(shelf), model_(model), session_observer_(this) { + system_tray_model_observation_.Observe(model_); + TimeView::ClockLayout clock_layout = shelf->IsHorizontalAlignment() ? TimeView::ClockLayout::HORIZONTAL_CLOCK : TimeView::ClockLayout::VERTICAL_CLOCK; time_view_ = new TimeView(clock_layout, Shell::Get()->system_tray_model()->clock()); AddChildView(time_view_); + + OnSystemTrayButtonSizeChanged(model_->GetSystemTrayButtonSize()); } TimeTrayItemView::~TimeTrayItemView() = default; @@ -44,6 +49,17 @@ time_view_->SetTextColor(TrayIconColor(state)); } +void TimeTrayItemView::OnSystemTrayButtonSizeChanged( + UnifiedSystemTrayModel::SystemTrayButtonSize system_tray_size) { + time_view_->SetShowDateWhenHorizontal( + features::IsScalableStatusAreaEnabled() && + system_tray_size == UnifiedSystemTrayModel::SystemTrayButtonSize::kLarge); +} + +void TimeTrayItemView::Reset() { + system_tray_model_observation_.Reset(); +} + const char* TimeTrayItemView::GetClassName() const { return "TimeTrayItemView"; }
diff --git a/ash/system/time/time_tray_item_view.h b/ash/system/time/time_tray_item_view.h index d1c29ae..ea190f6 100644 --- a/ash/system/time/time_tray_item_view.h +++ b/ash/system/time/time_tray_item_view.h
@@ -8,7 +8,9 @@ #include "ash/ash_export.h" #include "ash/public/cpp/session/session_observer.h" #include "ash/system/tray/tray_item_view.h" +#include "ash/system/unified/unified_system_tray_model.h" #include "base/macros.h" +#include "base/scoped_observation.h" namespace ash { class Shelf; @@ -17,9 +19,11 @@ class TimeView; -class TimeTrayItemView : public TrayItemView, public SessionObserver { +class ASH_EXPORT TimeTrayItemView : public TrayItemView, + public SessionObserver, + public UnifiedSystemTrayModel::Observer { public: - explicit TimeTrayItemView(Shelf* shelf); + TimeTrayItemView(Shelf* shelf, UnifiedSystemTrayModel* model); ~TimeTrayItemView() override; void UpdateAlignmentForShelf(Shelf* shelf); @@ -31,13 +35,26 @@ // SessionObserver: void OnSessionStateChanged(session_manager::SessionState state) override; + // UnifiedSystemTrayModel::Observer: + void OnSystemTrayButtonSizeChanged( + UnifiedSystemTrayModel::SystemTrayButtonSize system_tray_size) override; + + // Reset the view by removing observer to |model_|. + void Reset(); + // views::View: const char* GetClassName() const override; void OnThemeChanged() override; private: + friend class TimeTrayItemViewTest; + + UnifiedSystemTrayModel* model_ = nullptr; TimeView* time_view_ = nullptr; ScopedSessionObserver session_observer_; + base::ScopedObservation<UnifiedSystemTrayModel, + UnifiedSystemTrayModel::Observer> + system_tray_model_observation_{this}; DISALLOW_COPY_AND_ASSIGN(TimeTrayItemView); };
diff --git a/ash/system/time/time_tray_item_view_unittest.cc b/ash/system/time/time_tray_item_view_unittest.cc new file mode 100644 index 0000000..93c84cb5 --- /dev/null +++ b/ash/system/time/time_tray_item_view_unittest.cc
@@ -0,0 +1,97 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/system/time/time_tray_item_view.h" + +#include "ash/public/cpp/ash_features.h" +#include "ash/shelf/shelf.h" +#include "ash/system/time/time_view.h" +#include "ash/system/unified/unified_system_tray_model.h" +#include "ash/test/ash_test_base.h" +#include "base/test/scoped_feature_list.h" + +namespace ash { +namespace tray { + +class TimeTrayItemViewTest : public AshTestBase, + public testing::WithParamInterface<bool> { + public: + TimeTrayItemViewTest() = default; + ~TimeTrayItemViewTest() override = default; + + // AshTestBase: + void SetUp() override { + AshTestBase::SetUp(); + scoped_feature_list_.InitWithFeatureState( + features::kScalableStatusArea, is_scalable_status_area_enabled()); + + model_ = std::make_unique<UnifiedSystemTrayModel>(GetPrimaryShelf()); + time_tray_item_view_ = + std::make_unique<TimeTrayItemView>(GetPrimaryShelf(), model_.get()); + } + + void TearDown() override { + time_tray_item_view_.reset(); + model_.reset(); + AshTestBase::TearDown(); + } + + bool is_scalable_status_area_enabled() { return GetParam(); } + + // Returns true if the time view is in horizontal layout, false if it is in + // vertical layout. + bool IsTimeViewInHorizontalLayout() { + // Time view is in horizontal layout if its subview is in use (it transfers + // the ownership to the views hierarchy and becomes nullptr), + return !time_tray_item_view_->time_view_->horizontal_view_; + } + + bool ShouldShowDateInTimeView() { + return time_tray_item_view_->time_view_->show_date_when_horizontal_; + } + + protected: + base::test::ScopedFeatureList scoped_feature_list_; + std::unique_ptr<UnifiedSystemTrayModel> model_; + std::unique_ptr<TimeTrayItemView> time_tray_item_view_; +}; + +INSTANTIATE_TEST_SUITE_P(All, + TimeTrayItemViewTest, + testing::Bool() /* is_scalable_status_area_enabled */); + +TEST_P(TimeTrayItemViewTest, ShelfAlignment) { + // The tray should show time horizontal view when the shelf is bottom. + GetPrimaryShelf()->SetAlignment(ShelfAlignment::kBottom); + time_tray_item_view_->UpdateAlignmentForShelf(GetPrimaryShelf()); + EXPECT_TRUE(IsTimeViewInHorizontalLayout()); + + // The tray should show time vertical view when the shelf is left or right. + GetPrimaryShelf()->SetAlignment(ShelfAlignment::kLeft); + time_tray_item_view_->UpdateAlignmentForShelf(GetPrimaryShelf()); + EXPECT_FALSE(IsTimeViewInHorizontalLayout()); + + GetPrimaryShelf()->SetAlignment(ShelfAlignment::kRight); + time_tray_item_view_->UpdateAlignmentForShelf(GetPrimaryShelf()); + EXPECT_FALSE(IsTimeViewInHorizontalLayout()); + + // The tray should show time horizontal view when switching back to bottom + // shelf. + GetPrimaryShelf()->SetAlignment(ShelfAlignment::kBottom); + time_tray_item_view_->UpdateAlignmentForShelf(GetPrimaryShelf()); + EXPECT_TRUE(IsTimeViewInHorizontalLayout()); +} + +TEST_P(TimeTrayItemViewTest, DisplayChanged) { + UpdateDisplay("800x800"); + EXPECT_FALSE(ShouldShowDateInTimeView()); + + // Date should be shown in large screen size (when scalable status area is + // enabled). + UpdateDisplay("1680x800"); + EXPECT_EQ(is_scalable_status_area_enabled(), ShouldShowDateInTimeView()); +} + +} // namespace tray +} // namespace ash
diff --git a/ash/system/time/time_view.cc b/ash/system/time/time_view.cc index d91137ad..3fcc448 100644 --- a/ash/system/time/time_view.cc +++ b/ash/system/time/time_view.cc
@@ -54,6 +54,12 @@ // when the shelf is vertically aligned. const int kClockLeadingPadding = 8; +base::string16 FormatDate(const base::Time& time) { + // Use 'short' month format (e.g., "Oct") followed by non-padded day of + // month (e.g., "2", "10"). + return base::TimeFormatWithPattern(time, "LLLd"); +} + } // namespace TimeView::TimeView(ClockLayout clock_layout, ClockModel* model) @@ -112,6 +118,14 @@ vertical_label_minutes_->SetShadows(shadows); } +void TimeView::SetShowDateWhenHorizontal(bool show_date_when_horizontal) { + if (show_date_when_horizontal_ == show_date_when_horizontal) + return; + show_date_when_horizontal_ = show_date_when_horizontal; + UpdateText(); + PreferredSizeChanged(); +} + void TimeView::OnDateFormatChanged() { UpdateTimeFormat(); } @@ -189,7 +203,11 @@ base::string16 current_time = base::TimeFormatTimeOfDayWithHourClockType( now, model_->hour_clock_type(), base::kDropAmPm); - horizontal_label_->SetText(current_time); + base::string16 current_date_time = l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_DATE_TIME, FormatDate(now), current_time); + + horizontal_label_->SetText(show_date_when_horizontal_ ? current_date_time + : current_time); horizontal_label_->SetTooltipText(base::TimeFormatFriendlyDate(now)); horizontal_label_->NotifyAccessibilityEvent(ax::mojom::Event::kTextChanged, true);
diff --git a/ash/system/time/time_view.h b/ash/system/time/time_view.h index 576de84..550b1a7 100644 --- a/ash/system/time/time_view.h +++ b/ash/system/time/time_view.h
@@ -56,6 +56,9 @@ // Updates the time text shadow values. void SetTextShadowValues(const gfx::ShadowValues& shadows); + // Shows the date in horizontal view when |show_date_when_horizontal| is true. + void SetShowDateWhenHorizontal(bool show_date_when_horizontal); + // ClockObserver: void OnDateFormatChanged() override; void OnSystemClockTimeUpdated() override; @@ -69,6 +72,7 @@ private: friend class TimeViewTest; + friend class TimeTrayItemViewTest; // ActionableView: bool PerformAction(const ui::Event& event) override; @@ -107,6 +111,9 @@ views::Label* vertical_label_hours_; views::Label* vertical_label_minutes_; + // Indicates if date should be show in horizontal view. + bool show_date_when_horizontal_ = false; + // Invokes UpdateText() when the displayed time should change. base::OneShotTimer timer_;
diff --git a/ash/system/time/time_view_unittest.cc b/ash/system/time/time_view_unittest.cc index b764b0b0..803a54a 100644 --- a/ash/system/time/time_view_unittest.cc +++ b/ash/system/time/time_view_unittest.cc
@@ -76,5 +76,29 @@ EXPECT_FALSE(vertical_view()->parent()); } +// Test the show date mode in the time view. +TEST_F(TimeViewTest, ShowDateMode) { + CreateTimeView(TimeView::ClockLayout::HORIZONTAL_CLOCK); + base::string16 time_text = horizontal_label()->GetText(); + + // When showing date, the text is expected to be longer since it's showing + // more content. + time_view()->SetShowDateWhenHorizontal(true /* show_date_when_horizontal */); + EXPECT_GT(horizontal_label()->GetText(), time_text); + + // Resetting show date mode should show only the time. + time_view()->SetShowDateWhenHorizontal(false /* show_date_when_horizontal */); + EXPECT_EQ(time_text, horizontal_label()->GetText()); + + time_view()->UpdateClockLayout(TimeView::ClockLayout::VERTICAL_CLOCK); + base::string16 hours_text = vertical_label_hours()->GetText(); + base::string16 minutes_text = vertical_label_minutes()->GetText(); + + // Show date mode should not affect vertical view. + time_view()->SetShowDateWhenHorizontal(true /* show_date_when_horizontal */); + EXPECT_EQ(hours_text, vertical_label_hours()->GetText()); + EXPECT_EQ(minutes_text, vertical_label_minutes()->GetText()); +} + } // namespace tray } // namespace ash
diff --git a/ash/system/unified/unified_system_tray.cc b/ash/system/unified/unified_system_tray.cc index e686448..edf3808 100644 --- a/ash/system/unified/unified_system_tray.cc +++ b/ash/system/unified/unified_system_tray.cc
@@ -20,7 +20,6 @@ #include "ash/system/network/network_tray_view.h" #include "ash/system/power/tray_power.h" #include "ash/system/privacy_screen/privacy_screen_toast_controller.h" -#include "ash/system/status_area_widget.h" #include "ash/system/time/time_tray_item_view.h" #include "ash/system/time/time_view.h" #include "ash/system/tray/tray_constants.h" @@ -120,8 +119,7 @@ UnifiedSystemTray::UnifiedSystemTray(Shelf* shelf) : TrayBackgroundView(shelf), ui_delegate_(std::make_unique<UiDelegate>(this)), - model_(std::make_unique<UnifiedSystemTrayModel>( - shelf->GetStatusAreaWidget()->GetRootView())), + model_(std::make_unique<UnifiedSystemTrayModel>(shelf)), slider_bubble_controller_( std::make_unique<UnifiedSliderBubbleController>(this)), privacy_screen_toast_controller_( @@ -136,7 +134,7 @@ new CameraMicTrayItemView(shelf, CameraMicTrayItemView::Type::kMic)), notification_counter_item_(new NotificationCounterView(shelf)), quiet_mode_view_(new QuietModeView(shelf)), - time_view_(new tray::TimeTrayItemView(shelf)) { + time_view_(new tray::TimeTrayItemView(shelf, model())) { tray_container()->SetMargin( kUnifiedTrayContentPadding - ShelfConfig::Get()->status_area_hit_region_padding(), @@ -175,6 +173,10 @@ if (bubble_) bubble_->CloseNow(); bubble_.reset(); + + // Reset the view to remove its dependency from |model_|, since this view is + // destructed after |model_|. + time_view_->Reset(); } bool UnifiedSystemTray::IsBubbleShown() const {
diff --git a/ash/system/unified/unified_system_tray_model.cc b/ash/system/unified/unified_system_tray_model.cc index 14dd43b..37f8559 100644 --- a/ash/system/unified/unified_system_tray_model.cc +++ b/ash/system/unified/unified_system_tray_model.cc
@@ -5,11 +5,24 @@ #include "ash/system/unified/unified_system_tray_model.h" #include "ash/accessibility/accessibility_controller_impl.h" +#include "ash/shelf/shelf_widget.h" #include "ash/shell.h" +#include "ash/shell_observer.h" #include "ash/system/brightness_control_delegate.h" +#include "ash/system/status_area_widget.h" #include "base/bind.h" #include "chromeos/dbus/power_manager/backlight.pb.h" +namespace { + +// The minimum width for system tray with size of kMedium. +constexpr int kMinWidthMediumSystemTray = 800; + +// The maximum width for system tray with size of kMedium. +constexpr int kMaxWidthMediumSystemTray = 1280; + +} // namespace + namespace ash { class UnifiedSystemTrayModel::DBusObserver @@ -34,6 +47,31 @@ DISALLOW_COPY_AND_ASSIGN(DBusObserver); }; +class UnifiedSystemTrayModel::SizeObserver : public display::DisplayObserver, + public ShellObserver { + public: + explicit SizeObserver(UnifiedSystemTrayModel* owner); + ~SizeObserver() override; + SizeObserver(const SizeObserver&) = delete; + SizeObserver& operator=(const SizeObserver&) = delete; + + private: + // display::DisplayObserver: + void OnDisplayMetricsChanged(const display::Display& display, + uint32_t changed_metrics) override; + + // ShellObserver: + void OnShelfAlignmentChanged(aura::Window* root_window, + ShelfAlignment old_alignment) override; + + void Update(); + + UnifiedSystemTrayModel* const owner_; + + // Keep track of current system tray size. + UnifiedSystemTrayModel::SystemTrayButtonSize system_tray_size_; +}; + UnifiedSystemTrayModel::DBusObserver::DBusObserver( UnifiedSystemTrayModel* owner) : owner_(owner) { @@ -72,9 +110,51 @@ power_manager::BacklightBrightnessChange_Cause_USER_REQUEST); } -UnifiedSystemTrayModel::UnifiedSystemTrayModel(views::View* owner_view) - : dbus_observer_(std::make_unique<DBusObserver>(this)), - pagination_model_(std::make_unique<PaginationModel>(owner_view)) {} +UnifiedSystemTrayModel::SizeObserver::SizeObserver( + UnifiedSystemTrayModel* owner) + : owner_(owner) { + display::Screen::GetScreen()->AddObserver(this); + Shell::Get()->AddShellObserver(this); + system_tray_size_ = owner_->GetSystemTrayButtonSize(); +} + +UnifiedSystemTrayModel::SizeObserver::~SizeObserver() { + display::Screen::GetScreen()->RemoveObserver(this); + Shell::Get()->RemoveShellObserver(this); +} + +void UnifiedSystemTrayModel::SizeObserver::OnDisplayMetricsChanged( + const display::Display& display, + uint32_t changed_metrics) { + if (owner_->GetDisplay().id() != display.id()) + return; + Update(); +} + +void UnifiedSystemTrayModel::SizeObserver::OnShelfAlignmentChanged( + aura::Window* root_window, + ShelfAlignment old_alignment) { + Update(); +} + +void UnifiedSystemTrayModel::SizeObserver::Update() { + UnifiedSystemTrayModel::SystemTrayButtonSize new_size = + owner_->GetSystemTrayButtonSize(); + if (system_tray_size_ == new_size) + return; + + system_tray_size_ = new_size; + owner_->SystemTrayButtonSizeChanged(system_tray_size_); +} + +UnifiedSystemTrayModel::UnifiedSystemTrayModel(Shelf* shelf) + : shelf_(shelf), + dbus_observer_(std::make_unique<DBusObserver>(this)), + size_observer_(std::make_unique<SizeObserver>(this)) { + // |shelf_| might be null in unit tests. + pagination_model_ = std::make_unique<PaginationModel>( + shelf_ ? shelf_->GetStatusAreaWidget()->GetRootView() : nullptr); +} UnifiedSystemTrayModel::~UnifiedSystemTrayModel() = default; @@ -124,6 +204,23 @@ notification_changes_.clear(); } +UnifiedSystemTrayModel::SystemTrayButtonSize +UnifiedSystemTrayModel::GetSystemTrayButtonSize() const { + // |shelf_| might be null in unit tests, returns medium size as default. + if (!shelf_) + return SystemTrayButtonSize::kMedium; + + int display_size = shelf_->IsHorizontalAlignment() + ? GetDisplay().size().width() + : GetDisplay().size().height(); + + if (display_size < kMinWidthMediumSystemTray) + return SystemTrayButtonSize::kSmall; + if (display_size <= kMaxWidthMediumSystemTray) + return SystemTrayButtonSize::kMedium; + return SystemTrayButtonSize::kLarge; +} + void UnifiedSystemTrayModel::DisplayBrightnessChanged(float brightness, bool by_user) { display_brightness_ = brightness; @@ -138,4 +235,22 @@ observer.OnKeyboardBrightnessChanged(by_user); } +void UnifiedSystemTrayModel::SystemTrayButtonSizeChanged( + SystemTrayButtonSize system_tray_size) { + for (auto& observer : observers_) + observer.OnSystemTrayButtonSizeChanged(system_tray_size); +} + +const display::Display UnifiedSystemTrayModel::GetDisplay() const { + // |shelf_| might be null in unit tests, returns primary display as default. + if (!shelf_) + return display::Screen::GetScreen()->GetPrimaryDisplay(); + + return display::Screen::GetScreen()->GetDisplayNearestWindow( + shelf_->GetStatusAreaWidget() + ->GetRootView() + ->GetWidget() + ->GetNativeWindow()); +} + } // namespace ash
diff --git a/ash/system/unified/unified_system_tray_model.h b/ash/system/unified/unified_system_tray_model.h index 559954e3..e1253bd 100644 --- a/ash/system/unified/unified_system_tray_model.h +++ b/ash/system/unified/unified_system_tray_model.h
@@ -10,8 +10,14 @@ #include "base/observer_list.h" #include "chromeos/dbus/power/power_manager_client.h" +namespace display { +class Display; +} // namespace display + namespace ash { +class Shelf; + // Model class that stores UnifiedSystemTray's UI specific variables. Owned by // UnifiedSystemTray status area button. Not to be confused with UI agnostic // SystemTrayModel. @@ -36,6 +42,19 @@ NOTIFICATION_ID, }; + // Enumeration of possible sizes of the system tray button. Larger screen will + // have larger tray button with additional information. + enum class SystemTrayButtonSize { + // Display wifi, battery, notification counter icons and time. + kSmall = 0, + // Display those in small unified system tray, plus important notification + // icons. + kMedium = 1, + // Display those in medium unified system tray, plus the current date. + kLarge = 2, + kMaxValue = kLarge, + }; + class Observer { public: virtual ~Observer() {} @@ -43,9 +62,11 @@ // |by_user| is true when brightness is changed by user action. virtual void OnDisplayBrightnessChanged(bool by_user) {} virtual void OnKeyboardBrightnessChanged(bool by_user) {} + virtual void OnSystemTrayButtonSizeChanged( + SystemTrayButtonSize system_tray_size) {} }; - explicit UnifiedSystemTrayModel(views::View* owner_view); + explicit UnifiedSystemTrayModel(Shelf* shelf); ~UnifiedSystemTrayModel(); void AddObserver(Observer* observer); @@ -78,6 +99,9 @@ // NOTIFICATION_ID. void SetTargetNotification(const std::string& notification_id); + // Get the size of the system tray depends on the size of the display screen. + SystemTrayButtonSize GetSystemTrayButtonSize() const; + float display_brightness() const { return display_brightness_; } float keyboard_brightness() const { return keyboard_brightness_; } @@ -102,8 +126,15 @@ private: class DBusObserver; + // Keeps track all the sources that can change the size of system tray button. + class SizeObserver; + void DisplayBrightnessChanged(float brightness, bool by_user); void KeyboardBrightnessChanged(float brightness, bool by_user); + void SystemTrayButtonSizeChanged(SystemTrayButtonSize system_tray_size); + + // Get the display that owns the tray. + const display::Display GetDisplay() const; // Target mode which is used to decide the scroll position of the message // center on opening. See the comment in |NotificationTargetMode|. @@ -128,8 +159,12 @@ // <notification ID, if notification is manually expanded> std::map<std::string, bool> notification_changes_; + Shelf* const shelf_; + std::unique_ptr<DBusObserver> dbus_observer_; + std::unique_ptr<SizeObserver> size_observer_; + base::ObserverList<Observer>::Unchecked observers_; std::unique_ptr<PaginationModel> pagination_model_;
diff --git a/base/allocator/partition_allocator/thread_cache.cc b/base/allocator/partition_allocator/thread_cache.cc index 9621da0..d72100ea 100644 --- a/base/allocator/partition_allocator/thread_cache.cc +++ b/base/allocator/partition_allocator/thread_cache.cc
@@ -106,7 +106,9 @@ } void ThreadCacheRegistry::StartPeriodicPurge() { - PostDelayedPurgeTask(); + // Can be called several times, don't post multiple tasks. + if (!has_pending_purge_task_) + PostDelayedPurgeTask(); } void ThreadCacheRegistry::PostDelayedPurgeTask() {
diff --git a/base/run_loop.cc b/base/run_loop.cc index a0517fa..1865a3b1 100644 --- a/base/run_loop.cc +++ b/base/run_loop.cc
@@ -265,7 +265,7 @@ } #if DCHECK_IS_ON() -RunLoop::ScopedDisallowRunningForTesting::ScopedDisallowRunningForTesting() +RunLoop::ScopedDisallowRunning::ScopedDisallowRunning() : current_delegate_(GetTlsDelegate().Get()), previous_run_allowance_( current_delegate_ ? current_delegate_->allow_running_for_testing_ @@ -274,7 +274,7 @@ current_delegate_->allow_running_for_testing_ = false; } -RunLoop::ScopedDisallowRunningForTesting::~ScopedDisallowRunningForTesting() { +RunLoop::ScopedDisallowRunning::~ScopedDisallowRunning() { DCHECK_EQ(current_delegate_, GetTlsDelegate().Get()); if (current_delegate_) current_delegate_->allow_running_for_testing_ = previous_run_allowance_; @@ -283,10 +283,8 @@ // Defined out of line so that the compiler doesn't inline these and realize // the scope has no effect and then throws an "unused variable" warning in // non-dcheck builds. -RunLoop::ScopedDisallowRunningForTesting::ScopedDisallowRunningForTesting() = - default; -RunLoop::ScopedDisallowRunningForTesting::~ScopedDisallowRunningForTesting() = - default; +RunLoop::ScopedDisallowRunning::ScopedDisallowRunning() = default; +RunLoop::ScopedDisallowRunning::~ScopedDisallowRunning() = default; #endif // DCHECK_IS_ON() RunLoop::RunLoopTimeout::RunLoopTimeout() = default; @@ -309,7 +307,7 @@ #if DCHECK_IS_ON() DCHECK(delegate_->allow_running_for_testing_) << "RunLoop::Run() isn't allowed in the scope of a " - "ScopedDisallowRunningForTesting. Hint: if mixing " + "ScopedDisallowRunning. Hint: if mixing " "TestMockTimeTaskRunners on same thread, use TestMockTimeTaskRunner's " "API instead of RunLoop to drive individual task runners."; DCHECK(!run_called_);
diff --git a/base/run_loop.h b/base/run_loop.h index efd4895..483147e 100644 --- a/base/run_loop.h +++ b/base/run_loop.h
@@ -253,7 +253,7 @@ static void QuitCurrentWhenIdleDeprecated(); static RepeatingClosure QuitCurrentWhenIdleClosureDeprecated(); - // Run() will DCHECK if called while there's a ScopedDisallowRunningForTesting + // Run() will DCHECK if called while there's a ScopedDisallowRunning // in scope on its thread. This is useful to add safety to some test // constructs which allow multiple task runners to share the main thread in // unit tests. While the main thread can be shared by multiple runners to @@ -261,14 +261,12 @@ // RunLoop::Delegate per thread and RunLoop::Run() should only be invoked from // it (or it would result in incorrectly driving TaskRunner A while in // TaskRunner B's context). - class BASE_EXPORT ScopedDisallowRunningForTesting { + class BASE_EXPORT ScopedDisallowRunning { public: - ScopedDisallowRunningForTesting(); - ScopedDisallowRunningForTesting(const ScopedDisallowRunningForTesting&) = - delete; - ScopedDisallowRunningForTesting& operator=( - const ScopedDisallowRunningForTesting&) = delete; - ~ScopedDisallowRunningForTesting(); + ScopedDisallowRunning(); + ScopedDisallowRunning(const ScopedDisallowRunning&) = delete; + ScopedDisallowRunning& operator=(const ScopedDisallowRunning&) = delete; + ~ScopedDisallowRunning(); private: #if DCHECK_IS_ON()
diff --git a/base/run_loop_unittest.cc b/base/run_loop_unittest.cc index 3c0494d..7b44cb3 100644 --- a/base/run_loop_unittest.cc +++ b/base/run_loop_unittest.cc
@@ -532,13 +532,13 @@ RunLoop::RemoveNestingObserverOnCurrentThread(&nesting_observer); } -TEST_P(RunLoopTest, DisallowRunningForTesting) { - RunLoop::ScopedDisallowRunningForTesting disallow_running; +TEST_P(RunLoopTest, DisallowRunning) { + RunLoop::ScopedDisallowRunning disallow_running; EXPECT_DCHECK_DEATH({ run_loop_.RunUntilIdle(); }); } -TEST_P(RunLoopTest, ExpiredDisallowRunningForTesting) { - { RunLoop::ScopedDisallowRunningForTesting disallow_running; } +TEST_P(RunLoopTest, ExpiredDisallowRunning) { + { RunLoop::ScopedDisallowRunning disallow_running; } // Running should be fine after |disallow_running| goes out of scope. run_loop_.RunUntilIdle(); }
diff --git a/base/test/test_mock_time_task_runner.cc b/base/test/test_mock_time_task_runner.cc index 3b8cbda..b1f0196 100644 --- a/base/test/test_mock_time_task_runner.cc +++ b/base/test/test_mock_time_task_runner.cc
@@ -147,7 +147,7 @@ // Ref. TestMockTimeTaskRunner::RunsTasksInCurrentSequence(). TestMockTimeTaskRunner::ScopedContext::ScopedContext( scoped_refptr<TestMockTimeTaskRunner> scope) - : on_destroy_(ThreadTaskRunnerHandle::OverrideForTesting(scope)) { + : thread_task_runner_handle_override_(scope) { scope->RunUntilIdle(); } @@ -344,11 +344,10 @@ // Multiple test task runners can share the same thread for determinism in // unit tests. Make sure this TestMockTimeTaskRunner's tasks run in its scope. - ScopedClosureRunner undo_override; + base::Optional<ThreadTaskRunnerHandleOverrideForTesting> ttrh_override; if (!ThreadTaskRunnerHandle::IsSet() || ThreadTaskRunnerHandle::Get() != proxy_task_runner_.get()) { - undo_override = - ThreadTaskRunnerHandle::OverrideForTesting(proxy_task_runner_.get()); + ttrh_override.emplace(proxy_task_runner_.get()); } const TimeTicks original_now_ticks = NowTicks();
diff --git a/base/test/test_mock_time_task_runner.h b/base/test/test_mock_time_task_runner.h index 833f3eb..dbf075f 100644 --- a/base/test/test_mock_time_task_runner.h +++ b/base/test/test_mock_time_task_runner.h
@@ -21,6 +21,7 @@ #include "base/synchronization/lock.h" #include "base/test/test_pending_task.h" #include "base/threading/thread_checker_impl.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/time/clock.h" #include "base/time/tick_clock.h" #include "base/time/time.h" @@ -117,7 +118,8 @@ ~ScopedContext(); private: - ScopedClosureRunner on_destroy_; + ThreadTaskRunnerHandleOverrideForTesting + thread_task_runner_handle_override_; DISALLOW_COPY_AND_ASSIGN(ScopedContext); };
diff --git a/base/test/test_simple_task_runner.cc b/base/test/test_simple_task_runner.cc index 3e5d70ee..e8e5781 100644 --- a/base/test/test_simple_task_runner.cc +++ b/base/test/test_simple_task_runner.cc
@@ -85,10 +85,10 @@ // Multiple test task runners can share the same thread for determinism in // unit tests. Make sure this TestSimpleTaskRunner's tasks run in its scope. - ScopedClosureRunner undo_override; + base::Optional<ThreadTaskRunnerHandleOverrideForTesting> ttrh_override; if (!ThreadTaskRunnerHandle::IsSet() || ThreadTaskRunnerHandle::Get() != this) { - undo_override = ThreadTaskRunnerHandle::OverrideForTesting(this); + ttrh_override.emplace(this); } for (auto& task : tasks_to_run)
diff --git a/base/threading/sequenced_task_runner_handle.h b/base/threading/sequenced_task_runner_handle.h index 4822495..e74b5d19 100644 --- a/base/threading/sequenced_task_runner_handle.h +++ b/base/threading/sequenced_task_runner_handle.h
@@ -36,8 +36,7 @@ ~SequencedTaskRunnerHandle(); private: - // Friend needed for ThreadTaskRunnerHandle::OverrideForTesting(). - friend class ThreadTaskRunnerHandle; + friend class ThreadTaskRunnerHandleOverride; scoped_refptr<SequencedTaskRunner> task_runner_;
diff --git a/base/threading/thread_task_runner_handle.cc b/base/threading/thread_task_runner_handle.cc index ca57b36d..3690a60 100644 --- a/base/threading/thread_task_runner_handle.cc +++ b/base/threading/thread_task_runner_handle.cc
@@ -38,51 +38,6 @@ return !!thread_task_runner_tls.Pointer()->Get(); } -// static -ScopedClosureRunner ThreadTaskRunnerHandle::OverrideForTesting( - scoped_refptr<SingleThreadTaskRunner> overriding_task_runner) { - // OverrideForTesting() is not compatible with a SequencedTaskRunnerHandle - // already being set on this thread (except when it's set by the current - // ThreadTaskRunnerHandle). - DCHECK(!SequencedTaskRunnerHandle::IsSet() || IsSet()); - - if (!IsSet()) { - auto top_level_ttrh = std::make_unique<ThreadTaskRunnerHandle>( - std::move(overriding_task_runner)); - return ScopedClosureRunner(base::BindOnce( - [](std::unique_ptr<ThreadTaskRunnerHandle> ttrh_to_release) {}, - std::move(top_level_ttrh))); - } - - ThreadTaskRunnerHandle* ttrh = thread_task_runner_tls.Pointer()->Get(); - // Swap the two (and below bind |overriding_task_runner|, which is now the - // previous one, as the |task_runner_to_restore|). - ttrh->sequenced_task_runner_handle_.task_runner_ = overriding_task_runner; - ttrh->task_runner_.swap(overriding_task_runner); - - auto no_running_during_override = - std::make_unique<RunLoop::ScopedDisallowRunningForTesting>(); - - return ScopedClosureRunner(base::BindOnce( - [](scoped_refptr<SingleThreadTaskRunner> task_runner_to_restore, - SingleThreadTaskRunner* expected_task_runner_before_restore, - std::unique_ptr<RunLoop::ScopedDisallowRunningForTesting> - no_running_during_override) { - ThreadTaskRunnerHandle* ttrh = thread_task_runner_tls.Pointer()->Get(); - - DCHECK_EQ(expected_task_runner_before_restore, ttrh->task_runner_.get()) - << "Nested overrides must expire their ScopedClosureRunners " - "in LIFO order."; - - ttrh->sequenced_task_runner_handle_.task_runner_ = - task_runner_to_restore; - ttrh->task_runner_.swap(task_runner_to_restore); - }, - std::move(overriding_task_runner), - base::Unretained(ttrh->task_runner_.get()), - std::move(no_running_during_override))); -} - ThreadTaskRunnerHandle::ThreadTaskRunnerHandle( scoped_refptr<SingleThreadTaskRunner> task_runner) : task_runner_(std::move(task_runner)), @@ -98,4 +53,47 @@ thread_task_runner_tls.Pointer()->Set(nullptr); } +ThreadTaskRunnerHandleOverride::ThreadTaskRunnerHandleOverride( + scoped_refptr<SingleThreadTaskRunner> overriding_task_runner, + bool allow_nested_runloop) { + DCHECK(!SequencedTaskRunnerHandle::IsSet() || ThreadTaskRunnerHandle::IsSet()) + << "ThreadTaskRunnerHandleOverride is not compatible with a " + "SequencedTaskRunnerHandle already being set on this thread (except " + "when it's set by the current ThreadTaskRunnerHandle)."; + + if (!ThreadTaskRunnerHandle::IsSet()) { + top_level_thread_task_runner_handle_.emplace( + std::move(overriding_task_runner)); + return; + } + +#if DCHECK_IS_ON() + expected_task_runner_before_restore_ = overriding_task_runner.get(); +#endif + ThreadTaskRunnerHandle* ttrh = thread_task_runner_tls.Pointer()->Get(); + ttrh->sequenced_task_runner_handle_.task_runner_ = overriding_task_runner; + ttrh->task_runner_.swap(overriding_task_runner); + // Due to the swap, now `ttrh->task_runner_` points to the overriding task + // runner and `overriding_task_runner_` points to the previous task runner. + task_runner_to_restore_ = std::move(overriding_task_runner); + + if (!allow_nested_runloop) + no_running_during_override_.emplace(); +} + +ThreadTaskRunnerHandleOverride::~ThreadTaskRunnerHandleOverride() { + if (task_runner_to_restore_) { + ThreadTaskRunnerHandle* ttrh = thread_task_runner_tls.Pointer()->Get(); + +#if DCHECK_IS_ON() + DCHECK_EQ(expected_task_runner_before_restore_, ttrh->task_runner_.get()) + << "Nested overrides must expire their ThreadTaskRunnerHandleOverride " + "in LIFO order."; +#endif + + ttrh->sequenced_task_runner_handle_.task_runner_ = task_runner_to_restore_; + ttrh->task_runner_.swap(task_runner_to_restore_); + } +} + } // namespace base
diff --git a/base/threading/thread_task_runner_handle.h b/base/threading/thread_task_runner_handle.h index 892affc..105d29e0 100644 --- a/base/threading/thread_task_runner_handle.h +++ b/base/threading/thread_task_runner_handle.h
@@ -6,13 +6,20 @@ #define BASE_THREADING_THREAD_TASK_RUNNER_HANDLE_H_ #include "base/base_export.h" -#include "base/callback_helpers.h" #include "base/compiler_specific.h" +#include "base/dcheck_is_on.h" #include "base/macros.h" #include "base/memory/scoped_refptr.h" +#include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/threading/sequenced_task_runner_handle.h" +namespace blink { +namespace scheduler { +class MainThreadSchedulerImpl; +} // namespace scheduler +} // namespace blink + namespace base { // ThreadTaskRunnerHandle stores a reference to a thread's TaskRunner @@ -29,18 +36,6 @@ // the current thread. static bool IsSet() WARN_UNUSED_RESULT; - // Overrides ThreadTaskRunnerHandle::Get()'s |task_runner_| to point at - // |overriding_task_runner| until the returned ScopedClosureRunner goes out of - // scope (instantiates a ThreadTaskRunnerHandle for that scope if |!IsSet()|). - // Nested overrides are allowed but callers must ensure the - // ScopedClosureRunners expire in LIFO (stack) order. Note: nesting - // ThreadTaskRunnerHandles isn't generally desired but it's useful in unit - // tests where multiple task runners can share the main thread for simplicity - // and determinism. - static ScopedClosureRunner OverrideForTesting( - scoped_refptr<SingleThreadTaskRunner> overriding_task_runner) - WARN_UNUSED_RESULT; - // Binds |task_runner| to the current thread. |task_runner| must belong // to the current thread for this to succeed. explicit ThreadTaskRunnerHandle( @@ -48,6 +43,7 @@ ~ThreadTaskRunnerHandle(); private: + friend class ThreadTaskRunnerHandleOverride; scoped_refptr<SingleThreadTaskRunner> task_runner_; // Registers |task_runner_|'s SequencedTaskRunner interface as the @@ -57,6 +53,71 @@ DISALLOW_COPY_AND_ASSIGN(ThreadTaskRunnerHandle); }; +// ThreadTaskRunnerHandleOverride overrides the task runner returned by +// |ThreadTaskRunnerHandle::Get()| to point at |overriding_task_runner| until +// the |ThreadTaskRunnerHandleOverride| goes out of scope. +// ThreadTaskRunnerHandleOverride instantiates a new ThreadTaskRunnerHandle if +// ThreadTaskRunnerHandle is not instantiated on the current thread. Nested +// overrides are allowed but callers must ensure the +// |ThreadTaskRunnerHandleOverride| expire in LIFO (stack) order. +// +// Note: nesting ThreadTaskRunnerHandle is subtle and should be done with care, +// hence the need to friend and request a //base/OWNERS review for usage outside +// of tests. Use ThreadTaskRunnerHandleOverrideForTesting to bypass the friend +// requirement in tests. +class BASE_EXPORT ThreadTaskRunnerHandleOverride { + public: + ThreadTaskRunnerHandleOverride(const ThreadTaskRunnerHandleOverride&) = + delete; + ThreadTaskRunnerHandleOverride& operator=( + const ThreadTaskRunnerHandleOverride&) = delete; + ~ThreadTaskRunnerHandleOverride(); + + private: + friend class ThreadTaskRunnerHandleOverrideForTesting; + FRIEND_TEST_ALL_PREFIXES(ThreadTaskRunnerHandleTest, NestedRunLoop); + + // We expect ThreadTaskRunnerHandleOverride to be only needed under special + // circumstances. Require them to be enumerated as friends to require + // //base/OWNERS review. Use ThreadTaskRunnerHandleOverrideForTesting + // in unit tests to avoid the friend requirement. + + friend class blink::scheduler::MainThreadSchedulerImpl; + + // Constructs a ThreadTaskRunnerHandleOverride which will make + // ThreadTaskRunnerHandle::Get() return |overriding_task_runner| for its + // lifetime. |allow_nested_loop| specifies whether RunLoop::Run() is allowed + // during this override's lifetime. It's not recommended to allow this unless + // the current thread's scheduler guarantees that only tasks which pertain to + // |overriding_task_runner|'s context will be run by nested RunLoops. + explicit ThreadTaskRunnerHandleOverride( + scoped_refptr<SingleThreadTaskRunner> overriding_task_runner, + bool allow_nested_runloop = false); + + base::Optional<ThreadTaskRunnerHandle> top_level_thread_task_runner_handle_; + scoped_refptr<SingleThreadTaskRunner> task_runner_to_restore_; +#if DCHECK_IS_ON() + SingleThreadTaskRunner* expected_task_runner_before_restore_{nullptr}; +#endif + base::Optional<RunLoop::ScopedDisallowRunning> no_running_during_override_; +}; + +// Note: nesting ThreadTaskRunnerHandles isn't generally desired but it's useful +// in some unit tests where multiple task runners share the main thread for +// simplicity and determinism. Only use this when no other constructs will work +// (see base/test/task_environment.h and base/test/test_mock_time_task_runner.h +// for preferred alternatives). +class ThreadTaskRunnerHandleOverrideForTesting { + public: + explicit ThreadTaskRunnerHandleOverrideForTesting( + scoped_refptr<SingleThreadTaskRunner> overriding_task_runner) + : thread_task_runner_handle_override_(std::move(overriding_task_runner)) { + } + + private: + ThreadTaskRunnerHandleOverride thread_task_runner_handle_override_; +}; + } // namespace base #endif // BASE_THREADING_THREAD_TASK_RUNNER_HANDLE_H_
diff --git a/base/threading/thread_task_runner_handle_unittest.cc b/base/threading/thread_task_runner_handle_unittest.cc index 1aa02d1..03ad7b2 100644 --- a/base/threading/thread_task_runner_handle_unittest.cc +++ b/base/threading/thread_task_runner_handle_unittest.cc
@@ -5,7 +5,9 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/memory/ref_counted.h" +#include "base/run_loop.h" #include "base/test/gtest_util.h" +#include "base/test/task_environment.h" #include "base/test/test_simple_task_runner.h" #include "testing/gtest/include/gtest/gtest.h" @@ -33,7 +35,7 @@ { ThreadTaskRunnerHandle overriding_ttrh(overidding_task_runner); }); } -TEST(ThreadTaskRunnerHandleTest, OverrideForTestingExistingTTRH) { +TEST(ThreadTaskRunnerHandleTest, OverrideExistingTTRH) { scoped_refptr<SingleThreadTaskRunner> task_runner_1(new TestSimpleTaskRunner); scoped_refptr<SingleThreadTaskRunner> task_runner_2(new TestSimpleTaskRunner); scoped_refptr<SingleThreadTaskRunner> task_runner_3(new TestSimpleTaskRunner); @@ -48,15 +50,13 @@ { // Override. - ScopedClosureRunner undo_override_2 = - ThreadTaskRunnerHandle::OverrideForTesting(task_runner_2); + ThreadTaskRunnerHandleOverrideForTesting ttrh_override_2(task_runner_2); EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet()); EXPECT_EQ(task_runner_2, ThreadTaskRunnerHandle::Get()); { // Nested override. - ScopedClosureRunner undo_override_3 = - ThreadTaskRunnerHandle::OverrideForTesting(task_runner_3); + ThreadTaskRunnerHandleOverrideForTesting ttrh_override_3(task_runner_3); EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet()); EXPECT_EQ(task_runner_3, ThreadTaskRunnerHandle::Get()); } @@ -67,8 +67,7 @@ { // Backup to double override with another TTRH. - ScopedClosureRunner undo_override_4 = - ThreadTaskRunnerHandle::OverrideForTesting(task_runner_4); + ThreadTaskRunnerHandleOverrideForTesting ttrh_override_4(task_runner_4); EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet()); EXPECT_EQ(task_runner_4, ThreadTaskRunnerHandle::Get()); } @@ -81,22 +80,20 @@ EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); } -TEST(ThreadTaskRunnerHandleTest, OverrideForTestingNoExistingTTRH) { +TEST(ThreadTaskRunnerHandleTest, OverrideNoExistingTTRH) { scoped_refptr<SingleThreadTaskRunner> task_runner_1(new TestSimpleTaskRunner); scoped_refptr<SingleThreadTaskRunner> task_runner_2(new TestSimpleTaskRunner); EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); { // Override with no TTRH in place. - ScopedClosureRunner undo_override_1 = - ThreadTaskRunnerHandle::OverrideForTesting(task_runner_1); + ThreadTaskRunnerHandleOverrideForTesting ttrh_override_1(task_runner_1); EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet()); EXPECT_EQ(task_runner_1, ThreadTaskRunnerHandle::Get()); { // Nested override works the same. - ScopedClosureRunner undo_override_2 = - ThreadTaskRunnerHandle::OverrideForTesting(task_runner_2); + ThreadTaskRunnerHandleOverrideForTesting ttrh_override_2(task_runner_2); EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet()); EXPECT_EQ(task_runner_2, ThreadTaskRunnerHandle::Get()); } @@ -113,10 +110,32 @@ scoped_refptr<SingleThreadTaskRunner> overidding_task_runner( new TestSimpleTaskRunner); - ScopedClosureRunner undo_override = - ThreadTaskRunnerHandle::OverrideForTesting(task_runner); + ThreadTaskRunnerHandleOverrideForTesting ttrh_override(task_runner); EXPECT_DCHECK_DEATH( { ThreadTaskRunnerHandle overriding_ttrh(overidding_task_runner); }); } +TEST(ThreadTaskRunnerHandleTest, NestedRunLoop) { + test::SingleThreadTaskEnvironment task_environment; + EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet()); + scoped_refptr<SingleThreadTaskRunner> task_runner(new TestSimpleTaskRunner); + ThreadTaskRunnerHandleOverride ttrh_override(task_runner, + /*allow_nested_runloop=*/true); + EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet()); + EXPECT_EQ(task_runner, ThreadTaskRunnerHandle::Get()); + EXPECT_EQ(task_runner, SequencedTaskRunnerHandle::Get()); + RunLoop().RunUntilIdle(); +} + +TEST(ThreadTaskRunnerHandleTest, DeathOnNestedRunLoop) { + test::SingleThreadTaskEnvironment task_environment; + EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet()); + scoped_refptr<SingleThreadTaskRunner> task_runner(new TestSimpleTaskRunner); + ThreadTaskRunnerHandleOverrideForTesting ttrh_override(task_runner); + EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet()); + EXPECT_EQ(task_runner, ThreadTaskRunnerHandle::Get()); + EXPECT_EQ(task_runner, SequencedTaskRunnerHandle::Get()); + EXPECT_DCHECK_DEATH({ RunLoop().RunUntilIdle(); }); +} + } // namespace base
diff --git a/chrome/VERSION b/chrome/VERSION index 1fdb8ae..489bff3 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=89 MINOR=0 -BUILD=4386 +BUILD=4387 PATCH=0
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni index a5d7501..ca78a24c 100644 --- a/chrome/android/chrome_junit_test_java_sources.gni +++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -91,6 +91,7 @@ "junit/src/org/chromium/chrome/browser/firstrun/FirstRunAppRestrictionInfoTest.java", "junit/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencerTest.java", "junit/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationUnitTest.java", + "junit/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessorTest.java", "junit/src/org/chromium/chrome/browser/firstrun/PolicyLoadListenerUnitTest.java", "junit/src/org/chromium/chrome/browser/firstrun/SkipTosDialogPolicyListenerUnitTest.java", "junit/src/org/chromium/chrome/browser/firstrun/TosDialogBehaviorSharedPrefInvalidatorUnitTest.java",
diff --git a/chrome/android/features/autofill_assistant/BUILD.gn b/chrome/android/features/autofill_assistant/BUILD.gn index 66737614..df8b221 100644 --- a/chrome/android/features/autofill_assistant/BUILD.gn +++ b/chrome/android/features/autofill_assistant/BUILD.gn
@@ -115,6 +115,7 @@ "java/src/org/chromium/chrome/browser/autofill_assistant/DialogOnboardingCoordinator.java", "java/src/org/chromium/chrome/browser/autofill_assistant/FeedbackContext.java", "java/src/org/chromium/chrome/browser/autofill_assistant/LayoutUtils.java", + "java/src/org/chromium/chrome/browser/autofill_assistant/ScrollToHideGestureListener.java", "java/src/org/chromium/chrome/browser/autofill_assistant/SizeListenableLinearLayout.java", "java/src/org/chromium/chrome/browser/autofill_assistant/carousel/AssistantActionsCarouselCoordinator.java", "java/src/org/chromium/chrome/browser/autofill_assistant/carousel/AssistantActionsDecoration.java", @@ -127,6 +128,7 @@ "java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsCoordinator.java", "java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsModel.java", "java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsViewBinder.java", + "java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantPlaceholdersConfiguration.java", "java/src/org/chromium/chrome/browser/autofill_assistant/details/ImageClickthroughData.java", "java/src/org/chromium/chrome/browser/autofill_assistant/form/AssistantFormCoordinator.java", "java/src/org/chromium/chrome/browser/autofill_assistant/form/AssistantFormCounter.java", @@ -209,6 +211,7 @@ "java/src/org/chromium/chrome/browser/autofill_assistant/carousel/AssistantChip.java", "java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetails.java", "java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsModel.java", + "java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantPlaceholdersConfiguration.java", "java/src/org/chromium/chrome/browser/autofill_assistant/form/AssistantFormDelegate.java", "java/src/org/chromium/chrome/browser/autofill_assistant/form/AssistantFormInput.java", "java/src/org/chromium/chrome/browser/autofill_assistant/form/AssistantFormModel.java",
diff --git a/chrome/android/features/autofill_assistant/java/res/values-v17/dimens.xml b/chrome/android/features/autofill_assistant/java/res/values-v17/dimens.xml index e3a4261a..2300054 100644 --- a/chrome/android/features/autofill_assistant/java/res/values-v17/dimens.xml +++ b/chrome/android/features/autofill_assistant/java/res/values-v17/dimens.xml
@@ -6,6 +6,8 @@ <dimen name="autofill_assistant_bottombar_horizontal_spacing">24dp</dimen> <dimen name="autofill_assistant_bottombar_vertical_spacing">20dp</dimen> <dimen name="autofill_assistant_details_image_size">60dp</dimen> + <dimen name="autofill_assistant_details_text_placeholders_height">12dp</dimen> + <dimen name="autofill_assistant_details_text_placeholders_margin">4dp</dimen> <dimen name="autofill_assistant_poodle_size">32dp</dimen> <dimen name="autofill_assistant_profile_size">32dp</dimen> <dimen name="autofill_assistant_info_box_spacing">16dp</dimen>
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantBottomSheetContent.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantBottomSheetContent.java index e16188e3..c2c53edd 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantBottomSheetContent.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantBottomSheetContent.java
@@ -11,9 +11,11 @@ import androidx.annotation.Nullable; +import org.chromium.base.Callback; import org.chromium.base.supplier.Supplier; import org.chromium.chrome.autofill_assistant.R; import org.chromium.components.browser_ui.bottomsheet.BottomSheetContent; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; /** * The {@link BottomSheetContent} for the Autofill Assistant. It supports notifying the @@ -27,6 +29,9 @@ private ScrollView mContentScrollableView; private Supplier<AssistantBottomBarDelegate> mBottomBarDelegateSupplier; private boolean mPeekModeDisabled; + private BottomSheetController mController; + @Nullable + private Callback<Integer> mOffsetController; public AssistantBottomSheetContent( Context context, Supplier<AssistantBottomBarDelegate> supplier) { @@ -151,4 +156,18 @@ return bottomBarDelegate.onBackButtonPressed(); } + + @Override + public boolean contentControlsOffset() { + return true; + } + + @Override + public void setOffsetController(Callback<Integer> offsetController) { + mOffsetController = offsetController; + } + + public Callback<Integer> getOffsetController() { + return mOffsetController; + } }
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/ScrollToHideGestureListener.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/ScrollToHideGestureListener.java new file mode 100644 index 0000000..7f0a52c --- /dev/null +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/ScrollToHideGestureListener.java
@@ -0,0 +1,198 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.autofill_assistant; + +import android.animation.ValueAnimator; +import android.view.animation.DecelerateInterpolator; + +import androidx.annotation.Nullable; + +import org.chromium.base.Callback; +import org.chromium.base.MathUtils; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.SheetState; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetObserver; +import org.chromium.components.browser_ui.bottomsheet.EmptyBottomSheetObserver; +import org.chromium.content_public.browser.GestureStateListenerWithScroll; + +/** + * A Gesture listener that implements scroll-to-hide for the assistant bottomsheet when in FULL + * state. + */ +public class ScrollToHideGestureListener implements GestureStateListenerWithScroll { + /** Base duration of the animation of the sheet. 218 ms is a spec for material design. */ + private static final int BASE_ANIMATION_DURATION_MS = 218; + + private final BottomSheetController mBottomSheetController; + private final AssistantBottomSheetContent mContent; + @Nullable + private final BottomSheetObserver mStateChangeTracker = new StateChangeTracker(); + + private boolean mScrolling; + + /** Remembers the last value of scroll offset, to compute the delta for the next move. */ + private int mLastScrollOffsetY; + + /** + * A capture of {@code mBottomSheetController.getCurrentOffset()}. At the end of a scroll, it is + * compared with the current value to figure out whether the sheet was overall scrolled up or + * down. + */ + private float mOffsetMarkPx; + + /** This animator moves the sheet to its final position after scrolling ended. */ + private ValueAnimator mAnimator; + + public ScrollToHideGestureListener( + BottomSheetController bottomSheetController, AssistantBottomSheetContent content) { + mBottomSheetController = bottomSheetController; + mContent = content; + } + + @Override + public void onScrollStarted(int scrollOffsetY, int scrollExtentY) { + Callback<Integer> offsetController = mContent.getOffsetController(); + if (offsetController == null) return; + + // Scroll to hide only applies if the sheet is fully opened, and state is FULL or is being + // opened, and target state is FULL. + if (mBottomSheetController.getTargetSheetState() == SheetState.FULL) { + // This stops animation and freezes the sheet in place. + offsetController.onResult(mBottomSheetController.getCurrentOffset()); + } + if (mBottomSheetController.getSheetState() != SheetState.FULL) return; + + resetScrollingState(); // also cancels any running animations + mScrolling = true; + mLastScrollOffsetY = scrollOffsetY; + mOffsetMarkPx = mBottomSheetController.getCurrentOffset(); + mBottomSheetController.addObserver(mStateChangeTracker); + } + + @Override + public void onScrollEnded(int scrollOffsetY, int scrollExtentY) { + onScrollOffsetOrExtentChanged(scrollOffsetY, scrollExtentY); + + if (!mScrolling) return; + + resetScrollingState(); + + int maxOffsetPx = getMaxOffsetPx(); + int currentOffsetPx = mBottomSheetController.getCurrentOffset(); + if (currentOffsetPx == 0 || currentOffsetPx == maxOffsetPx) { + return; + } + + if (currentOffsetPx >= mOffsetMarkPx || scrollOffsetY == 0) { + animateTowards(maxOffsetPx); + } else { + animateTowards(0); + } + } + + @Override + public void onScrollOffsetOrExtentChanged(int scrollOffsetY, int scrollExtentY) { + if (!mScrolling) { + // It's possible for the scroll offset to reset to 0 outside of a scroll, if the page or + // viewport size change. Scrolling up is not possible so if the sheet is hidden or about + // to be hidden, show it. + if (scrollOffsetY == 0 && mBottomSheetController.getSheetState() == SheetState.FULL + && (mBottomSheetController.getCurrentOffset() == 0 || mAnimator != null)) { + animateTowards(getMaxOffsetPx()); + } + return; + } + + Callback<Integer> offsetController = mContent.getOffsetController(); + if (offsetController == null) { + resetScrollingState(); + return; + } + + // deltaPx is the value to add to the current sheet offset (height). It is negative when + // scrolling down, that is, when scrollOffsetY increases. + int deltaPx = mLastScrollOffsetY - scrollOffsetY; + mLastScrollOffsetY = scrollOffsetY; + + int maxOffsetPx = getMaxOffsetPx(); + int offsetPx = MathUtils.clamp( + mBottomSheetController.getCurrentOffset() + deltaPx, 0, maxOffsetPx); + offsetController.onResult(offsetPx); + + // If either extremes were reached, update the mark. The decision to fully show or hide will + // be relative to that point. + if (offsetPx == 0) { + mOffsetMarkPx = 0; + } else if (offsetPx >= maxOffsetPx) { + mOffsetMarkPx = maxOffsetPx; + } + } + + @Override + public void onFlingStartGesture(int scrollOffsetY, int scrollExtentY) { + // Flinging and scrolling are handled the same, the sheet follows the movement of the + // browser page. + onScrollStarted(scrollOffsetY, scrollExtentY); + } + + @Override + public void onFlingEndGesture(int scrollOffsetY, int scrollExtentY) { + onScrollEnded(scrollOffsetY, scrollExtentY); + } + + @Override + public void onDestroyed() { + resetScrollingState(); + } + + private int getMaxOffsetPx() { + return mContent.getContentView().getHeight() + mBottomSheetController.getTopShadowHeight(); + } + + private void resetScrollingState() { + mScrolling = false; + mLastScrollOffsetY = 0; + cancelAnimation(); + mBottomSheetController.removeObserver(mStateChangeTracker); + } + + private void cancelAnimation() { + if (mAnimator == null) return; + + mAnimator.cancel(); + mAnimator = null; + } + + /** Animate the sheet towards {@code goalOffsetPx} without changing its state. */ + private void animateTowards(int goalOffsetPx) { + Callback<Integer> offsetController = mContent.getOffsetController(); + if (offsetController == null) return; + + ValueAnimator animator = + ValueAnimator.ofInt(mBottomSheetController.getCurrentOffset(), goalOffsetPx); + animator.setDuration(BASE_ANIMATION_DURATION_MS); + animator.setInterpolator(new DecelerateInterpolator(1.0f)); + animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animator) { + if (mAnimator != animator) return; + + offsetController.onResult((Integer) animator.getAnimatedValue()); + } + }); + mAnimator = animator; + mAnimator.start(); + } + + /** Stop scrolling if the sheet leaves the FULL state during scrolling. */ + private class StateChangeTracker extends EmptyBottomSheetObserver { + @Override + public void onSheetStateChanged(@SheetState int newState) { + if (newState != SheetState.FULL) { + resetScrollingState(); + } + } + } +}
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetails.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetails.java index 3fe12c4..9dee6f73 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetails.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetails.java
@@ -13,11 +13,9 @@ @JNINamespace("autofill_assistant") public class AssistantDetails { private final String mTitle; - private final int mTitleMaxLines; private final String mImageUrl; private final String mImageAccessibilityHint; private final ImageClickthroughData mImageClickthroughData; - private final boolean mShowImagePlaceholder; private final String mDescriptionLine1; private final String mDescriptionLine2; private final String mDescriptionLine3; @@ -32,8 +30,6 @@ private boolean mHighlightLine2; /** Whether the third description line should be highlighted. */ private boolean mHighlightLine3; - /** Whether empty fields should have the animated placeholder background. */ - private final boolean mAnimatePlaceholders; /** * The correctly formatted price for the client locale, including the currency. * Example: '$20.50' or '20.50 €'. @@ -41,21 +37,20 @@ private final String mTotalPrice; /** An optional price label, such as 'Estimated Total incl. VAT'. */ private final String mTotalPriceLabel; + /** The configuration for the placeholders. */ + private final AssistantPlaceholdersConfiguration mPlaceholdersConfiguration; - public AssistantDetails(String title, int titleMaxLines, String imageUrl, - String imageAccessibilityHint, ImageClickthroughData imageClickthroughData, - boolean showImagePlaceholder, String totalPriceLabel, String totalPrice, + public AssistantDetails(String title, String imageUrl, String imageAccessibilityHint, + ImageClickthroughData imageClickthroughData, String totalPriceLabel, String totalPrice, String descriptionLine1, String descriptionLine2, String descriptionLine3, String priceAttribution, boolean userApprovalRequired, boolean highlightTitle, boolean highlightLine1, boolean highlightLine2, boolean highlightLine3, - boolean animatePlaceholders) { + AssistantPlaceholdersConfiguration placeholdersConfiguration) { this.mTotalPriceLabel = totalPriceLabel; this.mTitle = title; - this.mTitleMaxLines = titleMaxLines; this.mImageUrl = imageUrl; this.mImageAccessibilityHint = imageAccessibilityHint; this.mImageClickthroughData = imageClickthroughData; - this.mShowImagePlaceholder = showImagePlaceholder; this.mTotalPrice = totalPrice; this.mDescriptionLine1 = descriptionLine1; this.mDescriptionLine2 = descriptionLine2; @@ -67,17 +62,13 @@ this.mHighlightLine1 = highlightLine1; this.mHighlightLine2 = highlightLine2; this.mHighlightLine3 = highlightLine3; - this.mAnimatePlaceholders = animatePlaceholders; + this.mPlaceholdersConfiguration = placeholdersConfiguration; } String getTitle() { return mTitle; } - int getTitleMaxLines() { - return mTitleMaxLines; - } - String getImageUrl() { return mImageUrl; } @@ -94,10 +85,6 @@ return mImageClickthroughData; } - boolean getShowImagePlaceholder() { - return mShowImagePlaceholder; - } - String getDescriptionLine1() { return mDescriptionLine1; } @@ -142,30 +129,29 @@ return mHighlightLine3; } - boolean getAnimatePlaceholders() { - return mAnimatePlaceholders; + public AssistantPlaceholdersConfiguration getPlaceholdersConfiguration() { + return mPlaceholdersConfiguration; } /** * Create details with the given values. */ @CalledByNative - private static AssistantDetails create(String title, int titleMaxLines, String imageUrl, + private static AssistantDetails create(String title, String imageUrl, String imageAccessibilityHint, boolean allowImageClickthrough, String imageClickthroughDesc, String imageClickthroughPostiveText, String imageClickthroughNegativeText, String imageClickthroughUrl, - boolean showImagePlaceholder, String totalPriceLabel, String totalPrice, - String descriptionLine1, String descriptionLine2, String descriptionLine3, - String priceAttribution, boolean userApprovalRequired, boolean highlightTitle, - boolean highlightLine1, boolean highlightLine2, boolean highlightLine3, - boolean animatePlaceholders) { - return new AssistantDetails(title, titleMaxLines, imageUrl, imageAccessibilityHint, + String totalPriceLabel, String totalPrice, String descriptionLine1, + String descriptionLine2, String descriptionLine3, String priceAttribution, + boolean userApprovalRequired, boolean highlightTitle, boolean highlightLine1, + boolean highlightLine2, boolean highlightLine3, + AssistantPlaceholdersConfiguration placeholdersConfiguration) { + return new AssistantDetails(title, imageUrl, imageAccessibilityHint, new ImageClickthroughData(allowImageClickthrough, imageClickthroughDesc, imageClickthroughPostiveText, imageClickthroughNegativeText, imageClickthroughUrl), - showImagePlaceholder, totalPriceLabel, totalPrice, descriptionLine1, - descriptionLine2, descriptionLine3, priceAttribution, userApprovalRequired, - highlightTitle, highlightLine1, highlightLine2, highlightLine3, - animatePlaceholders); + totalPriceLabel, totalPrice, descriptionLine1, descriptionLine2, descriptionLine3, + priceAttribution, userApprovalRequired, highlightTitle, highlightLine1, + highlightLine2, highlightLine3, placeholdersConfiguration); } }
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsViewBinder.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsViewBinder.java index a0a98a2..a82e65c 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsViewBinder.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsViewBinder.java
@@ -21,7 +21,9 @@ import android.text.TextUtils; import android.util.TypedValue; import android.view.View; +import android.view.ViewGroup; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.StyleRes; @@ -90,6 +92,8 @@ private final int mImageHeight; private final int mPulseAnimationStartColor; private final int mPulseAnimationEndColor; + private final int mTextPlaceholdersHeight; + private final int mTextPlaceholdersMargin; private ValueAnimator mPulseAnimation; private ImageFetcher mImageFetcher; @@ -102,6 +106,10 @@ R.dimen.autofill_assistant_details_image_size); mPulseAnimationStartColor = context.getResources().getColor(R.color.modern_grey_300); mPulseAnimationEndColor = context.getResources().getColor(R.color.modern_grey_200); + mTextPlaceholdersHeight = context.getResources().getDimensionPixelSize( + R.dimen.autofill_assistant_details_text_placeholders_height); + mTextPlaceholdersMargin = context.getResources().getDimensionPixelSize( + R.dimen.autofill_assistant_details_text_placeholders_margin); mImageFetcher = imageFetcher; } @@ -144,21 +152,44 @@ AssistantTextUtils.applyVisualAppearanceTags( viewHolder.mPriceAttributionView, details.getPriceAttribution(), null); + AssistantPlaceholdersConfiguration placeholders = details.getPlaceholdersConfiguration(); + boolean hideDescriptionLine1 = details.getDescriptionLine1().isEmpty() + && !placeholders.getShowDescriptionLine1Placeholder(); + boolean hideDescriptionLine2 = details.getDescriptionLine2().isEmpty() + && !placeholders.getShowDescriptionLine2Placeholder(); + boolean hideDescriptionLine3 = details.getDescriptionLine3().isEmpty() + && !placeholders.getShowDescriptionLine3Placeholder(); + // Allow title line wrapping according to number of maximum allowed lines. - if (details.getTitleMaxLines() == 1) { + // TODO(crbug.com/806868): Should we move the hide/placeholders/maxLines logic to C++? + int titleMaxLines = 1; + if (hideDescriptionLine1) titleMaxLines++; + if (hideDescriptionLine2) titleMaxLines++; + + if (titleMaxLines == 1) { viewHolder.mTitleView.setSingleLine(true); viewHolder.mTitleView.setEllipsize(null); } else { viewHolder.mTitleView.setSingleLine(false); - viewHolder.mTitleView.setMaxLines(details.getTitleMaxLines()); + viewHolder.mTitleView.setMaxLines(titleMaxLines); viewHolder.mTitleView.setEllipsize(TextUtils.TruncateAt.END); } - hideIfEmpty(viewHolder.mDescriptionLine1View); - hideIfEmpty(viewHolder.mDescriptionLine2View); - hideIfEmpty(viewHolder.mDescriptionLine3View); + // Hide views without text or placeholders. + hideIf(viewHolder.mDescriptionLine1View, hideDescriptionLine1); + hideIf(viewHolder.mDescriptionLine2View, hideDescriptionLine2); + hideIf(viewHolder.mDescriptionLine3View, hideDescriptionLine3); hideIfEmpty(viewHolder.mPriceAttributionView); + // Set the height of the potential placeholders next to the image. + setTextHeightAndMargin(viewHolder.mTitleView, placeholders.getShowTitlePlaceholder()); + setTextHeightAndMargin(viewHolder.mDescriptionLine1View, + placeholders.getShowDescriptionLine1Placeholder()); + setTextHeightAndMargin(viewHolder.mDescriptionLine2View, + placeholders.getShowDescriptionLine2Placeholder()); + setTextHeightAndMargin(viewHolder.mDescriptionLine3View, + placeholders.getShowDescriptionLine3Placeholder()); + // If no price provided, hide the price view (containing separator, price label, and price). viewHolder.mPriceView.setVisibility( details.getTotalPrice().isEmpty() ? View.GONE : View.VISIBLE); @@ -167,7 +198,7 @@ setAccessibility(viewHolder.mImageView, details.getImageAccessibilityHint()); if (details.getImageUrl().isEmpty()) { - if (details.getShowImagePlaceholder()) { + if (placeholders.getShowImagePlaceholder()) { viewHolder.mImageView.setImageDrawable(viewHolder.mDefaultImage); viewHolder.mImageView.setOnClickListener(null); } else { @@ -197,7 +228,27 @@ } private void hideIfEmpty(TextView view) { - view.setVisibility(view.length() == 0 ? View.GONE : View.VISIBLE); + hideIf(view, view.length() == 0); + } + + private void hideIf(TextView view, boolean hide) { + view.setVisibility(hide ? View.GONE : View.VISIBLE); + } + + private void setTextHeightAndMargin(TextView view, boolean isPlaceholder) { + LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) view.getLayoutParams(); + + if (isPlaceholder) { + layoutParams.height = mTextPlaceholdersHeight; + layoutParams.topMargin = mTextPlaceholdersMargin; + layoutParams.bottomMargin = mTextPlaceholdersMargin; + } else { + layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT; + layoutParams.topMargin = 0; + layoutParams.bottomMargin = 0; + } + + view.setLayoutParams(layoutParams); } private void setTextStyles(AssistantDetails details, ViewHolder viewHolder) { @@ -217,21 +268,19 @@ setTextStyle(viewHolder.mTotalPriceView, details.getUserApprovalRequired(), /* highlight= */ false, R.style.TextAppearance_AssistantDetailsPrice); - if (shouldStartOrContinuePlaceholderAnimation(details, viewHolder)) { - startOrContinuePlaceholderAnimations(viewHolder); + if (shouldStartOrContinuePlaceholderAnimation(details.getPlaceholdersConfiguration())) { + startOrContinuePlaceholderAnimations(details, viewHolder); } else { stopPlaceholderAnimations(); } } private boolean shouldStartOrContinuePlaceholderAnimation( - AssistantDetails details, ViewHolder viewHolder) { - boolean isAtLeastOneFieldEmpty = viewHolder.mTitleView.length() == 0 - || viewHolder.mDescriptionLine1View.length() == 0 - || viewHolder.mDescriptionLine2View.length() == 0 - || viewHolder.mDescriptionLine3View.length() == 0 - || viewHolder.mImageView.getDrawable() == viewHolder.mDefaultImage; - return details.getAnimatePlaceholders() && isAtLeastOneFieldEmpty; + AssistantPlaceholdersConfiguration placeholders) { + return placeholders.getShowImagePlaceholder() || placeholders.getShowTitlePlaceholder() + || placeholders.getShowDescriptionLine1Placeholder() + || placeholders.getShowDescriptionLine2Placeholder() + || placeholders.getShowDescriptionLine3Placeholder(); } private void setTextStyle( @@ -258,7 +307,8 @@ return roundedBitmap; } - private void startOrContinuePlaceholderAnimations(ViewHolder viewHolder) { + private void startOrContinuePlaceholderAnimations( + AssistantDetails details, ViewHolder viewHolder) { if (mPulseAnimation != null) { return; } @@ -278,23 +328,23 @@ viewHolder.mDefaultImage.setColor(Color.TRANSPARENT); } }); + + AssistantPlaceholdersConfiguration placeholders = details.getPlaceholdersConfiguration(); mPulseAnimation.addUpdateListener(animation -> { int animatedValue = (int) animation.getAnimatedValue(); viewHolder.mTitleView.setBackgroundColor( - viewHolder.mTitleView.length() == 0 ? animatedValue : Color.TRANSPARENT); + placeholders.getShowTitlePlaceholder() ? animatedValue : Color.TRANSPARENT); viewHolder.mDescriptionLine1View.setBackgroundColor( - viewHolder.mDescriptionLine1View.length() == 0 ? animatedValue - : Color.TRANSPARENT); + placeholders.getShowDescriptionLine1Placeholder() ? animatedValue + : Color.TRANSPARENT); viewHolder.mDescriptionLine2View.setBackgroundColor( - viewHolder.mDescriptionLine2View.length() == 0 ? animatedValue - : Color.TRANSPARENT); + placeholders.getShowDescriptionLine2Placeholder() ? animatedValue + : Color.TRANSPARENT); viewHolder.mDescriptionLine3View.setBackgroundColor( - viewHolder.mDescriptionLine3View.length() == 0 ? animatedValue - : Color.TRANSPARENT); + placeholders.getShowDescriptionLine3Placeholder() ? animatedValue + : Color.TRANSPARENT); viewHolder.mDefaultImage.setColor( - viewHolder.mImageView.getDrawable() == viewHolder.mDefaultImage - ? animatedValue - : Color.TRANSPARENT); + placeholders.getShowImagePlaceholder() ? animatedValue : Color.TRANSPARENT); }); mPulseAnimation.start(); }
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantPlaceholdersConfiguration.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantPlaceholdersConfiguration.java new file mode 100644 index 0000000..96dce445 --- /dev/null +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantPlaceholdersConfiguration.java
@@ -0,0 +1,51 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.autofill_assistant.details; + +import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.JNINamespace; + +/** + * Configuration for the details placeholders. + */ +@JNINamespace("autofill_assistant") +public class AssistantPlaceholdersConfiguration { + private final boolean mShowImagePlaceholder; + private final boolean mShowTitlePlaceholder; + private final boolean mShowDescriptionLine1Placeholder; + private final boolean mShowDescriptionLine2Placeholder; + private final boolean mShowDescriptionLine3Placeholder; + + @CalledByNative + public AssistantPlaceholdersConfiguration(boolean showImagePlaceholder, + boolean showTitlePlaceholder, boolean showDescriptionLine1Placeholder, + boolean showDescriptionLine2Placeholder, boolean showDescriptionLine3Placeholder) { + mShowImagePlaceholder = showImagePlaceholder; + mShowTitlePlaceholder = showTitlePlaceholder; + mShowDescriptionLine1Placeholder = showDescriptionLine1Placeholder; + mShowDescriptionLine2Placeholder = showDescriptionLine2Placeholder; + mShowDescriptionLine3Placeholder = showDescriptionLine3Placeholder; + } + + public boolean getShowImagePlaceholder() { + return mShowImagePlaceholder; + } + + public boolean getShowTitlePlaceholder() { + return mShowTitlePlaceholder; + } + + public boolean getShowDescriptionLine1Placeholder() { + return mShowDescriptionLine1Placeholder; + } + + public boolean getShowDescriptionLine2Placeholder() { + return mShowDescriptionLine2Placeholder; + } + + public boolean getShowDescriptionLine3Placeholder() { + return mShowDescriptionLine3Placeholder; + } +}
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/trigger_scripts/AssistantTriggerScript.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/trigger_scripts/AssistantTriggerScript.java index 54e8011..e2f2580 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/trigger_scripts/AssistantTriggerScript.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/trigger_scripts/AssistantTriggerScript.java
@@ -20,6 +20,7 @@ import org.chromium.chrome.browser.autofill_assistant.AssistantRootViewContainer; import org.chromium.chrome.browser.autofill_assistant.BottomSheetUtils; import org.chromium.chrome.browser.autofill_assistant.LayoutUtils; +import org.chromium.chrome.browser.autofill_assistant.ScrollToHideGestureListener; import org.chromium.chrome.browser.autofill_assistant.carousel.AssistantChip; import org.chromium.chrome.browser.autofill_assistant.carousel.AssistantChipViewHolder; import org.chromium.chrome.browser.autofill_assistant.generic_ui.AssistantDimension; @@ -30,6 +31,7 @@ import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.StateChangeReason; import org.chromium.components.browser_ui.bottomsheet.BottomSheetObserver; import org.chromium.components.browser_ui.bottomsheet.EmptyBottomSheetObserver; +import org.chromium.content_public.browser.GestureListenerManager; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.base.ApplicationViewportInsetSupplier; @@ -60,6 +62,7 @@ private AssistantHeaderCoordinator mHeaderCoordinator; private AssistantHeaderModel mHeaderModel; + private ScrollToHideGestureListener mGestureListener; private LinearLayout mChipsContainer; private final int mInnerChipSpacing; /** Height of the bottom sheet's shadow, used to compute the viewport resize offset. */ @@ -152,6 +155,7 @@ } public void destroy() { + disableScrollToHide(); mBottomSheetController.removeObserver(mBottomSheetObserver); if (mHeaderCoordinator != null) { mHeaderCoordinator.destroy(); @@ -250,7 +254,7 @@ addChipsToContainer(mChipsContainer, mRightAlignedChips); } - public boolean show(boolean resizeVisualViewport) { + public boolean show(boolean resizeVisualViewport, boolean scrollToHide) { if (mHeaderModel == null || mHeaderCoordinator == null) { assert false : "createHeaderAndGetModel() must be called before show()"; return false; @@ -262,10 +266,14 @@ mBottomSheetController.addObserver(mBottomSheetObserver); BottomSheetUtils.showContentAndMaybeExpand(mBottomSheetController, mContent, /* shouldExpand = */ true, /* animate = */ mAnimateBottomSheet); + + if (scrollToHide) enableScrollToHide(); + return true; } public void hide() { + disableScrollToHide(); mBottomSheetController.removeObserver(mBottomSheetObserver); mBottomSheetController.hideContent(mContent, /* animate = */ mAnimateBottomSheet); mResizeVisualViewport = false; @@ -297,4 +305,18 @@ mInsetSupplier.set(resizing); } + + private void disableScrollToHide() { + if (mGestureListener == null) return; + + GestureListenerManager.fromWebContents(mWebContents).removeListener(mGestureListener); + mGestureListener = null; + } + + private void enableScrollToHide() { + if (mGestureListener != null) return; + + mGestureListener = new ScrollToHideGestureListener(mBottomSheetController, mContent); + GestureListenerManager.fromWebContents(mWebContents).addListener(mGestureListener); + } }
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/trigger_scripts/AssistantTriggerScriptBridge.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/trigger_scripts/AssistantTriggerScriptBridge.java index 9f0c648..7a8ca25 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/trigger_scripts/AssistantTriggerScriptBridge.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/trigger_scripts/AssistantTriggerScriptBridge.java
@@ -143,7 +143,7 @@ private boolean showTriggerScript(String[] cancelPopupMenuItems, int[] cancelPopupMenuActions, List<AssistantChip> leftAlignedChips, int[] leftAlignedChipsActions, List<AssistantChip> rightAlignedChips, int[] rightAlignedChipsActions, - boolean resizeVisualViewport) { + boolean resizeVisualViewport, boolean scrollToHide) { // Trigger scripts currently do not support switching activities (such as CCT->tab). // TODO(b/171776026): Re-inject dependencies on activity change to support CCT->tab. if (TabUtils.getActivity(TabUtils.fromWebContents(mWebContents)) != mContext) { @@ -154,7 +154,7 @@ mTriggerScript.setCancelPopupMenu(cancelPopupMenuItems, cancelPopupMenuActions); mTriggerScript.setLeftAlignedChips(leftAlignedChips, leftAlignedChipsActions); mTriggerScript.setRightAlignedChips(rightAlignedChips, rightAlignedChipsActions); - boolean shown = mTriggerScript.show(resizeVisualViewport); + boolean shown = mTriggerScript.show(resizeVisualViewport, scrollToHide); // A trigger script was displayed, users are no longer considered first-time users. if (shown) {
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 3de3cca..4fc8276 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
@@ -153,7 +153,10 @@ .setShowDetails(ShowDetailsProto.newBuilder().setDetails( DetailsProto.newBuilder() .setTitle("Details title") - .setShowImagePlaceholder(true))) + .setPlaceholders(DetailsProto.PlaceholdersConfiguration + .newBuilder() + .setShowImagePlaceholder(true) + .build()))) .build()); } // Add "Done" button.
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDetailsUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDetailsUiTest.java index cbd0968..c77c01f 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDetailsUiTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDetailsUiTest.java
@@ -45,6 +45,7 @@ import org.chromium.chrome.browser.autofill_assistant.details.AssistantDetails; import org.chromium.chrome.browser.autofill_assistant.details.AssistantDetailsCoordinator; import org.chromium.chrome.browser.autofill_assistant.details.AssistantDetailsModel; +import org.chromium.chrome.browser.autofill_assistant.details.AssistantPlaceholdersConfiguration; import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; @@ -53,6 +54,14 @@ @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) @RunWith(ChromeJUnit4ClassRunner.class) public class AutofillAssistantDetailsUiTest { + public static final AssistantPlaceholdersConfiguration NO_PLACEHOLDERS = + new AssistantPlaceholdersConfiguration( + /* showImagePlaceholder= */ false, + /* showTitlePlaceholder= */ false, + /* showDescriptionLine1Placeholder= */ false, + /* showDescriptionLine2Placeholder= */ false, + /* showDescriptionLine3Placeholder= */ false); + @Rule public CustomTabActivityTestRule mTestRule = new CustomTabActivityTestRule(); @@ -123,9 +132,9 @@ runOnUiThreadBlocking(() -> { model.set(AssistantDetailsModel.DETAILS, - new AssistantDetails("title", 1, "image", "hint", null, false, "Total", "$12", - "line 1", "line 2", "", "line 3", false, false, false, false, false, - false)); + new AssistantDetails("title", "image", "hint", null, "Total", "$12", "line 1", + "line 2", "", "line 3", false, false, false, false, false, + NO_PLACEHOLDERS)); }); onView(is(viewHolder.mImageView)).check(matches(isDisplayed())); @@ -148,9 +157,9 @@ runOnUiThreadBlocking(() -> { model.set(AssistantDetailsModel.DETAILS, - new AssistantDetails("title", 1, "image", "hint", null, false, "Total", "$12", - "line 1", "line 2", "", "line 3", false, false, false, false, false, - false)); + new AssistantDetails("title", "image", "hint", null, "Total", "$12", "line 1", + "line 2", "", "line 3", false, false, false, false, false, + NO_PLACEHOLDERS)); }); onView(is(viewHolder.mImageView)).check(matches(withContentDescription("hint"))); @@ -167,9 +176,9 @@ runOnUiThreadBlocking(() -> { model.set(AssistantDetailsModel.DETAILS, - new AssistantDetails("title", 1, "image", "", null, false, "Total", "$12", - "line 1", "line 2", "", "line 3", false, false, false, false, false, - false)); + new AssistantDetails("title", "image", "", null, "Total", "$12", "line 1", + "line 2", "", "line 3", false, false, false, false, false, + NO_PLACEHOLDERS)); }); onView(is(viewHolder.mImageView)).check(matches(withContentDescription(""))); @@ -184,25 +193,73 @@ AssistantDetailsCoordinator coordinator = createCoordinator(model); ViewHolder viewHolder = runOnUiThreadBlocking(() -> new ViewHolder(coordinator.getView())); - /* All description lines are set, title must be in single line. */ + /* Description lines 1 and 2 are set, title must be in single line. */ runOnUiThreadBlocking( () -> model.set(AssistantDetailsModel.DETAILS, - new AssistantDetails("title", 1, "image", "hint", null, false, - "Total", "$12", "line 1", "line 2", "", "line 3", false, - false, false, false, false, false))); + new AssistantDetails("title", "image", "hint", null, "Total", "$12", + "line 1", "line 2", "", "price", false, false, false, false, + false, NO_PLACEHOLDERS))); onView(is(viewHolder.mTitleView)).check(matches(isTextMaxLines(1))); onView(is(viewHolder.mTitleView)).check(matches(allOf(withText("title"), isDisplayed()))); - /* titleMaxLines is set to 2, check that it is properly applied. */ + /* Description line 1 is set, title must be max 2 lines. */ runOnUiThreadBlocking( () -> model.set(AssistantDetailsModel.DETAILS, - new AssistantDetails("title", 2, "image", "hint", null, false, - "Total", "$12", "line 1", "", "", "line 3", false, false, - false, false, false, false))); + new AssistantDetails("title", "image", "hint", null, "Total", "$12", + "line 1", "", "", "price", false, false, false, false, + false, NO_PLACEHOLDERS))); onView(is(viewHolder.mTitleView)).check(matches(isTextMaxLines(2))); onView(is(viewHolder.mTitleView)).check(matches(allOf(withText("title"), isDisplayed()))); + + /* Description line 2 is set, title must be max 2 lines. */ + runOnUiThreadBlocking( + () + -> model.set(AssistantDetailsModel.DETAILS, + new AssistantDetails("title", "image", "hint", null, "Total", "$12", + "", "line 2", "", "price", false, false, false, false, + false, NO_PLACEHOLDERS))); + onView(is(viewHolder.mTitleView)).check(matches(isTextMaxLines(2))); + onView(is(viewHolder.mTitleView)).check(matches(allOf(withText("title"), isDisplayed()))); + + /* None of description line 1 or 2 is set, title must be max 3 lines. */ + runOnUiThreadBlocking( + () + -> model.set(AssistantDetailsModel.DETAILS, + new AssistantDetails("title", "image", "hint", null, "Total", "$12", + "", "", "", "price", false, false, false, false, false, + NO_PLACEHOLDERS))); + onView(is(viewHolder.mTitleView)).check(matches(isTextMaxLines(3))); + onView(is(viewHolder.mTitleView)).check(matches(allOf(withText("title"), isDisplayed()))); + + /* There is a placeholder for description line 1, title must be max 2 lines. */ + runOnUiThreadBlocking( + () + -> model.set(AssistantDetailsModel.DETAILS, + new AssistantDetails("title", "image", "hint", null, "Total", "$12", + "", "", "", "price", false, false, false, false, false, + new AssistantPlaceholdersConfiguration( + /* showImagePlaceholder= */ false, + /* showTitlePlaceholder= */ false, + /* showDescriptionLine1Placeholder= */ true, + /* showDescriptionLine2Placeholder= */ false, + /* showDescriptionLine3Placeholder= */ false)))); + onView(is(viewHolder.mTitleView)).check(matches(isTextMaxLines(2))); + + /* There is a placeholder for description line 1 & 2, title must be max 1 line. */ + runOnUiThreadBlocking( + () + -> model.set(AssistantDetailsModel.DETAILS, + new AssistantDetails("title", "image", "hint", null, "Total", "$12", + "", "", "", "price", false, false, false, false, false, + new AssistantPlaceholdersConfiguration( + /* showImagePlaceholder= */ false, + /* showTitlePlaceholder= */ false, + /* showDescriptionLine1Placeholder= */ true, + /* showDescriptionLine2Placeholder= */ true, + /* showDescriptionLine3Placeholder= */ false)))); + onView(is(viewHolder.mTitleView)).check(matches(isTextMaxLines(1))); } @Test @@ -215,18 +272,18 @@ /* Description line 1 is set and should be visible. */ runOnUiThreadBlocking(() -> model.set(AssistantDetailsModel.DETAILS, - new AssistantDetails("title", 1, "image", "hint", - null, false, "", "", "line 1", "", "", "", - false, false, false, false, false, false))); + new AssistantDetails("title", "image", "hint", null, + "", "", "line 1", "", "", "", false, false, + false, false, false, NO_PLACEHOLDERS))); onView(is(viewHolder.mDescriptionLine1View)) .check(matches(allOf(withText("line 1"), isDisplayed()))); /* Description line 1 is not set and should be invisible. */ runOnUiThreadBlocking(() -> model.set(AssistantDetailsModel.DETAILS, - new AssistantDetails("title", 1, "image", "hint", - null, false, "", "", "", "", "", "", false, - false, false, false, false, false))); + new AssistantDetails("title", "image", "hint", null, + "", "", "", "", "", "", false, false, false, + false, false, NO_PLACEHOLDERS))); onView(is(viewHolder.mDescriptionLine1View)).check(matches(not(isDisplayed()))); } @@ -240,18 +297,18 @@ /* Description line 2 is set and should be visible. */ runOnUiThreadBlocking(() -> model.set(AssistantDetailsModel.DETAILS, - new AssistantDetails("title", 1, "image", "hint", - null, false, "", "", "", "line 2", "", "", - false, false, false, false, false, false))); + new AssistantDetails("title", "image", "hint", null, + "", "", "", "line 2", "", "", false, false, + false, false, false, NO_PLACEHOLDERS))); onView(is(viewHolder.mDescriptionLine2View)) .check(matches(allOf(withText("line 2"), isDisplayed()))); /* Description line 2 is not set and should be invisible. */ runOnUiThreadBlocking(() -> model.set(AssistantDetailsModel.DETAILS, - new AssistantDetails("title", 2, "image", "hint", - null, false, "", "", "", "", "", "", false, - false, false, false, false, false))); + new AssistantDetails("title", "image", "hint", null, + "", "", "", "", "", "", false, false, false, + false, false, NO_PLACEHOLDERS))); onView(is(viewHolder.mDescriptionLine2View)).check(matches(not(isDisplayed()))); } @@ -265,18 +322,18 @@ /* Description line 3 is set and should be visible. */ runOnUiThreadBlocking(() -> model.set(AssistantDetailsModel.DETAILS, - new AssistantDetails("title", 1, "image", "hint", - null, false, "", "", "", "", "line 3", "", - false, false, false, false, false, false))); + new AssistantDetails("title", "image", "hint", null, + "", "", "", "", "line 3", "", false, false, + false, false, false, NO_PLACEHOLDERS))); onView(is(viewHolder.mDescriptionLine3View)) .check(matches(allOf(withText("line 3"), isDisplayed()))); /* Description line 3 is not set and should be invisible. */ runOnUiThreadBlocking(() -> model.set(AssistantDetailsModel.DETAILS, - new AssistantDetails("title", 1, "image", "hint", - null, false, "", "", "", "", "", "line 3", - false, false, false, false, false, false))); + new AssistantDetails("title", "image", "hint", null, + "", "", "", "", "", "line 3", false, false, + false, false, false, NO_PLACEHOLDERS))); onView(is(viewHolder.mDescriptionLine3View)).check(matches(not(isDisplayed()))); } @@ -291,18 +348,18 @@ runOnUiThreadBlocking( () -> model.set(AssistantDetailsModel.DETAILS, - new AssistantDetails("title", 1, "image", "hint", null, false, - "Total", "$12", "", "", "", "price attribution", false, - false, false, false, false, false))); + new AssistantDetails("title", "image", "hint", null, "Total", "$12", + "", "", "", "price attribution", false, false, false, false, + false, NO_PLACEHOLDERS))); onView(is(viewHolder.mPriceAttributionView)) .check(matches(allOf(withText("price attribution"), isDisplayed()))); /* Price attribution is not set and should be invisible. */ runOnUiThreadBlocking(() -> model.set(AssistantDetailsModel.DETAILS, - new AssistantDetails("title", 2, "image", "hint", - null, false, "", "", "", "", "", "", false, - false, false, false, false, false))); + new AssistantDetails("title", "image", "hint", null, + "", "", "", "", "", "", false, false, false, + false, false, NO_PLACEHOLDERS))); onView(is(viewHolder.mPriceAttributionView)).check(matches(not(isDisplayed()))); } @@ -317,9 +374,9 @@ runOnUiThreadBlocking( () -> model.set(AssistantDetailsModel.DETAILS, - new AssistantDetails("title", 1, "image", "hint", null, false, - "Total", "$12", "line 1", "line 2", "line 3", "Est. total", - true, true, false, false, false, false))); + new AssistantDetails("title", "image", "hint", null, "Total", "$12", + "line 1", "line 2", "line 3", "Est. total", true, true, + false, false, false, NO_PLACEHOLDERS))); onView(is(viewHolder.mTitleView)).check(matches(hasTypefaceStyle(Typeface.BOLD_ITALIC))); onView(is(viewHolder.mDescriptionLine1View)) .check(matches(not(hasTypefaceStyle(Typeface.BOLD_ITALIC)))); @@ -334,9 +391,9 @@ runOnUiThreadBlocking( () -> model.set(AssistantDetailsModel.DETAILS, - new AssistantDetails("title", 1, "image", "hint", null, false, - "Total", "$12", "line 1", "line 2", "line 3", "Est. total", - true, false, true, false, false, false))); + new AssistantDetails("title", "image", "hint", null, "Total", "$12", + "line 1", "line 2", "line 3", "Est. total", true, false, + true, false, false, NO_PLACEHOLDERS))); onView(is(viewHolder.mTitleView)) .check(matches(not(hasTypefaceStyle(Typeface.BOLD_ITALIC)))); onView(is(viewHolder.mDescriptionLine1View)) @@ -352,9 +409,9 @@ runOnUiThreadBlocking( () -> model.set(AssistantDetailsModel.DETAILS, - new AssistantDetails("title", 1, "image", "hint", null, false, - "Total", "$12", "line 1", "line 2", "line 3", "Est. total", - true, false, false, true, false, false))); + new AssistantDetails("title", "image", "hint", null, "Total", "$12", + "line 1", "line 2", "line 3", "Est. total", true, false, + false, true, false, NO_PLACEHOLDERS))); onView(is(viewHolder.mTitleView)) .check(matches(not(hasTypefaceStyle(Typeface.BOLD_ITALIC)))); onView(is(viewHolder.mDescriptionLine1View)) @@ -370,9 +427,9 @@ runOnUiThreadBlocking( () -> model.set(AssistantDetailsModel.DETAILS, - new AssistantDetails("title", 1, "image", "hint", null, false, - "Total", "$12", "line 1", "line 2", "line 3", "Est. total", - true, false, false, false, true, false))); + new AssistantDetails("title", "image", "hint", null, "Total", "$12", + "line 1", "line 2", "line 3", "Est. total", true, false, + false, false, true, NO_PLACEHOLDERS))); onView(is(viewHolder.mTitleView)) .check(matches(not(hasTypefaceStyle(Typeface.BOLD_ITALIC)))); onView(is(viewHolder.mDescriptionLine1View)) @@ -394,9 +451,9 @@ runOnUiThreadBlocking(() -> { model.set(AssistantDetailsModel.DETAILS, - new AssistantDetails("<b>title</b>", 1, "image", "hint", null, false, - "<b>Total</b>", "<b>$12</b>", "<b>line 1</b>", "<b>line 2</b>", "", - "<b>line 3</b>", false, false, false, false, false, false)); + new AssistantDetails("<b>title</b>", "image", "hint", null, "<b>Total</b>", + "<b>$12</b>", "<b>line 1</b>", "<b>line 2</b>", "", "<b>line 3</b>", + false, false, false, false, false, NO_PLACEHOLDERS)); }); onView(withText("title")) @@ -412,4 +469,43 @@ onView(withText("line 3")) .check(matches(hasTypefaceSpan(0, "line 3".length() - 1, Typeface.BOLD))); } + + @Test + @MediumTest + public void testPlaceholders() throws Exception { + AssistantDetailsModel model = new AssistantDetailsModel(); + AssistantDetailsCoordinator coordinator = createCoordinator(model); + ViewHolder viewHolder = runOnUiThreadBlocking(() -> new ViewHolder(coordinator.getView())); + + // Without placeholders, the image and descriptions are hidden. The title is always + // displayed. + runOnUiThreadBlocking( + () + -> model.set(AssistantDetailsModel.DETAILS, + new AssistantDetails("title", "", "hint", null, "", "", "", "", "", + "", false, false, false, false, false, NO_PLACEHOLDERS))); + onView(is(viewHolder.mTitleView)).check(matches(isDisplayed())); + onView(is(viewHolder.mImageView)).check(matches(not(isDisplayed()))); + onView(is(viewHolder.mDescriptionLine1View)).check(matches(not(isDisplayed()))); + onView(is(viewHolder.mDescriptionLine2View)).check(matches(not(isDisplayed()))); + onView(is(viewHolder.mDescriptionLine3View)).check(matches(not(isDisplayed()))); + + // With placeholders, the image and descriptions are displayed. + runOnUiThreadBlocking( + () + -> model.set(AssistantDetailsModel.DETAILS, + new AssistantDetails("title", "", "hint", null, "", "", "", "", "", + "", false, false, false, false, false, + new AssistantPlaceholdersConfiguration( + /* showImagePlaceholder= */ true, + /* showTitlePlaceholder= */ true, + /* showDescriptionLine1Placeholder= */ true, + /* showDescriptionLine2Placeholder= */ true, + /* showDescriptionLine3Placeholder= */ true)))); + onView(is(viewHolder.mTitleView)).check(matches(isDisplayed())); + onView(is(viewHolder.mImageView)).check(matches(isDisplayed())); + onView(is(viewHolder.mDescriptionLine1View)).check(matches(isDisplayed())); + onView(is(viewHolder.mDescriptionLine2View)).check(matches(isDisplayed())); + onView(is(viewHolder.mDescriptionLine3View)).check(matches(isDisplayed())); + } }
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTriggerScriptIntegrationTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTriggerScriptIntegrationTest.java index 3127202e..ae0e668 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTriggerScriptIntegrationTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTriggerScriptIntegrationTest.java
@@ -15,6 +15,8 @@ import static androidx.test.espresso.matcher.ViewMatchers.withText; import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.greaterThan; import static org.chromium.base.test.util.CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL; import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.tapElement; @@ -35,6 +37,7 @@ import org.junit.Test; import org.junit.runner.RunWith; +import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.DisableIf; import org.chromium.chrome.autofill_assistant.R; @@ -63,7 +66,12 @@ import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.browser.Features; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; +import org.chromium.content_public.browser.GestureListenerManager; +import org.chromium.content_public.browser.GestureStateListener; +import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.test.util.TestThreadUtils; +import org.chromium.content_public.browser.test.util.TouchCommon; import org.chromium.net.test.EmbeddedTestServer; import java.util.ArrayList; @@ -572,4 +580,80 @@ Espresso.pressBack(); waitUntilViewMatchesCondition(withText("Hello world"), isCompletelyDisplayed()); } + + @Test + @MediumTest + @Features.EnableFeatures({ChromeFeatureList.AUTOFILL_ASSISTANT_DISABLE_ONBOARDING_FLOW, + ChromeFeatureList.AUTOFILL_ASSISTANT_PROACTIVE_HELP}) + public void + testScrollToHide() throws Exception { + GetTriggerScriptsResponseProto triggerScripts = + GetTriggerScriptsResponseProto.newBuilder() + .addTriggerScripts( + TriggerScriptProto + .newBuilder() + /* no trigger condition */ + .setUserInterface(createDefaultUI("Trigger script", + /* bubbleMessage = */ "", + /* withProgressBar = */ false) + .setScrollToHide(true))) + .build(); + + setupTriggerScripts(triggerScripts); + AutofillAssistantPreferencesUtil.setInitialPreferences(false); + startAutofillAssistantOnTab(TEST_PAGE_A); + + waitUntilViewMatchesCondition(withText("Trigger script"), isCompletelyDisplayed()); + + BottomSheetController bottomSheetController = + AutofillAssistantUiTestUtil.getBottomSheetController(mTestRule.getActivity()); + + CallbackHelper waitForScroll = new CallbackHelper(); + WebContents webContents = mTestRule.getWebContents(); + TestThreadUtils.runOnUiThreadBlocking(() -> { + GestureListenerManager.fromWebContents(webContents) + .addListener(new GestureStateListener() { + @Override + public void onScrollEnded(int scrollOffsetY, int scrollExtentY) { + waitForScroll.notifyCalled(); + } + }); + }); + int webContentX = TestThreadUtils.runOnUiThreadBlocking( + () -> webContents.getViewAndroidDelegate().getContainerView().getWidth() / 2); + int webContentY = TestThreadUtils.runOnUiThreadBlocking( + () -> webContents.getViewAndroidDelegate().getContainerView().getHeight() / 3); + + int offsetBeforeScroll = TestThreadUtils.runOnUiThreadBlocking( + () -> bottomSheetController.getCurrentOffset()); + assertThat(offsetBeforeScroll, greaterThan(0)); + + // Scroll more than the bottom sheet height, to be sure it's going to be completely hidden + // or shown due to the scroll. + int scrollDistance = (int) (bottomSheetController.getCurrentOffset() * 1.5f); + TouchCommon.performDrag(mTestRule.getActivity(), webContentX, webContentX, webContentY, + webContentY - scrollDistance, + /* stepCount*/ 10, /* duration in ms */ 250); + waitForScroll.waitForCallback("scroll down expected", /* currentCallCount= */ 0); + + // After scroll down, the bottom sheet is completely hidden. + int offsetAfterScrollDown = TestThreadUtils.runOnUiThreadBlocking( + () -> bottomSheetController.getCurrentOffset()); + Assert.assertEquals(0, offsetAfterScrollDown); + + TouchCommon.performDrag(mTestRule.getActivity(), webContentX, webContentX, webContentY, + webContentY + scrollDistance, /* stepCount*/ 10, /* duration in ms */ 250); + + waitForScroll.waitForCallback("scroll up expected", /* currentCallCount= */ 1); + + // Wait until the bottom sheet is fully back on the screen again before capturing one last + // offset. + waitUntilViewMatchesCondition(withText("Trigger script"), isCompletelyDisplayed()); + + int offsetAfterScrollUp = TestThreadUtils.runOnUiThreadBlocking( + () -> bottomSheetController.getCurrentOffset()); + + // After scroll up, the bottom sheet is visible again. + Assert.assertEquals(offsetBeforeScroll, offsetAfterScrollUp); + } }
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java index 0ebc2c2..0f54bcd 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java
@@ -182,11 +182,10 @@ () -> assistantCoordinator.getModel().getDetailsModel().set( AssistantDetailsModel.DETAILS, - new AssistantDetails(movieTitle, /* titleMaxLines = */ 1, + new AssistantDetails(movieTitle, /* imageUrl = */ "", /* imageAccessibilityHint = */ "", /* imageClickthroughData = */ null, - /* showImage = */ false, /* totalPriceLabel = */ "", /* totalPrice = */ "", descriptionLine1, descriptionLine2, descriptionLine3, @@ -195,7 +194,7 @@ /* highlightTitle= */ false, /* highlightLine1= */ false, /* highlightLine2 = */ false, /* highlightLine3 = */ false, - /* animatePlaceholders= */ false))); + AutofillAssistantDetailsUiTest.NO_PLACEHOLDERS))); onView(withId(R.id.details_title)) .check(matches(allOf(withText(movieTitle), withEffectiveVisibility(VISIBLE)))); onView(withId(R.id.details_line1))
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 0064f94..2a0abbae 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -30,6 +30,9 @@ import androidx.annotation.IntDef; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleObserver; +import androidx.lifecycle.LifecycleRegistry; import org.chromium.base.CallbackController; import org.chromium.base.CommandLine; @@ -39,6 +42,7 @@ import org.chromium.base.MemoryPressureListener; import org.chromium.base.ThreadUtils; import org.chromium.base.TraceEvent; +import org.chromium.base.annotations.UsedByReflection; import org.chromium.base.library_loader.LibraryLoader; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; @@ -329,6 +333,32 @@ }; /** + * This class is used to warm up the chrome split ClassLoader. See SplitChromeApplication for + * more info + */ + @UsedByReflection("SplitChromeApplication.java") + public static class Preload extends ChromeTabbedActivity { + private LifecycleRegistry mLifecycleRegistry; + + @UsedByReflection("SplitChromeApplication.java") + public Preload() {} + + @Override + public Lifecycle getLifecycle() { + if (mLifecycleRegistry == null) { + // LifecycleRegistry normally enforces it is called on the main thread, but this + // class will be preloaded in a background thread. The only method that gets called + // in the activity constructor is addObserver(), so just override that. + mLifecycleRegistry = new LifecycleRegistry(null) { + @Override + public void addObserver(LifecycleObserver observer) {} + }; + } + return mLifecycleRegistry; + } + } + + /** * Return whether the passed in component name matches any of the supported tabbed mode * activities. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitChromeApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitChromeApplication.java index 02c41c9..c4d7280 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitChromeApplication.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitChromeApplication.java
@@ -11,6 +11,8 @@ import android.content.Context; import android.content.pm.PackageManager; import android.os.Build; +import android.os.Handler; +import android.os.HandlerThread; import android.os.SystemClock; import org.chromium.base.ActivityState; @@ -92,18 +94,46 @@ // If the chrome module is not enabled or isolated splits are not supported (e.g. in Android // N), the onComplete function will run immediately so it must handle the case where the // base context of the application has not been set yet. - sSplitPreloader.preload(CHROME_SPLIT_NAME, (chromeContext) -> { - // When installed, the vr module is always loaded on startup, so preload here. - sSplitPreloader.preload("vr", null); - // If the chrome module is not enabled or isolated splits are not supported, - // chromeContext will have the same ClassLoader as the base context, so no need to - // replace the ClassLoaders here. - if (!context.getClassLoader().equals(chromeContext.getClassLoader())) { - // Replace the application Context's ClassLoader with the chrome ClassLoader, - // because the application ClassLoader is expected to be able to access all chrome - // classes. - BundleUtils.replaceClassLoader(this, chromeContext.getClassLoader()); - JNIUtils.setClassLoader(chromeContext.getClassLoader()); + sSplitPreloader.preload(CHROME_SPLIT_NAME, new SplitPreloader.OnComplete() { + @Override + public void runImmediatelyInBackgroundThread(Context chromeContext) { + // A new thread is started here because we do not want to delay returning the chrome + // Context, since that slows down startup. This thread must be a HandlerThread + // because AsyncInitializationActivity (a base class of ChromeTabbedActivity) + // creates a Handler, so needs to have a Looper prepared. + HandlerThread thread = new HandlerThread("ActivityPreload"); + thread.start(); + new Handler(thread.getLooper()).post(() -> { + try { + // Create a throwaway instance of ChromeTabbedActivity. This will warm up + // the chrome ClassLoader, and perform loading of classes used early in + // startup in the background. + chromeContext.getClassLoader() + .loadClass( + "org.chromium.chrome.browser.ChromeTabbedActivity$Preload") + .newInstance(); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + thread.quit(); + }); + } + + @Override + public void runInUiThread(Context chromeContext) { + // When installed, the vr module is always loaded on startup, so preload here. + sSplitPreloader.preload("vr", null); + // If the chrome module is not enabled or isolated splits are not supported, + // chromeContext will have the same ClassLoader as the base context, so no need to + // replace the ClassLoaders here. + if (!context.getClassLoader().equals(chromeContext.getClassLoader())) { + // Replace the application Context's ClassLoader with the chrome ClassLoader, + // because the application ClassLoader is expected to be able to access all + // chrome classes. + BundleUtils.replaceClassLoader( + SplitChromeApplication.this, chromeContext.getClassLoader()); + JNIUtils.setClassLoader(chromeContext.getClassLoader()); + } } }); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitPreloader.java b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitPreloader.java index 004a89ec..ab4c626 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitPreloader.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitPreloader.java
@@ -24,9 +24,23 @@ private final SimpleArrayMap<String, PreloadTask> mPreloadTasks = new SimpleArrayMap<>(); private final Context mContext; - /** Interface to run code after preload completion. */ + /** + * Interface to run code after preload completion. + */ public interface OnComplete { - void run(Context context); + /** + * Runs immediately on the background thread as soon as the split context is available. + * Note that normally runInUiThread() should be used instead because the context parameter + * here may have an incorrect ClassLoader due to b/172602571. This method should only be + * used for optimizations which need to run as soon as possible, and are safe throw away if + * a different ClassLoader ends up being used. + */ + default void runImmediatelyInBackgroundThread(Context unsafeClassLoaderContext) {} + + /** + * Guaranteed to run in the UI thread before {@link SplitPreloader#wait(String)} returns. + */ + default void runInUiThread(Context context) {} } private class PreloadTask extends AsyncTask<Void> { @@ -41,6 +55,9 @@ @Override protected Void doInBackground() { Context context = createSplitContext(); + if (mOnComplete != null) { + mOnComplete.runImmediatelyInBackgroundThread(context); + } return null; } @@ -63,7 +80,7 @@ if (mOnComplete != null) { // Recreate the context here to make sure we have the latest version, in case there // was a race to update the class loader cache, see b/172602571. - mOnComplete.run(createSplitContext()); + mOnComplete.runInUiThread(createSplitContext()); mOnComplete = null; } } @@ -82,10 +99,7 @@ /** Starts preloading a split context on a background thread. */ public void preload(String name, OnComplete onComplete) { - if (!BundleUtils.isIsolatedSplitInstalled(mContext, name)) { - if (onComplete != null) { - onComplete.run(mContext); - } + if (!BundleUtils.isIsolatedSplitInstalled(mContext, name) && onComplete == null) { return; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadActivity.java index 1d45cc8..c921675 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadActivity.java
@@ -16,6 +16,9 @@ import org.chromium.chrome.browser.download.home.DownloadManagerUiConfig; import org.chromium.chrome.browser.download.home.DownloadManagerUiConfigHelper; import org.chromium.chrome.browser.download.items.OfflineContentAggregatorNotificationBridgeUiFactory; +import org.chromium.chrome.browser.incognito.IncognitoUtils; +import org.chromium.chrome.browser.profiles.OTRProfileID; +import org.chromium.chrome.browser.profiles.ProfileKey; import org.chromium.components.browser_ui.modaldialog.AppModalPresenter; import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.ui.base.ActivityAndroidPermissionDelegate; @@ -46,6 +49,7 @@ mCurrentUrl = url; } }; + private OTRProfileID mOtrProfileID; @Override public void onCreate(Bundle savedInstanceState) { @@ -63,6 +67,7 @@ getIntent(), IntentHandler.EXTRA_PARENT_COMPONENT); mPermissionDelegate = new ActivityAndroidPermissionDelegate(new WeakReference<Activity>(this)); + mOtrProfileID = DownloadUtils.getOTRProfileIDFromIntent(getIntent()); DownloadManagerUiConfig config = DownloadManagerUiConfigHelper.fromFlags() @@ -91,7 +96,8 @@ @Override public void onResume() { super.onResume(); - DownloadUtils.checkForExternallyRemovedDownloads(mIsOffTheRecord); + ProfileKey profileKey = IncognitoUtils.getProfileKeyFromOTRProfileID(mOtrProfileID); + DownloadUtils.checkForExternallyRemovedDownloads(profileKey); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManagerImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManagerImpl.java index fc830c1..28d9d4f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManagerImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManagerImpl.java
@@ -39,6 +39,7 @@ import org.chromium.chrome.browser.init.BrowserParts; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; import org.chromium.chrome.browser.init.EmptyBrowserParts; +import org.chromium.chrome.browser.profiles.OTRProfileID; import org.chromium.components.offline_items_collection.ContentId; import org.chromium.components.offline_items_collection.LaunchLocation; import org.chromium.components.offline_items_collection.LegacyHelpers; @@ -239,6 +240,7 @@ boolean isOffTheRecord = entry == null ? IntentUtils.safeGetBooleanExtra(intent, EXTRA_IS_OFF_THE_RECORD, false) : entry.isOffTheRecord; + OTRProfileID otrProfileID = DownloadUtils.getOTRProfileIDFromIntent(intent); DownloadServiceDelegate downloadServiceDelegate = getServiceDelegate(id); checkNotNull(downloadServiceDelegate); @@ -252,11 +254,11 @@ intent.getIntExtra(EXTRA_DOWNLOAD_STATE_AT_CANCEL, -1)); DownloadMetrics.recordDownloadCancel( DownloadMetrics.CancelFrom.CANCEL_NOTIFICATION); - downloadServiceDelegate.cancelDownload(id, isOffTheRecord); + downloadServiceDelegate.cancelDownload(id, otrProfileID); break; case ACTION_DOWNLOAD_PAUSE: - downloadServiceDelegate.pauseDownload(id, isOffTheRecord); + downloadServiceDelegate.pauseDownload(id, otrProfileID); break; case ACTION_DOWNLOAD_RESUME:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java index c3a79ac..9e83c66 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
@@ -40,10 +40,12 @@ import org.chromium.chrome.browser.feature_engagement.TrackerFactory; import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.incognito.IncognitoUtils; import org.chromium.chrome.browser.media.MediaViewerUtils; import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.Pref; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; +import org.chromium.chrome.browser.profiles.OTRProfileID; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.profiles.ProfileKey; import org.chromium.chrome.browser.profiles.ProfileManager; @@ -402,7 +404,7 @@ DownloadNotificationService.clearResumptionAttemptLeft(); DownloadManagerService.getDownloadManagerService().checkForExternallyRemovedDownloads( - /*isOffTheRecord=*/false); + ProfileKey.getLastUsedRegularProfileKey()); mActivityLaunched = true; } } @@ -973,9 +975,10 @@ // Downloads started from incognito mode should not be resumed in reduced mode. if (!ProfileManager.isInitialized() && item.getDownloadInfo().isOffTheRecord()) return; + OTRProfileID otrProfileID = item.getDownloadInfo().getOTRProfileId(); DownloadManagerServiceJni.get().resumeDownload(getNativeDownloadManagerService(), DownloadManagerService.this, item.getId(), - getProfileKey(item.getDownloadInfo().isOffTheRecord()), hasUserGesture); + IncognitoUtils.getProfileKeyFromOTRProfileID(otrProfileID), hasUserGesture); } /** @@ -987,21 +990,23 @@ // Deprecated after new download backend. // TODO(shaktisahu): Add retry to offline content provider or route it from resume call. public void retryDownload(ContentId id, DownloadItem item, boolean hasUserGesture) { + OTRProfileID otrProfileID = item.getDownloadInfo().getOTRProfileId(); DownloadManagerServiceJni.get().retryDownload(getNativeDownloadManagerService(), DownloadManagerService.this, item.getId(), - getProfileKey(item.getDownloadInfo().isOffTheRecord()), hasUserGesture); + IncognitoUtils.getProfileKeyFromOTRProfileID(otrProfileID), hasUserGesture); } /** * Called to cancel a download. * @param id The {@link ContentId} of the download to cancel. - * @param isOffTheRecord Whether the download is off the record. + * @param otrProfileID The {@link OTRProfileID} of the download. Null if in regular mode. */ // Deprecated after new download backend. @Override - public void cancelDownload(ContentId id, boolean isOffTheRecord) { + public void cancelDownload(ContentId id, OTRProfileID otrProfileID) { DownloadManagerServiceJni.get().cancelDownload(getNativeDownloadManagerService(), - DownloadManagerService.this, id.id, getProfileKey(isOffTheRecord)); + DownloadManagerService.this, id.id, + IncognitoUtils.getProfileKeyFromOTRProfileID(otrProfileID)); DownloadProgress progress = mDownloadProgressMap.get(id.id); if (progress != null) { DownloadInfo info = @@ -1011,7 +1016,8 @@ removeDownloadProgress(id.id); } else { mDownloadNotifier.notifyDownloadCanceled(id); - DownloadInfoBarController infoBarController = getInfoBarController(isOffTheRecord); + DownloadInfoBarController infoBarController = + getInfoBarController(otrProfileID != null); if (infoBarController != null) infoBarController.onDownloadItemRemoved(id); } } @@ -1019,13 +1025,14 @@ /** * Called to pause a download. * @param id The {@link ContentId} of the download to pause. - * @param isOffTheRecord Whether the download is off the record. + * @param otrProfileID The {@link OTRProfileID} of the download. Null if in regular mode. */ // Deprecated after new download backend. @Override - public void pauseDownload(ContentId id, boolean isOffTheRecord) { + public void pauseDownload(ContentId id, OTRProfileID otrProfileID) { DownloadManagerServiceJni.get().pauseDownload(getNativeDownloadManagerService(), - DownloadManagerService.this, id.id, getProfileKey(isOffTheRecord)); + DownloadManagerService.this, id.id, + IncognitoUtils.getProfileKeyFromOTRProfileID(otrProfileID)); DownloadProgress progress = mDownloadProgressMap.get(id.id); // Calling pause will stop listening to the download item. Update its progress now. // If download is already completed, canceled or failed, there is no need to update the @@ -1048,14 +1055,15 @@ /** * Removes a download from the list. * @param downloadGuid GUID of the download. - * @param isOffTheRecord Whether the download is off the record. + * @param otrProfileID The {@link OTRProfileID} of the download. Null if in regular mode. * @param externallyRemoved If the file is externally removed by other applications. */ public void removeDownload( - final String downloadGuid, boolean isOffTheRecord, boolean externallyRemoved) { + final String downloadGuid, OTRProfileID otrProfileID, boolean externallyRemoved) { mHandler.post(() -> { DownloadManagerServiceJni.get().removeDownload(getNativeDownloadManagerService(), - DownloadManagerService.this, downloadGuid, getProfileKey(isOffTheRecord)); + DownloadManagerService.this, downloadGuid, + IncognitoUtils.getProfileKeyFromOTRProfileID(otrProfileID)); removeDownloadProgress(downloadGuid); }); @@ -1367,9 +1375,10 @@ // Deprecated after new download backend. public void renameDownload(ContentId id, String name, - Callback<Integer /*RenameResult*/> callback, boolean isOffTheRecord) { + Callback<Integer /*RenameResult*/> callback, OTRProfileID otrProfileID) { DownloadManagerServiceJni.get().renameDownload(getNativeDownloadManagerService(), - DownloadManagerService.this, id.id, name, callback, getProfileKey(isOffTheRecord)); + DownloadManagerService.this, id.id, name, callback, + IncognitoUtils.getProfileKeyFromOTRProfileID(otrProfileID)); } /** @@ -1416,12 +1425,11 @@ /** * Checks if the files associated with any downloads have been removed by an external action. - * @param isOffTheRecord Whether or not to check downloads for the off the record profile. + * @param profileKey The {@link ProfileKey} to check the downloads for the the given profile. */ - public void checkForExternallyRemovedDownloads(boolean isOffTheRecord) { + public void checkForExternallyRemovedDownloads(ProfileKey profileKey) { DownloadManagerServiceJni.get().checkForExternallyRemovedDownloads( - getNativeDownloadManagerService(), DownloadManagerService.this, - getProfileKey(isOffTheRecord)); + getNativeDownloadManagerService(), DownloadManagerService.this, profileKey); } // Deprecated after new download backend.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java index 35e12a9..913a7736 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java
@@ -32,6 +32,7 @@ import org.chromium.chrome.browser.notifications.NotificationUmaTracker; import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; +import org.chromium.chrome.browser.profiles.OTRProfileID; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.components.browser_ui.notifications.NotificationManagerProxy; import org.chromium.components.browser_ui.notifications.NotificationManagerProxyImpl; @@ -717,7 +718,12 @@ if (cancelActualDownload) { DownloadServiceDelegate delegate = getServiceDelegate(id); DownloadMetrics.recordDownloadCancel(DownloadMetrics.CancelFrom.CANCEL_SHUTDOWN); - delegate.cancelDownload(id, true); + // TODO(crbug.com/1164379): Pass OTRProfileID of the current OTR profile to cancel + // non-primary OTR downloads. + OTRProfileID otrProfileID = Profile.getLastUsedRegularProfile() + .getPrimaryOTRProfile() + .getOTRProfileID(); + delegate.cancelDownload(id, otrProfileID); delegate.destroyServiceDelegate(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadPage.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadPage.java index c96222b..5ae524fd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadPage.java
@@ -14,6 +14,8 @@ import org.chromium.chrome.browser.download.home.DownloadManagerCoordinatorFactoryHelper; import org.chromium.chrome.browser.download.home.DownloadManagerUiConfig; import org.chromium.chrome.browser.download.home.DownloadManagerUiConfigHelper; +import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.profiles.ProfileKey; import org.chromium.chrome.browser.ui.native_page.BasicNativePage; import org.chromium.chrome.browser.ui.native_page.NativePageHost; import org.chromium.components.embedder_support.util.UrlConstants; @@ -56,8 +58,10 @@ // resumed. mActivityStateListener = (activity1, newState) -> { if (newState == ActivityState.RESUMED) { - DownloadUtils.checkForExternallyRemovedDownloads( - activity.getCurrentTabModel().isIncognito()); + Profile profile = activity.getCurrentTabModel().getProfile(); + ProfileKey profileKey = profile == null ? ProfileKey.getLastUsedRegularProfileKey() + : profile.getProfileKey(); + DownloadUtils.checkForExternallyRemovedDownloads(profileKey); } }; ApplicationStatus.registerStateListenerForActivity(mActivityStateListener, activity);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadServiceDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadServiceDelegate.java index 40202e1..2c69487 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadServiceDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadServiceDelegate.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.download; +import org.chromium.chrome.browser.profiles.OTRProfileID; import org.chromium.components.offline_items_collection.ContentId; /** Interface for classes implementing concrete implementation of UI behavior. */ @@ -11,16 +12,16 @@ /** * Called to cancel a download. * @param id The {@link ContentId} of the download to cancel. - * @param isOffTheRecord Whether the download is off the record. + * @param otrProfileID The {@link OTRProfileID} of the download. Null if in regular mode. */ - void cancelDownload(ContentId id, boolean isOffTheRecord); + void cancelDownload(ContentId id, OTRProfileID otrProfileID); /** * Called to pause a download. * @param id The {@link ContentId} of the download to pause. - * @param isOffTheRecord Whether the download is off the record. + * @param otrProfileID The {@link OTRProfileID} of the download. Null if in regular mode. */ - void pauseDownload(ContentId id, boolean isOffTheRecord); + void pauseDownload(ContentId id, OTRProfileID otrProfileID); /** * Called to resume a paused download.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java index 3eac379..b9f0330 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java
@@ -43,6 +43,7 @@ import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadBridge; import org.chromium.chrome.browser.profiles.OTRProfileID; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.profiles.ProfileKey; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tabmodel.document.TabDelegate; @@ -230,19 +231,19 @@ * Issues a request to the {@link DownloadManagerService} associated to check for externally * removed downloads. * See {@link DownloadManagerService#checkForExternallyRemovedDownloads}. - * @param isOffTheRecord Whether to check downloads for the off the record profile. + * @param profileKey The {@link ProfileKey} to check downloads of the given profile. */ - public static void checkForExternallyRemovedDownloads(boolean isOffTheRecord) { + public static void checkForExternallyRemovedDownloads(ProfileKey profileKey) { if (ChromeFeatureList.isEnabled(ChromeFeatureList.DOWNLOAD_OFFLINE_CONTENT_PROVIDER)) { return; } - if (isOffTheRecord) { + if (profileKey.isOffTheRecord()) { DownloadManagerService.getDownloadManagerService().checkForExternallyRemovedDownloads( - true); + profileKey); } DownloadManagerService.getDownloadManagerService().checkForExternallyRemovedDownloads( - false); + ProfileKey.getLastUsedRegularProfileKey()); RecordUserAction.record( "Android.DownloadManager.CheckForExternallyRemovedItems"); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/OMADownloadHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/download/OMADownloadHandler.java index 43aa44b..0d78ae9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/OMADownloadHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/OMADownloadHandler.java
@@ -326,7 +326,7 @@ OfflineContentAggregatorFactory.get().removeItem(mDownloadInfo.getContentId()); } else { DownloadManagerService.getDownloadManagerService().removeDownload( - mDownloadInfo.getDownloadGuid(), mDownloadInfo.isOffTheRecord(), + mDownloadInfo.getDownloadGuid(), mDownloadInfo.getOTRProfileId(), false /* externallyRemoved */); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/LegacyDownloadProviderImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/LegacyDownloadProviderImpl.java index fcb8073..2e76dce 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/LegacyDownloadProviderImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/LegacyDownloadProviderImpl.java
@@ -16,6 +16,7 @@ import org.chromium.chrome.browser.download.DownloadMetrics; import org.chromium.chrome.browser.download.DownloadOpenSource; import org.chromium.chrome.browser.download.DownloadUtils; +import org.chromium.chrome.browser.profiles.OTRProfileID; import org.chromium.components.offline_items_collection.ContentId; import org.chromium.components.offline_items_collection.LegacyHelpers; import org.chromium.components.offline_items_collection.OfflineContentProvider; @@ -130,7 +131,7 @@ @Override public void removeItem(OfflineItem item) { DownloadManagerService.getDownloadManagerService().removeDownload( - item.id.id, item.isOffTheRecord, item.externallyRemoved); + item.id.id, OTRProfileID.deserialize(item.otrProfileId), item.externallyRemoved); FileDeletionQueue.get().delete(item.filePath); } @@ -138,13 +139,13 @@ public void cancelDownload(OfflineItem item) { DownloadMetrics.recordDownloadCancel(DownloadMetrics.CancelFrom.CANCEL_DOWNLOAD_HOME); DownloadManagerService.getDownloadManagerService().cancelDownload( - item.id, item.isOffTheRecord); + item.id, OTRProfileID.deserialize(item.otrProfileId)); } @Override public void pauseDownload(OfflineItem item) { DownloadManagerService.getDownloadManagerService().pauseDownload( - item.id, item.isOffTheRecord); + item.id, OTRProfileID.deserialize(item.otrProfileId)); } @Override @@ -200,7 +201,7 @@ public void renameItem( OfflineItem item, String name, Callback</*RenameResult*/ Integer> callback) { DownloadManagerService.getDownloadManagerService().renameDownload( - item.id, name, callback, item.isOffTheRecord); + item.id, name, callback, OTRProfileID.deserialize(item.otrProfileId)); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotificationBridgeUi.java b/chrome/android/java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotificationBridgeUi.java index 4b1bb453..439ce90 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotificationBridgeUi.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotificationBridgeUi.java
@@ -8,6 +8,7 @@ import org.chromium.chrome.browser.download.DownloadItem; import org.chromium.chrome.browser.download.DownloadNotifier; import org.chromium.chrome.browser.download.DownloadServiceDelegate; +import org.chromium.chrome.browser.profiles.OTRProfileID; import org.chromium.components.offline_items_collection.ContentId; import org.chromium.components.offline_items_collection.LegacyHelpers; import org.chromium.components.offline_items_collection.OfflineContentProvider; @@ -105,12 +106,12 @@ // DownloadServiceDelegate implementation. @Override - public void cancelDownload(ContentId id, boolean isOffTheRecord) { + public void cancelDownload(ContentId id, OTRProfileID otrProfileID) { mProvider.cancelDownload(id); } @Override - public void pauseDownload(ContentId id, boolean isOffTheRecord) { + public void pauseDownload(ContentId id, OTRProfileID otrProfileID) { mProvider.pauseDownload(id); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessor.java index 9454f70..eb33839 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessor.java
@@ -4,9 +4,9 @@ package org.chromium.chrome.browser.firstrun; +import android.accounts.Account; import android.app.Activity; -import org.chromium.base.Log; import org.chromium.chrome.browser.SyncFirstSetupCompleteSource; import org.chromium.chrome.browser.childaccounts.ChildAccountService; import org.chromium.chrome.browser.profiles.Profile; @@ -20,28 +20,28 @@ import org.chromium.components.signin.ChildAccountStatus; import org.chromium.components.signin.metrics.SigninAccessPoint; +import java.util.List; + /** * A helper to perform all necessary steps for forced sign in. * The helper performs: * - necessary child account checks; - * - automatic non-interactive forced sign in for child accounts; and + * - automatic non-interactive sign in for child accounts; and * The helper calls the observer's onSignInComplete() if * - nothing needs to be done, or when * - the sign in is complete. * * Usage: - * ForcedSigninProcessor.start(appContext). + * ForcedSigninProcessor.start(). */ public final class ForcedSigninProcessor { - private static final String TAG = "ForcedSignin"; - /* * Only for static usage. */ private ForcedSigninProcessor() {} /** - * Check whether a forced automatic signin is required and process it if it is. + * Check whether an automatic signin is required and process it if it is. * This is triggered once per Chrome Application lifetime and every time the Account state * changes with early exit if an account has already been signed in. */ @@ -50,37 +50,32 @@ boolean hasChildAccount = ChildAccountStatus.isChild(status); AccountManagementFragment.setSignOutAllowedPreferenceValue(!hasChildAccount); if (hasChildAccount) { - processForcedSignIn(); + // Account cache is already available when child account status is ready. + final List<Account> accounts = + AccountManagerFacadeProvider.getInstance().tryGetGoogleAccounts(); + assert accounts.size() == 1 : "Child account should be the only account on device!"; + signinAndEnableSync(accounts.get(0)); } }); } /** * Processes the fully automatic non-FRE-related forced sign-in. - * This is used to enforce the environment for Android EDU and child accounts. + * This is used to enforce the environment for child accounts. */ - private static void processForcedSignIn() { + private static void signinAndEnableSync(final Account childAccount) { final Profile profile = Profile.getLastUsedRegularProfile(); if (FirstRunUtils.canAllowSync() && IdentityServicesProvider.get().getIdentityManager(profile).hasPrimaryAccount()) { // TODO(https://crbug.com/1044206): Remove this. ProfileSyncService.get().setFirstSetupComplete(SyncFirstSetupCompleteSource.BASIC_FLOW); } - final SigninManager signinManager = IdentityServicesProvider.get().getSigninManager(profile); // By definition we have finished all the checks for first run. signinManager.onFirstRunCheckDone(); - if (!FirstRunUtils.canAllowSync() || !signinManager.isSignInAllowed()) { - Log.d(TAG, "Sign in disallowed"); - return; - } - AccountManagerFacadeProvider.getInstance().tryGetGoogleAccounts(accounts -> { - if (accounts.size() != 1) { - Log.d(TAG, "Incorrect number of accounts (%d)", accounts.size()); - return; - } - signinManager.signinAndEnableSync(SigninAccessPoint.FORCED_SIGNIN, accounts.get(0), + if (FirstRunUtils.canAllowSync() && signinManager.isSignInAllowed()) { + signinManager.signinAndEnableSync(SigninAccessPoint.FORCED_SIGNIN, childAccount, new SigninManager.SignInCallback() { @Override public void onSignInComplete() { @@ -92,7 +87,7 @@ @Override public void onSignInAborted() {} }); - }); + } } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoUtils.java index 1beeeec9..20ff3a8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoUtils.java
@@ -23,7 +23,9 @@ import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.customtabs.CustomTabIncognitoManager; +import org.chromium.chrome.browser.profiles.OTRProfileID; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.profiles.ProfileKey; import org.chromium.chrome.browser.tab.TabStateFileManager; import org.chromium.chrome.browser.tabmodel.IncognitoTabHost; import org.chromium.chrome.browser.tabmodel.IncognitoTabHostRegistry; @@ -234,6 +236,22 @@ return customTabIncognitoManager.getProfile(); } + /** + * Returns the {@link ProfileKey} from given {@link OTRProfileID}. If OTRProfileID is null, it + * is the key of regular profile. + * + * @param otrProfileID The {@link OTRProfileID} of the profile. Null for regular profile. + * @return The {@link ProfileKey} of the key. + */ + public static ProfileKey getProfileKeyFromOTRProfileID(OTRProfileID otrProfileID) { + // If off-the-record is not requested, the request might be before native initialization. + if (otrProfileID == null) return ProfileKey.getLastUsedRegularProfileKey(); + + return Profile.getLastUsedRegularProfile() + .getOffTheRecordProfile(otrProfileID) + .getProfileKey(); + } + @VisibleForTesting public static void setEnabledForTesting(Boolean enabled) { sIsEnabledForTesting = enabled;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java index 916d82b..8dce69dd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java
@@ -49,6 +49,7 @@ import org.chromium.chrome.browser.omnibox.OmniboxFocusReason; import org.chromium.chrome.browser.omnibox.voice.VoiceRecognitionHandler; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.profiles.ProfileKey; import org.chromium.chrome.browser.query_tiles.QueryTileSection.QueryInfo; import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory; import org.chromium.chrome.browser.suggestions.SuggestionsDependencyFactory; @@ -357,7 +358,7 @@ mBrowserControlsStateProvider.addObserver(this); DownloadManagerService.getDownloadManagerService().checkForExternallyRemovedDownloads( - /*isOffTheRecord=*/false); + ProfileKey.getLastUsedRegularProfileKey()); mTabStripAndToolbarHeight = activity.getResources().getDimensionPixelSize(R.dimen.tab_strip_and_toolbar_height);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java index 47a6a10..a73781c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java
@@ -524,7 +524,7 @@ // AccountManagerFacade couldn't create intent, use SigninUtils to open settings // instead. - SigninUtils.openSettingsForAllAccounts(getContext()); + SigninUtils.openSettingsForAllAccounts(getActivity()); }); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninUtils.java index c1d5e3ec..d08e5bf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninUtils.java
@@ -6,7 +6,6 @@ import android.accounts.Account; import android.app.Activity; -import android.content.Context; import android.content.Intent; import android.os.Build; import android.provider.Settings; @@ -47,30 +46,27 @@ /** * Opens a Settings page to configure settings for a single account. - * @param context Context to use when starting the Activity. + * @param activity Activity to use when starting the Activity. * @param account The account for which the Settings page should be opened. * @return Whether or not Android accepted the Intent. */ - public static boolean openSettingsForAccount(Context context, Account account) { + public static boolean openSettingsForAccount(Activity activity, Account account) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // ACCOUNT_SETTINGS_ACTION no longer works on Android O+, always open all accounts page. - return openSettingsForAllAccounts(context); + return openSettingsForAllAccounts(activity); } Intent intent = new Intent(ACCOUNT_SETTINGS_ACTION); intent.putExtra(ACCOUNT_SETTINGS_ACCOUNT_KEY, account); - if (!(context instanceof Activity)) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - return IntentUtils.safeStartActivity(context, intent); + return IntentUtils.safeStartActivity(activity, intent); } /** * Opens a Settings page with all accounts on the device. - * @param context Context to use when starting the Activity. + * @param activity Activity to use when starting the Activity. * @return Whether or not Android accepted the Intent. */ - public static boolean openSettingsForAllAccounts(Context context) { - Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS); - if (!(context instanceof Activity)) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - return IntentUtils.safeStartActivity(context, intent); + public static boolean openSettingsForAllAccounts(Activity activity) { + return IntentUtils.safeStartActivity(activity, new Intent(Settings.ACTION_SYNC_SETTINGS)); } @CalledByNative
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 9db80c9..487803e 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
@@ -159,13 +159,6 @@ } /** - * @return Whether sync is enabled to sync urls or open tabs with a non custom passphrase. - */ - public boolean isSyncingUrlsWithKeystorePassphrase() { - return mProfileSyncService.isSyncingUrlsWithKeystorePassphrase(); - } - - /** * Returns the SyncNotificationController. */ public SyncNotificationController getSyncNotificationController() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetTest.java index 727ef08..9e48cb7 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetTest.java
@@ -7,7 +7,10 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.chromium.base.test.util.CriteriaHelper.pollUiThread; import static org.chromium.chrome.browser.flags.ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE; @@ -20,6 +23,7 @@ import org.junit.Test; import org.junit.runner.RunWith; +import org.chromium.base.Callback; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Restriction; @@ -32,7 +36,9 @@ import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.SheetState; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.StateChangeReason; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetObserver; import org.chromium.components.browser_ui.bottomsheet.BottomSheetTestSupport; +import org.chromium.components.browser_ui.bottomsheet.EmptyBottomSheetObserver; import org.chromium.ui.test.util.UiRestriction; import java.util.concurrent.ExecutionException; @@ -246,6 +252,48 @@ mSheetController.getSheetState()); } + @Test + @MediumTest + public void testOffsetController() { + mLowPriorityContent.setContentControlsOffset(true); + + BottomSheetObserver forbidStateChanges = new EmptyBottomSheetObserver() { + @Override + public void onSheetOpened(@StateChangeReason int reason) { + fail("onSheetOpened unexpected"); + } + + @Override + public void onSheetClosed(@StateChangeReason int reason) { + fail("onSheetClosed unexpected"); + } + }; + runOnUiThreadBlocking(() -> { + assertTrue(mSheetController.requestShowContent(mLowPriorityContent, false)); + + Callback<Integer> offsetController = mLowPriorityContent.getOffsetController(); + assertNotNull(offsetController); + + mSheetController.addObserver(forbidStateChanges); + + int startOffset = mSheetController.getCurrentOffset(); + int modifiedOffset = startOffset / 2; + offsetController.onResult(modifiedOffset); + assertEquals(modifiedOffset, mSheetController.getCurrentOffset()); + + offsetController.onResult(0); + assertEquals(0, mSheetController.getCurrentOffset()); + + offsetController.onResult(startOffset); + assertEquals(startOffset, mSheetController.getCurrentOffset()); + + mSheetController.removeObserver(forbidStateChanges); + + mSheetController.hideContent(mLowPriorityContent, false); + assertNull(mLowPriorityContent.getOffsetController()); + }); + } + private void hideSheet() { runOnUiThreadBlocking(() -> mTestSupport.setSheetState(SheetState.HIDDEN, false)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/TestBottomSheetContent.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/TestBottomSheetContent.java index 98ea7146..7342abc1a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/TestBottomSheetContent.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/TestBottomSheetContent.java
@@ -12,6 +12,7 @@ import androidx.annotation.Nullable; +import org.chromium.base.Callback; import org.chromium.base.test.util.CallbackHelper; import org.chromium.components.browser_ui.bottomsheet.BottomSheetContent; import org.chromium.content_public.browser.test.util.TestThreadUtils; @@ -54,6 +55,13 @@ /** Whether this content intercepts back button presses. */ private boolean mHandleBackPress; + /** Set to true to ask for an offset controller. */ + private boolean mContentControlsOffset; + + /** Current offset controller. */ + @Nullable + private Callback<Integer> mOffsetController; + /** * @param context A context to inflate views with. * @param priority The content's priority. @@ -202,4 +210,22 @@ public int getSheetClosedAccessibilityStringId() { return android.R.string.copy; } + + @Override + public boolean contentControlsOffset() { + return mContentControlsOffset; + } + + @Override + public void setOffsetController(Callback<Integer> offsetController) { + mOffsetController = offsetController; + } + + public Callback<Integer> getOffsetController() { + return mOffsetController; + } + + public void setContentControlsOffset(boolean value) { + mContentControlsOffset = value; + } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/base/SplitPreloaderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/base/SplitPreloaderTest.java index 5953d05..dc519c9 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/base/SplitPreloaderTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/base/SplitPreloaderTest.java
@@ -7,6 +7,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -23,6 +24,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.util.CallbackHelper; import java.util.ArrayList; import java.util.List; @@ -84,14 +86,25 @@ } private static class OnCompleteTracker implements SplitPreloader.OnComplete { + private SplitContext mBackgroundContext; private SplitContext mUiContext; @Override - public void run(Context context) { + public void runImmediatelyInBackgroundThread(Context context) { + assertNull(mBackgroundContext); + mBackgroundContext = (SplitContext) context; + } + + @Override + public void runInUiThread(Context context) { assertNull(mUiContext); mUiContext = (SplitContext) context; } + public SplitContext getBackgroundContext() { + return mBackgroundContext; + } + public SplitContext getUiContext() { return mUiContext; } @@ -129,6 +142,8 @@ assertThat(mContext.getBackgroundThreadContextNames()).containsExactly(SPLIT_A); assertTrue(tracker.getUiContext().wasCreatedOnUiThread()); assertEquals(tracker.getUiContext().getName(), SPLIT_A); + assertFalse(tracker.getBackgroundContext().wasCreatedOnUiThread()); + assertEquals(tracker.getBackgroundContext().getName(), SPLIT_A); } @Test @@ -178,13 +193,29 @@ } @Test - public void testPreload_withOnComplete_splitNotInstalled() { - Context[] contextHolder = new Context[1]; - mPreloader.preload(SPLIT_A, (Context context) -> contextHolder[0] = context); + public void testPreload_withOnComplete_splitNotInstalled() throws Exception { + Context[] backgroundContextHolder = new Context[1]; + Context[] uiContextHolder = new Context[1]; + CallbackHelper helper = new CallbackHelper(); + mPreloader.preload(SPLIT_A, new SplitPreloader.OnComplete() { + @Override + public void runImmediatelyInBackgroundThread(Context context) { + backgroundContextHolder[0] = context; + helper.notifyCalled(); + } + + @Override + public void runInUiThread(Context context) { + uiContextHolder[0] = context; + } + }); + helper.waitForFirst(); + assertEquals(backgroundContextHolder[0], mContext); + mPreloader.wait(SPLIT_A); assertThat(mContext.getUiThreadContextNames()).isEmpty(); assertThat(mContext.getBackgroundThreadContextNames()).isEmpty(); - assertEquals(contextHolder[0], mContext); + assertEquals(uiContextHolder[0], mContext); } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessorTest.java new file mode 100644 index 0000000..542f588 --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessorTest.java
@@ -0,0 +1,140 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.firstrun; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.notNull; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.accounts.Account; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.SyncFirstSetupCompleteSource; +import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.signin.services.IdentityServicesProvider; +import org.chromium.chrome.browser.signin.services.SigninManager; +import org.chromium.chrome.browser.signin.services.SigninManager.SignInCallback; +import org.chromium.chrome.browser.sync.ProfileSyncService; +import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule; +import org.chromium.components.signin.AccountUtils; +import org.chromium.components.signin.ChildAccountStatus; +import org.chromium.components.signin.identitymanager.IdentityManager; +import org.chromium.components.signin.metrics.SigninAccessPoint; +import org.chromium.components.signin.test.util.FakeAccountManagerFacade; + +/** + * JUnit tests for {@link ForcedSigninProcessor}. + */ +@RunWith(BaseRobolectricTestRunner.class) +public class ForcedSigninProcessorTest { + private static final Account CHILD_ACCOUNT = + AccountUtils.createAccountFromName("child.account@gmail.com"); + + private final FakeAccountManagerFacade mFakeFacade = new FakeAccountManagerFacade(null) { + @Override + public void checkChildAccountStatus(Account account, ChildAccountStatusListener listener) { + listener.onStatusReady(account.equals(CHILD_ACCOUNT) ? ChildAccountStatus.REGULAR_CHILD + : ChildAccountStatus.NOT_CHILD); + } + }; + + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + + @Rule + public final AccountManagerTestRule mAccountManagerTestRule = + new AccountManagerTestRule(mFakeFacade); + + @Mock + private Profile mProfileMock; + + @Mock + private ProfileSyncService mProfileSyncServiceMock; + + @Mock + private SigninManager mSigninManagerMock; + + @Mock + private IdentityManager mIdentityManagerMock; + + @Before + public void setUp() { + Profile.setLastUsedProfileForTesting(mProfileMock); + ProfileSyncService.overrideForTests(mProfileSyncServiceMock); + IdentityServicesProvider.setInstanceForTests(mock(IdentityServicesProvider.class)); + + when(IdentityServicesProvider.get().getIdentityManager(mProfileMock)) + .thenReturn(mIdentityManagerMock); + when(mIdentityManagerMock.hasPrimaryAccount()).thenReturn(false); + + when(IdentityServicesProvider.get().getSigninManager(mProfileMock)) + .thenReturn(mSigninManagerMock); + doAnswer(invocation -> { + SignInCallback callback = invocation.getArgument(2); + callback.onSignInComplete(); + return null; + }) + .when(mSigninManagerMock) + .signinAndEnableSync(anyInt(), any(Account.class), notNull()); + } + + @Test + public void testStartWhenMoreThanOneAccountsOnDevice() { + mAccountManagerTestRule.addAccount(CHILD_ACCOUNT); + mAccountManagerTestRule.addAccount("adult.account@gmail.com"); + + ForcedSigninProcessor.start(); + verify(mSigninManagerMock, never()).onFirstRunCheckDone(); + } + + @Test + public void testStartWhenAdultAccountOnDevice() { + mAccountManagerTestRule.addAccount("adult.account@gmail.com"); + + ForcedSigninProcessor.start(); + verify(mSigninManagerMock, never()).onFirstRunCheckDone(); + } + + @Test + public void testStartWhenSigninNotAllowed() { + mAccountManagerTestRule.addAccount(CHILD_ACCOUNT); + when(mSigninManagerMock.isSignInAllowed()).thenReturn(false); + + ForcedSigninProcessor.start(); + verify(mSigninManagerMock).onFirstRunCheckDone(); + verify(mSigninManagerMock, never()) + .signinAndEnableSync(anyInt(), any(Account.class), any()); + verify(mProfileSyncServiceMock, never()) + .setFirstSetupComplete(SyncFirstSetupCompleteSource.BASIC_FLOW); + } + + @Test + public void testStartWhenSigninAllowed() { + mAccountManagerTestRule.addAccount(CHILD_ACCOUNT); + when(mSigninManagerMock.isSignInAllowed()).thenReturn(true); + + ForcedSigninProcessor.start(); + verify(mSigninManagerMock).onFirstRunCheckDone(); + verify(mSigninManagerMock) + .signinAndEnableSync( + eq(SigninAccessPoint.FORCED_SIGNIN), eq(CHILD_ACCOUNT), notNull()); + verify(mProfileSyncServiceMock) + .setFirstSetupComplete(SyncFirstSetupCompleteSource.BASIC_FLOW); + } +}
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd index 3ded6139..8388a92e 100644 --- a/chrome/app/chromium_strings.grd +++ b/chrome/app/chromium_strings.grd
@@ -1187,20 +1187,14 @@ <!-- Profile Picker --> <if expr="not chromeos and not is_android"> <message name="IDS_PROFILE_PICKER_MAIN_VIEW_TITLE" desc="Profile picker main view title"> - Who's using Chromium? + Welcome to Chromium profiles </message> <message name="IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE" desc="Profile picker main view subtitle"> - Use different profiles in Chromium to separate work and personal browsing, or for different people who use this device - </message> - <message name="IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE" desc="Remove warning message shown for signed in profiles shown when the user selects remove from the 3 dotted menu"> - This will permanently delete your browsing data from this device. To recover the data, sign in to Chromium as + With Chromium profiles you can separate all your Chromium stuff. Create profiles for friends and family, or split between work and fun. </message> <message name="IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_PROFILE_TYPE_CHOICE_TITLE" desc="Profile picker profile type choice title"> Set up your new Chromium profile </message> - <message name="IDS_PROFILE_PICKER_ASK_ON_STARTUP" desc="Text for the checkbox on the profile picker main view"> - Ask when Chromium opens - </message> <message name="IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_LOCAL_PROFILE_CREATION_TITLE" desc="Title for the local profile customiztion screen on the picker."> Customize your Chromium profile </message>
diff --git a/chrome/app/chromium_strings_grd/IDS_PROFILE_PICKER_ASK_ON_STARTUP.png.sha1 b/chrome/app/chromium_strings_grd/IDS_PROFILE_PICKER_ASK_ON_STARTUP.png.sha1 deleted file mode 100644 index e5670854..0000000 --- a/chrome/app/chromium_strings_grd/IDS_PROFILE_PICKER_ASK_ON_STARTUP.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -4cb9c6b65bb30ae0d4391ab58ca3a0d184460e51 \ No newline at end of file
diff --git a/chrome/app/chromium_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE.png.sha1 b/chrome/app/chromium_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE.png.sha1 index 6dc2496..25a234d7 100644 --- a/chrome/app/chromium_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE.png.sha1 +++ b/chrome/app/chromium_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE.png.sha1
@@ -1 +1 @@ -630ac6a34bb1915cfee2dd9e8ce472a56e302874 \ No newline at end of file +a064193913da1c2d06ab2a932d094c622e45a837 \ No newline at end of file
diff --git a/chrome/app/chromium_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_TITLE.png.sha1 b/chrome/app/chromium_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_TITLE.png.sha1 index 6dc2496..25a234d7 100644 --- a/chrome/app/chromium_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_TITLE.png.sha1 +++ b/chrome/app/chromium_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_TITLE.png.sha1
@@ -1 +1 @@ -630ac6a34bb1915cfee2dd9e8ce472a56e302874 \ No newline at end of file +a064193913da1c2d06ab2a932d094c622e45a837 \ No newline at end of file
diff --git a/chrome/app/chromium_strings_grd/IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE.png.sha1 b/chrome/app/chromium_strings_grd/IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE.png.sha1 deleted file mode 100644 index 0715e41..0000000 --- a/chrome/app/chromium_strings_grd/IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -de5d858671b12baa6ce008727ecbb34f2f2ec992 \ No newline at end of file
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd index 6eadb3b..f621942 100644 --- a/chrome/app/google_chrome_strings.grd +++ b/chrome/app/google_chrome_strings.grd
@@ -1203,20 +1203,14 @@ <!-- Profile Picker --> <if expr="not chromeos and not is_android"> <message name="IDS_PROFILE_PICKER_MAIN_VIEW_TITLE" desc="Profile picker main view title"> - Who's using Chrome? + Welcome to Chrome profiles </message> <message name="IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE" desc="Profile picker main view subtitle"> - Use different profiles in Chrome to separate work and personal browsing, or for different people who use this device - </message> - <message name="IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE" desc="Remove warning message shown for signed in profiles shown when the user selects remove from the 3 dotted menu"> - This will permanently delete your browsing data from this device. To recover the data, sign in to Chrome as + With Chrome profiles you can separate all your Chrome stuff. Create profiles for friends and family, or split between work and fun. </message> <message name="IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_PROFILE_TYPE_CHOICE_TITLE" desc="Profile picker profile type choice title"> Set up your new Chrome profile </message> - <message name="IDS_PROFILE_PICKER_ASK_ON_STARTUP" desc="Text for the checkbox on the profile picker main view"> - Ask when Chrome opens - </message> <message name="IDS_PROFILE_PICKER_PROFILE_CREATION_FLOW_LOCAL_PROFILE_CREATION_TITLE" desc="Title for the local profile customiztion screen on the picker."> Customize your Chrome profile </message>
diff --git a/chrome/app/google_chrome_strings_grd/IDS_PROFILE_PICKER_ASK_ON_STARTUP.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_PROFILE_PICKER_ASK_ON_STARTUP.png.sha1 deleted file mode 100644 index e5670854..0000000 --- a/chrome/app/google_chrome_strings_grd/IDS_PROFILE_PICKER_ASK_ON_STARTUP.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -4cb9c6b65bb30ae0d4391ab58ca3a0d184460e51 \ No newline at end of file
diff --git a/chrome/app/google_chrome_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE.png.sha1 index 6dc2496..25a234d7 100644 --- a/chrome/app/google_chrome_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE.png.sha1 +++ b/chrome/app/google_chrome_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE.png.sha1
@@ -1 +1 @@ -630ac6a34bb1915cfee2dd9e8ce472a56e302874 \ No newline at end of file +a064193913da1c2d06ab2a932d094c622e45a837 \ No newline at end of file
diff --git a/chrome/app/google_chrome_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_TITLE.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_TITLE.png.sha1 index 6dc2496..25a234d7 100644 --- a/chrome/app/google_chrome_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_TITLE.png.sha1 +++ b/chrome/app/google_chrome_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_TITLE.png.sha1
@@ -1 +1 @@ -630ac6a34bb1915cfee2dd9e8ce472a56e302874 \ No newline at end of file +a064193913da1c2d06ab2a932d094c622e45a837 \ No newline at end of file
diff --git a/chrome/app/google_chrome_strings_grd/IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE.png.sha1 deleted file mode 100644 index 0715e41..0000000 --- a/chrome/app/google_chrome_strings_grd/IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -de5d858671b12baa6ce008727ecbb34f2f2ec992 \ No newline at end of file
diff --git a/chrome/app/profiles_strings.grdp b/chrome/app/profiles_strings.grdp index c9e1d22..eff833b 100644 --- a/chrome/app/profiles_strings.grdp +++ b/chrome/app/profiles_strings.grdp
@@ -708,7 +708,7 @@ Add </message> <message name="IDS_PROFILE_PICKER_BROWSE_AS_GUEST_BUTTON" desc="Text for the profile picker main view button that launches guest session."> - Browse as Guest + Guest mode </message> <message name="IDS_PROFILE_PICKER_BACK_BUTTON_LABEL" desc="Label for a button that navigates user to the previous page"> Back @@ -723,17 +723,29 @@ Customize your profile, including its name </message> <message name="IDS_PROFILE_PICKER_PROFILE_MENU_REMOVE_TEXT" desc="Text of the remove button in profile card menu."> - Remove + Delete </message> <message name="IDS_PROFILE_PICKER_PROFILE_MENU_REMOVE_CONFIRM" desc="Text of the remove button in the remove warning."> - Remove this profile + Delete </message> <message name="IDS_PROFILE_PICKER_PROFILE_MENU_CUSTOMIZE_TEXT" desc="Text of the customize button in profile card menu"> - Customize + Edit </message> <message name="IDS_PROFILE_PICKER_PROFILE_MENU_INCOGNITO_TEXT" desc="Text of the incognito button in profile card menu"> Incognito </message> + <message name="IDS_PROFILE_PICKER_ASK_ON_STARTUP" desc="Text for the checkbox on the profile picker main view"> + Show on startup + </message> + <message name="IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE_TITLE" desc="Title of the remove warning message shown for signed in profiles, shown when the user selects remove from the 3 dotted menu"> + Delete this profile? + </message> + <message name="IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE" desc="Remove warning message shown for signed in profiles shown when the user selects remove from the 3 dotted menu"> + This will permanently delete your browsing data from this device. To recover the data, turn on sync as + </message> + <message name="IDS_PROFILE_PICKER_REMOVE_WARNING_LOCAL_PROFILE_TITLE" desc="Title of the remove warning message shown for local profiles, shown when the user selects remove from the 3 dotted menu."> + Delete this profile and its data? + </message> <message name="IDS_PROFILE_PICKER_REMOVE_WARNING_LOCAL_PROFILE" desc="Main text shown as a warning when attempting to remove an user."> This will permanently delete your browsing data from this device. </message>
diff --git a/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_ASK_ON_STARTUP.png.sha1 b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_ASK_ON_STARTUP.png.sha1 new file mode 100644 index 0000000..25a234d7 --- /dev/null +++ b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_ASK_ON_STARTUP.png.sha1
@@ -0,0 +1 @@ +a064193913da1c2d06ab2a932d094c622e45a837 \ No newline at end of file
diff --git a/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_BROWSE_AS_GUEST_BUTTON.png.sha1 b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_BROWSE_AS_GUEST_BUTTON.png.sha1 index fbd2c11..25a234d7 100644 --- a/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_BROWSE_AS_GUEST_BUTTON.png.sha1 +++ b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_BROWSE_AS_GUEST_BUTTON.png.sha1
@@ -1 +1 @@ -12998557c02a35e50d016c53c9ab9bc3a778c724 \ No newline at end of file +a064193913da1c2d06ab2a932d094c622e45a837 \ No newline at end of file
diff --git a/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_MENU_CUSTOMIZE_TEXT.png.sha1 b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_MENU_CUSTOMIZE_TEXT.png.sha1 index 84bc98d..30bfd4f 100644 --- a/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_MENU_CUSTOMIZE_TEXT.png.sha1 +++ b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_MENU_CUSTOMIZE_TEXT.png.sha1
@@ -1 +1 @@ -0eb8b376ac429f0fc430c520e66c21845aeb307c \ No newline at end of file +cce701c74e713ef7261c237cb86d70425f50d285 \ No newline at end of file
diff --git a/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_MENU_REMOVE_CONFIRM.png.sha1 b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_MENU_REMOVE_CONFIRM.png.sha1 index 051674e..d4f9de16 100644 --- a/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_MENU_REMOVE_CONFIRM.png.sha1 +++ b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_MENU_REMOVE_CONFIRM.png.sha1
@@ -1 +1 @@ -ec9a79cdffe13f9f6adcfd406bad942b52994845 \ No newline at end of file +2a3a3c3d5bf360187d890afbfe303e8c733403c5 \ No newline at end of file
diff --git a/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_MENU_REMOVE_TEXT.png.sha1 b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_MENU_REMOVE_TEXT.png.sha1 index e22eff3..30bfd4f 100644 --- a/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_MENU_REMOVE_TEXT.png.sha1 +++ b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_PROFILE_MENU_REMOVE_TEXT.png.sha1
@@ -1 +1 @@ -142eeb0b333995bb9e97f4e8deacb899fd9a3781 \ No newline at end of file +cce701c74e713ef7261c237cb86d70425f50d285 \ No newline at end of file
diff --git a/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_REMOVE_WARNING_LOCAL_PROFILE_TITLE.png.sha1 b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_REMOVE_WARNING_LOCAL_PROFILE_TITLE.png.sha1 new file mode 100644 index 0000000..c53cec3c --- /dev/null +++ b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_REMOVE_WARNING_LOCAL_PROFILE_TITLE.png.sha1
@@ -0,0 +1 @@ +2bacc5f33ddef4d028243d6e97f85797d5792774 \ No newline at end of file
diff --git a/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE.png.sha1 b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE.png.sha1 new file mode 100644 index 0000000..d4f9de16 --- /dev/null +++ b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE.png.sha1
@@ -0,0 +1 @@ +2a3a3c3d5bf360187d890afbfe303e8c733403c5 \ No newline at end of file
diff --git a/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE_TITLE.png.sha1 b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE_TITLE.png.sha1 new file mode 100644 index 0000000..cc1db8b --- /dev/null +++ b/chrome/app/profiles_strings_grdp/IDS_PROFILE_PICKER_REMOVE_WARNING_SIGNED_IN_PROFILE_TITLE.png.sha1
@@ -0,0 +1 @@ +408fca9dc377d9224566b3b54d059f351c2b7673 \ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index e2012e9..19699f1 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1385,6 +1385,24 @@ {"12 matches", kOmniboxUIMaxAutocompleteMatches12, base::size(kOmniboxUIMaxAutocompleteMatches12), nullptr}}; +const FeatureEntry::FeatureParam + kOmniboxDefaultTypedNavigationsToHttpsVariationsTimeout3s[] = { + {omnibox::kDefaultTypedNavigationsToHttpsTimeoutParam, "3s"}}; +const FeatureEntry::FeatureParam + kOmniboxDefaultTypedNavigationsToHttpsVariationsTimeout10s[] = { + {omnibox::kDefaultTypedNavigationsToHttpsTimeoutParam, "10s"}}; +const FeatureEntry::FeatureVariation + kOmniboxDefaultTypedNavigationsToHttpsVariations[] = { + {"3 second timeout", + kOmniboxDefaultTypedNavigationsToHttpsVariationsTimeout3s, + base::size(kOmniboxDefaultTypedNavigationsToHttpsVariationsTimeout3s), + nullptr}, + {"10 second timeout", + kOmniboxDefaultTypedNavigationsToHttpsVariationsTimeout10s, + base::size(kOmniboxDefaultTypedNavigationsToHttpsVariationsTimeout10s), + nullptr}, +}; + const FeatureEntry::FeatureParam kOmniboxMaxURLMatches2[] = { {OmniboxFieldTrial::kOmniboxMaxURLMatchesParam, "2"}}; const FeatureEntry::FeatureParam kOmniboxMaxURLMatches3[] = { @@ -2499,6 +2517,7 @@ const FeatureEntry::FeatureParam kPasswordsAccountStorage_ProfileStore[] = { {password_manager::features::kSaveToProfileStoreByDefault, "true"}, + {password_manager::features::kSaveToAccountStoreOnOptIn, "true"}, }; const FeatureEntry::FeatureVariation kPasswordsAccountStorageVariations[] = { @@ -4286,6 +4305,15 @@ flag_descriptions::kMemlogStackModeDescription, kOsAll, MULTI_VALUE_TYPE(kMemlogStackModeChoices)}, + {"omnibox-default-typed-navigations-to-https", + flag_descriptions::kOmniboxDefaultTypedNavigationsToHttpsName, + flag_descriptions::kOmniboxDefaultTypedNavigationsToHttpsDescription, + kOsAll, + FEATURE_WITH_PARAMS_VALUE_TYPE( + omnibox::kDefaultTypedNavigationsToHttps, + kOmniboxDefaultTypedNavigationsToHttpsVariations, + "OmniboxDefaultTypedNavigationsToHttps")}, + {"omnibox-ui-sometimes-elide-to-registrable-domain", flag_descriptions::kOmniboxUIMaybeElideToRegistrableDomainName, flag_descriptions::kOmniboxUIMaybeElideToRegistrableDomainDescription, @@ -6264,7 +6292,7 @@ FEATURE_WITH_PARAMS_VALUE_TYPE( password_manager::features::kPasswordChangeInSettings, kPasswordChangeInSettingsFeatureVariations, - "PasswordChangeInSettingsFeatureVariations")}, + "PasswordChangeInSettings")}, {"password-scripts-fetching", flag_descriptions::kPasswordScriptsFetchingName, flag_descriptions::kPasswordScriptsFetchingDescription, kOsAndroid,
diff --git a/chrome/browser/android/autofill_assistant/trigger_script_bridge_android.cc b/chrome/browser/android/autofill_assistant/trigger_script_bridge_android.cc index a6230d4..f8a77ea0 100644 --- a/chrome/browser/android/autofill_assistant/trigger_script_bridge_android.cc +++ b/chrome/browser/android/autofill_assistant/trigger_script_bridge_android.cc
@@ -223,7 +223,7 @@ ToJavaIntArray(env, cancel_popup_actions), jleft_aligned_chips, ToJavaIntArray(env, left_aligned_chip_actions), jright_aligned_chips, ToJavaIntArray(env, right_aligned_chip_actions), - proto.resize_visual_viewport()); + proto.resize_visual_viewport(), proto.scroll_to_hide()); trigger_script_coordinator_->OnTriggerScriptShown(success); }
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc index 98f058f..0e33bbe5 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
@@ -27,6 +27,7 @@ #include "chrome/android/features/autofill_assistant/jni_headers/AssistantInfoBox_jni.h" #include "chrome/android/features/autofill_assistant/jni_headers/AssistantModel_jni.h" #include "chrome/android/features/autofill_assistant/jni_headers/AssistantOverlayModel_jni.h" +#include "chrome/android/features/autofill_assistant/jni_headers/AssistantPlaceholdersConfiguration_jni.h" #include "chrome/android/features/autofill_assistant/jni_headers/AutofillAssistantUiController_jni.h" #include "chrome/browser/android/autofill_assistant/client_android.h" #include "chrome/browser/android/autofill_assistant/generic_ui_root_controller_android.h" @@ -1779,16 +1780,30 @@ jimage_accessibility_hint = ConvertUTF8ToJavaString(env, opt_image_accessibility_hint.value()); } + + // Create the placeholders configuration. We check here that the associated + // texts/urls are empty, so that on the Java side we can just check the + // placeholders configuration to know whether a placeholder should be shown or + // not. + auto placeholders = details->placeholders(); + auto jplaceholders = Java_AssistantPlaceholdersConfiguration_Constructor( + env, placeholders.show_image_placeholder() && details->imageUrl().empty(), + placeholders.show_title_placeholder() && details->title().empty(), + placeholders.show_description_line_1_placeholder() && + details->descriptionLine1().empty(), + placeholders.show_description_line_2_placeholder() && + details->descriptionLine2().empty(), + placeholders.show_description_line_3_placeholder() && + details->descriptionLine3().empty()); + auto jdetails = Java_AssistantDetails_create( env, ConvertUTF8ToJavaString(env, details->title()), - details->titleMaxLines(), ConvertUTF8ToJavaString(env, details->imageUrl()), jimage_accessibility_hint, details->imageAllowClickthrough(), ConvertUTF8ToJavaString(env, details->imageDescription()), ConvertUTF8ToJavaString(env, details->imagePositiveText()), ConvertUTF8ToJavaString(env, details->imageNegativeText()), ConvertUTF8ToJavaString(env, details->imageClickthroughUrl()), - details->showImagePlaceholder(), ConvertUTF8ToJavaString(env, details->totalPriceLabel()), ConvertUTF8ToJavaString(env, details->totalPrice()), ConvertUTF8ToJavaString(env, details->descriptionLine1()), @@ -1797,7 +1812,7 @@ ConvertUTF8ToJavaString(env, details->priceAttribution()), details->userApprovalRequired(), details->highlightTitle(), details->highlightLine1(), details->highlightLine2(), - details->highlightLine3(), details->animatePlaceholders()); + details->highlightLine3(), jplaceholders); Java_AssistantDetailsModel_setDetails(env, jmodel, jdetails); }
diff --git a/chrome/browser/apps/app_service/extension_apps_chromeos.cc b/chrome/browser/apps/app_service/extension_apps_chromeos.cc index 5091cd2b..ab3648b6 100644 --- a/chrome/browser/apps/app_service/extension_apps_chromeos.cc +++ b/chrome/browser/apps/app_service/extension_apps_chromeos.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/apps/app_service/extension_apps_chromeos.h" #include <memory> +#include <string> #include <utility> #include <vector> @@ -62,6 +63,7 @@ #include "extensions/browser/extension_system.h" #include "extensions/browser/management_policy.h" #include "extensions/browser/ui_util.h" +#include "extensions/common/constants.h" #include "extensions/common/extension_urls.h" #include "extensions/common/manifest_handlers/options_page_info.h" #include "ui/message_center/public/cpp/notification.h" @@ -502,36 +504,13 @@ return; } - bool is_disabled = - base::Contains(*disabled_system_features_pref, - base::Value(policy::SystemFeature::kCamera)); - auto* app_id = extension_misc::kCameraAppId; + UpdateAppDisabledState(disabled_system_features_pref, + policy::SystemFeature::kCamera, + extension_misc::kCameraAppId); - // Sometimes the policy is updated before the app is installed, so this way - // the disabled_apps_ is updated regardless the Publish should happen or not - // and the app will be published with the correct readiness upon its - // installation. - bool should_publish = (base::Contains(disabled_apps_, app_id) != is_disabled); - - if (is_disabled) { - disabled_apps_.insert(app_id); - } else { - disabled_apps_.erase(app_id); - } - - if (!should_publish) { - return; - } - - const auto* extension = MaybeGetExtension(app_id); - if (!extension) { - return; - } - - Publish( - Convert(extension, is_disabled ? apps::mojom::Readiness::kDisabledByPolicy - : apps::mojom::Readiness::kReady), - subscribers()); + UpdateAppDisabledState(disabled_system_features_pref, + policy::SystemFeature::kWebStore, + extensions::kWebStoreAppId); } bool ExtensionAppsChromeOs::Accepts(const extensions::Extension* extension) { @@ -730,4 +709,38 @@ return web_contents; } +void ExtensionAppsChromeOs::UpdateAppDisabledState( + const base::ListValue* disabled_system_features_pref, + int feature, + const std::string& app_id) { + const bool is_disabled = + base::Contains(*disabled_system_features_pref, base::Value(feature)); + // Sometimes the policy is updated before the app is installed, so this way + // the disabled_apps_ is updated regardless the Publish should happen or not + // and the app will be published with the correct readiness upon its + // installation. + const bool should_publish = + (base::Contains(disabled_apps_, app_id) != is_disabled); + + if (is_disabled) { + disabled_apps_.insert(app_id); + } else { + disabled_apps_.erase(app_id); + } + + if (!should_publish) { + return; + } + + const auto* extension = MaybeGetExtension(app_id); + if (!extension) { + return; + } + + Publish( + Convert(extension, is_disabled ? apps::mojom::Readiness::kDisabledByPolicy + : apps::mojom::Readiness::kReady), + subscribers()); +} + } // namespace apps
diff --git a/chrome/browser/apps/app_service/extension_apps_chromeos.h b/chrome/browser/apps/app_service/extension_apps_chromeos.h index beacd54..371a45b 100644 --- a/chrome/browser/apps/app_service/extension_apps_chromeos.h +++ b/chrome/browser/apps/app_service/extension_apps_chromeos.h
@@ -150,6 +150,11 @@ content::WebContents* LaunchImpl(AppLaunchParams&& params) override; + void UpdateAppDisabledState( + const base::ListValue* disabled_system_features_pref, + int feature, + const std::string& app_id); + apps::InstanceRegistry* instance_registry_; ScopedObserver<extensions::AppWindowRegistry, extensions::AppWindowRegistry::Observer>
diff --git a/chrome/browser/apps/app_service/notifications_browsertest.cc b/chrome/browser/apps/app_service/notifications_browsertest.cc index 68f4615..43acefb 100644 --- a/chrome/browser/apps/app_service/notifications_browsertest.cc +++ b/chrome/browser/apps/app_service/notifications_browsertest.cc
@@ -27,6 +27,7 @@ #include "chrome/browser/notifications/profile_notification.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" +#include "chrome/common/chrome_switches.h" #include "components/arc/arc_service_manager.h" #include "components/arc/arc_util.h" #include "components/arc/session/arc_bridge_service.h" @@ -265,6 +266,13 @@ ASSERT_TRUE(https_server_.Start()); } + void SetUpCommandLine(base::CommandLine* command_line) override { + extensions::PlatformAppBrowserTest::SetUpCommandLine(command_line); + command_line->AppendSwitchASCII( + switches::kDesktopPWAsAttentionBadgingCrOS, + switches::kDesktopPWAsAttentionBadgingCrOSApiAndNotifications); + } + std::string CreateWebApp(const GURL& url, const GURL& scope) const { auto web_app_info = std::make_unique<WebApplicationInfo>(); web_app_info->start_url = url;
diff --git a/chrome/browser/apps/app_service/web_apps_chromeos.cc b/chrome/browser/apps/app_service/web_apps_chromeos.cc index 8edb995..2d11921 100644 --- a/chrome/browser/apps/app_service/web_apps_chromeos.cc +++ b/chrome/browser/apps/app_service/web_apps_chromeos.cc
@@ -70,7 +70,7 @@ return cmdline->GetSwitchValueASCII( switches::kDesktopPWAsAttentionBadgingCrOS); } - return ""; + return switches::kDesktopPWAsAttentionBadgingCrOSApiOnly; } } // namespace @@ -556,9 +556,8 @@ // Show a badge only if a notification is showing. return has_notification; } else { - // When the flag is not set or set to "api-and-notifications" we show a - // badge if either a notification is showing or the Web Badging API has a - // badge set. + // When the flag is set to "api-and-notifications" we show a badge if either + // a notification is showing or the Web Badging API has a badge set. return badge_manager_ && badge_manager_->GetBadgeValue(app_id).has_value() ? apps::mojom::OptionalBool::kTrue : has_notification;
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc b/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc index b4b6e84..9f896b2 100644 --- a/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc +++ b/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc
@@ -25,10 +25,10 @@ #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" -#include "chrome/browser/chromeos/login/screens/sync_consent_screen.h" #include "chrome/browser/chromeos/login/test/device_state_mixin.h" #include "chrome/browser/chromeos/login/test/login_manager_mixin.h" #include "chrome/browser/chromeos/login/test/oobe_base_test.h" +#include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" @@ -1141,7 +1141,7 @@ // user) and announces the sync consent screen correctly. IN_PROC_BROWSER_TEST_F(SigninToUserProfileSwitchTest, LoginAsNewUser) { // Force sync screen. - auto reset = SyncConsentScreen::ForceBrandedBuildForTesting(true); + auto reset = WizardController::ForceBrandedBuildForTesting(true); AccessibilityManager::Get()->EnableSpokenFeedback(true); sm_.ExpectSpeechPattern("*");
diff --git a/chrome/browser/chromeos/crosapi/browser_manager.cc b/chrome/browser/chromeos/crosapi/browser_manager.cc index 3a710b3..901bdc91 100644 --- a/chrome/browser/chromeos/crosapi/browser_manager.cc +++ b/chrome/browser/chromeos/crosapi/browser_manager.cc
@@ -505,4 +505,8 @@ lacros_chrome_service_version_ = version; } +void BrowserManager::SetDeviceAccountPolicy(const std::string& policy_blob) { + environment_provider_->SetDeviceAccountPolicy(policy_blob); +} + } // namespace crosapi
diff --git a/chrome/browser/chromeos/crosapi/browser_manager.h b/chrome/browser/chromeos/crosapi/browser_manager.h index 11ac7f0..a9ccf2e79 100644 --- a/chrome/browser/chromeos/crosapi/browser_manager.h +++ b/chrome/browser/chromeos/crosapi/browser_manager.h
@@ -106,6 +106,11 @@ lacros_version_ = version; } + // Set the data of device account policy. It is the serialized blob of + // PolicyFetchResponse received from the server, or parsed from the file after + // is was validated by Ash. + void SetDeviceAccountPolicy(const std::string& policy_blob); + protected: // Notifies Mojo connection to lacros-chrome has been disconnected. void NotifyMojoDisconnected();
diff --git a/chrome/browser/chromeos/crosapi/browser_util.cc b/chrome/browser/chromeos/crosapi/browser_util.cc index f3c68b5a..c912c44 100644 --- a/chrome/browser/chromeos/crosapi/browser_util.cc +++ b/chrome/browser/chromeos/crosapi/browser_util.cc
@@ -70,6 +70,23 @@ } } +// Returns the vector containing policy data of the device account. In case of +// an error, returns nullopt. +base::Optional<std::vector<uint8_t>> GetDeviceAccountPolicy( + EnvironmentProvider* environment_provider) { + if (!user_manager::UserManager::IsInitialized()) { + LOG(ERROR) << "User not initialized."; + return base::nullopt; + } + const auto* primary_user = user_manager::UserManager::Get()->GetPrimaryUser(); + if (!primary_user) { + LOG(ERROR) << "No primary user."; + return base::nullopt; + } + std::string policy_data = environment_provider->GetDeviceAccountPolicy(); + return std::vector<uint8_t>(policy_data.begin(), policy_data.end()); +} + using InterfaceVersions = base::flat_map<base::Token, uint32_t>; template <typename T> void AddVersion(InterfaceVersions* map) { @@ -102,6 +119,7 @@ crosapi::mojom::ExoImeSupport::kConsumedByImeWorkaround; params->cros_user_id_hash = chromeos::ProfileHelper::GetUserIdHashFromProfile( ProfileManager::GetPrimaryUserProfile()); + params->device_account_policy = GetDeviceAccountPolicy(environment_provider); return params; } @@ -239,8 +257,8 @@ std::move(mojo_disconnected_callback)); // This is for backward compatibility. - // TODO(crbug.com/1156033): Remove InitDeperecated() invocation when lacros - // becomes new enough. + // TODO(crbug.com/1156033): Remove InitDeprecated() invocation when lacros + // becomes mature enough. lacros_chrome_service->InitDeprecated( GetLacrosInitParams(environment_provider));
diff --git a/chrome/browser/chromeos/crosapi/environment_provider.cc b/chrome/browser/chromeos/crosapi/environment_provider.cc index be0969a..4b36cae 100644 --- a/chrome/browser/chromeos/crosapi/environment_provider.cc +++ b/chrome/browser/chromeos/crosapi/environment_provider.cc
@@ -98,4 +98,13 @@ return account_id.GetGaiaId(); } +void EnvironmentProvider::SetDeviceAccountPolicy( + const std::string& policy_blob) { + device_account_policy_blob_ = policy_blob; +} + +std::string EnvironmentProvider::GetDeviceAccountPolicy() { + return device_account_policy_blob_; +} + } // namespace crosapi
diff --git a/chrome/browser/chromeos/crosapi/environment_provider.h b/chrome/browser/chromeos/crosapi/environment_provider.h index 0417191..284cf453 100644 --- a/chrome/browser/chromeos/crosapi/environment_provider.h +++ b/chrome/browser/chromeos/crosapi/environment_provider.h
@@ -28,6 +28,17 @@ // not the Lacros profile. virtual crosapi::mojom::DefaultPathsPtr GetDefaultPaths(); virtual std::string GetDeviceAccountGaiaId(); + + // Getter and setter for device account policy data. Used to pass data from + // Ash to Lacros. The format is serialized PolicyFetchResponse object. See + // components/policy/proto/device_management_backend.proto for details. + virtual std::string GetDeviceAccountPolicy(); + virtual void SetDeviceAccountPolicy(const std::string& policy_blob); + + private: + // The serialized PolicyFetchResponse object corresponding to the policy of + // device account. Used to pass the data from Ash to Lacros. + std::string device_account_policy_blob_; }; } // namespace crosapi
diff --git a/chrome/browser/chromeos/file_manager/file_manager_jstest.cc b/chrome/browser/chromeos/file_manager/file_manager_jstest.cc index de39c29..5dc1a875 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_jstest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_jstest.cc
@@ -83,7 +83,7 @@ } IN_PROC_BROWSER_TEST_F(FileManagerJsTest, FileManagerDialogBaseTest) { - RunTestURL("foreground/js/ui/file_manager_dialog_base_unittest_gen.html"); + RunTestURL("foreground/js/ui/file_manager_dialog_base_unittest.m_gen.html"); } IN_PROC_BROWSER_TEST_F(FileManagerJsTest, FileOperationHandlerTest) { @@ -145,7 +145,7 @@ } IN_PROC_BROWSER_TEST_F(FileManagerJsTest, FileTypeFiltersController) { - RunTestURL("foreground/js/file_type_filters_controller_unittest_gen.html"); + RunTestURL("foreground/js/file_type_filters_controller_unittest.m_gen.html"); } IN_PROC_BROWSER_TEST_F(FileManagerJsTest, FileType) { @@ -209,7 +209,7 @@ } IN_PROC_BROWSER_TEST_F(FileManagerJsTest, MultiMenu) { - RunTestURL("foreground/js/ui/multi_menu_unittest_gen.html"); + RunTestURL("foreground/js/ui/multi_menu_unittest.m_gen.html"); } IN_PROC_BROWSER_TEST_F(FileManagerJsTest, MultiMetadataProvider) { @@ -222,11 +222,11 @@ } IN_PROC_BROWSER_TEST_F(FileManagerJsTest, ProvidersModel) { - RunTestURL("foreground/js/providers_model_unittest_gen.html"); + RunTestURL("foreground/js/providers_model_unittest.m_gen.html"); } IN_PROC_BROWSER_TEST_F(FileManagerJsTest, SpinnerController) { - RunTestURL("foreground/js/spinner_controller_unittest_gen.html"); + RunTestURL("foreground/js/spinner_controller_unittest.m_gen.html"); } IN_PROC_BROWSER_TEST_F(FileManagerJsTest, TaskController) {
diff --git a/chrome/browser/chromeos/login/configuration_based_oobe_browsertest.cc b/chrome/browser/chromeos/login/configuration_based_oobe_browsertest.cc index a6557c9..99ac3d1 100644 --- a/chrome/browser/chromeos/login/configuration_based_oobe_browsertest.cc +++ b/chrome/browser/chromeos/login/configuration_based_oobe_browsertest.cc
@@ -128,7 +128,8 @@ LoadConfiguration(); // Make sure that OOBE is run as an "official" build. - branded_build_override_ = WizardController::ForceBrandedBuildForTesting(); + branded_build_override_ = + WizardController::ForceBrandedBuildForTesting(true); // Clear portal list (as it is by default in OOBE). NetworkHandler::Get()->network_state_handler()->SetCheckPortalList("");
diff --git a/chrome/browser/chromeos/login/demo_mode/demo_setup_browsertest.cc b/chrome/browser/chromeos/login/demo_mode/demo_setup_browsertest.cc index 4d92f1af..fcf1536 100644 --- a/chrome/browser/chromeos/login/demo_mode/demo_setup_browsertest.cc +++ b/chrome/browser/chromeos/login/demo_mode/demo_setup_browsertest.cc
@@ -148,7 +148,8 @@ update_engine_client()->set_update_check_result( UpdateEngineClient::UPDATE_RESULT_FAILED); DisableConfirmationDialogAnimations(); - branded_build_override_ = WizardController::ForceBrandedBuildForTesting(); + branded_build_override_ = + WizardController::ForceBrandedBuildForTesting(true); DisconnectAllNetworks(); }
diff --git a/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_impl.cc b/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_impl.cc index eb8f16bd..225609c 100644 --- a/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_impl.cc +++ b/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_impl.cc
@@ -259,7 +259,13 @@ policy::BrowserPolicyConnectorChromeOS* connector = g_browser_process->platform_part()->browser_policy_connector_chromeos(); // Re-enrollment is not implemented for Active Directory. - if (connector->IsCloudManaged() && + // If an enrollment domain is already fixed in install attributes and + // re-enrollment happens via login, domains need to be equal. + // If there is a mismatch between domain set in install attributes and + // auto re-enrollment domain provided by the server, policy validation will + // fail later in the process. + if (connector->IsCloudManaged() && !enrolling_user_domain_.empty() && + !enrollment_config_.is_mode_attestation() && connector->GetEnterpriseEnrollmentDomain() != enrolling_user_domain_) { LOG(ERROR) << "Trying to re-enroll to a different domain than " << connector->GetEnterpriseEnrollmentDomain();
diff --git a/chrome/browser/chromeos/login/enrollment/hands_off_enrollment_browsertest.cc b/chrome/browser/chromeos/login/enrollment/hands_off_enrollment_browsertest.cc index 5e2700f..8c25854 100644 --- a/chrome/browser/chromeos/login/enrollment/hands_off_enrollment_browsertest.cc +++ b/chrome/browser/chromeos/login/enrollment/hands_off_enrollment_browsertest.cc
@@ -52,7 +52,8 @@ MixinBasedInProcessBrowserTest::SetUpOnMainThread(); // Set official build so EULA screen is not skipped by default. - branded_build_override_ = WizardController::ForceBrandedBuildForTesting(); + branded_build_override_ = + WizardController::ForceBrandedBuildForTesting(true); // Sets all network services into idle state to simulate disconnected state. NetworkStateHandler::NetworkStateList networks;
diff --git a/chrome/browser/chromeos/login/login_ui_shelf_visibility_browsertest.cc b/chrome/browser/chromeos/login/login_ui_shelf_visibility_browsertest.cc index a6fbc8e..044d06b 100644 --- a/chrome/browser/chromeos/login/login_ui_shelf_visibility_browsertest.cc +++ b/chrome/browser/chromeos/login/login_ui_shelf_visibility_browsertest.cc
@@ -67,7 +67,7 @@ // Verifies that guest button and add user button are hidden on post-login // screens, after a user session is started. IN_PROC_BROWSER_TEST_F(LoginUIShelfVisibilityTest, PostLoginScreen) { - auto autoreset = SyncConsentScreen::ForceBrandedBuildForTesting(true); + auto autoreset = WizardController::ForceBrandedBuildForTesting(true); EXPECT_TRUE(ash::LoginScreenTestApi::ClickAddUserButton()); test::OobeGaiaPageWaiter().WaitUntilReady(); LoginDisplayHost::default_host()
diff --git a/chrome/browser/chromeos/login/oobe_interactive_ui_test.cc b/chrome/browser/chromeos/login/oobe_interactive_ui_test.cc index 44c3ad65..a63e1aa1 100644 --- a/chrome/browser/chromeos/login/oobe_interactive_ui_test.cc +++ b/chrome/browser/chromeos/login/oobe_interactive_ui_test.cc
@@ -652,10 +652,8 @@ std::tuple<bool, bool, bool, ArcState>> { public: OobeInteractiveUITest() { - // TODO(https://crbug.com/1130502): Merge these functions into one. - branded_build_override_ = WizardController::ForceBrandedBuildForTesting(); - sync_branded_build_override_ = - SyncConsentScreen::ForceBrandedBuildForTesting(true); + branded_build_override_ = + WizardController::ForceBrandedBuildForTesting(true); } ~OobeInteractiveUITest() override = default; @@ -693,7 +691,6 @@ private: std::unique_ptr<base::AutoReset<bool>> branded_build_override_; - std::unique_ptr<base::AutoReset<bool>> sync_branded_build_override_; FakeGaiaMixin fake_gaia_{&mixin_host_, embedded_test_server()}; FakeEulaMixin fake_eula_{&mixin_host_, embedded_test_server()};
diff --git a/chrome/browser/chromeos/login/screens/gaia_screen.cc b/chrome/browser/chromeos/login/screens/gaia_screen.cc index 2654f27..f231ac0 100644 --- a/chrome/browser/chromeos/login/screens/gaia_screen.cc +++ b/chrome/browser/chromeos/login/screens/gaia_screen.cc
@@ -25,8 +25,8 @@ switch (result) { case Result::BACK: return "Back"; - case Result::CLOSE_DIALOG: - return "CloseDialog"; + case Result::CANCEL: + return "Cancel"; case Result::ENTERPRISE_ENROLL: return "EnterpriseEnroll"; case Result::START_CONSUMER_KIOSK: @@ -83,21 +83,15 @@ } void GaiaScreen::OnUserAction(const std::string& action_id) { - if (action_id == kUserActionBack || action_id == kUserActionCancel) { - // `kUserActionBack` will go back to user creation screen if possible. - // `kUserActionCancel` will stay at the gaia screen and reload the screen. - if (action_id == kUserActionBack && context()->is_user_creation_enabled) { - exit_callback_.Run(Result::BACK); - } else { - HandleCancel(); - } - return; - } - if (action_id == kUserActionStartEnrollment) { + if (action_id == kUserActionBack) { + exit_callback_.Run(Result::BACK); + } else if (action_id == kUserActionCancel) { + exit_callback_.Run(Result::CANCEL); + } else if (action_id == kUserActionStartEnrollment) { exit_callback_.Run(Result::ENTERPRISE_ENROLL); - return; + } else { + BaseScreen::OnUserAction(action_id); } - BaseScreen::OnUserAction(action_id); } bool GaiaScreen::HandleAccelerator(ash::LoginAcceleratorAction action) { @@ -112,15 +106,4 @@ return false; } -void GaiaScreen::HandleCancel() { - // Close the user pod if it exists and gaia is the first screen, or reload - // the page. - if (LoginDisplayHost::default_host()->HasUserPods() && - !context()->is_user_creation_enabled) { - exit_callback_.Run(Result::CLOSE_DIALOG); - } else { - LoadOnline(EmptyAccountId()); - } -} - } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screens/gaia_screen.h b/chrome/browser/chromeos/login/screens/gaia_screen.h index 8ad51606..31ba35f 100644 --- a/chrome/browser/chromeos/login/screens/gaia_screen.h +++ b/chrome/browser/chromeos/login/screens/gaia_screen.h
@@ -24,7 +24,7 @@ enum class Result { BACK, - CLOSE_DIALOG, + CANCEL, ENTERPRISE_ENROLL, START_CONSUMER_KIOSK, }; @@ -51,8 +51,6 @@ void OnUserAction(const std::string& action_id) override; bool HandleAccelerator(ash::LoginAcceleratorAction action) override; - void HandleCancel(); - GaiaView* view_ = nullptr; ScreenExitCallback exit_callback_;
diff --git a/chrome/browser/chromeos/login/screens/parental_handoff_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/parental_handoff_screen_browsertest.cc index 1ce0dd0f..2a21f1c 100644 --- a/chrome/browser/chromeos/login/screens/parental_handoff_screen_browsertest.cc +++ b/chrome/browser/chromeos/login/screens/parental_handoff_screen_browsertest.cc
@@ -14,7 +14,6 @@ #include "base/test/scoped_feature_list.h" #include "chrome/browser/chromeos/login/screens/assistant_optin_flow_screen.h" #include "chrome/browser/chromeos/login/screens/edu_coexistence_login_screen.h" -#include "chrome/browser/chromeos/login/screens/sync_consent_screen.h" #include "chrome/browser/chromeos/login/test/fake_gaia_mixin.h" #include "chrome/browser/chromeos/login/test/js_checker.h" #include "chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h" @@ -95,7 +94,7 @@ base::HistogramTester histogram_tester_; - std::unique_ptr<base::AutoReset<bool>> chrome_sync_is_google_branded_build_; + std::unique_ptr<base::AutoReset<bool>> is_google_branded_build_; std::unique_ptr<base::AutoReset<bool>> assistant_is_enabled_; @@ -108,8 +107,8 @@ } void ParentalHandoffScreenBrowserTest::SetUpOnMainThread() { - chrome_sync_is_google_branded_build_ = - SyncConsentScreen::ForceBrandedBuildForTesting(true); + is_google_branded_build_ = + WizardController::ForceBrandedBuildForTesting(true); assistant_is_enabled_ = AssistantOptInFlowScreen::ForceLibAssistantEnabledForTesting(false); ParentalHandoffScreen* screen = GetParentalHandoffScreen();
diff --git a/chrome/browser/chromeos/login/screens/recommend_apps_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/recommend_apps_screen_browsertest.cc index 4cc2163..e7404e41 100644 --- a/chrome/browser/chromeos/login/screens/recommend_apps_screen_browsertest.cc +++ b/chrome/browser/chromeos/login/screens/recommend_apps_screen_browsertest.cc
@@ -17,7 +17,6 @@ #include "chrome/browser/chromeos/login/screens/recommend_apps/recommend_apps_fetcher.h" #include "chrome/browser/chromeos/login/screens/recommend_apps/recommend_apps_fetcher_delegate.h" #include "chrome/browser/chromeos/login/screens/recommend_apps/scoped_test_recommend_apps_fetcher_factory.h" -#include "chrome/browser/chromeos/login/screens/sync_consent_screen.h" #include "chrome/browser/chromeos/login/test/js_checker.h" #include "chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h" #include "chrome/browser/chromeos/login/test/login_manager_mixin.h" @@ -554,7 +553,7 @@ IN_PROC_BROWSER_TEST_F(RecommendAppsScreenManagedTest, SkipDueToManagedUser) { // Force the sync screen to be shown so that OOBE isn't destroyed // right after login due to all screens being skipped. - auto autoreset = SyncConsentScreen::ForceBrandedBuildForTesting(true); + auto autoreset = WizardController::ForceBrandedBuildForTesting(true); // Mark user as managed. user_policy_mixin_.RequestPolicyUpdate();
diff --git a/chrome/browser/chromeos/login/screens/sync_consent_browsertest.cc b/chrome/browser/chromeos/login/screens/sync_consent_browsertest.cc index 2c81f72..4e42e86 100644 --- a/chrome/browser/chromeos/login/screens/sync_consent_browsertest.cc +++ b/chrome/browser/chromeos/login/screens/sync_consent_browsertest.cc
@@ -129,7 +129,7 @@ public: SyncConsentTest() : force_branded_build_( - SyncConsentScreen::ForceBrandedBuildForTesting(true)) {} + WizardController::ForceBrandedBuildForTesting(true)) {} ~SyncConsentTest() override = default; void SetUpOnMainThread() override { @@ -252,7 +252,7 @@ }; IN_PROC_BROWSER_TEST_F(SyncConsentTest, SkippedNotBrandedBuild) { - auto autoreset = SyncConsentScreen::ForceBrandedBuildForTesting(false); + auto autoreset = WizardController::ForceBrandedBuildForTesting(false); LoginToSyncConsentScreen(); WaitForScreenExit(); @@ -264,7 +264,7 @@ IN_PROC_BROWSER_TEST_F(SyncConsentTest, SkippedSyncDisabledByPolicy) { // Set up screen and policy. - auto autoreset = SyncConsentScreen::ForceBrandedBuildForTesting(true); + auto autoreset = WizardController::ForceBrandedBuildForTesting(true); SyncConsentScreen* screen = GetSyncConsentScreen(); screen->SetProfileSyncDisabledByPolicyForTesting(true); @@ -584,7 +584,7 @@ IN_PROC_BROWSER_TEST_F(SyncConsentSplitSettingsSyncTest, SkippedNotBrandedBuild) { - auto autoreset = SyncConsentScreen::ForceBrandedBuildForTesting(false); + auto autoreset = WizardController::ForceBrandedBuildForTesting(false); LoginToSyncConsentScreen(); WaitForScreenExit(); EXPECT_EQ(screen_result_.value(), SyncConsentScreen::Result::NOT_APPLICABLE);
diff --git a/chrome/browser/chromeos/login/screens/sync_consent_screen.cc b/chrome/browser/chromeos/login/screens/sync_consent_screen.cc index d460cf8c..fe37e6401f 100644 --- a/chrome/browser/chromeos/login/screens/sync_consent_screen.cc +++ b/chrome/browser/chromeos/login/screens/sync_consent_screen.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/check.h" #include "base/metrics/histogram_functions.h" +#include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/consent_auditor/consent_auditor_factory.h" #include "chrome/browser/profiles/profile.h" @@ -54,13 +55,6 @@ } // namespace // static -#if BUILDFLAG(GOOGLE_CHROME_BRANDING) -bool g_is_branded_build = true; -#else -bool g_is_branded_build = false; -#endif - -// static std::string SyncConsentScreen::GetResultString(Result result) { switch (result) { case Result::NEXT: @@ -273,17 +267,6 @@ } } -// static -std::unique_ptr<base::AutoReset<bool>> -SyncConsentScreen::ForceBrandedBuildForTesting(bool value) { - return std::make_unique<base::AutoReset<bool>>(&g_is_branded_build, value); -} - -// static -bool SyncConsentScreen::IsBrandedBuildForTesting() { - return g_is_branded_build; -} - void SyncConsentScreen::SetDelegateForTesting( SyncConsentScreen::SyncConsentScreenTestDelegate* delegate) { test_delegate_ = delegate; @@ -307,7 +290,7 @@ // Skip for non-branded (e.g. developer) builds. Check this after the account // type checks so we don't try to enable sync in browser_tests for those // account types. - if (!g_is_branded_build) + if (!WizardController::IsBrandedBuild()) return SyncScreenBehavior::kSkipAndEnableNonBrandedBuild; const user_manager::UserManager* user_manager =
diff --git a/chrome/browser/chromeos/login/screens/sync_consent_screen.h b/chrome/browser/chromeos/login/screens/sync_consent_screen.h index a486e91..be499ce 100644 --- a/chrome/browser/chromeos/login/screens/sync_consent_screen.h +++ b/chrome/browser/chromeos/login/screens/sync_consent_screen.h
@@ -104,11 +104,6 @@ // Enables sync if required when skipping the dialog. void MaybeEnableSyncForSkip(); - static std::unique_ptr<base::AutoReset<bool>> ForceBrandedBuildForTesting( - bool value); - - static bool IsBrandedBuildForTesting(); - // Sets internal condition "Sync disabled by policy" for tests. void SetProfileSyncDisabledByPolicyForTesting(bool value);
diff --git a/chrome/browser/chromeos/login/test/oobe_screens_utils.cc b/chrome/browser/chromeos/login/test/oobe_screens_utils.cc index af442a3b..50f020a 100644 --- a/chrome/browser/chromeos/login/test/oobe_screens_utils.cc +++ b/chrome/browser/chromeos/login/test/oobe_screens_utils.cc
@@ -144,25 +144,25 @@ } void WaitForEulaScreen() { - if (!WizardController::IsBrandedBuildForTesting()) + if (!WizardController::IsBrandedBuild()) return; WaitFor(EulaView::kScreenId); } void TapEulaAccept() { - if (!WizardController::IsBrandedBuildForTesting()) + if (!WizardController::IsBrandedBuild()) return; test::OobeJS().TapOnPath({"oobe-eula-md", "acceptButton"}); } void WaitForSyncConsentScreen() { - if (!SyncConsentScreen::IsBrandedBuildForTesting()) + if (!WizardController::IsBrandedBuild()) return; WaitFor(SyncConsentScreenView::kScreenId); } void ExitScreenSyncConsent() { - if (!SyncConsentScreen::IsBrandedBuildForTesting()) + if (!WizardController::IsBrandedBuild()) return; SyncConsentScreen* screen = static_cast<SyncConsentScreen*>( WizardController::default_controller()->GetScreen(
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc index 7613700..7c162da9 100644 --- a/chrome/browser/chromeos/login/wizard_controller.cc +++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -957,10 +957,22 @@ OnScreenExit(GaiaView::kScreenId, GaiaScreen::GetResultString(result)); switch (result) { case GaiaScreen::Result::BACK: - AdvanceToScreen(UserCreationView::kScreenId); - break; - case GaiaScreen::Result::CLOSE_DIALOG: - LoginDisplayHost::default_host()->HideOobeDialog(); + case GaiaScreen::Result::CANCEL: + if (result == GaiaScreen::Result::BACK && + wizard_context_->is_user_creation_enabled) { + // `Result::BACK` is only triggered when pressing back button. It goes + // back to UserCreationScreen if screen is enabled; otherwise, it + // behaves the same as `Result::CANCEL` which is triggered by pressing + // ESC key. + AdvanceToScreen(UserCreationView::kScreenId); + break; + } + if (LoginDisplayHost::default_host()->HasUserPods() && + !wizard_context_->is_user_creation_enabled) { + LoginDisplayHost::default_host()->HideOobeDialog(); + } else { + GetScreen<GaiaScreen>()->LoadOnline(EmptyAccountId()); + } break; case GaiaScreen::Result::ENTERPRISE_ENROLL: ShowEnrollmentScreenIfEligible(); @@ -2023,8 +2035,8 @@ // static std::unique_ptr<base::AutoReset<bool>> -WizardController::ForceBrandedBuildForTesting() { - return std::make_unique<base::AutoReset<bool>>(&is_branded_build_, true); +WizardController::ForceBrandedBuildForTesting(bool value) { + return std::make_unique<base::AutoReset<bool>>(&is_branded_build_, value); } // static
diff --git a/chrome/browser/chromeos/login/wizard_controller.h b/chrome/browser/chromeos/login/wizard_controller.h index 199d17dc..7910275 100644 --- a/chrome/browser/chromeos/login/wizard_controller.h +++ b/chrome/browser/chromeos/login/wizard_controller.h
@@ -111,13 +111,16 @@ static void SkipEnrollmentPromptsForTesting(); // Forces screens that should only appear in chrome branded builds to show. - static std::unique_ptr<base::AutoReset<bool>> ForceBrandedBuildForTesting(); + static std::unique_ptr<base::AutoReset<bool>> ForceBrandedBuildForTesting( + bool value); // Returns true if OOBE is operating under the // Zero-Touch Hands-Off Enrollment Flow. static bool UsingHandsOffEnrollment(); - static bool IsBrandedBuildForTesting() { return is_branded_build_; } + // Returns true if this is a branded build, value could be overwritten by + // `ForceBrandedBuildForTesting`. + static bool IsBrandedBuild() { return is_branded_build_; } bool is_initialized() { return is_initialized_; }
diff --git a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc index 06eaa0c..bb0fee0 100644 --- a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc +++ b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
@@ -484,7 +484,8 @@ WizardControllerTest::SetUpOnMainThread(); // Make sure that OOBE is run as an "official" build. - branded_build_override_ = WizardController::ForceBrandedBuildForTesting(); + branded_build_override_ = + WizardController::ForceBrandedBuildForTesting(true); WizardController* wizard_controller = WizardController::default_controller(); @@ -2723,7 +2724,8 @@ WizardControllerTest::SetUpOnMainThread(); // Make sure that OOBE is run as an "official" build. - branded_build_override_ = WizardController::ForceBrandedBuildForTesting(); + branded_build_override_ = + WizardController::ForceBrandedBuildForTesting(true); WizardController* wizard_controller = WizardController::default_controller();
diff --git a/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.cc b/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.cc index 25eca10..1bc3858 100644 --- a/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.cc +++ b/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.cc
@@ -18,6 +18,7 @@ const char kBrowserSettingsFeature[] = "browser_settings"; const char kOsSettingsFeature[] = "os_settings"; const char kScanningFeature[] = "scanning"; +const char kWebStoreFeature[] = "web_store"; const char kBlockedDisableMode[] = "blocked"; const char kHiddenDisableMode[] = "hidden"; @@ -78,6 +79,8 @@ return SystemFeature::kBrowserSettings; if (system_feature == kScanningFeature) return SystemFeature::kScanning; + if (system_feature == kWebStoreFeature) + return SystemFeature::kWebStore; LOG(ERROR) << "Unsupported system feature: " << system_feature; return kUnknownSystemFeature;
diff --git a/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.h b/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.h index 2d3070c..8708af2 100644 --- a/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.h +++ b/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.h
@@ -18,13 +18,14 @@ // A system feature that can be disabled by SystemFeaturesDisableList policy. // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. -enum SystemFeature { +enum SystemFeature : int { kUnknownSystemFeature = 0, kCamera = 1, // The camera chrome app on Chrome OS. kBrowserSettings = 2, // Browser settings. kOsSettings = 3, // The settings feature on Chrome OS. kScanning = 4, // The scan SWA on Chrome OS. - kMaxValue = kScanning + kWebStore = 5, // The web store chrome app on Chrome OS. + kMaxValue = kWebStore }; // A disabling mode that decides the user experience when a system feature is @@ -40,6 +41,7 @@ extern const char kBrowserSettingsFeature[]; extern const char kOsSettingsFeature[]; extern const char kScanningFeature[]; +extern const char kWebStoreFeature[]; extern const char kBlockedDisableMode[]; extern const char kHiddenDisableMode[];
diff --git a/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler_unittest.cc b/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler_unittest.cc index ecaa003..970e308b 100644 --- a/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler_unittest.cc +++ b/chrome/browser/chromeos/policy/system_features_disable_list_policy_handler_unittest.cc
@@ -67,12 +67,16 @@ histogram_tester_.ExpectBucketCount(kSystemFeaturesDisableListHistogram, SystemFeature::kUnknownSystemFeature, /*amount*/ 0); + histogram_tester_.ExpectBucketCount(kSystemFeaturesDisableListHistogram, + SystemFeature::kWebStore, + /*amount*/ 0); features_list.ClearList(); features_list.Append("camera"); features_list.Append("os_settings"); features_list.Append("scanning"); features_list.Append("gallery"); + features_list.Append("web_store"); policy_map.Set(policy::key::kSystemFeaturesDisableList, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, @@ -88,11 +92,12 @@ expected_list.Append(SystemFeature::kOsSettings); expected_list.Append(SystemFeature::kScanning); expected_list.Append(SystemFeature::kUnknownSystemFeature); + expected_list.Append(SystemFeature::kWebStore); EXPECT_TRUE(prefs.GetValue(policy_prefs::kSystemFeaturesDisableList, &value)); EXPECT_EQ(expected_list, *value); - histogram_tester_.ExpectTotalCount(kSystemFeaturesDisableListHistogram, 5); + histogram_tester_.ExpectTotalCount(kSystemFeaturesDisableListHistogram, 6); histogram_tester_.ExpectBucketCount(kSystemFeaturesDisableListHistogram, SystemFeature::kCamera, /*amount*/ 1); @@ -108,5 +113,8 @@ histogram_tester_.ExpectBucketCount(kSystemFeaturesDisableListHistogram, SystemFeature::kUnknownSystemFeature, /*amount*/ 1); + histogram_tester_.ExpectBucketCount(kSystemFeaturesDisableListHistogram, + SystemFeature::kWebStore, + /*amount*/ 1); } } // namespace policy
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc b/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc index a2904b2..b2ff2f90 100644 --- a/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc +++ b/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc
@@ -13,6 +13,7 @@ #include "base/metrics/histogram_macros.h" #include "base/sequence_checker.h" #include "base/sequenced_task_runner.h" +#include "chrome/browser/chromeos/crosapi/browser_manager.h" #include "chrome/browser/chromeos/policy/cached_policy_key_loader_chromeos.h" #include "chrome/browser/chromeos/policy/value_validation/onc_user_policy_value_validator.h" #include "chrome/browser/lifetime/application_lifetime.h" @@ -282,6 +283,17 @@ cached_policy_key_loader_->cached_policy_key()); status_ = STATUS_OK; +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (crosapi::BrowserManager::Get()) { + std::string policy_blob; + // Since the policy have passed all the validations, the serialization must + // succeed. + bool success = validator->policy()->SerializeToString(&policy_blob); + DCHECK(success); + crosapi::BrowserManager::Get()->SetDeviceAccountPolicy(policy_blob); + } +#endif + NotifyStoreLoaded(); }
diff --git a/chrome/browser/chromeos/system/automatic_reboot_manager_unittest.cc b/chrome/browser/chromeos/system/automatic_reboot_manager_unittest.cc index 58f4e26..0ac70ec 100644 --- a/chrome/browser/chromeos/system/automatic_reboot_manager_unittest.cc +++ b/chrome/browser/chromeos/system/automatic_reboot_manager_unittest.cc
@@ -205,7 +205,8 @@ bool reboot_after_update_ = false; base::test::TaskEnvironment task_environment_; - base::ScopedClosureRunner reset_main_thread_task_runner_; + base::ThreadTaskRunnerHandleOverrideForTesting + thread_task_runner_handle_override_; TestingPrefServiceSimple local_state_; MockUserManager* mock_user_manager_; // Not owned. @@ -308,8 +309,7 @@ AutomaticRebootManagerBasicTest::AutomaticRebootManagerBasicTest() : task_runner_(new TestAutomaticRebootManagerTaskRunner), - reset_main_thread_task_runner_( - base::ThreadTaskRunnerHandle::OverrideForTesting(task_runner_)), + thread_task_runner_handle_override_(task_runner_), mock_user_manager_(new MockUserManager), user_manager_enabler_(base::WrapUnique(mock_user_manager_)) {}
diff --git a/chrome/browser/chromeos/web_applications/chrome_camera_app_ui_delegate.cc b/chrome/browser/chromeos/web_applications/chrome_camera_app_ui_delegate.cc index aad16cd2..5415cddb 100644 --- a/chrome/browser/chromeos/web_applications/chrome_camera_app_ui_delegate.cc +++ b/chrome/browser/chromeos/web_applications/chrome_camera_app_ui_delegate.cc
@@ -6,6 +6,7 @@ #include <vector> +#include "ash/public/cpp/tablet_mode.h" #include "base/files/file_path.h" #include "base/system/sys_info.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" @@ -53,7 +54,7 @@ } bool ChromeCameraAppUIDelegate::CameraAppDialog::CanMaximizeDialog() const { - return true; + return !ash::TabletMode::Get()->InTabletMode(); } void ChromeCameraAppUIDelegate::CameraAppDialog::GetDialogSize(
diff --git a/chrome/browser/data_saver/subresource_redirect_login_robots_browsertest.cc b/chrome/browser/data_saver/subresource_redirect_login_robots_browsertest.cc index a3a5640..ba39cfd 100644 --- a/chrome/browser/data_saver/subresource_redirect_login_robots_browsertest.cc +++ b/chrome/browser/data_saver/subresource_redirect_login_robots_browsertest.cc
@@ -14,6 +14,8 @@ #include "build/build_config.h" #include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h" #include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings_factory.h" +#include "chrome/browser/login_detection/login_detection_type.h" +#include "chrome/browser/login_detection/login_detection_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/subresource_redirect/https_image_compression_infobar_decider.h" #include "chrome/browser/ui/browser.h" @@ -301,6 +303,8 @@ params["robots_rules_receive_timeout"] = "1000"; enabled_features.emplace_back(blink::features::kSubresourceRedirect, params); + enabled_features.emplace_back(login_detection::kLoginDetection, + base::FieldTrialParams()); } scoped_feature_list_.InitWithFeaturesAndParameters(enabled_features, {}); InProcessBrowserTest::SetUp(); @@ -748,4 +752,50 @@ {"/load_image/image.png"}); } +IN_PROC_BROWSER_TEST_F( + SubresourceRedirectLoginRobotsBrowserTest, + DISABLE_ON_WIN_MAC_CHROMEOS(TestNoCompressionOnLoggedInPage)) { + robots_rules_server_.AddRobotsRules(GetHttpsTestURL("/"), + {{kRuleTypeAllow, "*"}}); + // Trigger OAuth login by triggering OAuth start and complete. + ui_test_utils::NavigateToURL(browser(), + GetHttpsTestURL("/simple.html?initial")); + histogram_tester_.ExpectUniqueSample( + "Login.PageLoad.DetectionType", + login_detection::LoginDetectionType::kNoLogin, 1); + ui_test_utils::NavigateToURL( + browser(), https_test_server_.GetURL("oauth_server.com", + "/simple.html?client_id=user")); + histogram_tester_.ExpectBucketCount( + "Login.PageLoad.DetectionType", + login_detection::LoginDetectionType::kNoLogin, 2); + + ui_test_utils::NavigateToURL(browser(), + GetHttpsTestURL("/simple.html?code=123")); + histogram_tester_.ExpectBucketCount( + "Login.PageLoad.DetectionType", + login_detection::LoginDetectionType::kOauthFirstTimeLoginFlow, 1); + + // The next navigation will be treated as logged-in. + NavigateAndWaitForLoad(browser(), GetHttpsTestURL("/load_image/image.html")); + histogram_tester_.ExpectBucketCount( + "Login.PageLoad.DetectionType", + login_detection::LoginDetectionType::kOauthLogin, 1); + + // No image compression will be triggered. + histogram_tester_.ExpectTotalCount( + "SubresourceRedirect.CompressionAttempt.ResponseCode", 0); + histogram_tester_.ExpectTotalCount( + "SubresourceRedirect.CompressionAttempt.ServerResponded", 0); + histogram_tester_.ExpectTotalCount( + "SubresourceRedirect.RobotsRulesFetcher.ResponseCode", 0); + histogram_tester_.ExpectTotalCount( + "SubresourceRedirect.RobotsRules.Browser.InMemoryCacheHit", 0); + histogram_tester_.ExpectTotalCount( + "SubresourceRedirect.ImageCompressionNotificationInfoBar", 0); + + robots_rules_server_.VerifyRequestedOrigins({}); + image_compression_server_.VerifyRequestedImagePaths({}); +} + } // namespace subresource_redirect
diff --git a/chrome/browser/enterprise/reporting/browser_report_generator_desktop.cc b/chrome/browser/enterprise/reporting/browser_report_generator_desktop.cc index 5d9594e..98de7db 100644 --- a/chrome/browser/enterprise/reporting/browser_report_generator_desktop.cc +++ b/chrome/browser/enterprise/reporting/browser_report_generator_desktop.cc
@@ -76,12 +76,10 @@ base::flat_set<base::FilePath> extension_request_profile_paths = throttler->GetProfiles(); - for (const auto* entry : g_browser_process->profile_manager() - ->GetProfileAttributesStorage() - .GetAllProfilesAttributes()) { - // Exclude Guest profiles. - if (entry->IsGuest()) - continue; + for (const auto* entry : + g_browser_process->profile_manager() + ->GetProfileAttributesStorage() + .GetAllProfilesAttributes(/*include_guest_profile=*/false)) { #if BUILDFLAG(IS_CHROMEOS_ASH) // Skip sign-in and lock screen app profile on Chrome OS. if (!chromeos::ProfileHelper::IsRegularProfilePath(
diff --git a/chrome/browser/extensions/api/alarms/alarms_apitest.cc b/chrome/browser/extensions/api/alarms/alarms_apitest.cc index 64a4ea24..eef7d65 100644 --- a/chrome/browser/extensions/api/alarms/alarms_apitest.cc +++ b/chrome/browser/extensions/api/alarms/alarms_apitest.cc
@@ -6,7 +6,6 @@ #include "content/public/test/browser_test.h" #include "extensions/browser/event_router.h" #include "extensions/common/api/test.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" #include "net/dns/mock_host_resolver.h" @@ -25,11 +24,6 @@ ExtensionApiTest::SetUpOnMainThread(); host_resolver()->AddRule("*", "127.0.0.1"); ASSERT_TRUE(StartEmbeddedTestServer()); - - // Service Workers are currently only available on certain channels, so set - // the channel for those tests. - if (GetParam() == ContextType::kServiceWorker) - current_channel_ = std::make_unique<ScopedWorkerBasedExtensionsChannel>(); } static std::unique_ptr<base::ListValue> BuildEventArguments( @@ -48,9 +42,6 @@ return LoadExtensionWithFlags( test_data_dir_.AppendASCII("alarms").AppendASCII(path), flags); } - - private: - std::unique_ptr<ScopedWorkerBasedExtensionsChannel> current_channel_; }; INSTANTIATE_TEST_SUITE_P(EventPage,
diff --git a/chrome/browser/extensions/api/bookmarks/bookmark_apitest.cc b/chrome/browser/extensions/api/bookmarks/bookmark_apitest.cc index 5b2b6e1..09c46fdc 100644 --- a/chrome/browser/extensions/api/bookmarks/bookmark_apitest.cc +++ b/chrome/browser/extensions/api/bookmarks/bookmark_apitest.cc
@@ -19,7 +19,6 @@ #include "components/bookmarks/test/bookmark_test_helpers.h" #include "components/prefs/pref_service.h" #include "content/public/test/browser_test.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" using bookmarks::BookmarkModel; @@ -29,16 +28,6 @@ class BookmarksApiTest : public ExtensionApiTest, public testing::WithParamInterface<ContextType> { - public: - BookmarksApiTest() { - // Service Workers are currently only available on certain channels, so set - // the channel for those tests. - if (GetParam() == ContextType::kServiceWorker) - current_channel_ = std::make_unique<ScopedWorkerBasedExtensionsChannel>(); - } - - private: - std::unique_ptr<ScopedWorkerBasedExtensionsChannel> current_channel_; }; INSTANTIATE_TEST_SUITE_P(EventPage,
diff --git a/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc b/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc index b84fdaf..686ad11 100644 --- a/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc +++ b/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc
@@ -41,7 +41,6 @@ #include "content/public/test/test_utils.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/test_extension_registry_observer.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" namespace extensions { @@ -222,14 +221,6 @@ class ExtensionContentSettingsApiLazyTest : public ExtensionContentSettingsApiTest, public testing::WithParamInterface<ContextType> { - public: - ExtensionContentSettingsApiLazyTest() { - // Service Workers are currently only available on certain channels, so set - // the channel for those tests. - if (GetParam() == ContextType::kServiceWorker) - current_channel_ = std::make_unique<ScopedWorkerBasedExtensionsChannel>(); - } - protected: bool RunLazyTest(const std::string& extension_name) { int browser_test_flags = kFlagNone; @@ -239,8 +230,6 @@ return RunExtensionTestWithFlagsAndArg(extension_name, nullptr, browser_test_flags, kFlagNone); } - - std::unique_ptr<ScopedWorkerBasedExtensionsChannel> current_channel_; }; INSTANTIATE_TEST_SUITE_P(EventPage,
diff --git a/chrome/browser/extensions/api/context_menus/context_menu_apitest.cc b/chrome/browser/extensions/api/context_menus/context_menu_apitest.cc index 9a1a6a3..43682fb 100644 --- a/chrome/browser/extensions/api/context_menus/context_menu_apitest.cc +++ b/chrome/browser/extensions/api/context_menus/context_menu_apitest.cc
@@ -20,7 +20,6 @@ #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "extensions/browser/extension_action.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" #include "extensions/test/result_catcher.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "ui/base/models/menu_model.h" @@ -33,7 +32,6 @@ }; IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ServiceWorkerContextMenus) { - ScopedWorkerBasedExtensionsChannel worker_channel_override; ASSERT_TRUE(RunExtensionTestWithFlags("context_menus/event_page", kFlagRunAsServiceWorkerBasedExtension, kFlagNone))
diff --git a/chrome/browser/extensions/api/cookies/cookies_apitest.cc b/chrome/browser/extensions/api/cookies/cookies_apitest.cc index 9e8b0fe..4a7cd854 100644 --- a/chrome/browser/extensions/api/cookies/cookies_apitest.cc +++ b/chrome/browser/extensions/api/cookies/cookies_apitest.cc
@@ -6,7 +6,6 @@ #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/test/browser_test.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" #include "net/cookies/cookie_util.h" namespace extensions { @@ -21,14 +20,6 @@ class CookiesApiTest : public ExtensionApiTest, public testing::WithParamInterface<ContextType> { - public: - CookiesApiTest() { - // Service Workers are currently only available on certain channels, so set - // the channel for those tests. - if (GetParam() == ContextType::kServiceWorker) - current_channel_ = std::make_unique<ScopedWorkerBasedExtensionsChannel>(); - } - protected: bool RunTest(const std::string& extension_name) { return RunTestWithFlags(extension_name, kFlagNone); @@ -56,8 +47,6 @@ return RunExtensionTestWithFlags(extension_name, browser_test_flags, kFlagNone); } - - std::unique_ptr<ScopedWorkerBasedExtensionsChannel> current_channel_; }; INSTANTIATE_TEST_SUITE_P(EventPage,
diff --git a/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc b/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc index c4aa4201..7eef0ce 100644 --- a/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc +++ b/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc
@@ -58,7 +58,6 @@ #include "extensions/browser/process_manager.h" #include "extensions/browser/test_extension_registry_observer.h" #include "extensions/common/feature_switch.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" #include "net/test/embedded_test_server/embedded_test_server.h" @@ -153,14 +152,7 @@ class BrowserActionApiLazyTest : public BrowserActionApiTest, public testing::WithParamInterface<ContextType> { - public: - BrowserActionApiLazyTest() { - // Service Workers are currently only available on certain channels, so set - // the channel for those tests. - if (GetParam() == ContextType::kServiceWorker) - current_channel_ = std::make_unique<ScopedWorkerBasedExtensionsChannel>(); - } - + protected: const extensions::Extension* LoadExtensionWithParamFlags( const base::FilePath& path) { int flags = kFlagEnableFileAccess; @@ -237,8 +229,6 @@ private: base::test::ScopedFeatureList feature_list_; - std::unique_ptr<extensions::ScopedWorkerBasedExtensionsChannel> - current_channel_; }; IN_PROC_BROWSER_TEST_P(BrowserActionApiLazyTest, Basic) {
diff --git a/chrome/browser/extensions/api/management/management_api_browsertest.cc b/chrome/browser/extensions/api/management/management_api_browsertest.cc index 1cab1a0..b12525b 100644 --- a/chrome/browser/extensions/api/management/management_api_browsertest.cc +++ b/chrome/browser/extensions/api/management/management_api_browsertest.cc
@@ -31,7 +31,6 @@ #include "extensions/browser/extension_registry.h" #include "extensions/browser/notification_types.h" #include "extensions/common/extension_builder.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" #include "extensions/test/extension_test_message_listener.h" #if BUILDFLAG(IS_CHROMEOS_ASH) @@ -64,24 +63,13 @@ class ExtensionManagementApiTestWithBackgroundType : public ExtensionManagementApiBrowserTest, public testing::WithParamInterface<ContextType> { - public: - ExtensionManagementApiTestWithBackgroundType() { - // Service Workers are currently only available on certain channels, so set - // the channel for those tests. - if (GetParam() == ContextType::kServiceWorker) - current_channel_ = std::make_unique<ScopedWorkerBasedExtensionsChannel>(); - } - + protected: const Extension* LoadExtensionWithParamFlags(const base::FilePath& path) { int flags = kFlagEnableFileAccess; if (GetParam() == ContextType::kServiceWorker) flags |= ExtensionBrowserTest::kFlagRunAsServiceWorkerBasedExtension; return LoadExtensionWithFlags(path, flags); } - - private: - std::unique_ptr<extensions::ScopedWorkerBasedExtensionsChannel> - current_channel_; }; INSTANTIATE_TEST_SUITE_P(PersistentBackground,
diff --git a/chrome/browser/extensions/api/messaging/native_messaging_apitest.cc b/chrome/browser/extensions/api/messaging/native_messaging_apitest.cc index 8fef91e..6244a7c 100644 --- a/chrome/browser/extensions/api/messaging/native_messaging_apitest.cc +++ b/chrome/browser/extensions/api/messaging/native_messaging_apitest.cc
@@ -25,7 +25,6 @@ #include "components/keep_alive_registry/keep_alive_types.h" #include "content/public/test/browser_test.h" #include "extensions/browser/process_manager.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" #include "extensions/test/result_catcher.h" namespace extensions { @@ -52,14 +51,6 @@ class NativeMessagingLazyApiTest : public NativeMessagingApiTest, public testing::WithParamInterface<ContextType> { - public: - NativeMessagingLazyApiTest() { - // Service Workers are currently only available on certain channels, so set - // the channel for those tests. - if (GetParam() == ContextType::kServiceWorker) - current_channel_ = std::make_unique<ScopedWorkerBasedExtensionsChannel>(); - } - protected: bool RunLazyTest(const std::string& extension_name) { if (GetParam() == ContextType::kEventPage) { @@ -68,8 +59,6 @@ return RunExtensionTestWithFlags( extension_name, kFlagRunAsServiceWorkerBasedExtension, kFlagNone); } - - std::unique_ptr<ScopedWorkerBasedExtensionsChannel> current_channel_; }; INSTANTIATE_TEST_SUITE_P(EventPage,
diff --git a/chrome/browser/extensions/api/metrics_private/metrics_apitest.cc b/chrome/browser/extensions/api/metrics_private/metrics_apitest.cc index 66e7e0d..54e4e43 100644 --- a/chrome/browser/extensions/api/metrics_private/metrics_apitest.cc +++ b/chrome/browser/extensions/api/metrics_private/metrics_apitest.cc
@@ -14,7 +14,6 @@ #include "chrome/browser/extensions/extension_apitest.h" #include "components/variations/variations_associated_data.h" #include "content/public/test/browser_test.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" namespace extensions { @@ -138,13 +137,6 @@ : public ExtensionApiTest, public testing::WithParamInterface<ContextType> { public: - ExtensionMetricsApiTest() { - // Service Workers are currently only available on certain channels, so set - // the channel for those tests. - if (GetParam() == ContextType::kServiceWorker) - current_channel_ = std::make_unique<ScopedWorkerBasedExtensionsChannel>(); - } - bool RunComponentTestWithParamFlag(const std::string& extension_name) { int flags = kFlagNone; if (GetParam() == ContextType::kServiceWorker) @@ -153,9 +145,6 @@ return RunExtensionTestWithFlags(extension_name, flags, kFlagLoadAsComponent); } - - private: - std::unique_ptr<ScopedWorkerBasedExtensionsChannel> current_channel_; }; INSTANTIATE_TEST_SUITE_P(PersistentBackground,
diff --git a/chrome/browser/extensions/api/page_capture/page_capture_apitest.cc b/chrome/browser/extensions/api/page_capture/page_capture_apitest.cc index 86cd394e..fad5fe6 100644 --- a/chrome/browser/extensions/api/page_capture/page_capture_apitest.cc +++ b/chrome/browser/extensions/api/page_capture/page_capture_apitest.cc
@@ -25,7 +25,6 @@ #include "extensions/browser/extension_dialog_auto_confirm.h" #include "extensions/common/permissions/permission_set.h" #include "extensions/common/permissions/permissions_data.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" #include "extensions/common/url_pattern_set.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" @@ -79,14 +78,7 @@ class ExtensionPageCaptureApiTest : public ExtensionApiTest, public testing::WithParamInterface<ContextType> { - public: - ExtensionPageCaptureApiTest() { - // Service Workers are currently only available on certain channels, so set - // the channel for those tests. - if (GetParam() == ContextType::kServiceWorker) - current_channel_ = std::make_unique<ScopedWorkerBasedExtensionsChannel>(); - } - + protected: void SetUpCommandLine(base::CommandLine* command_line) override { ExtensionApiTest::SetUpCommandLine(command_line); command_line->AppendSwitchASCII(switches::kJavaScriptFlags, "--expose-gc"); @@ -123,9 +115,6 @@ if (GetParam() != ContextType::kServiceWorker) delegate->WaitForFinalRelease(); } - - private: - std::unique_ptr<ScopedWorkerBasedExtensionsChannel> current_channel_; }; INSTANTIATE_TEST_SUITE_P(PersistentBackground,
diff --git a/chrome/browser/extensions/api/permissions/permissions_apitest.cc b/chrome/browser/extensions/api/permissions/permissions_apitest.cc index a311cb4c..ea47a37 100644 --- a/chrome/browser/extensions/api/permissions/permissions_apitest.cc +++ b/chrome/browser/extensions/api/permissions/permissions_apitest.cc
@@ -16,7 +16,6 @@ #include "content/public/test/browser_test.h" #include "extensions/browser/extension_prefs.h" #include "extensions/common/permissions/permission_set.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" #include "extensions/common/switches.h" #include "net/dns/mock_host_resolver.h" @@ -52,15 +51,6 @@ class PermissionsApiTestWithContextType : public PermissionsApiTest, public testing::WithParamInterface<ContextType> { - public: - PermissionsApiTestWithContextType() { - // Service Workers are currently only available on certain channels, so set - // the channel for those tests. - if (GetParam() == ContextType::kServiceWorker) { - current_channel_ = std::make_unique<ScopedWorkerBasedExtensionsChannel>(); - } - } - protected: bool RunTest(const std::string& extension_name) { int browser_test_flags = kFlagNone; @@ -69,10 +59,6 @@ return RunExtensionTestWithFlags(extension_name, browser_test_flags, kFlagNone); } - - private: - std::unique_ptr<extensions::ScopedWorkerBasedExtensionsChannel> - current_channel_; }; IN_PROC_BROWSER_TEST_F(PermissionsApiTest, PermissionsFail) {
diff --git a/chrome/browser/extensions/api/runtime/runtime_apitest.cc b/chrome/browser/extensions/api/runtime/runtime_apitest.cc index 02dee5d..4720055 100644 --- a/chrome/browser/extensions/api/runtime/runtime_apitest.cc +++ b/chrome/browser/extensions/api/runtime/runtime_apitest.cc
@@ -19,7 +19,6 @@ #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/test_extension_registry_observer.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" #include "extensions/test/test_extension_dir.h" @@ -33,13 +32,7 @@ class RuntimeApiTest : public ExtensionApiTest, public testing::WithParamInterface<ContextType> { public: - RuntimeApiTest() { - // Service Workers are currently only available on certain channels, so set - // the channel for those tests. - if (GetParam() == ContextType::kServiceWorker) - current_channel_ = std::make_unique<ScopedWorkerBasedExtensionsChannel>(); - } - + RuntimeApiTest() = default; RuntimeApiTest(const RuntimeApiTest&) = delete; RuntimeApiTest& operator=(const RuntimeApiTest&) = delete; @@ -58,10 +51,6 @@ return RunExtensionTestWithFlags(extension_name, flags, kFlagNone); } - - private: - std::unique_ptr<extensions::ScopedWorkerBasedExtensionsChannel> - current_channel_; }; INSTANTIATE_TEST_SUITE_P(PersistentBackground,
diff --git a/chrome/browser/extensions/api/test/apitest_apitest.cc b/chrome/browser/extensions/api/test/apitest_apitest.cc index ea4df5af..e6de56cd 100644 --- a/chrome/browser/extensions/api/test/apitest_apitest.cc +++ b/chrome/browser/extensions/api/test/apitest_apitest.cc
@@ -6,7 +6,6 @@ #include "chrome/browser/extensions/extension_apitest.h" #include "content/public/test/browser_test.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" #include "extensions/test/result_catcher.h" #include "extensions/test/test_extension_dir.h" @@ -24,16 +23,8 @@ } // namespace -class TestAPITest - : public ExtensionApiTest, - public testing::WithParamInterface<ExtensionApiTest::ContextType> { +class TestAPITest : public ExtensionApiTest { public: - TestAPITest() { - // Service Workers are currently only available on certain channels, so set - // the channel for those tests. - if (GetParam() == ContextType::kServiceWorker) - current_channel_ = std::make_unique<ScopedWorkerBasedExtensionsChannel>(); - } ~TestAPITest() override = default; // Loads and returns an extension with the given |background_script|. @@ -42,7 +33,6 @@ private: std::vector<std::unique_ptr<TestExtensionDir>> test_dirs_; - std::unique_ptr<ScopedWorkerBasedExtensionsChannel> current_channel_; }; const Extension* TestAPITest::LoadExtensionWithBackgroundScript( @@ -56,13 +46,13 @@ } // TODO(devlin): This test name should be more descriptive. -IN_PROC_BROWSER_TEST_P(TestAPITest, ApiTest) { +IN_PROC_BROWSER_TEST_F(TestAPITest, ApiTest) { ASSERT_TRUE(RunExtensionTest("apitest")) << message_; } // Verifies that failing an assert in a promise will properly fail and end the // test. -IN_PROC_BROWSER_TEST_P(TestAPITest, FailedAssertsInPromises) { +IN_PROC_BROWSER_TEST_F(TestAPITest, FailedAssertsInPromises) { ResultCatcher result_catcher; constexpr char kBackgroundJs[] = R"(chrome.test.runTests([ @@ -80,7 +70,7 @@ } // Verifies that using await and assert'ing aspects of the results succeeds. -IN_PROC_BROWSER_TEST_P(TestAPITest, AsyncAwaitAssertions_Succeed) { +IN_PROC_BROWSER_TEST_F(TestAPITest, AsyncAwaitAssertions_Succeed) { ResultCatcher result_catcher; constexpr char kBackgroundJs[] = R"(chrome.test.runTests([ @@ -98,7 +88,7 @@ // Verifies that using await and having failed assertions properly fails the // test. -IN_PROC_BROWSER_TEST_P(TestAPITest, AsyncAwaitAssertions_Failed) { +IN_PROC_BROWSER_TEST_F(TestAPITest, AsyncAwaitAssertions_Failed) { ResultCatcher result_catcher; constexpr char kBackgroundJs[] = R"(chrome.test.runTests([ @@ -117,7 +107,7 @@ // Verifies that we can assert values on chrome.runtime.lastError after using // await with an API call. -IN_PROC_BROWSER_TEST_P(TestAPITest, AsyncAwaitAssertions_LastError) { +IN_PROC_BROWSER_TEST_F(TestAPITest, AsyncAwaitAssertions_LastError) { ResultCatcher result_catcher; constexpr char kBackgroundJs[] = R"(chrome.test.runTests([ @@ -135,14 +125,4 @@ EXPECT_TRUE(result_catcher.GetNextResult()); } -INSTANTIATE_TEST_SUITE_P( - EventPage, - TestAPITest, - ::testing::Values(ExtensionApiTest::ContextType::kEventPage)); - -INSTANTIATE_TEST_SUITE_P( - ServiceWorker, - TestAPITest, - ::testing::Values(ExtensionApiTest::ContextType::kServiceWorker)); - } // namespace extensions
diff --git a/chrome/browser/extensions/execute_script_apitest.cc b/chrome/browser/extensions/execute_script_apitest.cc index 2824714..7c34ee2 100644 --- a/chrome/browser/extensions/execute_script_apitest.cc +++ b/chrome/browser/extensions/execute_script_apitest.cc
@@ -9,7 +9,6 @@ #include "chrome/common/chrome_paths.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/test/browser_test.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" #include "net/base/filename_util.h" #include "net/dns/mock_host_resolver.h" @@ -31,13 +30,6 @@ class ExecuteScriptApiTest : public ExecuteScriptApiTestBase, public testing::WithParamInterface<ContextType> { protected: - ExecuteScriptApiTest() { - // Service Workers are currently only available on certain channels, so set - // the channel for those tests. - if (GetParam() == ContextType::kServiceWorker) - current_channel_ = std::make_unique<ScopedWorkerBasedExtensionsChannel>(); - } - bool RunTest(const std::string& extension_name) { int browser_test_flags = kFlagNone; if (GetParam() == ContextType::kServiceWorker) @@ -55,9 +47,6 @@ return RunExtensionTestWithFlags(extension_name, browser_test_flags, kFlagNone); } - - private: - std::unique_ptr<ScopedWorkerBasedExtensionsChannel> current_channel_; }; INSTANTIATE_TEST_SUITE_P(PersistentBackground,
diff --git a/chrome/browser/extensions/extension_context_menu_browsertest.cc b/chrome/browser/extensions/extension_context_menu_browsertest.cc index 091201aa..d6dc890 100644 --- a/chrome/browser/extensions/extension_context_menu_browsertest.cc +++ b/chrome/browser/extensions/extension_context_menu_browsertest.cc
@@ -37,7 +37,6 @@ #include "extensions/browser/test_management_policy.h" #include "extensions/common/extension_set.h" #include "extensions/common/features/feature_channel.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" #include "net/dns/mock_host_resolver.h" @@ -260,15 +259,6 @@ : public ExtensionContextMenuBrowserTest, public testing::WithParamInterface<ContextType> { public: - ExtensionContextMenuLazyTest() { - // Service Workers are currently only available on certain channels, so set - // the channel for those tests. - if (GetParam() == ContextType::kServiceWorker) { - current_channel_ = - std::make_unique<extensions::ScopedWorkerBasedExtensionsChannel>(); - } - } - void SetUpOnMainThread() override { ExtensionContextMenuBrowserTest::SetUpOnMainThread(); // Set shorter delays to prevent test timeouts. @@ -349,10 +339,6 @@ ASSERT_TRUE(update.WaitUntilSatisfied()); ASSERT_EQ(!enabled, menu->IsCommandIdEnabled(command_id)); } - - private: - std::unique_ptr<extensions::ScopedWorkerBasedExtensionsChannel> - current_channel_; }; class ExtensionContextMenuPersistentTest
diff --git a/chrome/browser/extensions/service_worker_apitest.cc b/chrome/browser/extensions/service_worker_apitest.cc index 6f3f709b..7c12f6e 100644 --- a/chrome/browser/extensions/service_worker_apitest.cc +++ b/chrome/browser/extensions/service_worker_apitest.cc
@@ -70,7 +70,6 @@ #include "extensions/common/extensions_client.h" #include "extensions/common/manifest_handlers/background_info.h" #include "extensions/common/permissions/permissions_data.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" #include "extensions/common/value_builder.h" #include "extensions/common/verifier_formats.h" #include "extensions/test/background_page_watcher.h" @@ -153,19 +152,15 @@ }; class ServiceWorkerTest : public ExtensionApiTest { - public: - ServiceWorkerTest() : current_channel_(version_info::Channel::STABLE) {} - explicit ServiceWorkerTest(version_info::Channel channel) - : current_channel_(channel) {} - - ~ServiceWorkerTest() override {} + protected: + ServiceWorkerTest() = default; + ~ServiceWorkerTest() override = default; void SetUpOnMainThread() override { ExtensionApiTest::SetUpOnMainThread(); host_resolver()->AddRule("*", "127.0.0.1"); } - protected: // Returns the ProcessManager for the test's profile. ProcessManager* process_manager() { return ProcessManager::Get(profile()); } @@ -238,27 +233,10 @@ content::BrowserContext::GetDefaultStoragePartition( browser()->profile()) ->GetServiceWorkerContext(); - base::RunLoop run_loop; - size_t ref_count = 0; - auto set_ref_count = [](size_t* ref_count, base::RunLoop* run_loop, - size_t external_request_count) { - *ref_count = external_request_count; - run_loop->Quit(); - }; - sw_context->CountExternalRequestsForTest( - origin, base::BindOnce(set_ref_count, &ref_count, &run_loop)); - run_loop.Run(); - return ref_count; + return sw_context->CountExternalRequestsForTest(origin); } private: - // Sets the channel to "stable". - // Not useful after we've opened extension Service Workers to stable - // channel. - // TODO(lazyboy): Remove this when ExtensionServiceWorkersEnabled() is - // removed. - ScopedCurrentChannel current_channel_; - DISALLOW_COPY_AND_ASSIGN(ServiceWorkerTest); }; @@ -306,8 +284,6 @@ } private: - ScopedWorkerBasedExtensionsChannel channel_; - DISALLOW_COPY_AND_ASSIGN(ServiceWorkerBasedBackgroundTest); }; @@ -903,8 +879,6 @@ } private: - ScopedWorkerBasedExtensionsChannel channel_; - DISALLOW_COPY_AND_ASSIGN(ServiceWorkerLazyBackgroundTest); }; @@ -2512,8 +2486,8 @@ : public ServiceWorkerTest, public testing::WithParamInterface<version_info::Channel> { public: - ServiceWorkerCheckBindingsTest() : ServiceWorkerTest(GetParam()) {} - ~ServiceWorkerCheckBindingsTest() override {} + ServiceWorkerCheckBindingsTest() = default; + ~ServiceWorkerCheckBindingsTest() override = default; private: DISALLOW_COPY_AND_ASSIGN(ServiceWorkerCheckBindingsTest);
diff --git a/chrome/browser/extensions/service_worker_messaging_apitest.cc b/chrome/browser/extensions/service_worker_messaging_apitest.cc index 0704e71..3f77b5a 100644 --- a/chrome/browser/extensions/service_worker_messaging_apitest.cc +++ b/chrome/browser/extensions/service_worker_messaging_apitest.cc
@@ -11,7 +11,6 @@ #include "content/public/test/browser_test.h" #include "content/public/test/service_worker_test_helpers.h" #include "extensions/browser/service_worker/service_worker_test_utils.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" #include "extensions/test/test_extension_dir.h" @@ -94,8 +93,6 @@ extensions::ScopedTestNativeMessagingHost test_host_; private: - ScopedWorkerBasedExtensionsChannel current_channel_; - DISALLOW_COPY_AND_ASSIGN(ServiceWorkerMessagingTest); };
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index f1df1d25..faf4cfc 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -3573,6 +3573,11 @@ "expiry_milestone": 90 }, { + "name": "omnibox-default-typed-navigations-to-https", + "owners": ["meacer", "chrome-omnibox-team@google.com"], + "expiry_milestone": 93 + }, + { "name": "omnibox-disable-cgi-param-matching", "owners": [ "yoangela", "chrome-omnibox-team@google.com" ], "expiry_milestone": 90
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 34cf6b2..5a84604 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1529,6 +1529,16 @@ "the current page is provided as the first suggestion without a title. " "Enabling this flag causes the title to be displayed."; +const char kOmniboxDefaultTypedNavigationsToHttpsName[] = + "Omnibox - Use HTTPS as the default protocol for navigations"; +const char kOmniboxDefaultTypedNavigationsToHttpsDescription[] = + "Use HTTPS as the default protocol when the user types a URL without " + "a protocol in the omnibox such as 'example.com'. Presently, such an entry " + "navigates to http://example.com. When this feature is enabled, it will " + "navigate to https://example.com if the HTTPS URL is available. If Chrome " + "can't determine the availability of the HTTPS URL within the timeout, it " + "will fall back to the HTTP URL."; + const char kOmniboxExperimentalSuggestScoringName[] = "Omnibox Experimental Suggest Scoring"; const char kOmniboxExperimentalSuggestScoringDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index ea8bf99..f4ae4db 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -904,6 +904,9 @@ extern const char kOmniboxDisplayTitleForCurrentUrlName[]; extern const char kOmniboxDisplayTitleForCurrentUrlDescription[]; +extern const char kOmniboxDefaultTypedNavigationsToHttpsName[]; +extern const char kOmniboxDefaultTypedNavigationsToHttpsDescription[]; + extern const char kOmniboxExperimentalSuggestScoringName[]; extern const char kOmniboxExperimentalSuggestScoringDescription[];
diff --git a/chrome/browser/installable/installable_manager_browsertest.cc b/chrome/browser/installable/installable_manager_browsertest.cc index e76d448f..ec020f6 100644 --- a/chrome/browser/installable/installable_manager_browsertest.cc +++ b/chrome/browser/installable/installable_manager_browsertest.cc
@@ -1425,7 +1425,6 @@ "/banners/manifest_data_url_icon.json")); run_loop.Run(); - EXPECT_FALSE(tester->manifest().IsEmpty()); EXPECT_FALSE(tester->manifest_url().is_empty()); @@ -1508,6 +1507,56 @@ } } +// The case that a service worker doesn't return an offline response for the +// start_url, but does for the manifest scope. +// - manifest's scope: /banners/ +// - manifest's start_url: /banners/manifest_test_page.html?ignore +// - service worker's scope: /banners/ +IN_PROC_BROWSER_TEST_P(InstallableManagerOfflineCapabilityBrowserTest, + CheckNotOfflineCapableStartUrl) { + // This test wants to check the service worker that doesn't support offline + // pages, so ignore the cases when `is_service_worker_offline_supported_` is + // true. + if (IsServiceWorkerOfflineSupported()) + return; + + base::RunLoop run_loop; + std::unique_ptr<CallbackTester> tester( + new CallbackTester(run_loop.QuitClosure())); + + NavigateAndRunInstallableManager( + browser(), tester.get(), GetWebAppParams(), + GetURLOfPageWithServiceWorkerAndManifest( + "/banners/manifest_not_offline_capable_url.json")); + + run_loop.Run(); + + EXPECT_FALSE(tester->manifest().IsEmpty()); + EXPECT_FALSE(tester->manifest_url().is_empty()); + EXPECT_FALSE(tester->primary_icon_url().is_empty()); + EXPECT_NE(nullptr, tester->primary_icon()); + EXPECT_TRUE(tester->valid_manifest()); + EXPECT_TRUE(tester->splash_icon_url().is_empty()); + EXPECT_EQ(nullptr, tester->splash_icon()); + CheckServiceWorkerForTester(tester.get()); + + InstallableManager* manager = GetManager(browser()); + + EXPECT_FALSE(manager->manifest().IsEmpty()); + EXPECT_FALSE(manager->manifest_url().is_empty()); + EXPECT_TRUE(manager->valid_manifest()); + EXPECT_EQ(1u, manager->icons_.size()); + EXPECT_FALSE( + (manager->icon_url(InstallableManager::IconUsage::kPrimary).is_empty())); + EXPECT_NE(nullptr, (manager->icon(InstallableManager::IconUsage::kPrimary))); + EXPECT_EQ(NO_ERROR_DETECTED, manager->manifest_error()); + EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error()); + EXPECT_EQ(NO_ERROR_DETECTED, + (manager->icon_error(InstallableManager::IconUsage::kPrimary))); + EXPECT_TRUE(!manager->task_queue_.HasCurrent()); + CheckServiceWorkerForInstallableManager(manager); +} + IN_PROC_BROWSER_TEST_F(InstallableManagerBrowserTest, CheckNestedCallsToGetData) { // Verify that we can call GetData while in a callback from GetData.
diff --git a/chrome/browser/metrics/extensions_metrics_provider_unittest.cc b/chrome/browser/metrics/extensions_metrics_provider_unittest.cc index f5509ff..0304504 100644 --- a/chrome/browser/metrics/extensions_metrics_provider_unittest.cc +++ b/chrome/browser/metrics/extensions_metrics_provider_unittest.cc
@@ -28,7 +28,6 @@ #include "extensions/common/extension.h" #include "extensions/common/extension_builder.h" #include "extensions/common/extension_set.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" #include "extensions/common/value_builder.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/metrics_proto/extension_install.pb.h" @@ -367,7 +366,6 @@ } { // Test that service worker scripts are reported correctly. - extensions::ScopedWorkerBasedExtensionsChannel worker_channel_override; scoped_refptr<const Extension> extension = ExtensionBuilder("service worker") .SetBackgroundContext(
diff --git a/chrome/browser/policy/chrome_browser_policy_connector.cc b/chrome/browser/policy/chrome_browser_policy_connector.cc index f76d437..68551a2 100644 --- a/chrome/browser/policy/chrome_browser_policy_connector.cc +++ b/chrome/browser/policy/chrome_browser_policy_connector.cc
@@ -15,6 +15,7 @@ #include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "build/branding_buildflags.h" +#include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/policy/configuration_policy_handler_list_factory.h" @@ -62,6 +63,10 @@ #include "chrome/browser/browser_switcher/browser_switcher_policy_migrator.h" #endif +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "components/policy/core/common/policy_loader_lacros.h" +#endif + namespace policy { namespace { bool command_line_enabled_for_testing = false; @@ -205,6 +210,12 @@ new MacPreferences(), bundle_id); return std::make_unique<AsyncPolicyProvider>(GetSchemaRegistry(), std::move(loader)); +#elif BUILDFLAG(IS_CHROMEOS_LACROS) + auto loader = std::make_unique<PolicyLoaderLacros>( + base::ThreadPool::CreateSequencedTaskRunner( + {base::MayBlock(), base::TaskPriority::BEST_EFFORT})); + return std::make_unique<AsyncPolicyProvider>(GetSchemaRegistry(), + std::move(loader)); #elif defined(OS_POSIX) && !defined(OS_ANDROID) base::FilePath config_dir_path; if (base::PathService::Get(chrome::DIR_POLICY_FILES, &config_dir_path)) {
diff --git a/chrome/browser/policy/system_features_policy_browsertest.cc b/chrome/browser/policy/system_features_policy_browsertest.cc index 6d3b75d..1773c147 100644 --- a/chrome/browser/policy/system_features_policy_browsertest.cc +++ b/chrome/browser/policy/system_features_policy_browsertest.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/values.h" #include "chrome/browser/apps/app_service/app_icon_factory.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" @@ -43,126 +44,139 @@ return web_contents->GetTitle(); } + void EnableExtensions(bool skip_session_components) { + auto* profile = browser()->profile(); + extensions::ComponentLoader::EnableBackgroundExtensionsForTesting(); + extensions::ExtensionSystem::Get(profile) + ->extension_service() + ->component_loader() + ->AddDefaultComponentExtensions(skip_session_components); + base::RunLoop().RunUntilIdle(); + } + + // Disables specified system features or enables all if system_features is + // empty. + void UpdateSystemFeaturesDisableList(base::Value system_features) { + PolicyMap policies; + policies.Set(key::kSystemFeaturesDisableList, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, + std::move(system_features), nullptr); + UpdateProviderPolicy(policies); + } + + void VerifyAppState(const char* app_id, + apps::mojom::Readiness expected_readiness, + bool blocked_icon) { + auto* profile = browser()->profile(); + extensions::ExtensionRegistry* registry = + extensions::ExtensionRegistry::Get(profile); + ASSERT_TRUE(registry->enabled_extensions().GetByID(app_id)); + + apps::AppServiceProxy* proxy = + apps::AppServiceProxyFactory::GetForProfile(profile); + proxy->FlushMojoCallsForTesting(); + + proxy->AppRegistryCache().ForOneApp( + app_id, + [&expected_readiness, &blocked_icon](const apps::AppUpdate& update) { + EXPECT_EQ(expected_readiness, update.Readiness()); + if (blocked_icon) { + EXPECT_TRUE(apps::IconEffects::kBlocked & + update.IconKey()->icon_effects); + } else { + EXPECT_FALSE(apps::IconEffects::kBlocked & + update.IconKey()->icon_effects); + } + }); + } + private: base::test::ScopedFeatureList scoped_feature_list_; }; IN_PROC_BROWSER_TEST_F(SystemFeaturesPolicyTest, DisableCameraBeforeInstall) { - PolicyMap policies; base::Value system_features(base::Value::Type::LIST); system_features.Append(kCameraFeature); - policies.Set(key::kSystemFeaturesDisableList, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, - std::move(system_features), nullptr); - UpdateProviderPolicy(policies); + UpdateSystemFeaturesDisableList(std::move(system_features)); + EnableExtensions(false); + VerifyAppState(extension_misc::kCameraAppId, + apps::mojom::Readiness::kDisabledByPolicy, true); - auto* profile = browser()->profile(); - extensions::ComponentLoader::EnableBackgroundExtensionsForTesting(); - extensions::ExtensionSystem::Get(profile) - ->extension_service() - ->component_loader() - ->AddDefaultComponentExtensions(false); - base::RunLoop().RunUntilIdle(); - - extensions::ExtensionRegistry* registry = - extensions::ExtensionRegistry::Get(profile); - ASSERT_TRUE( - registry->enabled_extensions().GetByID(extension_misc::kCameraAppId)); - - apps::AppServiceProxy* proxy = - apps::AppServiceProxyFactory::GetForProfile(profile); - proxy->FlushMojoCallsForTesting(); - - proxy->AppRegistryCache().ForOneApp( - extension_misc::kCameraAppId, [](const apps::AppUpdate& update) { - EXPECT_EQ(apps::mojom::Readiness::kDisabledByPolicy, - update.Readiness()); - EXPECT_TRUE(apps::IconEffects::kBlocked & - update.IconKey()->icon_effects); - }); - - policies.Set(key::kSystemFeaturesDisableList, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::Value(), nullptr); - UpdateProviderPolicy(policies); - - ASSERT_TRUE( - registry->enabled_extensions().GetByID(extension_misc::kCameraAppId)); - - proxy->FlushMojoCallsForTesting(); - proxy->AppRegistryCache().ForOneApp( - extension_misc::kCameraAppId, [](const apps::AppUpdate& update) { - EXPECT_EQ(apps::mojom::Readiness::kReady, update.Readiness()); - EXPECT_FALSE(apps::IconEffects::kBlocked & - update.IconKey()->icon_effects); - }); + UpdateSystemFeaturesDisableList(base::Value()); + VerifyAppState(extension_misc::kCameraAppId, apps::mojom::Readiness::kReady, + false); } IN_PROC_BROWSER_TEST_F(SystemFeaturesPolicyTest, DisableCameraAfterInstall) { - auto* profile = browser()->profile(); - extensions::ComponentLoader::EnableBackgroundExtensionsForTesting(); - extensions::ExtensionSystem::Get(profile) - ->extension_service() - ->component_loader() - ->AddDefaultComponentExtensions(false); - base::RunLoop().RunUntilIdle(); - - PolicyMap policies; + EnableExtensions(false); base::Value system_features(base::Value::Type::LIST); system_features.Append(kCameraFeature); - policies.Set(key::kSystemFeaturesDisableList, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, - std::move(system_features), nullptr); - UpdateProviderPolicy(policies); + UpdateSystemFeaturesDisableList(std::move(system_features)); - extensions::ExtensionRegistry* registry = - extensions::ExtensionRegistry::Get(profile); - ASSERT_TRUE( - registry->enabled_extensions().GetByID(extension_misc::kCameraAppId)); + VerifyAppState(extension_misc::kCameraAppId, + apps::mojom::Readiness::kDisabledByPolicy, true); - apps::AppServiceProxy* proxy = - apps::AppServiceProxyFactory::GetForProfile(profile); - proxy->FlushMojoCallsForTesting(); - proxy->AppRegistryCache().ForOneApp( - extension_misc::kCameraAppId, [](const apps::AppUpdate& update) { - EXPECT_EQ(apps::mojom::Readiness::kDisabledByPolicy, - update.Readiness()); - EXPECT_TRUE(apps::IconEffects::kBlocked & - update.IconKey()->icon_effects); - }); + UpdateSystemFeaturesDisableList(base::Value()); + VerifyAppState(extension_misc::kCameraAppId, apps::mojom::Readiness::kReady, + false); +} - policies.Set(key::kSystemFeaturesDisableList, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::Value(), nullptr); - UpdateProviderPolicy(policies); +IN_PROC_BROWSER_TEST_F(SystemFeaturesPolicyTest, DisableWebStoreBeforeInstall) { + base::Value system_features(base::Value::Type::LIST); + system_features.Append(kWebStoreFeature); + UpdateSystemFeaturesDisableList(std::move(system_features)); + EnableExtensions(true); + VerifyAppState(extensions::kWebStoreAppId, + apps::mojom::Readiness::kDisabledByPolicy, true); - ASSERT_TRUE( - registry->enabled_extensions().GetByID(extension_misc::kCameraAppId)); + UpdateSystemFeaturesDisableList(base::Value()); + VerifyAppState(extensions::kWebStoreAppId, apps::mojom::Readiness::kReady, + false); +} - proxy->FlushMojoCallsForTesting(); - proxy->AppRegistryCache().ForOneApp( - extension_misc::kCameraAppId, [](const apps::AppUpdate& update) { - EXPECT_EQ(apps::mojom::Readiness::kReady, update.Readiness()); - EXPECT_FALSE(apps::IconEffects::kBlocked & - update.IconKey()->icon_effects); - }); +IN_PROC_BROWSER_TEST_F(SystemFeaturesPolicyTest, DisableWebStoreAfterInstall) { + EnableExtensions(false); + base::Value system_features(base::Value::Type::LIST); + system_features.Append(kWebStoreFeature); + UpdateSystemFeaturesDisableList(std::move(system_features)); + + VerifyAppState(extensions::kWebStoreAppId, + apps::mojom::Readiness::kDisabledByPolicy, true); + + UpdateSystemFeaturesDisableList(base::Value()); + VerifyAppState(extensions::kWebStoreAppId, apps::mojom::Readiness::kReady, + false); +} + +IN_PROC_BROWSER_TEST_F(SystemFeaturesPolicyTest, + DisableCameraAndWebStoreAfterInstall) { + EnableExtensions(false); + base::Value system_features(base::Value::Type::LIST); + system_features.Append(kWebStoreFeature); + system_features.Append(kCameraFeature); + UpdateSystemFeaturesDisableList(std::move(system_features)); + + VerifyAppState(extensions::kWebStoreAppId, + apps::mojom::Readiness::kDisabledByPolicy, true); + VerifyAppState(extension_misc::kCameraAppId, + apps::mojom::Readiness::kDisabledByPolicy, true); + + UpdateSystemFeaturesDisableList(base::Value()); + VerifyAppState(extensions::kWebStoreAppId, apps::mojom::Readiness::kReady, + false); } IN_PROC_BROWSER_TEST_F(SystemFeaturesPolicyTest, RedirectChromeSettingsURL) { PolicyMap policies; base::Value system_features(base::Value::Type::LIST); system_features.Append(kBrowserSettingsFeature); - policies.Set(key::kSystemFeaturesDisableList, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, - std::move(system_features), nullptr); - UpdateProviderPolicy(policies); + UpdateSystemFeaturesDisableList(std::move(system_features)); GURL settings_url = GURL(chrome::kChromeUISettingsURL); EXPECT_EQ(l10n_util::GetStringUTF16(IDS_CHROME_URLS_DISABLED_PAGE_HEADER), GetWebUITitle(settings_url)); - policies.Set(key::kSystemFeaturesDisableList, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::Value(), nullptr); - UpdateProviderPolicy(policies); - + UpdateSystemFeaturesDisableList(base::Value()); EXPECT_EQ(l10n_util::GetStringUTF16(IDS_SETTINGS_SETTINGS), GetWebUITitle(settings_url)); }
diff --git a/chrome/browser/profiles/profile_attributes_storage.cc b/chrome/browser/profiles/profile_attributes_storage.cc index ed9eb11..b8047cc4 100644 --- a/chrome/browser/profiles/profile_attributes_storage.cc +++ b/chrome/browser/profiles/profile_attributes_storage.cc
@@ -245,7 +245,7 @@ } std::vector<ProfileAttributesEntry*> -ProfileAttributesStorage::GetAllProfilesAttributes() { +ProfileAttributesStorage::GetAllProfilesAttributes(bool include_guest_profile) { std::vector<ProfileAttributesEntry*> ret; for (const auto& path_and_entry : profile_attributes_entries_) { ProfileAttributesEntry* entry; @@ -253,7 +253,8 @@ bool success = GetProfileAttributesWithPath( base::FilePath(path_and_entry.first), &entry); DCHECK(success); - ret.push_back(entry); + if (!entry->IsGuest() || include_guest_profile) + ret.push_back(entry); } return ret; } @@ -261,7 +262,8 @@ std::vector<ProfileAttributesEntry*> ProfileAttributesStorage::GetAllProfilesAttributesSorted( bool use_local_profile_name) { - std::vector<ProfileAttributesEntry*> ret = GetAllProfilesAttributes(); + std::vector<ProfileAttributesEntry*> ret = + GetAllProfilesAttributes(/*include_guest_profile=*/false); // Do not allocate the collator and sort if it is not necessary. if (ret.size() < 2) return ret; @@ -317,7 +319,8 @@ // Loop through previously named profiles to ensure we're not duplicating. std::vector<ProfileAttributesEntry*> entries = - const_cast<ProfileAttributesStorage*>(this)->GetAllProfilesAttributes(); + const_cast<ProfileAttributesStorage*>(this)->GetAllProfilesAttributes( + /*include_guest_profile=*/false); if (std::none_of(entries.begin(), entries.end(), [name](ProfileAttributesEntry* entry) { @@ -364,7 +367,8 @@ std::unordered_set<size_t> used_icon_indices; std::vector<ProfileAttributesEntry*> entries = - const_cast<ProfileAttributesStorage*>(this)->GetAllProfilesAttributes(); + const_cast<ProfileAttributesStorage*>(this)->GetAllProfilesAttributes( + /*include_guest_profile=*/false); for (const ProfileAttributesEntry* entry : entries) used_icon_indices.insert(entry->GetAvatarIconIndex()); @@ -423,15 +427,14 @@ #endif void ProfileAttributesStorage::RecordProfilesState() { - std::vector<ProfileAttributesEntry*> entries = GetAllProfilesAttributes(); + std::vector<ProfileAttributesEntry*> entries = + GetAllProfilesAttributes(/*include_guest_profile=*/false); if (entries.size() == 0) return; MultiProfileUserType type = GetMultiProfileUserType(entries); for (ProfileAttributesEntry* entry : entries) { - if (entry->IsGuest()) - continue; RecordProfileState(entry, profile_metrics::StateSuffix::kAll); switch (type) {
diff --git a/chrome/browser/profiles/profile_attributes_storage.h b/chrome/browser/profiles/profile_attributes_storage.h index 416fe39..67759b3 100644 --- a/chrome/browser/profiles/profile_attributes_storage.h +++ b/chrome/browser/profiles/profile_attributes_storage.h
@@ -69,9 +69,13 @@ // Returns a vector containing one attributes entry per known profile. They // are not sorted in any particular order. - std::vector<ProfileAttributesEntry*> GetAllProfilesAttributes(); + std::vector<ProfileAttributesEntry*> GetAllProfilesAttributes( + bool include_guest_profile = false); + // Returns all non-Guest profile attributes sorted by name. std::vector<ProfileAttributesEntry*> GetAllProfilesAttributesSortedByName(); + + // Returns all non-Guest profile attributes sorted by local profile name. std::vector<ProfileAttributesEntry*> GetAllProfilesAttributesSortedByLocalProfilName();
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.html b/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.html index 8386804..bc4d9f31 100644 --- a/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.html +++ b/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.html
@@ -67,6 +67,11 @@ margin-inline-start: 0; } + network-list { + --cr-network-row-padding-bottom: 8px; + --cr-network-row-padding-top: 8px; + --cr-network-row-height: auto; + } </style> <template is="dom-if" if="[[!!euicc_]]" restamp> <div class="cellular-network-list-header esim-list-header flex">
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/multidevice_page/BUILD.gn index d92899e..4caf1172 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/BUILD.gn
@@ -85,6 +85,7 @@ js_library("multidevice_notification_access_setup_dialog") { deps = [ + ":multidevice_constants", "//ui/webui/resources/js:i18n_behavior", "//ui/webui/resources/js:web_ui_listener_behavior", ] @@ -284,6 +285,7 @@ js_library("multidevice_notification_access_setup_dialog.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.m.js" ] deps = [ + ":multidevice_constants.m", "//ui/webui/resources/js:i18n_behavior.m", "//ui/webui/resources/js:web_ui_listener_behavior.m", ]
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.html index 41a5a46..a02d654 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.html +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.html
@@ -8,6 +8,7 @@ <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="multidevice_browser_proxy.html"> +<link rel="import" href="multidevice_constants.html"> <link rel="import" href="../localized_link/localized_link.html"> <link rel="import" href="../os_icons.html"> <link rel="import" href="../../settings_shared_css.html">
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.js index 75b1d04..cba28d1 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.js
@@ -120,6 +120,11 @@ */ onSetupStateChanged_(setupState) { this.setupState_ = setupState; + if (this.setupState_ === + NotificationAccessSetupOperationStatus.COMPLETED_SUCCESSFULLY) { + this.browserProxy_.setFeatureEnabledState( + settings.MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS, true); + } }, /**
diff --git a/chrome/browser/resources/settings/metrics_browser_proxy.js b/chrome/browser/resources/settings/metrics_browser_proxy.js index 47c054ec..5d8f5f1 100644 --- a/chrome/browser/resources/settings/metrics_browser_proxy.js +++ b/chrome/browser/resources/settings/metrics_browser_proxy.js
@@ -54,19 +54,20 @@ * @enum {number} */ export const SafetyCheckInteractions = { - SAFETY_CHECK_START: 0, - SAFETY_CHECK_UPDATES_RELAUNCH: 1, - SAFETY_CHECK_PASSWORDS_MANAGE: 2, - SAFETY_CHECK_SAFE_BROWSING_MANAGE: 3, - SAFETY_CHECK_EXTENSIONS_REVIEW: 4, - SAFETY_CHECK_CHROME_CLEANER_REBOOT: 5, - SAFETY_CHECK_CHROME_CLEANER_REVIEW_INFECTED_STATE: 6, - SAFETY_CHECK_PASSWORDS_MANAGE_THROUGH_CARET_NAVIGATION: 7, - SAFETY_CHECK_SAFE_BROWSING_MANAGE_THROUGH_CARET_NAVIGATION: 8, - SAFETY_CHECK_EXTENSIONS_REVIEW_THROUGH_CARET_NAVIGATION: 9, - SAFETY_CHECK_CHROME_CLEANER_CARET_NAVIGATION: 10, + RUN_SAFETY_CHECK: 0, + UPDATES_RELAUNCH: 1, + PASSWORDS_MANAGE_COMPROMISED_PASSWORDS: 2, + SAFE_BROWSING_MANAGE: 3, + EXTENSIONS_REVIEW: 4, + CHROME_CLEANER_REBOOT: 5, + CHROME_CLEANER_REVIEW_INFECTED_STATE: 6, + PASSWORDS_CARET_NAVIGATION: 7, + SAFE_BROWSING_CARET_NAVIGATION: 8, + EXTENSIONS_CARET_NAVIGATION: 9, + CHROME_CLEANER_CARET_NAVIGATION: 10, + PASSWORDS_MANAGE_WEAK_PASSWORDS: 11, // Leave this at the end. - COUNT: 11, + COUNT: 12, }; /**
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_chrome_cleaner_child.js b/chrome/browser/resources/settings/safety_check_page/safety_check_chrome_cleaner_child.js index a1b2ad5..7b5bd5a 100644 --- a/chrome/browser/resources/settings/safety_check_page/safety_check_chrome_cleaner_child.js +++ b/chrome/browser/resources/settings/safety_check_page/safety_check_chrome_cleaner_child.js
@@ -196,15 +196,14 @@ switch (this.status_) { case SafetyCheckChromeCleanerStatus.INFECTED: this.logUserInteraction_( - SafetyCheckInteractions - .SAFETY_CHECK_CHROME_CLEANER_REVIEW_INFECTED_STATE, + SafetyCheckInteractions.CHROME_CLEANER_REVIEW_INFECTED_STATE, 'Settings.SafetyCheck.ChromeCleanerReviewInfectedState'); // Navigate to Chrome cleaner UI. this.navigateToFoilPage_(); break; case SafetyCheckChromeCleanerStatus.REBOOT_REQUIRED: this.logUserInteraction_( - SafetyCheckInteractions.SAFETY_CHECK_CHROME_CLEANER_REBOOT, + SafetyCheckInteractions.CHROME_CLEANER_REBOOT, 'Settings.SafetyCheck.ChromeCleanerReboot'); this.chromeCleanupBrowserProxy_.restartComputer(); break; @@ -239,7 +238,7 @@ onRowClick_: function() { if (this.isRowClickable_()) { this.logUserInteraction_( - SafetyCheckInteractions.SAFETY_CHECK_CHROME_CLEANER_CARET_NAVIGATION, + SafetyCheckInteractions.CHROME_CLEANER_CARET_NAVIGATION, 'Settings.SafetyCheck.ChromeCleanerCaretNavigation'); this.navigateToFoilPage_(); }
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_extensions_child.js b/chrome/browser/resources/settings/safety_check_page/safety_check_extensions_child.js index c482261b..aa116d0 100644 --- a/chrome/browser/resources/settings/safety_check_page/safety_check_extensions_child.js +++ b/chrome/browser/resources/settings/safety_check_page/safety_check_extensions_child.js
@@ -131,7 +131,7 @@ onButtonClick_: function() { // Log click both in action and histogram. this.metricsBrowserProxy_.recordSafetyCheckInteractionHistogram( - SafetyCheckInteractions.SAFETY_CHECK_EXTENSIONS_REVIEW); + SafetyCheckInteractions.EXTENSIONS_REVIEW); this.metricsBrowserProxy_.recordAction( 'Settings.SafetyCheck.ReviewExtensions'); this.openExtensionsPage_(); @@ -163,8 +163,7 @@ if (this.isRowClickable_()) { // Log click both in action and histogram. this.metricsBrowserProxy_.recordSafetyCheckInteractionHistogram( - SafetyCheckInteractions - .SAFETY_CHECK_EXTENSIONS_REVIEW_THROUGH_CARET_NAVIGATION); + SafetyCheckInteractions.EXTENSIONS_CARET_NAVIGATION); this.metricsBrowserProxy_.recordAction( 'Settings.SafetyCheck.ReviewExtensionsThroughCaretNavigation'); this.openExtensionsPage_();
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 cb7e141e..24f7499 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
@@ -105,7 +105,7 @@ runSafetyCheck_: function() { // Log click both in action and histogram. this.metricsBrowserProxy_.recordSafetyCheckInteractionHistogram( - SafetyCheckInteractions.SAFETY_CHECK_START); + SafetyCheckInteractions.RUN_SAFETY_CHECK); this.metricsBrowserProxy_.recordAction('Settings.SafetyCheck.Start'); // Trigger safety check.
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_passwords_child.js b/chrome/browser/resources/settings/safety_check_page/safety_check_passwords_child.js index c4337ce9a..60337a7 100644 --- a/chrome/browser/resources/settings/safety_check_page/safety_check_passwords_child.js +++ b/chrome/browser/resources/settings/safety_check_page/safety_check_passwords_child.js
@@ -135,7 +135,7 @@ onButtonClick_: function() { // Log click both in action and histogram. this.metricsBrowserProxy_.recordSafetyCheckInteractionHistogram( - SafetyCheckInteractions.SAFETY_CHECK_PASSWORDS_MANAGE); + SafetyCheckInteractions.PASSWORDS_MANAGE_COMPROMISED_PASSWORDS); this.metricsBrowserProxy_.recordAction( 'Settings.SafetyCheck.ManagePasswords'); this.openPasswordCheckPage_(); @@ -154,10 +154,13 @@ if (this.isRowClickable_()) { // Log click both in action and histogram. this.metricsBrowserProxy_.recordSafetyCheckInteractionHistogram( - SafetyCheckInteractions - .SAFETY_CHECK_PASSWORDS_MANAGE_THROUGH_CARET_NAVIGATION); + this.status_ === SafetyCheckPasswordsStatus.WEAK_PASSWORDS_EXIST ? + SafetyCheckInteractions.PASSWORDS_MANAGE_WEAK_PASSWORDS : + SafetyCheckInteractions.PASSWORDS_CARET_NAVIGATION); this.metricsBrowserProxy_.recordAction( - 'Settings.SafetyCheck.ManagePasswordsThroughCaretNavigation'); + this.status_ === SafetyCheckPasswordsStatus.WEAK_PASSWORDS_EXIST ? + 'Settings.SafetyCheck.ManageWeakPasswords' : + 'Settings.SafetyCheck.ManagePasswordsThroughCaretNavigation'); this.openPasswordCheckPage_(); } },
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_safe_browsing_child.js b/chrome/browser/resources/settings/safety_check_page/safety_check_safe_browsing_child.js index 28667ec..2f4630c1 100644 --- a/chrome/browser/resources/settings/safety_check_page/safety_check_safe_browsing_child.js +++ b/chrome/browser/resources/settings/safety_check_page/safety_check_safe_browsing_child.js
@@ -134,7 +134,7 @@ onButtonClick_: function() { // Log click both in action and histogram. this.metricsBrowserProxy_.recordSafetyCheckInteractionHistogram( - SafetyCheckInteractions.SAFETY_CHECK_SAFE_BROWSING_MANAGE); + SafetyCheckInteractions.SAFE_BROWSING_MANAGE); this.metricsBrowserProxy_.recordAction( 'Settings.SafetyCheck.ManageSafeBrowsing'); this.openSecurityPage_(); @@ -168,8 +168,7 @@ if (this.isRowClickable_()) { // Log click both in action and histogram. this.metricsBrowserProxy_.recordSafetyCheckInteractionHistogram( - SafetyCheckInteractions - .SAFETY_CHECK_SAFE_BROWSING_MANAGE_THROUGH_CARET_NAVIGATION); + SafetyCheckInteractions.SAFE_BROWSING_CARET_NAVIGATION); this.metricsBrowserProxy_.recordAction( 'Settings.SafetyCheck.ManageSafeBrowsingThroughCaretNavigation'); this.openSecurityPage_();
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_updates_child.js b/chrome/browser/resources/settings/safety_check_page/safety_check_updates_child.js index cddfc3c8..a2cad3fc 100644 --- a/chrome/browser/resources/settings/safety_check_page/safety_check_updates_child.js +++ b/chrome/browser/resources/settings/safety_check_page/safety_check_updates_child.js
@@ -119,7 +119,7 @@ onButtonClick_: function() { // Log click both in action and histogram. this.metricsBrowserProxy_.recordSafetyCheckInteractionHistogram( - SafetyCheckInteractions.SAFETY_CHECK_UPDATES_RELAUNCH); + SafetyCheckInteractions.UPDATES_RELAUNCH); this.metricsBrowserProxy_.recordAction( 'Settings.SafetyCheck.RelaunchAfterUpdates');
diff --git a/chrome/browser/ssl/typed_navigation_upgrade_throttle.cc b/chrome/browser/ssl/typed_navigation_upgrade_throttle.cc index b3c60e6..86cbdf1 100644 --- a/chrome/browser/ssl/typed_navigation_upgrade_throttle.cc +++ b/chrome/browser/ssl/typed_navigation_upgrade_throttle.cc
@@ -25,13 +25,14 @@ namespace { -// Delay in milliseconds before falling back to the HTTP URL. +// Delay before falling back to the HTTP URL. // This can be changed in tests. // - If the HTTPS load finishes successfully during this time, the timer is // cleared and no more work is done. // - Otherwise, a new navigation to the the fallback HTTP URL is started. constexpr base::FeatureParam<base::TimeDelta> kFallbackDelay{ - &omnibox::kDefaultTypedNavigationsToHttps, "timeout", + &omnibox::kDefaultTypedNavigationsToHttps, + omnibox::kDefaultTypedNavigationsToHttpsTimeoutParam, base::TimeDelta::FromSeconds(3)}; bool IsNavigationUsingHttpsAsDefaultScheme(content::NavigationHandle* handle) {
diff --git a/chrome/browser/ssl/typed_navigation_upgrade_throttle_browsertest.cc b/chrome/browser/ssl/typed_navigation_upgrade_throttle_browsertest.cc index 025696b..6e8d295 100644 --- a/chrome/browser/ssl/typed_navigation_upgrade_throttle_browsertest.cc +++ b/chrome/browser/ssl/typed_navigation_upgrade_throttle_browsertest.cc
@@ -92,7 +92,7 @@ std::vector<base::Feature> disabled_features; if (IsFeatureEnabled()) { base::FieldTrialParams params; - params["timeout"] = + params[omnibox::kDefaultTypedNavigationsToHttpsTimeoutParam] = base::NumberToString(fallback_delay.InMilliseconds()) + "ms"; enabled_features.emplace_back(omnibox::kDefaultTypedNavigationsToHttps, params);
diff --git a/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc b/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc index a6f8c85..9b9af29b 100644 --- a/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc +++ b/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc
@@ -29,7 +29,6 @@ #include "components/subresource_filter/core/common/activation_decision.h" #include "components/subresource_filter/core/common/activation_scope.h" #include "components/subresource_filter/core/mojom/subresource_filter.mojom.h" -#include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "services/metrics/public/cpp/ukm_source_id.h" @@ -98,18 +97,6 @@ } } -subresource_filter::mojom::ActivationLevel -ChromeSubresourceFilterClient::OnPageActivationComputed( - content::NavigationHandle* navigation_handle, - subresource_filter::mojom::ActivationLevel initial_activation_level, - subresource_filter::ActivationDecision* decision) { - // TODO(crbug.com/1116095): Once SafeBrowsingActivationThrottle knows about - // ProfileInteractionManager, it can invoke ProfileInteractionManager directly - // and SubresourceFilterClient::OnPageActivationComputed() can be eliminated. - return profile_interaction_manager_->OnPageActivationComputed( - navigation_handle, initial_activation_level, decision); -} - void ChromeSubresourceFilterClient::OnAdsViolationTriggered( content::RenderFrameHost* rfh, subresource_filter::mojom::AdsViolation triggered_violation) { @@ -129,6 +116,11 @@ : nullptr; } +subresource_filter::ProfileInteractionManager* +ChromeSubresourceFilterClient::GetProfileInteractionManager() { + return profile_interaction_manager_.get(); +} + void ChromeSubresourceFilterClient::ShowUI(const GURL& url) { #if defined(OS_ANDROID) InfoBarService* infobar_service =
diff --git a/chrome/browser/subresource_filter/chrome_subresource_filter_client.h b/chrome/browser/subresource_filter/chrome_subresource_filter_client.h index 0ef6322..72ee4a3 100644 --- a/chrome/browser/subresource_filter/chrome_subresource_filter_client.h +++ b/chrome/browser/subresource_filter/chrome_subresource_filter_client.h
@@ -15,13 +15,11 @@ class GURL; namespace content { -class NavigationHandle; class WebContents; } // namespace content namespace subresource_filter { class ContentSubresourceFilterThrottleManager; -class ProfileInteractionManager; class SubresourceFilterProfileContext; } // namespace subresource_filter @@ -47,15 +45,13 @@ // SubresourceFilterClient: void ShowNotification() override; - subresource_filter::mojom::ActivationLevel OnPageActivationComputed( - content::NavigationHandle* navigation_handle, - subresource_filter::mojom::ActivationLevel initial_activation_level, - subresource_filter::ActivationDecision* decision) override; void OnAdsViolationTriggered( content::RenderFrameHost* rfh, subresource_filter::mojom::AdsViolation triggered_violation) override; const scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> GetSafeBrowsingDatabaseManager() override; + subresource_filter::ProfileInteractionManager* GetProfileInteractionManager() + override; void OnReloadRequested() override; private:
diff --git a/chrome/browser/subresource_redirect/subresource_redirect_observer.cc b/chrome/browser/subresource_redirect/subresource_redirect_observer.cc index b3aed23..f3aa2e7c 100644 --- a/chrome/browser/subresource_redirect/subresource_redirect_observer.cc +++ b/chrome/browser/subresource_redirect/subresource_redirect_observer.cc
@@ -4,6 +4,9 @@ #include "chrome/browser/subresource_redirect/subresource_redirect_observer.h" +#include "chrome/browser/login_detection/login_detection_keyed_service.h" +#include "chrome/browser/login_detection/login_detection_keyed_service_factory.h" +#include "chrome/browser/login_detection/login_detection_type.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h" #include "chrome/browser/profiles/profile.h" @@ -145,13 +148,33 @@ navigation_handle)) { return; } + content::RenderFrameHost* render_frame_host = + navigation_handle->GetRenderFrameHost(); // Handle login robots based compression mode. if (ShouldEnableLoginRobotsCheckedCompression()) { + auto* login_detection_keyed_service = + login_detection::LoginDetectionKeyedServiceFactory::GetForProfile( + Profile::FromBrowserContext(web_contents()->GetBrowserContext())); + if (!login_detection_keyed_service) + return; + + is_https_image_compression_applied_ = + login_detection_keyed_service->GetPersistentLoginDetection( + navigation_handle->GetURL()) == + login_detection::LoginDetectionType::kNoLogin; + + mojo::AssociatedRemote<mojom::SubresourceRedirectHintsReceiver> + hints_receiver; + render_frame_host->GetRemoteAssociatedInterfaces()->GetInterface( + &hints_receiver); + hints_receiver->SetLoggedInState(!is_https_image_compression_applied_); + + if (!is_https_image_compression_applied_) + return; + SubresourceRedirectDocumentHost::GetOrCreateForCurrentDocument( navigation_handle->GetRenderFrameHost()); - // TODO(1149853): Handle whether page is logged-in and disable compression. - is_https_image_compression_applied_ = true; return; } @@ -163,8 +186,6 @@ if (!optimization_guide_decider) return; - content::RenderFrameHost* render_frame_host = - navigation_handle->GetRenderFrameHost(); optimization_guide_decider->CanApplyOptimizationAsync( navigation_handle, optimization_guide::proto::COMPRESS_PUBLIC_IMAGES, base::BindOnce(
diff --git a/chrome/browser/ui/extensions/extensions_container.h b/chrome/browser/ui/extensions/extensions_container.h index f00cfe1..1e3b45d 100644 --- a/chrome/browser/ui/extensions/extensions_container.h +++ b/chrome/browser/ui/extensions/extensions_container.h
@@ -76,7 +76,11 @@ virtual void ShowToolbarActionBubbleAsync( std::unique_ptr<ToolbarActionsBarBubbleDelegate> bubble) = 0; + // Toggle the Extensions menu (as if the user clicked the puzzle piece icon). virtual void ToggleExtensionsMenu() = 0; + + // Whether there are any Extensions registered with the ExtensionsContainer. + virtual bool HasAnyExtensions() const = 0; }; #endif // CHROME_BROWSER_UI_EXTENSIONS_EXTENSIONS_CONTAINER_H_
diff --git a/chrome/browser/ui/profile_picker.cc b/chrome/browser/ui/profile_picker.cc index 6460acd..d5800f2 100644 --- a/chrome/browser/ui/profile_picker.cc +++ b/chrome/browser/ui/profile_picker.cc
@@ -71,13 +71,13 @@ return false; std::vector<ProfileAttributesEntry*> profile_attributes = - profile_manager->GetProfileAttributesStorage().GetAllProfilesAttributes(); + profile_manager->GetProfileAttributesStorage().GetAllProfilesAttributes( + /*include_guest_profile=*/false); int number_of_active_profiles = std::count_if(profile_attributes.begin(), profile_attributes.end(), [](ProfileAttributesEntry* entry) { return (base::Time::Now() - entry->GetActiveTime() < - kActiveTimeThreshold) && - !entry->IsGuest(); + kActiveTimeThreshold); }); // Don't show the profile picker at launch if the user has less than two // active profiles. However, if the user has already seen the profile picker
diff --git a/chrome/browser/ui/thumbnails/OWNERS b/chrome/browser/ui/thumbnails/OWNERS index 3a92f21..f71a866 100644 --- a/chrome/browser/ui/thumbnails/OWNERS +++ b/chrome/browser/ui/thumbnails/OWNERS
@@ -1,2 +1,6 @@ +# Primary dfried@chromium.org +collinbaker@chromium.org + +# Backup pbos@chromium.org
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_bar.cc b/chrome/browser/ui/toolbar/toolbar_actions_bar.cc index 77768513..4ca4d53 100644 --- a/chrome/browser/ui/toolbar/toolbar_actions_bar.cc +++ b/chrome/browser/ui/toolbar/toolbar_actions_bar.cc
@@ -608,10 +608,17 @@ void ToolbarActionsBar::ToggleExtensionsMenu() { // This is only implemented by |ExtensionsToolbarContainer|. - // TODO(crbug.com/943702): Remove this entire class. + // TODO(crbug.com/1165609): Remove this entire class. NOTREACHED(); } +bool ToolbarActionsBar::HasAnyExtensions() const { + // This is only implemented by |ExtensionsToolbarContainer|. + // TODO(crbug.com/1165609): Remove this entire class. + NOTREACHED(); + return false; +} + bool ToolbarActionsBar::CloseOverflowMenuIfOpen() { return delegate_->CloseOverflowMenuIfOpen(); }
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_bar.h b/chrome/browser/ui/toolbar/toolbar_actions_bar.h index ccf320e..2797c65 100644 --- a/chrome/browser/ui/toolbar/toolbar_actions_bar.h +++ b/chrome/browser/ui/toolbar/toolbar_actions_bar.h
@@ -249,6 +249,7 @@ void ShowToolbarActionBubbleAsync( std::unique_ptr<ToolbarActionsBarBubbleDelegate> bubble) override; void ToggleExtensionsMenu() override; + bool HasAnyExtensions() const override; private: // Returns the insets by which the icon area bounds (See GetIconAreaRect())
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_button.h b/chrome/browser/ui/views/extensions/extensions_toolbar_button.h index 3351f7e..e31bafa28 100644 --- a/chrome/browser/ui/views/extensions/extensions_toolbar_button.h +++ b/chrome/browser/ui/views/extensions/extensions_toolbar_button.h
@@ -26,8 +26,8 @@ ExtensionsToolbarButton& operator=(const ExtensionsToolbarButton&) = delete; ~ExtensionsToolbarButton() override; - // Activate the Extensions menu. If the ExtensionsToolbarContainer is in - // kAutoHide mode this will cause it to show. + // Toggle the Extensions menu. If the ExtensionsToolbarContainer is in + // kAutoHide mode and hidden this will cause it to show. void ToggleExtensionsMenu(); bool IsExtensionsMenuShowing() const;
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc index 84d6c8b..b7bad1f 100644 --- a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc +++ b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc
@@ -391,6 +391,10 @@ extensions_button_->ToggleExtensionsMenu(); } +bool ExtensionsToolbarContainer::HasAnyExtensions() const { + return !actions_.empty(); +} + void ExtensionsToolbarContainer::OnTabStripModelChanged( TabStripModel* tab_strip_model, const TabStripModelChange& change, @@ -407,7 +411,11 @@ int index) { CreateActionForId(action_id); ReorderViews(); - UpdateContainerVisibility(); + + // Auto hide mode should not become visible due to extensions being added, + // only due to user interaction. + if (display_mode_ != DisplayMode::kAutoHide) + UpdateContainerVisibility(); } void ExtensionsToolbarContainer::OnToolbarActionRemoved( @@ -712,7 +720,7 @@ bool ExtensionsToolbarContainer::ShouldContainerBeVisible() const { // The container (and extensions-menu button) should not be visible if we have // no extensions. - if (actions_.empty()) + if (!HasAnyExtensions()) return false; // All other display modes are constantly visible.
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_container.h b/chrome/browser/ui/views/extensions/extensions_toolbar_container.h index c2f0bc5..2a9d6b62 100644 --- a/chrome/browser/ui/views/extensions/extensions_toolbar_container.h +++ b/chrome/browser/ui/views/extensions/extensions_toolbar_container.h
@@ -54,13 +54,13 @@ // be hidden if the available space does not allow for them. Compact mode is // used in smaller windows (e.g. web apps) where // there may not be enough space to display the buttons. + // TODO(crbug.com/1155421): Remove kCompact in favour of kAutoHide once the + // |kDesktopPWAsElidedExtensionsMenu| flag is removed. kCompact, // In auto hide mode the menu icon is hidden until // extensions_button()->ToggleExtensionsMenu() is called by the embedder. - // This - // is used for windows that want to minimize the number of visible icons in - // their - // toolbar (e.g. web apps). + // This is used for windows that want to minimize the number of visible + // icons in their toolbar (e.g. web apps). kAutoHide, }; @@ -141,6 +141,7 @@ void ShowToolbarActionBubbleAsync( std::unique_ptr<ToolbarActionsBarBubbleDelegate> bubble) override; void ToggleExtensionsMenu() override; + bool HasAnyExtensions() const override; // ToolbarActionView::Delegate: content::WebContents* GetCurrentWebContents() override;
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view.cc b/chrome/browser/ui/views/profiles/profile_menu_view.cc index ae0f53c..b667b84 100644 --- a/chrome/browser/ui/views/profiles/profile_menu_view.cc +++ b/chrome/browser/ui/views/profiles/profile_menu_view.cc
@@ -695,11 +695,9 @@ ->GetProfileAttributesStorage() .GetAllProfilesAttributesSortedByName(); for (ProfileAttributesEntry* profile_entry : profile_entries) { - // Guest profile and the current profile are excluded. - if (profile_entry->IsGuest() || - profile_entry->GetPath() == browser()->profile()->GetPath()) { + // The current profile is excluded. + if (profile_entry->GetPath() == browser()->profile()->GetPath()) continue; - } AddSelectableProfile( ui::ImageModel::FromImage(
diff --git a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc index 4589dba..2af1946d 100644 --- a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc +++ b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc
@@ -97,6 +97,19 @@ return &web_app_frame_toolbar_helper_; } + bool IsMenuCommandEnabled(int command_id) { + auto app_menu_model = std::make_unique<WebAppMenuModel>( + /*provider=*/nullptr, helper()->app_browser()); + app_menu_model->Init(); + ui::MenuModel* model = app_menu_model.get(); + int index = -1; + if (!app_menu_model->GetModelAndIndexForCommandId(command_id, &model, + &index)) { + return false; + } + return model->IsEnabledAt(index); + } + private: net::EmbeddedTestServer https_server_; WebAppFrameToolbarTestHelper web_app_frame_toolbar_helper_; @@ -311,26 +324,27 @@ IN_PROC_BROWSER_TEST_F(WebAppFrameToolbarBrowserTest_ElidedExtensionsMenu, Test) { - LoadTestPopUpExtension(browser()->profile()); helper()->InstallAndLaunchWebApp(browser(), GURL("https://test.org")); - WebAppToolbarButtonContainer* toolbar_button_container = - helper()->web_app_frame_toolbar()->get_right_container_for_testing(); + // There should be no menu entry for opening the Extensions menu prior to + // installing Extensions. + EXPECT_FALSE(IsMenuCommandEnabled(WebAppMenuModel::kExtensionsMenuCommandId)); + + // Install test Extension. + LoadTestPopUpExtension(browser()->profile()); // There should be no visible Extensions icon. + WebAppToolbarButtonContainer* toolbar_button_container = + helper()->web_app_frame_toolbar()->get_right_container_for_testing(); EXPECT_FALSE(toolbar_button_container->extensions_container()->GetVisible()); // There should be a menu entry for opening the Extensions menu. + EXPECT_TRUE(IsMenuCommandEnabled(WebAppMenuModel::kExtensionsMenuCommandId)); + + // Trigger the Extensions menu entry. auto app_menu_model = std::make_unique<WebAppMenuModel>( /*provider=*/nullptr, helper()->app_browser()); app_menu_model->Init(); - ui::MenuModel* model = app_menu_model.get(); - int index = -1; - const bool found = app_menu_model->GetModelAndIndexForCommandId( - WebAppMenuModel::kExtensionsMenuCommandId, &model, &index); - EXPECT_TRUE(found); - EXPECT_TRUE(model->IsEnabledAt(index)); - app_menu_model->ExecuteCommand(WebAppMenuModel::kExtensionsMenuCommandId, /*event_flags=*/0); @@ -371,12 +385,5 @@ EXPECT_TRUE(toolbar_button_container->extensions_container()->GetVisible()); // There should be no menu entry for opening the Extensions menu. - auto app_menu_model = std::make_unique<WebAppMenuModel>( - /*provider=*/nullptr, helper()->app_browser()); - app_menu_model->Init(); - ui::MenuModel* model = app_menu_model.get(); - int index = -1; - const bool found = app_menu_model->GetModelAndIndexForCommandId( - WebAppMenuModel::kExtensionsMenuCommandId, &model, &index); - EXPECT_FALSE(found); + EXPECT_FALSE(IsMenuCommandEnabled(WebAppMenuModel::kExtensionsMenuCommandId)); }
diff --git a/chrome/browser/ui/web_applications/web_app_menu_model.cc b/chrome/browser/ui/web_applications/web_app_menu_model.cc index 0e00a55..0b94013 100644 --- a/chrome/browser/ui/web_applications/web_app_menu_model.cc +++ b/chrome/browser/ui/web_applications/web_app_menu_model.cc
@@ -47,7 +47,8 @@ case kExtensionsMenuCommandId: return base::FeatureList::IsEnabled(features::kExtensionsToolbarMenu) && base::FeatureList::IsEnabled( - features::kDesktopPWAsElidedExtensionsMenu); + features::kDesktopPWAsElidedExtensionsMenu) && + browser()->window()->GetExtensionsContainer()->HasAnyExtensions(); default: return AppMenuModel::IsCommandIdEnabled(command_id); }
diff --git a/chrome/browser/ui/webui/read_later/read_later_ui.cc b/chrome/browser/ui/webui/read_later/read_later_ui.cc index 87ad0a0..b43cd929 100644 --- a/chrome/browser/ui/webui/read_later/read_later_ui.cc +++ b/chrome/browser/ui/webui/read_later/read_later_ui.cc
@@ -34,7 +34,10 @@ } // namespace ReadLaterUI::ReadLaterUI(content::WebUI* web_ui) - : ui::MojoBubbleWebUIController(web_ui) { + : ui::MojoBubbleWebUIController(web_ui), + webui_load_timer_(web_ui->GetWebContents(), + "ReadingList.WebUI.LoadDocumentTime", + "ReadingList.WebUI.LoadCompletedTime") { content::WebUIDataSource* source = content::WebUIDataSource::Create(chrome::kChromeUIReadLaterHost); static constexpr webui::LocalizedString kLocalizedStrings[] = {
diff --git a/chrome/browser/ui/webui/read_later/read_later_ui.h b/chrome/browser/ui/webui/read_later/read_later_ui.h index 5532f286..86ddb50 100644 --- a/chrome/browser/ui/webui/read_later/read_later_ui.h +++ b/chrome/browser/ui/webui/read_later/read_later_ui.h
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "chrome/browser/ui/webui/read_later/read_later.mojom.h" +#include "chrome/browser/ui/webui/webui_load_timer.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" @@ -40,6 +41,8 @@ mojo::Receiver<read_later::mojom::PageHandlerFactory> page_factory_receiver_{ this}; + WebuiLoadTimer webui_load_timer_; + WEB_UI_CONTROLLER_TYPE_DECL(); };
diff --git a/chrome/browser/ui/webui/signin/profile_picker_handler.cc b/chrome/browser/ui/webui/signin/profile_picker_handler.cc index b33a898..0432221 100644 --- a/chrome/browser/ui/webui/signin/profile_picker_handler.cc +++ b/chrome/browser/ui/webui/signin/profile_picker_handler.cc
@@ -637,9 +637,6 @@ // Vector of nullptr entries. std::vector<ProfileAttributesEntry*> entries(number_of_profiles); for (ProfileAttributesEntry* entry : ordered_entries) { - if (entry->IsGuest()) - continue; - DCHECK(profiles_order_.find(entry->GetPath()) != profiles_order_.end()); size_t index = profiles_order_[entry->GetPath()]; DCHECK_LT(index, number_of_profiles); @@ -655,8 +652,6 @@ const int avatar_icon_size = kProfileCardAvatarSize * web_ui()->GetDeviceScaleFactor(); for (const ProfileAttributesEntry* entry : entries) { - if (entry->IsGuest()) - continue; auto profile_entry = std::make_unique<base::DictionaryValue>(); profile_entry->SetKey("profilePath", util::FilePathToValue(entry->GetPath()));
diff --git a/chrome/browser/ui/webui/signin/profile_picker_handler.h b/chrome/browser/ui/webui/signin/profile_picker_handler.h index 61e1eb9..1966cb08 100644 --- a/chrome/browser/ui/webui/signin/profile_picker_handler.h +++ b/chrome/browser/ui/webui/signin/profile_picker_handler.h
@@ -91,7 +91,7 @@ void SetProfilesOrder(const std::vector<ProfileAttributesEntry*>& entries); // Returns the list of profiles in the same order as when the picker - // was first shown. + // was first shown. Guest profile is not included here. std::vector<ProfileAttributesEntry*> GetProfileAttributes(); // Creation time of the handler, to measure performance on startup. Only set
diff --git a/chrome/browser/vr/base_scheduler_delegate_unittest.cc b/chrome/browser/vr/base_scheduler_delegate_unittest.cc index 363d56c..903c99249 100644 --- a/chrome/browser/vr/base_scheduler_delegate_unittest.cc +++ b/chrome/browser/vr/base_scheduler_delegate_unittest.cc
@@ -54,8 +54,7 @@ void SetUp() override { test_task_runner_ = base::WrapRefCounted(new base::TestMockTimeTaskRunner()); - on_destroy_ = - base::ThreadTaskRunnerHandle::OverrideForTesting(test_task_runner_); + task_runner_handle_override_.emplace(test_task_runner_); } void FastForwardBy(base::TimeDelta delta) { @@ -64,7 +63,8 @@ private: scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_; - base::ScopedClosureRunner on_destroy_; + base::Optional<base::ThreadTaskRunnerHandleOverrideForTesting> + task_runner_handle_override_; }; TEST_F(SchedulerDelegateTest, NoTimeoutWhenWebXrFrameArrivesFast) {
diff --git a/chrome/browser/web_applications/components/external_install_options.cc b/chrome/browser/web_applications/components/external_install_options.cc index 434ecaa..833d7b5 100644 --- a/chrome/browser/web_applications/components/external_install_options.cc +++ b/chrome/browser/web_applications/components/external_install_options.cc
@@ -61,6 +61,7 @@ options.bypass_service_worker_check, options.require_manifest, options.force_reinstall, + options.force_reinstall_for_milestone, options.wait_for_windows_closed, options.install_placeholder, options.reinstall_placeholder, @@ -133,6 +134,8 @@ << install_options.bypass_service_worker_check << "\n require_manifest: " << install_options.require_manifest << "\n force_reinstall: " << install_options.force_reinstall + << "\n force_reinstall_for_milestone: " + << install_options.force_reinstall_for_milestone << "\n wait_for_windows_closed: " << install_options.wait_for_windows_closed << "\n install_placeholder: " << install_options.install_placeholder
diff --git a/chrome/browser/web_applications/components/external_install_options.h b/chrome/browser/web_applications/components/external_install_options.h index 7031fc9a..836b0f9 100644 --- a/chrome/browser/web_applications/components/external_install_options.h +++ b/chrome/browser/web_applications/components/external_install_options.h
@@ -109,6 +109,12 @@ // Whether the app should be reinstalled even if it is already installed. bool force_reinstall = false; + // Whether we should update the app if the browser's binary milestone number + // goes from less the milestone specified to greater or equal than the + // milestone specified. For example, if this value is 89 then we update the + // app on all browser upgrades from <89 to >=89. The update happens only once. + base::Optional<int> force_reinstall_for_milestone; + // Whether we should wait for all app windows being closed before reinstalling // the placeholder. bool wait_for_windows_closed = false;
diff --git a/chrome/browser/web_applications/external_web_app_manager.cc b/chrome/browser/web_applications/external_web_app_manager.cc index 4d102e6..5caea6046 100644 --- a/chrome/browser/web_applications/external_web_app_manager.cc +++ b/chrome/browser/web_applications/external_web_app_manager.cc
@@ -392,6 +392,16 @@ debug_info_->enabled_configs = parsed_configs.options_list; } + // Triggers |force_reinstall| in PendingAppManager if milestone increments + // across |force_reinstall_for_milestone|. + for (ExternalInstallOptions& options : parsed_configs.options_list) { + if (options.force_reinstall_for_milestone && + IsReinstallPastMilestoneNeededSinceLastSync( + options.force_reinstall_for_milestone.value())) { + options.force_reinstall = true; + } + } + UMA_HISTOGRAM_COUNTS_100(kHistogramEnabledCount, parsed_configs.options_list.size()); UMA_HISTOGRAM_COUNTS_100(kHistogramDisabledCount, disabled_count); @@ -417,8 +427,8 @@ PendingAppManager::SynchronizeCallback callback, std::map<GURL, PendingAppManager::InstallResult> install_results, std::map<GURL, bool> uninstall_results) { - // Note that we are storing the Chrome version instead of a "has synchronised" - // bool in order to do version update specific logic in the future. + // Note that we are storing the Chrome version (milestone number) instead of a + // "has synchronised" bool in order to do version update specific logic. profile_->GetPrefs()->SetString( prefs::kWebAppsLastPreinstallSynchronizeVersion, version_info::GetMajorVersionNumber()); @@ -491,6 +501,17 @@ return ExternallyInstalledWebAppPrefs(prefs).HasNoApps(); } +bool ExternalWebAppManager::IsReinstallPastMilestoneNeededSinceLastSync( + int force_reinstall_for_milestone) { + PrefService* prefs = profile_->GetPrefs(); + std::string last_preinstall_synchronize_milestone = + prefs->GetString(prefs::kWebAppsLastPreinstallSynchronizeVersion); + + return IsReinstallPastMilestoneNeeded(last_preinstall_synchronize_milestone, + version_info::GetMajorVersionNumber(), + force_reinstall_for_milestone); +} + ExternalWebAppManager::DebugInfo::DebugInfo() = default; ExternalWebAppManager::DebugInfo::~DebugInfo() = default;
diff --git a/chrome/browser/web_applications/external_web_app_manager.h b/chrome/browser/web_applications/external_web_app_manager.h index f8837f5f..0f74073 100644 --- a/chrome/browser/web_applications/external_web_app_manager.h +++ b/chrome/browser/web_applications/external_web_app_manager.h
@@ -119,6 +119,11 @@ // profile. bool IsNewUser(); + // |force_reinstall_for_milestone| is a major version number. See + // components/version_info/version_info.h. + bool IsReinstallPastMilestoneNeededSinceLastSync( + int force_reinstall_for_milestone); + PendingAppManager* pending_app_manager_ = nullptr; Profile* const profile_;
diff --git a/chrome/browser/web_applications/external_web_app_utils.cc b/chrome/browser/web_applications/external_web_app_utils.cc index 643b6c53..2032be7 100644 --- a/chrome/browser/web_applications/external_web_app_utils.cc +++ b/chrome/browser/web_applications/external_web_app_utils.cc
@@ -148,6 +148,10 @@ // "theme_color": "red" constexpr char kOfflineManifestThemeColorArgbHex[] = "theme_color_argb_hex"; +// Contains numeric milestone number M like 89 (the Chrome version). The app +// gets updated if browser's binary milestone number goes from <M to >=M. +constexpr char kForceReinstallForMilestone[] = "force_reinstall_for_milestone"; + } // namespace OptionsOrError ParseConfig(FileUtilsWrapper& file_utils, @@ -356,6 +360,16 @@ " set with no ", kOfflineManifest, " available"}); } + // force_reinstall_for_milestone + value = app_config.FindKey(kForceReinstallForMilestone); + if (value) { + if (!value->is_int()) { + return base::StrCat({file.AsUTF8Unsafe(), " had an invalid ", + kForceReinstallForMilestone}); + } + options.force_reinstall_for_milestone = value->GetInt(); + } + return options; } @@ -495,4 +509,23 @@ std::move(app_info)); } +bool IsReinstallPastMilestoneNeeded( + base::StringPiece last_preinstall_synchronize_milestone_str, + base::StringPiece current_milestone_str, + int force_reinstall_for_milestone) { + int last_preinstall_synchronize_milestone = 0; + if (!base::StringToInt(last_preinstall_synchronize_milestone_str, + &last_preinstall_synchronize_milestone)) { + return false; + } + + int current_milestone = 0; + if (!base::StringToInt(current_milestone_str, ¤t_milestone)) + return false; + + return last_preinstall_synchronize_milestone < + force_reinstall_for_milestone && + current_milestone >= force_reinstall_for_milestone; +} + } // namespace web_app
diff --git a/chrome/browser/web_applications/external_web_app_utils.h b/chrome/browser/web_applications/external_web_app_utils.h index dd735f4..9d689be 100644 --- a/chrome/browser/web_applications/external_web_app_utils.h +++ b/chrome/browser/web_applications/external_web_app_utils.h
@@ -8,6 +8,7 @@ #include <string> #include "base/optional.h" +#include "base/strings/string_piece.h" #include "chrome/browser/web_applications/components/external_install_options.h" #include "third_party/abseil-cpp/absl/types/variant.h" @@ -36,6 +37,16 @@ const base::FilePath& file, const base::Value& offline_manifest); +// Returns true if we need to update the app. |current_milestone_str| is the +// browser's binary milestone number. +// |last_preinstall_synchronize_milestone_str| is a previous milestone for the +// user's data state. For example, if |force_reinstall_for_milestone| value is +// 89 then we need to update the app on all browser upgrades from <89 to >=89. +bool IsReinstallPastMilestoneNeeded( + base::StringPiece last_preinstall_synchronize_milestone_str, + base::StringPiece current_milestone_str, + int force_reinstall_for_milestone); + } // namespace web_app #endif // CHROME_BROWSER_WEB_APPLICATIONS_EXTERNAL_WEB_APP_UTILS_H_
diff --git a/chrome/browser/web_applications/external_web_app_utils_unittest.cc b/chrome/browser/web_applications/external_web_app_utils_unittest.cc index 6e8a832..d4bf053 100644 --- a/chrome/browser/web_applications/external_web_app_utils_unittest.cc +++ b/chrome/browser/web_applications/external_web_app_utils_unittest.cc
@@ -443,4 +443,51 @@ )")) << "theme_color_argb_hex is valid"; } +TEST_F(ExternalWebAppUtilsTest, ForceReinstallForMilestone) { + base::Optional<ExternalInstallOptions> non_number = ParseConfig(R"( + { + "app_url": "https://test.org", + "launch_container": "window", + "force_reinstall_for_milestone": "error", + "user_type": ["test"] + } + )"); + EXPECT_FALSE(non_number.has_value()); + + base::Optional<ExternalInstallOptions> number = ParseConfig(R"( + { + "app_url": "https://test.org", + "launch_container": "window", + "force_reinstall_for_milestone": 89, + "user_type": ["test"] + } + )"); + EXPECT_TRUE(number.has_value()); + EXPECT_EQ(89, number->force_reinstall_for_milestone); +} + +TEST_F(ExternalWebAppUtilsTest, IsReinstallPastMilestoneNeeded) { + // Arguments: last_preinstall_synchronize_milestone, current_milestone, + // force_reinstall_for_milestone. + EXPECT_FALSE(IsReinstallPastMilestoneNeeded("87", "87", 89)); + EXPECT_FALSE(IsReinstallPastMilestoneNeeded("87", "88", 89)); + EXPECT_FALSE(IsReinstallPastMilestoneNeeded("88", "88", 89)); + EXPECT_TRUE(IsReinstallPastMilestoneNeeded("88", "89", 89)); + EXPECT_FALSE(IsReinstallPastMilestoneNeeded("89", "89", 89)); + EXPECT_FALSE(IsReinstallPastMilestoneNeeded("89", "90", 89)); + EXPECT_FALSE(IsReinstallPastMilestoneNeeded("90", "90", 89)); + EXPECT_FALSE(IsReinstallPastMilestoneNeeded("90", "91", 89)); + EXPECT_FALSE(IsReinstallPastMilestoneNeeded("91", "91", 89)); + + // Long jumps: + EXPECT_FALSE(IsReinstallPastMilestoneNeeded("80", "85", 89)); + EXPECT_TRUE(IsReinstallPastMilestoneNeeded("80", "100", 89)); + EXPECT_FALSE(IsReinstallPastMilestoneNeeded("90", "95", 89)); + + // Wrong input: + EXPECT_FALSE(IsReinstallPastMilestoneNeeded("error", "90", 89)); + EXPECT_FALSE(IsReinstallPastMilestoneNeeded("88", "error", 89)); + EXPECT_FALSE(IsReinstallPastMilestoneNeeded("error", "error", 0)); +} + } // namespace web_app
diff --git a/chrome/browser/web_applications/web_app_mover.h b/chrome/browser/web_applications/web_app_mover.h index 04d8685..b0ff80a5 100644 --- a/chrome/browser/web_applications/web_app_mover.h +++ b/chrome/browser/web_applications/web_app_mover.h
@@ -8,6 +8,7 @@ #include <memory> #include "base/callback.h" +#include "base/callback_helpers.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" @@ -107,4 +108,4 @@ } // namespace web_app -#endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_MOVER_H_ \ No newline at end of file +#endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_MOVER_H_
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 05e0781..6124f62 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-master-1610408110-1b25c741a858a17df9d643531610232aedd2e5da.profdata +chrome-linux-master-1610431066-b046cf295bac84ed9eefc440cb75a6df945c21fe.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 2f4b4b7..ffd6067 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-master-1610408110-5a618b6e0bdb5b4a60796f5aa8c6f6759f78cdd3.profdata +chrome-mac-master-1610431066-5d7d40ce59ba8e505b376b46e02fe57205cb3e46.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 648021c..724313c 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-master-1610398040-59038019b78fe7d9277311f636fda97275a69be4.profdata +chrome-win32-master-1610420273-f729673981a14d4f8cc70d6513013e1d16474c41.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index bf52c0a..cd7d99d 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-master-1610387594-34ec7be13acbaa9470ba5363f8af27b0c42697d0.profdata +chrome-win64-master-1610431066-60b154442ebb054827e182b9c834d6f36e05d2b3.profdata
diff --git a/chrome/common/subresource_redirect_service.mojom b/chrome/common/subresource_redirect_service.mojom index bd242ef..300c46c 100644 --- a/chrome/common/subresource_redirect_service.mojom +++ b/chrome/common/subresource_redirect_service.mojom
@@ -36,4 +36,10 @@ interface SubresourceRedirectHintsReceiver { // Sends the public image URL hints from the browser to renderers. SetCompressPublicImagesHints(CompressPublicImagesHints images_hints); + + + // Sets whether the current page is determined to be logged in. This guides + // whether subresource redirect based compression will be enabled. Sent from + // the browser to renderers on navigation commit. + SetLoggedInState(bool is_logged_in); };
diff --git a/chrome/renderer/subresource_redirect/login_robots_decider_agent.cc b/chrome/renderer/subresource_redirect/login_robots_decider_agent.cc index 8e28e97..dea688c 100644 --- a/chrome/renderer/subresource_redirect/login_robots_decider_agent.cc +++ b/chrome/renderer/subresource_redirect/login_robots_decider_agent.cc
@@ -32,6 +32,7 @@ case RobotsRulesParser::CheckResult::kAllowed: return RedirectResult::kRedirectable; case RobotsRulesParser::CheckResult::kDisallowed: + case RobotsRulesParser::CheckResult::kInvalidated: return RedirectResult::kIneligibleRobotsDisallowed; case RobotsRulesParser::CheckResult::kTimedout: case RobotsRulesParser::CheckResult::kDisallowedAfterTimeout: @@ -39,12 +40,10 @@ } } -// Converts the robots rules CheckResult to RedirectResult and passes to the -// callback. -void SendRedirectResultToCallback( - LoginRobotsDeciderAgent::ShouldRedirectDecisionCallback callback, - RobotsRulesParser::CheckResult check_result) { - std::move(callback).Run(ConvertToRedirectResult(check_result)); +void RecordRedirectResultMetric(RedirectResult redirect_result) { + LOCAL_HISTOGRAM_ENUMERATION( + "SubresourceRedirect.LoginRobotsDeciderAgent.RedirectResult", + redirect_result); } } // namespace @@ -65,6 +64,8 @@ ShouldRedirectDecisionCallback callback) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(url.is_valid()); + if (redirect_result_ != RedirectResult::kRedirectable) + return redirect_result_; if (!render_frame()->IsMainFrame()) return RedirectResult::kIneligibleSubframeResource; @@ -83,21 +84,51 @@ base::Optional<RobotsRulesParser::CheckResult> result = robots_rules_parser_cache.CheckRobotsRules( - url, - base::BindOnce(&SendRedirectResultToCallback, std::move(callback))); - if (result) - return ConvertToRedirectResult(*result); + routing_id(), url, + base::BindOnce( + &LoginRobotsDeciderAgent::OnShouldRedirectSubresourceResult, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + if (result) { + RedirectResult redirect_result = ConvertToRedirectResult(*result); + RecordRedirectResultMetric(redirect_result); + return redirect_result; + } return base::nullopt; } +void LoginRobotsDeciderAgent::OnShouldRedirectSubresourceResult( + LoginRobotsDeciderAgent::ShouldRedirectDecisionCallback callback, + RobotsRulesParser::CheckResult check_result) { + // Verify if the navigation is still allowed to redirect. + if (redirect_result_ != RedirectResult::kRedirectable) { + RecordRedirectResultMetric(redirect_result_); + std::move(callback).Run(redirect_result_); + return; + } + RedirectResult redirect_result = ConvertToRedirectResult(check_result); + RecordRedirectResultMetric(redirect_result); + std::move(callback).Run(redirect_result); +} + +void LoginRobotsDeciderAgent::ReadyToCommitNavigation( + blink::WebDocumentLoader* document_loader) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + redirect_result_ = RedirectResult::kUnknown; + GetRobotsRulesParserCache().InvalidatePendingRequests(routing_id()); +} + +void LoginRobotsDeciderAgent::SetLoggedInState(bool is_logged_in) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + redirect_result_ = is_logged_in ? RedirectResult::kIneligibleLoginDetected + : RedirectResult::kRedirectable; +} + void LoginRobotsDeciderAgent::RecordMetricsOnLoadFinished( const GURL& url, int64_t content_length, RedirectResult redirect_result) { - LOCAL_HISTOGRAM_ENUMERATION( - "SubresourceRedirect.LoginRobotsDeciderAgent.RedirectResult", - redirect_result); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // TODO(crbug.com/1148980): Record coverage metrics }
diff --git a/chrome/renderer/subresource_redirect/login_robots_decider_agent.h b/chrome/renderer/subresource_redirect/login_robots_decider_agent.h index 72b0b8e..774cc15 100644 --- a/chrome/renderer/subresource_redirect/login_robots_decider_agent.h +++ b/chrome/renderer/subresource_redirect/login_robots_decider_agent.h
@@ -6,6 +6,7 @@ #define CHROME_RENDERER_SUBRESOURCE_REDIRECT_LOGIN_ROBOTS_DECIDER_AGENT_H_ #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "base/threading/thread_checker.h" #include "base/timer/timer.h" #include "chrome/renderer/subresource_redirect/public_resource_decider_agent.h" @@ -37,9 +38,14 @@ void UpdateRobotsRulesForTesting(const url::Origin& origin, const base::Optional<std::string>& rules); + // content::RenderFrameObserver: + void ReadyToCommitNavigation( + blink::WebDocumentLoader* document_loader) override; + // mojom::SubresourceRedirectHintsReceiver: void SetCompressPublicImagesHints( mojom::CompressPublicImagesHintsPtr images_hints) override; + void SetLoggedInState(bool is_logged_in) override; // PublicResourceDeciderAgent: base::Optional<RedirectResult> ShouldRedirectSubresource( @@ -49,9 +55,21 @@ int64_t content_length, RedirectResult redirect_result) override; + // Callback invoked when should redirect check result is available. + void OnShouldRedirectSubresourceResult( + ShouldRedirectDecisionCallback callback, + RobotsRulesParser::CheckResult check_result); + bool IsMainFrame() const; + // Current state of the redirect compression that should be used for the + // current navigation. + RedirectResult redirect_result_ = RedirectResult::kUnknown; + THREAD_CHECKER(thread_checker_); + + // Used to get a weak pointer to |this|. + base::WeakPtrFactory<LoginRobotsDeciderAgent> weak_ptr_factory_{this}; }; } // namespace subresource_redirect
diff --git a/chrome/renderer/subresource_redirect/login_robots_decider_agent_browsertest.cc b/chrome/renderer/subresource_redirect/login_robots_decider_agent_browsertest.cc index ab6c89a..9fdd1b46 100644 --- a/chrome/renderer/subresource_redirect/login_robots_decider_agent_browsertest.cc +++ b/chrome/renderer/subresource_redirect/login_robots_decider_agent_browsertest.cc
@@ -73,6 +73,10 @@ result_receiver.redirect_result() == RedirectResult::kRedirectable; } + void SetLoggedInState(bool is_logged_in) { + login_robots_decider_agent_->SetLoggedInState(is_logged_in); + } + protected: void SetUp() override { ChromeRenderViewTest::SetUp(); @@ -91,6 +95,7 @@ TEST_F(SubresourceRedirectLoginRobotsDeciderAgentTest, TestAllowDisallowSingleOrigin) { + SetLoggedInState(false); SetUpRobotsRules("https://foo.com", {{kRuleTypeAllow, "/public"}, {kRuleTypeDisallow, "/private"}}); EXPECT_TRUE(ShouldRedirectSubresource("https://foo.com/public.jpg")); @@ -103,6 +108,7 @@ TEST_F(SubresourceRedirectLoginRobotsDeciderAgentTest, TestHTTPRulesAreSeparate) { + SetLoggedInState(false); SetUpRobotsRules("https://foo.com", {{kRuleTypeAllow, "/public"}, {kRuleTypeDisallow, "/private"}}); EXPECT_FALSE(ShouldRedirectSubresource("http://foo.com/public.jpg")); @@ -116,6 +122,7 @@ } TEST_F(SubresourceRedirectLoginRobotsDeciderAgentTest, TestURLWithArguments) { + SetLoggedInState(false); SetUpRobotsRules("https://foo.com", {{kRuleTypeAllow, "/*.jpg$"}, {kRuleTypeDisallow, "/*.png?*arg_disallowed"}, @@ -140,6 +147,7 @@ TEST_F(SubresourceRedirectLoginRobotsDeciderAgentTest, TestRulesAreCaseSensitive) { + SetLoggedInState(false); SetUpRobotsRules("https://foo.com", {{kRuleTypeAllow, "/allowed"}, {kRuleTypeAllow, "/CamelCase"}, {kRuleTypeAllow, "/CAPITALIZE"}, @@ -152,4 +160,13 @@ EXPECT_FALSE(ShouldRedirectSubresource("https://foo.com/capitalize.jpg")); } +TEST_F(SubresourceRedirectLoginRobotsDeciderAgentTest, + TestDisabledWhenLoggedIn) { + SetLoggedInState(true); + SetUpRobotsRules("https://foo.com", {{kRuleTypeAllow, "/public"}, + {kRuleTypeDisallow, "/private"}}); + EXPECT_FALSE(ShouldRedirectSubresource("https://foo.com/public.jpg")); + EXPECT_FALSE(ShouldRedirectSubresource("https://foo.com/private.jpg")); +} + } // namespace subresource_redirect
diff --git a/chrome/renderer/subresource_redirect/login_robots_url_loader_throttle_browsertest.cc b/chrome/renderer/subresource_redirect/login_robots_url_loader_throttle_browsertest.cc index 99f8fa6..b9e5fd7 100644 --- a/chrome/renderer/subresource_redirect/login_robots_url_loader_throttle_browsertest.cc +++ b/chrome/renderer/subresource_redirect/login_robots_url_loader_throttle_browsertest.cc
@@ -84,17 +84,13 @@ NOTIMPLEMENTED(); } - void VerifyRedirectResult(RedirectResult expected_result) { - base::HistogramTester histogram_tester; + void VerifyWillProcessResponse() { network::mojom::URLResponseHeadPtr head = network::CreateURLResponseHead(net::HTTP_OK); head->headers->SetHeader("Content-Length", "1024"); bool defer = false; throttle_->WillProcessResponse(GURL("https://foo.com/img.jpg"), head.get(), &defer); - histogram_tester.ExpectUniqueSample( - "SubresourceRedirect.LoginRobotsDeciderAgent.RedirectResult", - expected_result, 1); EXPECT_FALSE(defer); } @@ -150,6 +146,10 @@ blink::PreviewsTypes::SUBRESOURCE_REDIRECT_ON)); } + void SetLoggedInState(bool is_logged_in) { + login_robots_decider_agent_->SetLoggedInState(is_logged_in); + } + protected: void SetUp() override { ChromeRenderViewTest::SetUp(); @@ -163,9 +163,10 @@ &associated_interfaces_, view_->GetMainRenderFrame()); } - private: + protected: LoginRobotsDeciderAgent* login_robots_decider_agent_; base::test::ScopedFeatureList scoped_feature_list_; + base::HistogramTester histogram_tester_; }; TEST_F(SubresourceRedirectLoginRobotsURLLoaderThrottleTest, @@ -221,6 +222,7 @@ TestGetSubresourceURL) { struct TestCase { int previews_state; + bool is_logged_in; std::string original_url; GURL redirected_subresource_url; // Empty URL means there will be no // redirect. @@ -229,17 +231,20 @@ const TestCase kTestCases[]{ { blink::PreviewsTypes::SUBRESOURCE_REDIRECT_ON, + false, "https://www.test.com/public_img.jpg", GetSubresourceURLForURL(GURL("https://www.test.com/public_img.jpg")), }, { blink::PreviewsTypes::SUBRESOURCE_REDIRECT_ON, + false, "https://www.test.com/public_img.jpg#anchor", GetSubresourceURLForURL( GURL("https://www.test.com/public_img.jpg#anchor")), }, { blink::PreviewsTypes::SUBRESOURCE_REDIRECT_ON, + false, "https://www.test.com/public_img.jpg?public_arg1=bar&public_arg2", GetSubresourceURLForURL( GURL("https://www.test.com/" @@ -248,14 +253,23 @@ // Private images will not be redirected. { blink::PreviewsTypes::SUBRESOURCE_REDIRECT_ON, + false, "https://www.test.com/private_img.jpg", GURL(), }, { blink::PreviewsTypes::SUBRESOURCE_REDIRECT_ON, + false, "https://www.test.com/public_img.jpg&private_arg1=foo", GURL(), }, + // No redirection when logged-in + { + blink::PreviewsTypes::SUBRESOURCE_REDIRECT_ON, + true, + "https://www.test.com/public_img.jpg", + GURL(), + }, }; blink::WebNetworkStateNotifier::SetSaveDataEnabled(true); @@ -264,6 +278,7 @@ {kRuleTypeDisallow, ""}}); for (const TestCase& test_case : kTestCases) { + SetLoggedInState(test_case.is_logged_in); auto throttle = CreateLoginRobotsDecider( test_case.original_url, network::mojom::RequestDestination::kImage, test_case.previews_state); @@ -288,6 +303,7 @@ TEST_F(SubresourceRedirectLoginRobotsURLLoaderThrottleTest, TestRobotsRulesSentBeforeThrottle) { blink::WebNetworkStateNotifier::SetSaveDataEnabled(true); + SetLoggedInState(false); SetUpRobotsRules("https://www.test.com", {{kRuleTypeAllow, "/public"}, {kRuleTypeDisallow, ""}}); @@ -296,8 +312,6 @@ CreateURLLoaderThrottleInfo("https://www.test.com/public.jpg"); auto throttle_info2 = CreateURLLoaderThrottleInfo("https://www.test.com/private.jpg"); - throttle_info1->VerifyRedirectResult(RedirectResult::kRedirectable); - throttle_info2->VerifyRedirectResult(RedirectResult::kRedirectable); throttle_info1->SendStartRequestAndVerifyDeferral( WillStartRequestDeferralState::kRedirected); @@ -307,9 +321,14 @@ EXPECT_FALSE(throttle_info2->did_resume()); EXPECT_FALSE(throttle_info1->did_restart_with_url_reset_and_flags()); EXPECT_FALSE(throttle_info2->did_restart_with_url_reset_and_flags()); - throttle_info1->VerifyRedirectResult(RedirectResult::kRedirectable); - throttle_info2->VerifyRedirectResult( - RedirectResult::kIneligibleRobotsDisallowed); + histogram_tester_.ExpectTotalCount( + "SubresourceRedirect.LoginRobotsDeciderAgent.RedirectResult", 2); + histogram_tester_.ExpectBucketCount( + "SubresourceRedirect.LoginRobotsDeciderAgent.RedirectResult", + RedirectResult::kRedirectable, 1); + histogram_tester_.ExpectBucketCount( + "SubresourceRedirect.LoginRobotsDeciderAgent.RedirectResult", + RedirectResult::kIneligibleRobotsDisallowed, 1); } // Tests the cases when robots rules are sent, after throttles are @@ -317,6 +336,7 @@ TEST_F(SubresourceRedirectLoginRobotsURLLoaderThrottleTest, TestRobotsRulesSentAfterThrottle) { blink::WebNetworkStateNotifier::SetSaveDataEnabled(true); + SetLoggedInState(false); auto throttle_info1 = CreateURLLoaderThrottleInfo("https://www.test.com/public.jpg"); @@ -344,15 +364,23 @@ EXPECT_TRUE(throttle_info2->did_restart_with_url_reset_and_flags()); EXPECT_TRUE(throttle_info2->did_resume()); - throttle_info1->VerifyRedirectResult(RedirectResult::kRedirectable); - throttle_info2->VerifyRedirectResult( - RedirectResult::kIneligibleRobotsDisallowed); + throttle_info1->VerifyWillProcessResponse(); + throttle_info2->VerifyWillProcessResponse(); + histogram_tester_.ExpectTotalCount( + "SubresourceRedirect.LoginRobotsDeciderAgent.RedirectResult", 2); + histogram_tester_.ExpectBucketCount( + "SubresourceRedirect.LoginRobotsDeciderAgent.RedirectResult", + RedirectResult::kRedirectable, 1); + histogram_tester_.ExpectBucketCount( + "SubresourceRedirect.LoginRobotsDeciderAgent.RedirectResult", + RedirectResult::kIneligibleRobotsDisallowed, 1); } // Tests the cases when robots rules retrieval timesout. TEST_F(SubresourceRedirectLoginRobotsURLLoaderThrottleTest, TestRobotsRulesTimeout) { blink::WebNetworkStateNotifier::SetSaveDataEnabled(true); + SetLoggedInState(false); auto throttle_info1 = CreateURLLoaderThrottleInfo("https://www.test.com/public.jpg"); @@ -377,10 +405,13 @@ EXPECT_TRUE(throttle_info2->did_restart_with_url_reset_and_flags()); EXPECT_TRUE(throttle_info2->did_resume()); - throttle_info1->VerifyRedirectResult( - RedirectResult::kIneligibleRobotsTimeout); - throttle_info2->VerifyRedirectResult( - RedirectResult::kIneligibleRobotsTimeout); + throttle_info1->VerifyWillProcessResponse(); + throttle_info2->VerifyWillProcessResponse(); + histogram_tester_.ExpectTotalCount( + "SubresourceRedirect.LoginRobotsDeciderAgent.RedirectResult", 2); + histogram_tester_.ExpectBucketCount( + "SubresourceRedirect.LoginRobotsDeciderAgent.RedirectResult", + RedirectResult::kIneligibleRobotsTimeout, 2); } } // namespace subresource_redirect
diff --git a/chrome/renderer/subresource_redirect/public_image_hints_decider_agent.cc b/chrome/renderer/subresource_redirect/public_image_hints_decider_agent.cc index a78fb22..39eee6f 100644 --- a/chrome/renderer/subresource_redirect/public_image_hints_decider_agent.cc +++ b/chrome/renderer/subresource_redirect/public_image_hints_decider_agent.cc
@@ -160,6 +160,7 @@ break; case RedirectResult::kIneligibleRobotsDisallowed: case RedirectResult::kIneligibleRobotsTimeout: + case RedirectResult::kIneligibleLoginDetected: NOTREACHED(); } mojo::PendingRemote<ukm::mojom::UkmRecorderInterface> recorder; @@ -198,4 +199,10 @@ ClearImageHints(); } +void PublicImageHintsDeciderAgent::SetLoggedInState(bool is_logged_in) { + // This mojo from browser process should not be called for public image hints + // based compression. + NOTIMPLEMENTED(); +} + } // namespace subresource_redirect
diff --git a/chrome/renderer/subresource_redirect/public_image_hints_decider_agent.h b/chrome/renderer/subresource_redirect/public_image_hints_decider_agent.h index 27c592a..7c05277 100644 --- a/chrome/renderer/subresource_redirect/public_image_hints_decider_agent.h +++ b/chrome/renderer/subresource_redirect/public_image_hints_decider_agent.h
@@ -42,6 +42,7 @@ // mojom::SubresourceRedirectHintsReceiver: void SetCompressPublicImagesHints( mojom::CompressPublicImagesHintsPtr images_hints) override; + void SetLoggedInState(bool is_logged_in) override; // PublicResourceDeciderAgent: base::Optional<RedirectResult> ShouldRedirectSubresource(
diff --git a/chrome/renderer/subresource_redirect/redirect_result.h b/chrome/renderer/subresource_redirect/redirect_result.h index c0a2b766..b41d438 100644 --- a/chrome/renderer/subresource_redirect/redirect_result.h +++ b/chrome/renderer/subresource_redirect/redirect_result.h
@@ -57,7 +57,10 @@ // Because the robots rules fetch timedout. kIneligibleRobotsTimeout, - kMaxValue = RedirectResult::kIneligibleRobotsTimeout + // Because the page was detected to be logged-in. + kIneligibleLoginDetected, + + kMaxValue = RedirectResult::kIneligibleLoginDetected }; } // namespace subresource_redirect
diff --git a/chrome/renderer/subresource_redirect/robots_rules_parser.cc b/chrome/renderer/subresource_redirect/robots_rules_parser.cc index 0658232a..f8aa4d81 100644 --- a/chrome/renderer/subresource_redirect/robots_rules_parser.cc +++ b/chrome/renderer/subresource_redirect/robots_rules_parser.cc
@@ -126,21 +126,27 @@ } // Respond to the pending requests, even if robots proto parse failed. - for (auto& request : pending_check_requests_) { - std::move(request.first).Run(CheckRobotsRulesImmediate(request.second)); + for (auto& requests : pending_check_requests_) { + for (auto& request : requests.second) { + std::move(request.first).Run(CheckRobotsRulesImmediate(request.second)); + } } pending_check_requests_.clear(); } base::Optional<RobotsRulesParser::CheckResult> -RobotsRulesParser::CheckRobotsRules(const GURL& url, +RobotsRulesParser::CheckRobotsRules(int routing_id, + const GURL& url, CheckResultCallback callback) { std::string path_with_query = url.path(); if (url.has_query()) base::StrAppend(&path_with_query, {"?", url.query()}); if (rules_receive_state_ == RulesReceiveState::kTimerRunning) { DCHECK(rules_receive_timeout_timer_.IsRunning()); - pending_check_requests_.emplace_back( + auto it = pending_check_requests_.insert(std::make_pair( + routing_id, + std::vector<std::pair<CheckResultCallback, std::string>>())); + it.first->second.emplace_back( std::make_pair(std::move(callback), path_with_query)); return base::nullopt; } @@ -172,11 +178,24 @@ void RobotsRulesParser::OnRulesReceiveTimeout() { DCHECK(!rules_receive_timeout_timer_.IsRunning()); rules_receive_state_ = RulesReceiveState::kTimeout; - for (auto& request : pending_check_requests_) - std::move(request.first).Run(CheckResult::kTimedout); + for (auto& requests : pending_check_requests_) { + for (auto& request : requests.second) { + std::move(request.first).Run(CheckResult::kTimedout); + } + } pending_check_requests_.clear(); RecordRobotsRulesReceiveResultHistogram( SubresourceRedirectRobotsRulesReceiveResult::kTimeout); } +void RobotsRulesParser::InvalidatePendingRequests(int routing_id) { + auto it = pending_check_requests_.find(routing_id); + if (it == pending_check_requests_.end()) + return; + for (auto& request : it->second) { + std::move(request.first).Run(CheckResult::kInvalidated); + } + pending_check_requests_.erase(it); +} + } // namespace subresource_redirect
diff --git a/chrome/renderer/subresource_redirect/robots_rules_parser.h b/chrome/renderer/subresource_redirect/robots_rules_parser.h index 5ffa5c7..a350a197 100644 --- a/chrome/renderer/subresource_redirect/robots_rules_parser.h +++ b/chrome/renderer/subresource_redirect/robots_rules_parser.h
@@ -37,6 +37,8 @@ kTimedout, // Timeout in retrieving the robots rules kDisallowedAfterTimeout, // Timeout got triggered already, and the resource // was disallowed + kInvalidated, // The result check was invalidated, before robots rules are + // received or timeout triggered. }; enum class RulesReceiveState { @@ -73,10 +75,16 @@ // added to |pending_check_requests_| and called when a decision can be made // like when rules are retrieved, or rule fetch timeout, etc. // The robots rules check will make use of the |url| path and query - // parameters.The |url| origin, ref fragment, etc are immaterial. - base::Optional<CheckResult> CheckRobotsRules(const GURL& url, + // parameters.The |url| origin, ref fragment, etc are immaterial. |routing_id| + // is the render frame ID for which this URL is requested for. + base::Optional<CheckResult> CheckRobotsRules(int routing_id, + const GURL& url, CheckResultCallback callback); + // Invalidate and cancel the pending requests that were added for + // |routing_id|. + void InvalidatePendingRequests(int routing_id); + private: friend class SubresourceRedirectRobotsRulesParserTest; @@ -107,9 +115,10 @@ // Ordered list of robots rules from longest to shortest. std::vector<RobotsRule> robots_rules_; - // Contains the requests that are pending for robots rules to be received. - // Holds the URL path and the callback. - std::vector<std::pair<CheckResultCallback, std::string>> + // Contains the requests that are pending for robots rules to be received, + // keyed by routing ID. Key is the rouging ID and the value holds the URL path + // and the callback. + std::map<int, std::vector<std::pair<CheckResultCallback, std::string>>> pending_check_requests_; // To trigger the timeout for the robots rules to be received.
diff --git a/chrome/renderer/subresource_redirect/robots_rules_parser_cache.cc b/chrome/renderer/subresource_redirect/robots_rules_parser_cache.cc index e40dd4d..e7d77be5 100644 --- a/chrome/renderer/subresource_redirect/robots_rules_parser_cache.cc +++ b/chrome/renderer/subresource_redirect/robots_rules_parser_cache.cc
@@ -25,10 +25,16 @@ base::Optional<RobotsRulesParser::CheckResult> RobotsRulesParserCache::CheckRobotsRules( + int routing_id, const GURL& url, RobotsRulesParser::CheckResultCallback callback) { return GetRobotsRulesParserForOrigin(url::Origin::Create(url)) - .CheckRobotsRules(url, std::move(callback)); + .CheckRobotsRules(routing_id, url, std::move(callback)); +} + +void RobotsRulesParserCache::InvalidatePendingRequests(int routing_id) { + for (auto& entry : parsers_cache_) + entry.second->InvalidatePendingRequests(routing_id); } RobotsRulesParser& RobotsRulesParserCache::GetRobotsRulesParserForOrigin(
diff --git a/chrome/renderer/subresource_redirect/robots_rules_parser_cache.h b/chrome/renderer/subresource_redirect/robots_rules_parser_cache.h index acf5a1e50..1f0d985 100644 --- a/chrome/renderer/subresource_redirect/robots_rules_parser_cache.h +++ b/chrome/renderer/subresource_redirect/robots_rules_parser_cache.h
@@ -34,9 +34,13 @@ // should be returned and the |callback| will be invoked when the decision was // made. base::Optional<RobotsRulesParser::CheckResult> CheckRobotsRules( + int routing_id, const GURL& url, RobotsRulesParser::CheckResultCallback callback); + // Invalidate and cancel the pending requests for the robots rules parser. + void InvalidatePendingRequests(int routing_id); + private: // Returns a reference to the robots rules parser for the |origin| from the // cache. An entry is created if it does not exist.
diff --git a/chrome/renderer/subresource_redirect/robots_rules_parser_unittest.cc b/chrome/renderer/subresource_redirect/robots_rules_parser_unittest.cc index 3565f3a..8df3d73 100644 --- a/chrome/renderer/subresource_redirect/robots_rules_parser_unittest.cc +++ b/chrome/renderer/subresource_redirect/robots_rules_parser_unittest.cc
@@ -39,6 +39,8 @@ base::WeakPtrFactory<CheckResultReceiver> weak_ptr_factory_{this}; }; +const int kRenderFrameID = 1; + class SubresourceRedirectRobotsRulesParserTest : public testing::Test { public: SubresourceRedirectRobotsRulesParserTest() @@ -56,10 +58,12 @@ // Verify robots rules check result is received synchronously with the // expected result. void CheckRobotsRules(const std::string& url_path_with_query, - RobotsRulesParser::CheckResult expected_result) { + RobotsRulesParser::CheckResult expected_result, + int render_frame_id = kRenderFrameID) { CheckResultReceiver result_receiver; auto result = robots_rules_parser_.CheckRobotsRules( - GURL(kTestOrigin + url_path_with_query), result_receiver.GetCallback()); + render_frame_id, GURL(kTestOrigin + url_path_with_query), + result_receiver.GetCallback()); EXPECT_FALSE(result_receiver.did_receive_result()); EXPECT_EQ(expected_result, result); } @@ -67,10 +71,11 @@ // Verify robots rules check result is received asynchronously, and returns // the receiver that can be used to check the result. std::unique_ptr<CheckResultReceiver> CheckRobotsRulesAsync( - const std::string& url_path_with_query) { + const std::string& url_path_with_query, + int render_frame_id = kRenderFrameID) { auto result_receiver = std::make_unique<CheckResultReceiver>(); EXPECT_FALSE(robots_rules_parser_.CheckRobotsRules( - GURL(kTestOrigin + url_path_with_query), + render_frame_id, GURL(kTestOrigin + url_path_with_query), result_receiver->GetCallback())); return result_receiver; } @@ -196,10 +201,11 @@ auto receiver1 = std::make_unique<CheckResultReceiver>(); auto receiver2 = std::make_unique<CheckResultReceiver>(); - robots_rules_parser->CheckRobotsRules(GURL("https://test.com/foo.jpg"), + robots_rules_parser->CheckRobotsRules(kRenderFrameID, + GURL("https://test.com/foo.jpg"), receiver1->GetCallback()); - robots_rules_parser->CheckRobotsRules(GURL("https://test.com/bar"), - receiver2->GetCallback()); + robots_rules_parser->CheckRobotsRules( + kRenderFrameID, GURL("https://test.com/bar"), receiver2->GetCallback()); EXPECT_FALSE(receiver1->did_receive_result()); EXPECT_FALSE(receiver2->did_receive_result()); VerifyTotalRobotsRulesApplyHistograms(0); @@ -372,4 +378,41 @@ VerifyTotalRobotsRulesApplyHistograms(6); } +TEST_F(SubresourceRedirectRobotsRulesParserTest, + TestInvalidatePendingRequests) { + auto receiver1 = CheckRobotsRulesAsync("/allowed.jpg", 1 /*render_frame_id*/); + auto receiver2 = + CheckRobotsRulesAsync("/disallowed.jpg", 1 /*render_frame_id*/); + auto receiver3 = CheckRobotsRulesAsync("/allowed.jpg", 2 /*render_frame_id*/); + auto receiver4 = + CheckRobotsRulesAsync("/disallowed.jpg", 2 /*render_frame_id*/); + + // Invalidate should cancel requests for that render frame ID. + robots_rules_parser_.InvalidatePendingRequests(1 /*render_frame_id*/); + EXPECT_TRUE(receiver1->did_receive_result()); + EXPECT_TRUE(receiver2->did_receive_result()); + EXPECT_EQ(RobotsRulesParser::CheckResult::kInvalidated, + receiver1->check_result()); + EXPECT_EQ(RobotsRulesParser::CheckResult::kInvalidated, + receiver2->check_result()); + EXPECT_FALSE(receiver3->did_receive_result()); + EXPECT_FALSE(receiver4->did_receive_result()); + VerifyTotalRobotsRulesApplyHistograms(0); + + // When robots rules are retrieved, the + SetUpRobotsRules({{kRuleTypeAllow, "/allow*"}, {kRuleTypeDisallow, "/*"}}); + EXPECT_TRUE(receiver3->did_receive_result()); + EXPECT_TRUE(receiver4->did_receive_result()); + EXPECT_EQ(RobotsRulesParser::CheckResult::kAllowed, + receiver3->check_result()); + EXPECT_EQ(RobotsRulesParser::CheckResult::kDisallowed, + receiver4->check_result()); + VerifyTotalRobotsRulesApplyHistograms(2); + + CheckRobotsRules("/allowed.jpg", RobotsRulesParser::CheckResult::kAllowed); + CheckRobotsRules("/disallowed.jpg", + RobotsRulesParser::CheckResult::kDisallowed); + VerifyTotalRobotsRulesApplyHistograms(4); +} + } // namespace subresource_redirect
diff --git a/chrome/test/base/extension_js_browser_test.cc b/chrome/test/base/extension_js_browser_test.cc index 2c0dedf..8e985fd 100644 --- a/chrome/test/base/extension_js_browser_test.cc +++ b/chrome/test/base/extension_js_browser_test.cc
@@ -19,9 +19,9 @@ ExtensionJSBrowserTest::~ExtensionJSBrowserTest() {} void ExtensionJSBrowserTest::WaitForExtension(const char* extension_id, - const base::Closure& load_cb) { + base::OnceClosure load_cb) { load_waiter_.reset(new ExtensionLoadWaiterOneShot()); - load_waiter_->WaitForExtension(extension_id, load_cb); + load_waiter_->WaitForExtension(extension_id, std::move(load_cb)); } bool ExtensionJSBrowserTest::RunJavascriptTestF(bool is_async,
diff --git a/chrome/test/base/extension_js_browser_test.h b/chrome/test/base/extension_js_browser_test.h index 9380d234..e050e58 100644 --- a/chrome/test/base/extension_js_browser_test.h +++ b/chrome/test/base/extension_js_browser_test.h
@@ -22,7 +22,7 @@ protected: // Waits for an extension to load; returns immediately if already loaded. - void WaitForExtension(const char* extension_id, const base::Closure& load_cb); + void WaitForExtension(const char* extension_id, base::OnceClosure load_cb); // Method required for js2gtest. // Runs |test_fixture|.|test_name| using the framework in test_api.js.
diff --git a/chrome/test/base/extension_load_waiter_one_shot.cc b/chrome/test/base/extension_load_waiter_one_shot.cc index 6f33d7b..e421f59e 100644 --- a/chrome/test/base/extension_load_waiter_one_shot.cc +++ b/chrome/test/base/extension_load_waiter_one_shot.cc
@@ -16,7 +16,7 @@ ExtensionLoadWaiterOneShot::~ExtensionLoadWaiterOneShot() = default; void ExtensionLoadWaiterOneShot::WaitForExtension(const char* extension_id, - const base::Closure& load_cb) { + base::OnceClosure load_cb) { CHECK(!extension_id_) << "ExtensionLoadWaiterOneShot should only be used once."; extension_id_ = extension_id; @@ -24,7 +24,7 @@ registrar_.Add(this, extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_FIRST_LOAD, content::NotificationService::AllSources()); - load_cb.Run(); + std::move(load_cb).Run(); load_looper_->Run(); }
diff --git a/chrome/test/base/extension_load_waiter_one_shot.h b/chrome/test/base/extension_load_waiter_one_shot.h index 7ab89154..cc2646d8 100644 --- a/chrome/test/base/extension_load_waiter_one_shot.h +++ b/chrome/test/base/extension_load_waiter_one_shot.h
@@ -26,7 +26,7 @@ // Waits for extension with |extension_id| to load. The id should be a pointer // to a static char array. - void WaitForExtension(const char* extension_id, const base::Closure& load_cb); + void WaitForExtension(const char* extension_id, base::OnceClosure load_cb); // content::NotificationObserver overrides. void Observe(int type,
diff --git a/chrome/test/data/banners/manifest_not_offline_capable_url.json b/chrome/test/data/banners/manifest_not_offline_capable_url.json new file mode 100644 index 0000000..62a45df --- /dev/null +++ b/chrome/test/data/banners/manifest_not_offline_capable_url.json
@@ -0,0 +1,39 @@ +{ + "name": "Manifest test app with not offline capable start_url", + "icons": [ + { + "src": "launcher-icon-1x.png", + "sizes": "48x48", + "type": "image/png" + }, + { + "src": "launcher-icon-1-5x.png", + "sizes": "72x72", + "type": "image/png" + }, + { + "src": "launcher-icon-2x.png", + "sizes": "96x96", + "type": "image/png", + "purpose": "any monochrome" + }, + { + "src": "launcher-icon-3x.png", + "sizes": "144x144", + "type": "image/png" + }, + { + "src": "launcher-icon-4x.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "image-512px.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "start_url": "manifest_test_page.html?ignore", + "display": "standalone", + "orientation": "landscape" +}
diff --git a/chrome/test/data/pdf/BUILD.gn b/chrome/test/data/pdf/BUILD.gn index de7f52cb..cb5e25e 100644 --- a/chrome/test/data/pdf/BUILD.gn +++ b/chrome/test/data/pdf/BUILD.gn
@@ -146,6 +146,7 @@ js_library("navigator_test") { deps = [ ":test_util", + "../webui:test_browser_proxy.m", "//chrome/browser/resources/pdf:navigator", "//chrome/browser/resources/pdf:open_pdf_params_parser", "//chrome/browser/resources/pdf:pdf_scripting_api",
diff --git a/chrome/test/data/pdf/navigator_test.js b/chrome/test/data/pdf/navigator_test.js index 76cda3f..9d70f39 100644 --- a/chrome/test/data/pdf/navigator_test.js +++ b/chrome/test/data/pdf/navigator_test.js
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestBrowserProxy} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/_test_resources/webui/test_browser_proxy.m.js'; import {NavigatorDelegate, PdfNavigator, WindowOpenDisposition} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/navigator.js'; import {OpenPdfParamsParser} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/open_pdf_params_parser.js'; import {PDFScriptingAPI} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_scripting_api.js'; @@ -9,37 +10,28 @@ import {getZoomableViewport, MockDocumentDimensions, MockElement, MockSizer, MockViewportChangedCallback} from './test_util.js'; /** @implements {NavigatorDelegate} */ -class MockNavigatorDelegate { +class MockNavigatorDelegate extends TestBrowserProxy { constructor() { - this.navigateInCurrentTabCalled = false; - this.navigateInNewTabCalled = false; - this.navigateInNewWindowCalled = false; - this.url = undefined; + super([ + 'navigateInCurrentTab', + 'navigateInNewTab', + 'navigateInNewWindow', + ]); } /** @override */ navigateInCurrentTab(url) { - this.navigateInCurrentTabCalled = true; - this.url = url || '<called, but no url set>'; + this.methodCalled('navigateInCurrentTab', url); } /** @override */ navigateInNewTab(url) { - this.navigateInNewTabCalled = true; - this.url = url || '<called, but no url set>'; + this.methodCalled('navigateInNewTab', url); } /** @override */ navigateInNewWindow(url) { - this.navigateInNewWindowCalled = true; - this.url = url || '<called, but no url set>'; - } - - reset() { - this.navigateInCurrentTabCalled = false; - this.navigateInNewTabCalled = false; - this.navigateInNewWindowCalled = false; - this.url = undefined; + this.methodCalled('navigateInNewWindow', url); } } @@ -62,23 +54,26 @@ navigatorDelegate.reset(); await navigator.navigate(url, disposition); chrome.test.assertFalse(viewportChangedCallback.wasCalled); - chrome.test.assertEq(expectedResultUrl, navigatorDelegate.url); if (expectedResultUrl === undefined) { return; } + + let actualUrl = null; switch (disposition) { case WindowOpenDisposition.CURRENT_TAB: - chrome.test.assertTrue(navigatorDelegate.navigateInCurrentTabCalled); + actualUrl = await navigatorDelegate.whenCalled('navigateInCurrentTab'); break; case WindowOpenDisposition.NEW_BACKGROUND_TAB: - chrome.test.assertTrue(navigatorDelegate.navigateInNewTabCalled); + actualUrl = await navigatorDelegate.whenCalled('navigateInNewTab'); break; case WindowOpenDisposition.NEW_WINDOW: - chrome.test.assertTrue(navigatorDelegate.navigateInNewWindowCalled); + actualUrl = await navigatorDelegate.whenCalled('navigateInNewWindow'); break; default: break; } + + chrome.test.assertEq(expectedResultUrl, actualUrl); } /** @@ -166,7 +161,7 @@ await navigator.navigate( url + '#US', WindowOpenDisposition.NEW_BACKGROUND_TAB); chrome.test.assertFalse(mockCallback.wasCalled); - chrome.test.assertTrue(navigatorDelegate.navigateInNewTabCalled); + await navigatorDelegate.whenCalled('navigateInNewTab'); chrome.test.assertEq(0, viewport.position.x); chrome.test.assertEq(0, viewport.position.y); @@ -184,7 +179,7 @@ // navigating results, as this link will open in the same tab. await navigator.navigate(url + '#ABC', WindowOpenDisposition.CURRENT_TAB); chrome.test.assertFalse(mockCallback.wasCalled); - chrome.test.assertTrue(navigatorDelegate.navigateInCurrentTabCalled); + await navigatorDelegate.whenCalled('navigateInCurrentTab'); chrome.test.assertEq(0, viewport.position.x); chrome.test.assertEq(300, viewport.position.y); chrome.test.succeed();
diff --git a/chrome/test/data/webui/new_tab_page/modules/module_descriptor_test.js b/chrome/test/data/webui/new_tab_page/modules/module_descriptor_test.js new file mode 100644 index 0000000..522288f --- /dev/null +++ b/chrome/test/data/webui/new_tab_page/modules/module_descriptor_test.js
@@ -0,0 +1,51 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {BrowserProxy, ModuleDescriptor} from 'chrome://new-tab-page/new_tab_page.js'; +import {createTestProxy} from 'chrome://test/new_tab_page/test_support.js'; + +suite('NewTabPageModulesModuleDescriptorTest', () => { + /** + * @implements {BrowserProxy} + * @extends {TestBrowserProxy} + */ + let testProxy; + + setup(() => { + PolymerTest.clearBody(); + testProxy = createTestProxy(); + BrowserProxy.instance_ = testProxy; + }); + + test('instantiate module with data', async () => { + // Arrange. + const element = document.createElement('div'); + const moduleDescriptor = + new ModuleDescriptor('foo', 100, () => Promise.resolve(element)); + testProxy.setResultFor('now', 123); + + // Act. + await moduleDescriptor.initialize(); + + // Assert. + assertEquals(element, moduleDescriptor.element); + const [id, now] = await testProxy.handler.whenCalled('onModuleLoaded'); + assertEquals(1, testProxy.handler.getCallCount('onModuleLoaded')); + assertEquals('foo', id); + assertEquals(123, now); + }); + + test('instantiate module without data', async () => { + // Arrange. + const moduleDescriptor = + new ModuleDescriptor('foo', 100, () => Promise.resolve(null)); + + // Act. + await moduleDescriptor.initialize(); + + // Assert. + assertEquals(null, moduleDescriptor.element); + assertEquals(0, testProxy.handler.getCallCount('onModuleLoaded')); + }); +});
diff --git a/chrome/test/data/webui/new_tab_page/new_tab_page_browsertest.js b/chrome/test/data/webui/new_tab_page/new_tab_page_browsertest.js index 6719105..5af4594 100644 --- a/chrome/test/data/webui/new_tab_page/new_tab_page_browsertest.js +++ b/chrome/test/data/webui/new_tab_page/new_tab_page_browsertest.js
@@ -196,6 +196,19 @@ }); // eslint-disable-next-line no-var +var NewTabPageModulesModuleDescriptorTest = + class extends NewTabPageBrowserTest { + /** @override */ + get browsePreload() { + return 'chrome://new-tab-page/test_loader.html?module=new_tab_page/modules/module_descriptor_test.js'; + } +}; + +TEST_F('NewTabPageModulesModuleDescriptorTest', 'All', function() { + mocha.run(); +}); + +// eslint-disable-next-line no-var var NewTabPageModulesModuleRegistryTest = class extends NewTabPageBrowserTest { /** @override */ get browsePreload() {
diff --git a/chrome/test/data/webui/settings/chromeos/multidevice_notification_access_setup_dialog_tests.js b/chrome/test/data/webui/settings/chromeos/multidevice_notification_access_setup_dialog_tests.js index b8bef55..b96e135 100644 --- a/chrome/test/data/webui/settings/chromeos/multidevice_notification_access_setup_dialog_tests.js +++ b/chrome/test/data/webui/settings/chromeos/multidevice_notification_access_setup_dialog_tests.js
@@ -82,6 +82,7 @@ assertFalse(!!buttonContainer.querySelector('#doneButton')); assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); + assertEquals(browserProxy.getCallCount('setFeatureEnabledState'), 0); simulateStatusChanged( NotificationAccessSetupOperationStatus.COMPLETED_SUCCESSFULLY); assertFalse(isSetupInstructionsShownSeparately()); @@ -90,6 +91,10 @@ assertTrue(!!buttonContainer.querySelector('#doneButton')); assertFalse(!!buttonContainer.querySelector('#tryAgainButton')); + // The feature becomes enabled when the status becomes + // NotificationAccessSetupOperationStatus.COMPLETED_SUCCESSFULLY. + assertEquals(browserProxy.getCallCount('setFeatureEnabledState'), 1); + assertTrue(notificationAccessSetupDialog.$$('#dialog').open); buttonContainer.querySelector('#doneButton').click(); assertFalse(notificationAccessSetupDialog.$$('#dialog').open);
diff --git a/chrome/test/data/webui/settings/safety_check_chrome_cleaner_test.js b/chrome/test/data/webui/settings/safety_check_chrome_cleaner_test.js index e27e367..fa4b3cc2 100644 --- a/chrome/test/data/webui/settings/safety_check_chrome_cleaner_test.js +++ b/chrome/test/data/webui/settings/safety_check_chrome_cleaner_test.js
@@ -168,8 +168,7 @@ // User clicks the button. page.$$('#safetyCheckChild').$$('#button').click(); await expectLogging( - SafetyCheckInteractions - .SAFETY_CHECK_CHROME_CLEANER_REVIEW_INFECTED_STATE, + SafetyCheckInteractions.CHROME_CLEANER_REVIEW_INFECTED_STATE, 'Settings.SafetyCheck.ChromeCleanerReviewInfectedState'); // Ensure the correct Settings page is shown. assertEquals(routes.CHROME_CLEANUP, Router.getInstance().getCurrentRoute()); @@ -190,7 +189,7 @@ // User clicks the button. page.$$('#safetyCheckChild').$$('#button').click(); await expectLogging( - SafetyCheckInteractions.SAFETY_CHECK_CHROME_CLEANER_REBOOT, + SafetyCheckInteractions.CHROME_CLEANER_REBOOT, 'Settings.SafetyCheck.ChromeCleanerReboot'); // Ensure the browser proxy call is done. return chromeCleanupBrowserProxy.whenCalled('restartComputer'); @@ -210,7 +209,7 @@ page.$$('#safetyCheckChild').click(); // Ensure UMA is logged. await expectLogging( - SafetyCheckInteractions.SAFETY_CHECK_CHROME_CLEANER_CARET_NAVIGATION, + SafetyCheckInteractions.CHROME_CLEANER_CARET_NAVIGATION, 'Settings.SafetyCheck.ChromeCleanerCaretNavigation'); // Ensure the correct Settings page is shown. assertEquals(routes.CHROME_CLEANUP, Router.getInstance().getCurrentRoute()); @@ -230,7 +229,7 @@ page.$$('#safetyCheckChild').click(); // Ensure UMA is logged. await expectLogging( - SafetyCheckInteractions.SAFETY_CHECK_CHROME_CLEANER_CARET_NAVIGATION, + SafetyCheckInteractions.CHROME_CLEANER_CARET_NAVIGATION, 'Settings.SafetyCheck.ChromeCleanerCaretNavigation'); // Ensure the correct Settings page is shown. assertEquals(routes.CHROME_CLEANUP, Router.getInstance().getCurrentRoute()); @@ -261,7 +260,7 @@ page.$$('#safetyCheckChild').click(); // Ensure UMA is logged. await expectLogging( - SafetyCheckInteractions.SAFETY_CHECK_CHROME_CLEANER_CARET_NAVIGATION, + SafetyCheckInteractions.CHROME_CLEANER_CARET_NAVIGATION, 'Settings.SafetyCheck.ChromeCleanerCaretNavigation'); // Ensure the correct Settings page is shown. assertEquals(routes.CHROME_CLEANUP, Router.getInstance().getCurrentRoute()); @@ -281,7 +280,7 @@ page.$$('#safetyCheckChild').click(); // Ensure UMA is logged. await expectLogging( - SafetyCheckInteractions.SAFETY_CHECK_CHROME_CLEANER_CARET_NAVIGATION, + SafetyCheckInteractions.CHROME_CLEANER_CARET_NAVIGATION, 'Settings.SafetyCheck.ChromeCleanerCaretNavigation'); // Ensure the correct Settings page is shown. assertEquals(routes.CHROME_CLEANUP, Router.getInstance().getCurrentRoute()); @@ -301,7 +300,7 @@ page.$$('#safetyCheckChild').click(); // Ensure UMA is logged. await expectLogging( - SafetyCheckInteractions.SAFETY_CHECK_CHROME_CLEANER_CARET_NAVIGATION, + SafetyCheckInteractions.CHROME_CLEANER_CARET_NAVIGATION, 'Settings.SafetyCheck.ChromeCleanerCaretNavigation'); // Ensure the correct Settings page is shown. assertEquals(routes.CHROME_CLEANUP, Router.getInstance().getCurrentRoute());
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 9746a906..d269550 100644 --- a/chrome/test/data/webui/settings/safety_check_page_test.js +++ b/chrome/test/data/webui/settings/safety_check_page_test.js
@@ -204,7 +204,7 @@ page.$$('#safetyCheckParentButton').click(); // Ensure UMA is logged. assertEquals( - SafetyCheckInteractions.SAFETY_CHECK_START, + SafetyCheckInteractions.RUN_SAFETY_CHECK, await metricsBrowserProxy.whenCalled( 'recordSafetyCheckInteractionHistogram')); assertEquals( @@ -472,7 +472,7 @@ page.$$('#safetyCheckChild').$$('#button').click(); // Ensure UMA is logged. assertEquals( - SafetyCheckInteractions.SAFETY_CHECK_UPDATES_RELAUNCH, + SafetyCheckInteractions.UPDATES_RELAUNCH, await metricsBrowserProxy.whenCalled( 'recordSafetyCheckInteractionHistogram')); assertEquals( @@ -571,8 +571,7 @@ page.$$('#safetyCheckChild').click(); // Ensure UMA is logged. assertEquals( - SafetyCheckInteractions - .SAFETY_CHECK_PASSWORDS_MANAGE_THROUGH_CARET_NAVIGATION, + SafetyCheckInteractions.PASSWORDS_CARET_NAVIGATION, await metricsBrowserProxy.whenCalled( 'recordSafetyCheckInteractionHistogram')); assertEquals( @@ -602,7 +601,7 @@ page.$$('#safetyCheckChild').$$('#button').click(); // Ensure UMA is logged. assertEquals( - SafetyCheckInteractions.SAFETY_CHECK_PASSWORDS_MANAGE, + SafetyCheckInteractions.PASSWORDS_MANAGE_COMPROMISED_PASSWORDS, await metricsBrowserProxy.whenCalled( 'recordSafetyCheckInteractionHistogram')); assertEquals( @@ -619,6 +618,32 @@ PasswordManagerProxy.PasswordCheckReferrer.SAFETY_CHECK, referrer); }); + test('passwordWeakUiTest', async function() { + fireSafetyCheckPasswordsEvent( + SafetyCheckPasswordsStatus.WEAK_PASSWORDS_EXIST); + flush(); + assertSafetyCheckChild({ + page: page, + iconStatus: SafetyCheckIconStatus.INFO, + label: 'Passwords', + rowClickable: true, + }); + + // User clicks the manage passwords button. + page.$$('#safetyCheckChild').click(); + // Ensure UMA is logged. + assertEquals( + SafetyCheckInteractions.PASSWORDS_MANAGE_WEAK_PASSWORDS, + await metricsBrowserProxy.whenCalled( + 'recordSafetyCheckInteractionHistogram')); + assertEquals( + 'Settings.SafetyCheck.ManageWeakPasswords', + await metricsBrowserProxy.whenCalled('recordAction')); + // Ensure the correct Settings page is shown. + assertEquals( + routes.CHECK_PASSWORDS, Router.getInstance().getCurrentRoute()); + }); + test('passwordInfoStatesUiTest', function() { // Iterate over all states for (const state of Object.values(SafetyCheckPasswordsStatus)) { @@ -639,7 +664,6 @@ break; case SafetyCheckPasswordsStatus.QUOTA_LIMIT: case SafetyCheckPasswordsStatus.ERROR: - case SafetyCheckPasswordsStatus.WEAK_PASSWORDS_EXIST: assertSafetyCheckChild({ page: page, iconStatus: SafetyCheckIconStatus.INFO, @@ -703,8 +727,7 @@ page.$$('#safetyCheckChild').click(); // Ensure UMA is logged. assertEquals( - SafetyCheckInteractions - .SAFETY_CHECK_SAFE_BROWSING_MANAGE_THROUGH_CARET_NAVIGATION, + SafetyCheckInteractions.SAFE_BROWSING_CARET_NAVIGATION, await metricsBrowserProxy.whenCalled( 'recordSafetyCheckInteractionHistogram')); assertEquals( @@ -754,7 +777,7 @@ page.$$('#safetyCheckChild').$$('#button').click(); // Ensure UMA is logged. assertEquals( - SafetyCheckInteractions.SAFETY_CHECK_SAFE_BROWSING_MANAGE, + SafetyCheckInteractions.SAFE_BROWSING_MANAGE, await metricsBrowserProxy.whenCalled( 'recordSafetyCheckInteractionHistogram')); assertEquals( @@ -824,7 +847,7 @@ page.$$('#safetyCheckChild').$$('#button').click(); // Ensure UMA is logged. assertEquals( - SafetyCheckInteractions.SAFETY_CHECK_EXTENSIONS_REVIEW, + SafetyCheckInteractions.EXTENSIONS_REVIEW, await metricsBrowserProxy.whenCalled( 'recordSafetyCheckInteractionHistogram')); assertEquals( @@ -871,8 +894,7 @@ page.$$('#safetyCheckChild').click(); // Ensure UMA is logged. assertEquals( - SafetyCheckInteractions - .SAFETY_CHECK_EXTENSIONS_REVIEW_THROUGH_CARET_NAVIGATION, + SafetyCheckInteractions.EXTENSIONS_CARET_NAVIGATION, await metricsBrowserProxy.whenCalled( 'recordSafetyCheckInteractionHistogram')); assertEquals(
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 7aef9b5..1ff8f7a 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -13718.0.0 \ No newline at end of file +13719.0.0 \ No newline at end of file
diff --git a/chromeos/components/help_app_ui/BUILD.gn b/chromeos/components/help_app_ui/BUILD.gn index b888e97..e6392cf 100644 --- a/chromeos/components/help_app_ui/BUILD.gn +++ b/chromeos/components/help_app_ui/BUILD.gn
@@ -133,6 +133,7 @@ js_library("test_driver_js") { testonly = true sources = [ "test/driver.js" ] + externs_list = [ "//third_party/chaijs/externs/chai-3.5.js" ] deps = [ ":test_driver_api_js", "//chromeos/components/help_app_ui/resources:browser_proxy",
diff --git a/chromeos/components/help_app_ui/resources/browser_proxy.js b/chromeos/components/help_app_ui/resources/browser_proxy.js index ca0b96b..32ff8bc 100644 --- a/chromeos/components/help_app_ui/resources/browser_proxy.js +++ b/chromeos/components/help_app_ui/resources/browser_proxy.js
@@ -37,6 +37,7 @@ const TITLE_ID = 'title'; const BODY_ID = 'body'; const CATEGORY_ID = 'main-category'; +const SUBCATEGORY_ID = 'subcategory'; const SUBHEADING_ID = 'subheading'; /** @@ -79,9 +80,17 @@ weight: 0.1, }, ]; + if (searchable_item.subcategoryNames) { + for (let i = 0; i < searchable_item.subcategoryNames.length; ++i) { + contents.push({ + id: SUBCATEGORY_ID + i, + content: toString16(searchable_item.subcategoryNames[i]), + weight: 0.1, + }); + } + } // If there are subheadings, use those instead of the body. - if (searchable_item.subheadings - && searchable_item.subheadings.length > 0) { + if (searchable_item.subheadings) { for (let i = 0; i < searchable_item.subheadings.length; ++i) { contents.push({ id: SUBHEADING_ID + i,
diff --git a/chromeos/components/help_app_ui/test/help_app_guest_ui_browsertest.js b/chromeos/components/help_app_ui/test/help_app_guest_ui_browsertest.js index d4a1725a..244f094 100644 --- a/chromeos/components/help_app_ui/test/help_app_guest_ui_browsertest.js +++ b/chromeos/components/help_app_ui/test/help_app_guest_ui_browsertest.js
@@ -98,6 +98,72 @@ ]); }); +// Test that search works for the categories and subcategories of searchable +// items. +GUEST_TEST('GuestCanSearchWithCategories', async () => { + const delegate = await waitForInitialIndexUpdate(); + + await delegate.addOrUpdateSearchIndex([{ + // Main category match. No subcategories. + id: 'test-id-1', + title: 'Title with of article', + body: 'Body text', + mainCategoryName: 'Verycomplicatedsearchtoken', + locale: 'en-US', + },{ + // Subcategory match. + id: 'test-id-2', + title: 'Title 2', + subcategoryNames: [ + 'Subcategory 1', + 'verycomplicatedsearchtoken in subcategory. Verycomplicatedsearchtoken', + 'Another subcategory with verycomplicatedsearchtoken', + ], + body: 'Body text', + mainCategoryName: 'Help', + locale: 'en-US', + },{ + // Should not appear in the results. + id: 'test-id-3', + title: 'Title of irrelevant article', + body: 'Body text', + mainCategoryName: 'Help', + locale: 'en-US', + }]); + + // Keep polling until the index finishes updating or too much time has passed. + /** @type {?helpApp.FindResponse} */ + let response = null; + for (let numTries = 0; numTries < 50; numTries++) { + // This search query was chosen because it is unlikely to show any search + // results for the real app's data. + response = await delegate.findInSearchIndex('verycomplicatedsearchtoken'); + if (response && response.results && response.results.length > 0) break; + await new Promise(resolve => {setTimeout(resolve, 50)}); + } + + // Don't test the ordering of search results because they should have similar + // relevance. + chai.expect(response.results).to.have.deep.members([ + // This result only matches on the main category. + { + id: 'test-id-1', + titlePositions: [], + subheadingIndex: null, + subheadingPositions: null, + bodyPositions: [], + }, + // This result only matches on the second and third subcategories. + { + id: 'test-id-2', + titlePositions: [], + subheadingIndex: null, + subheadingPositions: null, + bodyPositions: [], + }, + ]); +}); + // Test that the guest frame can clear the search index. GUEST_TEST('GuestCanClearSearchIndex', async () => { const delegate = await waitForInitialIndexUpdate();
diff --git a/chromeos/components/help_app_ui/test/help_app_ui_browsertest.js b/chromeos/components/help_app_ui/test/help_app_ui_browsertest.js index e219c01..aadfe4b5 100644 --- a/chromeos/components/help_app_ui/test/help_app_ui_browsertest.js +++ b/chromeos/components/help_app_ui/test/help_app_ui_browsertest.js
@@ -84,6 +84,11 @@ testDone(); }); +TEST_F('HelpAppUIBrowserTest', 'GuestCanSearchWithCategories', async () => { + await runTestInGuest('GuestCanSearchWithCategories'); + testDone(); +}); + TEST_F('HelpAppUIBrowserTest', 'GuestCanClearSearchIndex', async () => { await runTestInGuest('GuestCanClearSearchIndex'); testDone();
diff --git a/chromeos/crosapi/mojom/crosapi.mojom b/chromeos/crosapi/mojom/crosapi.mojom index ebdb116..cdc6005 100644 --- a/chromeos/crosapi/mojom/crosapi.mojom +++ b/chromeos/crosapi/mojom/crosapi.mojom
@@ -215,7 +215,7 @@ // If ash-chrome is newer than lacros-chrome, then some fields may not be // processed by lacros-chrome. // -// Next version: 11 +// Next version: 12 [Stable] struct LacrosInitParams { // This is ash-chrome's version of the AshChromeService interface. This is @@ -282,6 +282,14 @@ // Do not use this to construct paths, use DefaultPaths for that purpose. [MinVersion=10] string? cros_user_id_hash@10; + + // Policy blob of the device account. If present, it's a managed account with + // policy data. If empty, it's unmanaged account. If absent, an error occurred + // while loading policy data. The format is serialized PolicyFetchResponse + // object. See components/policy/proto/device_management_backend.proto for + // details. + [MinVersion=11] + array<uint8>? device_account_policy@11; }; // LacrosChromeService defines the APIs that live in lacros-chrome and
diff --git a/chromeos/dbus/hermes/fake_hermes_manager_client.cc b/chromeos/dbus/hermes/fake_hermes_manager_client.cc index 991f8a7..610a7fd 100644 --- a/chromeos/dbus/hermes/fake_hermes_manager_client.cc +++ b/chromeos/dbus/hermes/fake_hermes_manager_client.cc
@@ -88,6 +88,9 @@ euicc_client_test->AddFakeCarrierProfile(dbus::ObjectPath(kDefaultEuiccPath), hermes::profile::State::kInactive, ""); + euicc_client_test->AddFakeCarrierProfile(dbus::ObjectPath(kDefaultEuiccPath), + hermes::profile::State::kPending, + ""); } void FakeHermesManagerClient::NotifyAvailableEuiccListChanged() {
diff --git a/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillManagerWrapper.java b/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillManagerWrapper.java index 21215e7c..63ecfa7 100644 --- a/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillManagerWrapper.java +++ b/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillManagerWrapper.java
@@ -5,6 +5,7 @@ package org.chromium.components.autofill; import android.annotation.TargetApi; +import android.content.ComponentName; import android.content.Context; import android.graphics.Rect; import android.os.Build; @@ -29,7 +30,8 @@ // NOTE: As a result of the above, the tag below still references the name of this class from // when it was originally developed specifically for Android WebView. public static final String TAG = "AwAutofillManager"; - + private static final String AWG_COMPONENT_NAME = + "com.google.android.gms/com.google.android.gms.autofill.service.AutofillService"; /** * The observer of suggestion window. */ @@ -58,17 +60,32 @@ private boolean mDestroyed; private boolean mDisabled; private ArrayList<WeakReference<InputUIObserver>> mInputUIObservers; + // Indicates if AwG is the current Android autofill service. + private final boolean mIsAwGCurrentAutofillService; public AutofillManagerWrapper(Context context) { updateLogStat(); if (isLoggable()) log("constructor"); mAutofillManager = context.getSystemService(AutofillManager.class); mDisabled = mAutofillManager == null || !mAutofillManager.isEnabled(); + if (mDisabled) { + mIsAwGCurrentAutofillService = false; if (isLoggable()) log("disabled"); return; } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + ComponentName componentName = mAutofillManager.getAutofillServiceComponentName(); + if (componentName != null) { + mIsAwGCurrentAutofillService = + AWG_COMPONENT_NAME.equals(componentName.flattenToString()); + } else { + mIsAwGCurrentAutofillService = false; + } + } else { + mIsAwGCurrentAutofillService = false; + } mMonitor = new AutofillInputUIMonitor(this); mAutofillManager.registerCallback(mMonitor); } @@ -142,6 +159,14 @@ return mDisabled; } + /** + * Only work for Android P and beyond. Always return false for Android O. + * @return if the Autofill with Google is the current autofill service. + */ + public boolean isAwGCurrentAutofillService() { + return mIsAwGCurrentAutofillService; + } + private boolean checkAndWarnIfDestroyed() { if (mDestroyed) { Log.w(TAG, "Application attempted to call on a destroyed AutofillManagerWrapper",
diff --git a/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillProvider.java b/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillProvider.java index 6326536..df54e7c 100644 --- a/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillProvider.java +++ b/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillProvider.java
@@ -319,7 +319,7 @@ assert Build.VERSION.SDK_INT >= Build.VERSION_CODES.O; mAutofillManager = manager; mContainerView = containerView; - mAutofillUMA = new AutofillProviderUMA(context); + mAutofillUMA = new AutofillProviderUMA(context, manager.isAwGCurrentAutofillService()); mInputUIObserver = new AutofillManagerWrapper.InputUIObserver() { @Override public void onInputUIShown() { @@ -440,6 +440,9 @@ int virtualId = mRequest.getVirtualId((short) focus); notifyVirtualViewEntered(mContainerView, virtualId, absBound); mAutofillUMA.onSessionStarted(mAutofillManager.isDisabled()); + if (hasServerPrediction) { + mAutofillUMA.onServerTypeAvailable(formData, /*afterSessionStarted=*/false); + } mAutofillTriggeredTimeMillis = System.currentTimeMillis(); mAutofillManager.notifyNewSessionStarted(); @@ -756,10 +759,12 @@ @CalledByNative private void onQueryDone(boolean success) { mRequest.onQueryDone(success); + mAutofillUMA.onServerTypeAvailable( + success ? mRequest.mFormData : null, /*afterSessionStarted*/ true); mAutofillManager.onQueryDone(success); } - private static boolean isQueryServerFieldTypesEnabled() { + public static boolean isQueryServerFieldTypesEnabled() { if (sIsQueryServerFieldTypesEnabled == null) { sIsQueryServerFieldTypesEnabled = AutofillProviderJni.get().isQueryServerFieldTypesEnabled();
diff --git a/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillProviderUMA.java b/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillProviderUMA.java index 394cd84..3f4ea07 100644 --- a/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillProviderUMA.java +++ b/components/autofill/android/provider/java/src/org/chromium/components/autofill/AutofillProviderUMA.java
@@ -5,6 +5,7 @@ package org.chromium.components.autofill; import android.content.Context; +import android.os.Build; import org.chromium.autofill.mojom.SubmissionSource; import org.chromium.base.ContextUtils; @@ -26,6 +27,10 @@ public static final String UMA_AUTOFILL_CREATED_BY_ACTIVITY_CONTEXT = "Autofill.WebView.CreatedByActivityContext"; + // Records whether the current autofill service is AwG. + public static final String UMA_AUTOFILL_AWG_IS_CURRENT_SERVICE = + "Autofill.WebView.AwGIsCurrentService"; + // Records what happened in an autofill session. public static final String UMA_AUTOFILL_AUTOFILL_SESSION = "Autofill.WebView.AutofillSession"; // The possible value of UMA_AUTOFILL_AUTOFILL_SESSION. @@ -45,6 +50,25 @@ public static final int USER_NOT_SELECT_SUGGESTION_USER_NOT_CHANGE_FORM_NO_FORM_SUBMITTED = 13; public static final int AUTOFILL_SESSION_HISTOGRAM_COUNT = 14; + // The possible values for the server prediction availability. + public static final String UMA_AUTOFILL_SERVER_PREDICTION_AVAILABILITY = + "Autofill.WebView.ServerPredicton.PredictionAvailability"; + public static final int SERVER_PREDICTION_NOT_AVAILABLE = 0; + public static final int SERVER_PREDICTION_AVAILABLE_ON_SESSION_STARTS = 1; + public static final int SERVER_PREDICTION_AVAILABLE_AFTER_SESSION_STARTS = 2; + public static final int SERVER_PREDICTION_AVAILABLE_COUNT = 3; + + // The possible values for the AwG suggestion availability. + public static final String UMA_AUTOFILL_AWG_SUGGSTION_AVAILABILITY = + "Autofill.WebView.ServerPrediction.AwGSuggestionAvailability"; + public static final int AWG_NO_SUGGESTION = 0; + public static final int AWG_HAS_SUGGESTION_NO_AUTOFILL = 1; + public static final int AWG_HAS_SUGGESTION_AUTOFILLED = 2; + public static final int AWG_SUGGSTION_AVAILABLE_COUNT = 3; + + public static final String UMA_AUTOFILL_VALID_SERVER_PREDICTION = + "Autofill.WebView.ServerPredicton.HasValidServerPrediction"; + // Records whether user changed autofilled field if user ever changed the form. The action isn't // recorded if user didn't change form at all. public static final String UMA_AUTOFILL_USER_CHANGED_AUTOFILLED_FIELD = @@ -120,6 +144,31 @@ if (mSuggestionTimeMillis != null) { recordTimesHistogram(UMA_AUTOFILL_SUGGESTION_TIME, mSuggestionTimeMillis); } + if (!mServerPredictionAvailable && AutofillProvider.isQueryServerFieldTypesEnabled()) { + RecordHistogram.recordEnumeratedHistogram( + UMA_AUTOFILL_SERVER_PREDICTION_AVAILABILITY, + SERVER_PREDICTION_NOT_AVAILABLE, SERVER_PREDICTION_AVAILABLE_COUNT); + } + } + + public void onServerTypeAvailable(FormData formData, boolean afterSessionStarted) { + if (!AutofillProvider.isQueryServerFieldTypesEnabled()) return; + mServerPredictionAvailable = true; + RecordHistogram.recordEnumeratedHistogram(UMA_AUTOFILL_SERVER_PREDICTION_AVAILABILITY, + afterSessionStarted ? SERVER_PREDICTION_AVAILABLE_AFTER_SESSION_STARTS + : SERVER_PREDICTION_AVAILABLE_ON_SESSION_STARTS, + SERVER_PREDICTION_AVAILABLE_COUNT); + if (formData != null) { + boolean hasValidServerData = false; + for (FormFieldData fieldData : formData.mFields) { + if (!fieldData.getServerType().equals("NO_SERVER_DATA")) { + hasValidServerData = true; + break; + } + } + RecordHistogram.recordBooleanHistogram( + UMA_AUTOFILL_VALID_SERVER_PREDICTION, hasValidServerData); + } } private int toUMAAutofillSessionValue() { @@ -174,19 +223,62 @@ private int mState; private Boolean mUserChangedAutofilledField; + + // Indicates whether the server prediction arrives. + private boolean mServerPredictionAvailable; + } + + /** + * The class to record Autofill.WebView.ServerPrediction.AwGSuggestion, is only instantiated + * when the Android platform AutofillServcie is AwG, This will give us more actual result in + * A/B experiment while only AwG supports the server prediction. + */ + private static class ServerPredictionRecorder { + private boolean mHasSuggestions; + private boolean mAutofilled; + private boolean mRecorded; + + public void onSuggestionDisplayed() { + mHasSuggestions = true; + } + + public void onAutofill() { + mAutofilled = true; + } + + public void recordHistograms() { + if (mRecorded) return; + mRecorded = true; + int sample = AWG_NO_SUGGESTION; + if (mHasSuggestions) { + sample = mAutofilled ? AWG_HAS_SUGGESTION_AUTOFILLED + : AWG_HAS_SUGGESTION_NO_AUTOFILL; + } + RecordHistogram.recordEnumeratedHistogram( + UMA_AUTOFILL_AWG_SUGGSTION_AVAILABILITY, sample, AWG_SUGGSTION_AVAILABLE_COUNT); + } } private SessionRecorder mRecorder; private Boolean mAutofillDisabled; - public AutofillProviderUMA(Context context) { + private final boolean mIsAwGCurrentAutofillService; + private ServerPredictionRecorder mServerPredictionRecorder; + + public AutofillProviderUMA(Context context, boolean isAwGCurrentAutofillService) { RecordHistogram.recordBooleanHistogram(UMA_AUTOFILL_CREATED_BY_ACTIVITY_CONTEXT, ContextUtils.activityFromContext(context) != null); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + RecordHistogram.recordBooleanHistogram( + UMA_AUTOFILL_AWG_IS_CURRENT_SERVICE, isAwGCurrentAutofillService); + } + mIsAwGCurrentAutofillService = isAwGCurrentAutofillService; } public void onFormSubmitted(int submissionSource) { if (mRecorder != null) mRecorder.record(SessionRecorder.EVENT_FORM_SUBMITTED); recordSession(); + if (mServerPredictionRecorder != null) mServerPredictionRecorder.recordHistograms(); // We record this no matter autofill service is disabled or not. RecordHistogram.recordEnumeratedHistogram(UMA_AUTOFILL_SUBMISSION_SOURCE, toUMASubmissionSource(submissionSource), SUBMISSION_SOURCE_HISTOGRAM_COUNT); @@ -201,6 +293,9 @@ if (mRecorder != null) recordSession(); mRecorder = new SessionRecorder(); + if (mIsAwGCurrentAutofillService) { + mServerPredictionRecorder = new ServerPredictionRecorder(); + } } public void onVirtualStructureProvided() { @@ -212,10 +307,12 @@ mRecorder.record(SessionRecorder.EVENT_SUGGESTION_DISPLAYED); mRecorder.setSuggestionTimeMillis(suggestionTimeMillis); } + if (mServerPredictionRecorder != null) mServerPredictionRecorder.onSuggestionDisplayed(); } public void onAutofill() { if (mRecorder != null) mRecorder.record(SessionRecorder.EVENT_FORM_AUTOFILLED); + if (mServerPredictionRecorder != null) mServerPredictionRecorder.onAutofill(); } public void onUserChangeFieldValue(boolean isPreviouslyAutofilled) { @@ -227,6 +324,17 @@ } } + /** + * Invoked when the server query was done or has arrived when the autofill sension starts. + * + * @param formData the form of the current session, is null if the query failed. + * @param afterSessionStarted true if the server type predication arrive after the session + * starts. + */ + public void onServerTypeAvailable(FormData formData, boolean afterSessionStarted) { + mRecorder.onServerTypeAvailable(formData, afterSessionStarted); + } + private void recordSession() { if (mAutofillDisabled != null && !mAutofillDisabled.booleanValue() && mRecorder != null) { mRecorder.recordHistogram();
diff --git a/components/autofill/android/provider/test_support/autofill_provider_test_helper.cc b/components/autofill/android/provider/test_support/autofill_provider_test_helper.cc index 080ee9a..a5d2e44d 100644 --- a/components/autofill/android/provider/test_support/autofill_provider_test_helper.cc +++ b/components/autofill/android/provider/test_support/autofill_provider_test_helper.cc
@@ -71,9 +71,10 @@ } if (found_fields_count > 0) { signatures = autofill::test::GetEncodedSignatures(*(j.second)); - CHECK(found_fields_count == field_ids.size()); + break; } } + CHECK(found_fields_count == field_ids.size()); std::string response_string; CHECK(response.SerializeToString(&response_string));
diff --git a/components/autofill_assistant/browser/details.cc b/components/autofill_assistant/browser/details.cc index d864f63..bf5ba0c 100644 --- a/components/autofill_assistant/browser/details.cc +++ b/components/autofill_assistant/browser/details.cc
@@ -253,10 +253,9 @@ if (show_initial.value_or("true") == "false") { return false; } - // Whenever details are updated from parameters we want to animate missing - // data. - proto_.set_animate_placeholders(true); - proto_.set_show_image_placeholder(true); + // Whenever details are updated from parameters we want to show a placeholder + // for the image. + proto_.mutable_placeholders()->set_show_image_placeholder(true); if (MaybeUpdateFromDetailsParameters(context)) { Update(); return true; @@ -370,10 +369,6 @@ return proto_.title(); } -int Details::titleMaxLines() const { - return title_max_lines_; -} - const std::string Details::imageUrl() const { return proto_.image_url(); } @@ -405,10 +400,6 @@ return proto_.image_clickthrough_data().clickthrough_url(); } -bool Details::showImagePlaceholder() const { - return proto_.show_image_placeholder(); -} - const std::string Details::totalPriceLabel() const { return proto_.total_price_label(); } @@ -453,8 +444,8 @@ return change_flags_.highlight_line3(); } -bool Details::animatePlaceholders() const { - return proto_.animate_placeholders(); +DetailsProto::PlaceholdersConfiguration Details::placeholders() const { + return proto_.placeholders(); } void Details::ClearChanges() { @@ -473,16 +464,6 @@ price_attribution_content_.assign(proto_.total_price().empty() ? std::string() : proto_.description_line_3()); - - bool isDescriptionLine1Empty = descriptionLine1().empty(); - bool isDescriptionLine2Empty = descriptionLine2().empty(); - if (isDescriptionLine1Empty && isDescriptionLine2Empty) { - title_max_lines_ = 3; - } else if (isDescriptionLine1Empty || isDescriptionLine2Empty) { - title_max_lines_ = 2; - } else { - title_max_lines_ = 1; - } } } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/details.h b/components/autofill_assistant/browser/details.h index ec48966..c43a7f5 100644 --- a/components/autofill_assistant/browser/details.h +++ b/components/autofill_assistant/browser/details.h
@@ -57,7 +57,6 @@ Details* details); const std::string title() const; - int titleMaxLines() const; const std::string imageUrl() const; const base::Optional<std::string> imageAccessibilityHint() const; bool imageAllowClickthrough() const; @@ -65,7 +64,6 @@ const std::string imagePositiveText() const; const std::string imageNegativeText() const; const std::string imageClickthroughUrl() const; - bool showImagePlaceholder() const; const std::string totalPriceLabel() const; const std::string totalPrice() const; const std::string descriptionLine1() const; @@ -77,7 +75,7 @@ bool highlightLine1() const; bool highlightLine2() const; bool highlightLine3() const; - bool animatePlaceholders() const; + DetailsProto::PlaceholdersConfiguration placeholders() const; // Clears all change flags. void ClearChanges(); @@ -98,9 +96,6 @@ DetailsProto proto_; DetailsChangesProto change_flags_; - // Maximum of lines for the title. - int title_max_lines_ = 1; - // Content to be shown in description line 1 in the UI. std::string description_line_1_content_;
diff --git a/components/autofill_assistant/browser/details_unittest.cc b/components/autofill_assistant/browser/details_unittest.cc index cdcfbe0f..046bf58a 100644 --- a/components/autofill_assistant/browser/details_unittest.cc +++ b/components/autofill_assistant/browser/details_unittest.cc
@@ -87,8 +87,7 @@ Details details; details.UpdateFromParameters(*context); - EXPECT_TRUE(details.animatePlaceholders()); - EXPECT_TRUE(details.showImagePlaceholder()); + EXPECT_TRUE(details.placeholders().show_image_placeholder()); } TEST_F(DetailsTest, UpdateFromParametersUpdateFromDetails) { @@ -109,7 +108,7 @@ Details details; EXPECT_TRUE(details.UpdateFromParameters(*context)); - EXPECT_TRUE(details.animatePlaceholders()); + EXPECT_TRUE(details.placeholders().show_image_placeholder()); EXPECT_THAT(details.title(), Eq("title")); EXPECT_THAT(details.descriptionLine1(), Eq("line1")); EXPECT_THAT(details.descriptionLine2(), Eq("line2")); @@ -137,8 +136,7 @@ Details details; EXPECT_TRUE(details.UpdateFromParameters(*context)); - EXPECT_TRUE(details.animatePlaceholders()); - EXPECT_TRUE(details.showImagePlaceholder()); + EXPECT_TRUE(details.placeholders().show_image_placeholder()); EXPECT_THAT(details.title(), Eq("movie_name")); EXPECT_THAT(details.descriptionLine2(), Eq("movie_theater")); EXPECT_THAT(details.descriptionLine1(), @@ -287,42 +285,6 @@ EXPECT_FALSE(details.descriptionLine1().empty()); } -TEST_F(DetailsTest, GetTitleMaxLines) { - Details details; - - ShowDetailsProto proto_no_description; - proto_no_description.mutable_details()->set_title("title"); - EXPECT_TRUE(Details::UpdateFromProto(proto_no_description, &details)); - EXPECT_THAT(details.titleMaxLines(), Eq(3)); - - ShowDetailsProto proto_description1; - proto_description1.mutable_details()->set_title("title"); - proto_description1.mutable_details()->set_description_line_1("line 1"); - EXPECT_TRUE(Details::UpdateFromProto(proto_description1, &details)); - EXPECT_THAT(details.titleMaxLines(), Eq(2)); - - ShowDetailsProto proto_description2; - proto_description2.mutable_details()->set_title("title"); - proto_description2.mutable_details()->set_description_line_2("line 2"); - EXPECT_TRUE(Details::UpdateFromProto(proto_description2, &details)); - EXPECT_THAT(details.titleMaxLines(), Eq(2)); - - ShowDetailsProto proto_description1_date; - proto_description1_date.mutable_details()->set_title("title"); - SetDateTimeProto( - proto_description1_date.mutable_details()->mutable_datetime(), 2019, 9, - 26, 16, 40, 2); - EXPECT_TRUE(Details::UpdateFromProto(proto_description1_date, &details)); - EXPECT_THAT(details.titleMaxLines(), Eq(2)); - - ShowDetailsProto proto_both_descriptions; - proto_both_descriptions.mutable_details()->set_title("title"); - proto_both_descriptions.mutable_details()->set_description_line_1("line 1"); - proto_both_descriptions.mutable_details()->set_description_line_2("line 2"); - EXPECT_TRUE(Details::UpdateFromProto(proto_both_descriptions, &details)); - EXPECT_THAT(details.titleMaxLines(), Eq(1)); -} - TEST_F(DetailsTest, GetDescriptionLine1) { base::test::ScopedRestoreICUDefaultLocale restore_locale; @@ -443,14 +405,13 @@ EXPECT_THAT(details.imageClickthroughUrl(), Eq("url")); } -TEST_F(DetailsTest, GetPlaceholderFlags) { +TEST_F(DetailsTest, GetPlaceholderConfiguration) { Details details; ShowDetailsProto proto; - proto.mutable_details()->set_show_image_placeholder(true); - proto.mutable_details()->set_animate_placeholders(true); + proto.mutable_details()->mutable_placeholders()->set_show_image_placeholder( + true); EXPECT_TRUE(Details::UpdateFromProto(proto, &details)); - EXPECT_TRUE(details.showImagePlaceholder()); - EXPECT_TRUE(details.animatePlaceholders()); + EXPECT_TRUE(details.placeholders().show_image_placeholder()); } TEST_F(DetailsTest, GetTotalPrice) {
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index ef836189..d5fdfc9 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -596,6 +596,13 @@ // Whether the visual viewport should be resized to allow scrolling to the // bottom of the page while the trigger script is being displayed. optional bool resize_visual_viewport = 8; + // Whether the bottom sheet should temporarily disappear when scrolling down + // the website, to move out of the way. + // + // Avoid setting both resize_visual_viewport and scroll_to_hide to true, as + // the resulting behavior is confusing: the bottom sheet can pop back up after + // a scroll down instead of staying hidden in some situations. + optional bool scroll_to_hide = 9; } // An action could be performed. @@ -2274,11 +2281,8 @@ message DetailsProto { optional string title = 1; - oneof image { - string image_url = 2; - // When set to true shows placeholder in place of an image. - bool show_image_placeholder = 10; - } + optional string image_url = 2; + // Specifies the hint for accessibility. If set to empty, the image will not // be announced by accessibility. optional string image_accessibility_hint = 14; @@ -2317,17 +2321,30 @@ optional DateTimeProto datetime = 3; optional string description = 4; - // Asks the UI to show animated placeholders for missing fields. - // The placeholder will be shown on effectively missing: - // * title - // * image - // * description line (1, 2 or 3) - // TODO(crbug.com/806868): Make the fields for displaying placeholders - // configurable by the server. - optional bool animate_placeholders = 11; + // The configuration for the placeholders. + message PlaceholdersConfiguration { + // Show a placeholder if |DetailsProto.image_url| is empty. + optional bool show_image_placeholder = 1; + + // Show a placeholder if |DetailsProto.title| is empty. + optional bool show_title_placeholder = 2; + + // Show a placeholder if |DetailsProto.description_line_1| is empty. + optional bool show_description_line_1_placeholder = 3; + + // Show a placeholder if |DetailsProto.description_line_2| is empty. + optional bool show_description_line_2_placeholder = 4; + + // Show a placeholder if |DetailsProto.description_line_3| is empty. + optional bool show_description_line_3_placeholder = 5; + } + + // The placeholders configuration. Note that a placeholder will be shown only + // if the associated data is empty. + optional PlaceholdersConfiguration placeholders = 15; // Deprecated, no longer supported. - reserved 5; + reserved 5, 10, 11; } // Show contextual information.
diff --git a/components/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc b/components/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc index 6fc8c69..5611c9d 100644 --- a/components/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc +++ b/components/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc
@@ -22,7 +22,6 @@ #include "components/content_settings/browser/test_page_specific_content_settings_delegate.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h" -#include "components/subresource_filter/content/browser/subresource_filter_client.h" #include "components/subresource_filter/content/browser/subresource_filter_observer_manager.h" #include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.h" #include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.h" @@ -48,31 +47,13 @@ "ContentSettings.Popups.StrongBlocker.NumBlocked"; class SafeBrowsingTriggeredPopupBlockerTest - : public content::RenderViewHostTestHarness, - public subresource_filter::SubresourceFilterClient { + : public content::RenderViewHostTestHarness { public: SafeBrowsingTriggeredPopupBlockerTest() = default; ~SafeBrowsingTriggeredPopupBlockerTest() override { settings_map_->ShutdownOnUIThread(); } - // subresource_filter::SubresourceFilterClient: - void ShowNotification() override {} - subresource_filter::mojom::ActivationLevel OnPageActivationComputed( - content::NavigationHandle* navigation_handle, - subresource_filter::mojom::ActivationLevel initial_activation_level, - subresource_filter::ActivationDecision* decision) override { - return initial_activation_level; - } - void OnAdsViolationTriggered( - content::RenderFrameHost*, - subresource_filter::mojom::AdsViolation) override {} - const scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> - GetSafeBrowsingDatabaseManager() override { - return nullptr; - } - void OnReloadRequested() override {} - // content::RenderViewHostTestHarness: void SetUp() override { content::RenderViewHostTestHarness::SetUp(); @@ -161,7 +142,7 @@ content::NavigationHandle* handle) { return std::make_unique< subresource_filter::SubresourceFilterSafeBrowsingActivationThrottle>( - handle, this, content::GetIOThreadTaskRunner({}), + handle, /*delegate=*/nullptr, content::GetIOThreadTaskRunner({}), fake_safe_browsing_database_); }
diff --git a/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheet.java b/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheet.java index 4614ff6..19657ea 100644 --- a/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheet.java +++ b/components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheet.java
@@ -180,6 +180,12 @@ */ private int mScrollableHeight; + /** + * The instance passed to the current content that is allowed to + * change the sheet offset. + */ + private Callback<Integer> mOffsetController; + @Override public boolean shouldGestureMoveSheet(MotionEvent initialEvent, MotionEvent currentEvent) { // If the sheet is scrolling off-screen or in the process of hiding, gestures should not @@ -526,6 +532,10 @@ if (mSheetContent != null) { mSheetContent.setContentSizeListener(null); mSheetContent.getContentView().removeOnLayoutChangeListener(this); + if (mOffsetController != null) { + mSheetContent.setOffsetController(null); + mOffsetController = null; + } } if (content != null && getParent() == null) { @@ -667,8 +677,21 @@ /** * Sets the sheet's offset relative to the bottom of the screen. * @param offset The offset that the sheet should be. + * @param reason The reason for the sheet offset to change to report to listeners. */ void setSheetOffsetFromBottom(float offset, @StateChangeReason int reason) { + setSheetOffsetFromBottom(offset, reason, /* reportOpenClosed= */ true); + } + + /** + * Sets the sheet's offset relative to the bottom of the screen. + * @param offset The offset that the sheet should be. + * @param reason The reason for the sheet offset to change to report to listeners. + * @param reportOpenClosed {@code true} to allow reporting the sheet opened or closed as a + * result of this change. {@code reason} is never used when this is {@code false}. + */ + void setSheetOffsetFromBottom( + float offset, @StateChangeReason int reason, boolean reportOpenClosed) { mCurrentOffsetPx = offset; // The browser controls offset is added here so that the sheet's toolbar behaves like the @@ -679,28 +702,32 @@ setTranslationY(translationY); - // Do open/close computation based on the minimum allowed state by the sheet's content. - // Note that when transitioning from hidden to peek, even dismissable sheets may want - // to have a peek state. - @SheetState - int minSwipableState = getMinSwipableSheetState(); - if (isPeekStateEnabled() && (!isSheetOpen() || mTargetState == SheetState.PEEK)) { - minSwipableState = SheetState.PEEK; - } + if (reportOpenClosed) { + // Do open/close computation based on the minimum allowed state by the sheet's content. + // Note that when transitioning from hidden to peek, even dismissable sheets may want + // to have a peek state. + @SheetState + int minSwipableState = getMinSwipableSheetState(); + if (isPeekStateEnabled() && (!isSheetOpen() || mTargetState == SheetState.PEEK)) { + minSwipableState = SheetState.PEEK; + } - float minScrollableHeight = getSheetHeightForState(minSwipableState); - boolean isAtMinHeight = MathUtils.areFloatsEqual(getCurrentOffsetPx(), minScrollableHeight); - boolean heightLessThanPeek = getCurrentOffsetPx() < minScrollableHeight; - // Trigger the onSheetClosed event when the sheet is moving toward the hidden state if peek - // is disabled. This should be fine since touch is disabled when the sheet's target is - // hidden. - boolean triggerCloseWithHidden = !isPeekStateEnabled() && mTargetState == SheetState.HIDDEN; + float minScrollableHeight = getSheetHeightForState(minSwipableState); + boolean isAtMinHeight = + MathUtils.areFloatsEqual(getCurrentOffsetPx(), minScrollableHeight); + boolean heightLessThanPeek = getCurrentOffsetPx() < minScrollableHeight; + // Trigger the onSheetClosed event when the sheet is moving toward the hidden state if + // peek is disabled. This should be fine since touch is disabled when the sheet's target + // is hidden. + boolean triggerCloseWithHidden = + !isPeekStateEnabled() && mTargetState == SheetState.HIDDEN; - if (isSheetOpen() && (heightLessThanPeek || isAtMinHeight || triggerCloseWithHidden)) { - onSheetClosed(reason); - } else if (!isSheetOpen() && mTargetState != SheetState.HIDDEN - && getCurrentOffsetPx() > minScrollableHeight) { - onSheetOpened(reason); + if (isSheetOpen() && (heightLessThanPeek || isAtMinHeight || triggerCloseWithHidden)) { + onSheetClosed(reason); + } else if (!isSheetOpen() && mTargetState != SheetState.HIDDEN + && getCurrentOffsetPx() > minScrollableHeight) { + onSheetOpened(reason); + } } sendOffsetChangeEvents(); @@ -1228,18 +1255,34 @@ protected void onSheetContentChanged(@Nullable final BottomSheetContent content) { mSheetContent = content; - if (content != null && isFullHeightWrapContent()) { - // Listen for layout/size changes. - if (!content.setContentSizeListener(this::onContentSizeChanged)) { - content.getContentView().addOnLayoutChangeListener(this); + if (content != null) { + if (isFullHeightWrapContent()) { + // Listen for layout/size changes. + if (!content.setContentSizeListener(this::onContentSizeChanged)) { + content.getContentView().addOnLayoutChangeListener(this); + } + + invalidateContentDesiredHeight(); + ensureContentIsWrapped(/* animate= */ true); + + // HALF state is forbidden when wrapping the content. + if (mCurrentState == SheetState.HALF) { + setSheetState(SheetState.FULL, /* animate= */ true); + } } + if (content.contentControlsOffset()) { + mOffsetController = new Callback<Integer>() { + @Override + public void onResult(Integer offsetPx) { + if (this != mOffsetController) return; - invalidateContentDesiredHeight(); - ensureContentIsWrapped(/* animate= */ true); - - // HALF state is forbidden when wrapping the content. - if (mCurrentState == SheetState.HALF) { - setSheetState(SheetState.FULL, /* animate= */ true); + cancelAnimation(); + setSheetOffsetFromBottom( + MathUtils.clamp(offsetPx, 0, (int) getMaxOffsetPx()), + StateChangeReason.NONE, /* reportOpenClosed=*/false); + } + }; + content.setOffsetController(mOffsetController); } } @@ -1267,6 +1310,12 @@ */ private void onContentSizeChanged(int width, int height, int oldWidth, int oldHeight) { boolean heightChanged = mContentDesiredHeight != height; + boolean widthChanged = mContentWidth != width; + + // onContentSizeChanged() is sometimes called when there's no size change, because of + // animations running in the content. Ignore these calls. + if (!heightChanged && !widthChanged) return; + mContentDesiredHeight = height; mContentWidth = width;
diff --git a/components/browser_ui/android/bottomsheet/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetContent.java b/components/browser_ui/android/bottomsheet/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetContent.java index 554352d..9b0c55e7 100644 --- a/components/browser_ui/android/bottomsheet/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetContent.java +++ b/components/browser_ui/android/bottomsheet/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetContent.java
@@ -9,6 +9,8 @@ import androidx.annotation.IntDef; import androidx.annotation.Nullable; +import org.chromium.base.Callback; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -205,4 +207,23 @@ * typically the name of your feature followed by 'closed'. */ int getSheetClosedAccessibilityStringId(); + + /** + * Return {@code true} if the content expects {@link #setOffsetController} to be called. + * + * This is an experimental feature. Use it at your own risks. TODO(b/177037825): Remove or + * cleanup. + */ + default boolean contentControlsOffset() { + return false; + } + + /** + * Set or reset the set offset callback. + * + * The active content can use this callback to move the sheet to the given offset. + * + * Only called if {@link #contentControlsOffset} returns {@code true}. + */ + default void setOffsetController(@Nullable Callback<Integer> setOffset) {} }
diff --git a/components/full_restore/BUILD.gn b/components/full_restore/BUILD.gn index f1c2363..3276bb6 100644 --- a/components/full_restore/BUILD.gn +++ b/components/full_restore/BUILD.gn
@@ -52,5 +52,6 @@ ":full_restore", "//content/test:test_support", "//testing/gtest", + "//ui/aura:test_support", ] }
diff --git a/components/full_restore/full_restore_read_and_save_unittest.cc b/components/full_restore/full_restore_read_and_save_unittest.cc index f14404d..5e71b5e4 100644 --- a/components/full_restore/full_restore_read_and_save_unittest.cc +++ b/components/full_restore/full_restore_read_and_save_unittest.cc
@@ -17,17 +17,23 @@ #include "components/full_restore/full_restore_save_handler.h" #include "components/full_restore/full_restore_utils.h" #include "components/full_restore/restore_data.h" +#include "components/full_restore/window_info.h" #include "content/public/test/browser_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/aura/test/test_windows.h" +#include "ui/aura/window.h" namespace full_restore { namespace { -const char kAppId[] = "aaa"; +constexpr char kAppId[] = "aaa"; -const int32_t kId1 = 100; -const int32_t kId2 = 200; +constexpr int32_t kId1 = 100; +constexpr int32_t kId2 = 200; + +constexpr int32_t kActivationIndex1 = 100; +constexpr int32_t kActivationIndex2 = 101; } // namespace @@ -71,7 +77,19 @@ file_path, std::make_unique<full_restore::AppLaunchInfo>(kAppId, id)); } - void VerifyRestoreData(const base::FilePath& file_path, int32_t id) { + void CreateWindowInfo(int32_t id, int32_t index) { + std::unique_ptr<aura::Window> window( + aura::test::CreateTestWindowWithId(id, nullptr)); + WindowInfo window_info; + window_info.window = window.get(); + window->SetProperty(full_restore::kWindowIdKey, id); + window_info.activation_index = index; + full_restore::SaveWindowInfo(window_info); + } + + void VerifyRestoreData(const base::FilePath& file_path, + int32_t id, + int32_t index) { ReadFromFile(file_path); const auto* restore_data = GetRestoreData(file_path); @@ -88,6 +106,10 @@ // Verify for |id| const auto app_restore_data_it = launch_list_it->second.find(id); EXPECT_TRUE(app_restore_data_it != launch_list_it->second.end()); + + const auto& data = app_restore_data_it->second; + EXPECT_TRUE(data->activation_index.has_value()); + EXPECT_EQ(index, data->activation_index.value()); } content::BrowserTaskEnvironment& task_environment() { @@ -112,15 +134,23 @@ FullRestoreSaveHandler* save_handler = FullRestoreSaveHandler::GetInstance(); base::OneShotTimer* timer = save_handler->GetTimerForTesting(); - // Add app launch info, and verity the timer starts. + // Add app launch info, and verify the timer starts. AddAppLaunchInfo(GetPath(), kId1); EXPECT_TRUE(timer->IsRunning()); - // Add one more app launch info, and verity the timer is still running. + // Add one more app launch info, and verify the timer is still running. AddAppLaunchInfo(GetPath(), kId2); EXPECT_TRUE(timer->IsRunning()); - // Simulate timeout, and verity the timer stops. + // Simulate timeout, and verify the timer stops. + timer->FireNow(); + CreateWindowInfo(kId2, kActivationIndex2); + task_environment().RunUntilIdle(); + EXPECT_FALSE(timer->IsRunning()); + + // Modify the window info, and verify the timer starts. + CreateWindowInfo(kId1, kActivationIndex1); + EXPECT_TRUE(timer->IsRunning()); timer->FireNow(); task_environment().RunUntilIdle(); @@ -142,9 +172,17 @@ const auto app_restore_data_it1 = launch_list_it->second.find(kId1); EXPECT_TRUE(app_restore_data_it1 != launch_list_it->second.end()); + const auto& data1 = app_restore_data_it1->second; + EXPECT_TRUE(data1->activation_index.has_value()); + EXPECT_EQ(kActivationIndex1, data1->activation_index.value()); + // Verify for |kId2| const auto app_restore_data_it2 = launch_list_it->second.find(kId2); EXPECT_TRUE(app_restore_data_it2 != launch_list_it->second.end()); + + const auto& data2 = app_restore_data_it2->second; + EXPECT_TRUE(data2->activation_index.has_value()); + EXPECT_EQ(kActivationIndex2, data2->activation_index.value()); } TEST_F(FullRestoreReadAndSaveTest, MultipleFilePaths) { @@ -156,20 +194,28 @@ ASSERT_TRUE(tmp_dir1.CreateUniqueTempDir()); ASSERT_TRUE(tmp_dir2.CreateUniqueTempDir()); - // Add app launch info for |tmp_dir1|, and verity the timer starts. + // Add app launch info for |tmp_dir1|, and verify the timer starts. AddAppLaunchInfo(tmp_dir1.GetPath(), kId1); EXPECT_TRUE(timer->IsRunning()); - // Add app launch info for |tmp_dir2|, and verity the timer is still running. + // Add app launch info for |tmp_dir2|, and verify the timer is still running. AddAppLaunchInfo(tmp_dir2.GetPath(), kId2); EXPECT_TRUE(timer->IsRunning()); - // Simulate timeout, and verity the timer stops. + // Simulate timeout, and verify the timer stops. + timer->FireNow(); + CreateWindowInfo(kId2, kActivationIndex2); + task_environment().RunUntilIdle(); + EXPECT_FALSE(timer->IsRunning()); + + // Modify the window info, and verify the timer starts. + CreateWindowInfo(kId1, kActivationIndex1); + EXPECT_TRUE(timer->IsRunning()); timer->FireNow(); task_environment().RunUntilIdle(); - VerifyRestoreData(tmp_dir1.GetPath(), kId1); - VerifyRestoreData(tmp_dir2.GetPath(), kId2); + VerifyRestoreData(tmp_dir1.GetPath(), kId1, kActivationIndex1); + VerifyRestoreData(tmp_dir2.GetPath(), kId2, kActivationIndex2); } } // namespace full_restore
diff --git a/components/full_restore/full_restore_save_handler.cc b/components/full_restore/full_restore_save_handler.cc index 30686585..6b8adc3 100644 --- a/components/full_restore/full_restore_save_handler.cc +++ b/components/full_restore/full_restore_save_handler.cc
@@ -124,6 +124,10 @@ profile_path_to_restore_data_[it->second.first].ModifyWindowInfo( it->second.second, window_id, window_info); + + pending_save_profile_paths_.insert(it->second.first); + + MaybeStartSaveTimer(); } void FullRestoreSaveHandler::Flush(const base::FilePath& profile_path) { @@ -173,23 +177,24 @@ pending_save_profile_paths_.clear(); } -void FullRestoreSaveHandler::OnSaveFinished(const base::FilePath& file_path) { - save_running_.erase(file_path); +void FullRestoreSaveHandler::OnSaveFinished( + const base::FilePath& profile_path) { + save_running_.erase(profile_path); } FullRestoreFileHandler* FullRestoreSaveHandler::GetFileHandler( - const base::FilePath& file_path) { - if (profile_path_to_file_handler_.find(file_path) == + const base::FilePath& profile_path) { + if (profile_path_to_file_handler_.find(profile_path) == profile_path_to_file_handler_.end()) { - profile_path_to_file_handler_[file_path] = - base::MakeRefCounted<FullRestoreFileHandler>(file_path); + profile_path_to_file_handler_[profile_path] = + base::MakeRefCounted<FullRestoreFileHandler>(profile_path); } - return profile_path_to_file_handler_[file_path].get(); + return profile_path_to_file_handler_[profile_path].get(); } base::SequencedTaskRunner* FullRestoreSaveHandler::BackendTaskRunner( - const base::FilePath& file_path) { - return GetFileHandler(file_path)->owning_task_runner(); + const base::FilePath& profile_path) { + return GetFileHandler(profile_path)->owning_task_runner(); } } // namespace full_restore
diff --git a/components/full_restore/full_restore_save_handler.h b/components/full_restore/full_restore_save_handler.h index b0f3ebd..67f7ddc 100644 --- a/components/full_restore/full_restore_save_handler.h +++ b/components/full_restore/full_restore_save_handler.h
@@ -54,11 +54,11 @@ // aura::WindowObserver: void OnWindowDestroyed(aura::Window* window) override; - // Save |app_launch_info| to the full restore file in |profile_path|. + // Saves |app_launch_info| to the full restore file in |profile_path|. void SaveAppLaunchInfo(const base::FilePath& profile_path, std::unique_ptr<AppLaunchInfo> app_launch_info); - // Save |window_info| to |profile_path_to_restore_data_|. + // Saves |window_info| to |profile_path_to_restore_data_|. void SaveWindowInfo(const WindowInfo& window_info); // Flushes the full restore file in |profile_path| with the current restore @@ -78,12 +78,13 @@ // Passes |profile_path_to_restore_data_| to the backend for saving. void Save(); - // Invoked when write to file operation for |file_path| is finished. - void OnSaveFinished(const base::FilePath& file_path); + // Invoked when write to file operation for |profile_path| is finished. + void OnSaveFinished(const base::FilePath& profile_path); - FullRestoreFileHandler* GetFileHandler(const base::FilePath& file_path); + FullRestoreFileHandler* GetFileHandler(const base::FilePath& profile_path); - base::SequencedTaskRunner* BackendTaskRunner(const base::FilePath& file_path); + base::SequencedTaskRunner* BackendTaskRunner( + const base::FilePath& profile_path); // Records whether there are new updates for saving between each saving delay. // |pending_save_profile_paths_| is cleared when Save is invoked.
diff --git a/components/full_restore/full_restore_utils.cc b/components/full_restore/full_restore_utils.cc index ca329658..ac9177a 100644 --- a/components/full_restore/full_restore_utils.cc +++ b/components/full_restore/full_restore_utils.cc
@@ -17,13 +17,13 @@ DEFINE_UI_CLASS_PROPERTY_KEY(int32_t, kWindowIdKey, 0) DEFINE_UI_CLASS_PROPERTY_KEY(int32_t, kRestoreWindowIdKey, 0) -void SaveAppLaunchInfo(const base::FilePath& profile_dir, +void SaveAppLaunchInfo(const base::FilePath& profile_path, std::unique_ptr<AppLaunchInfo> app_launch_info) { if (!ash::features::IsFullRestoreEnabled() || !app_launch_info) return; FullRestoreSaveHandler::GetInstance()->SaveAppLaunchInfo( - profile_dir, std::move(app_launch_info)); + profile_path, std::move(app_launch_info)); } void SaveWindowInfo(const WindowInfo& window_info) {
diff --git a/components/full_restore/full_restore_utils.h b/components/full_restore/full_restore_utils.h index 0fcf698..88bd7aa 100644 --- a/components/full_restore/full_restore_utils.h +++ b/components/full_restore/full_restore_utils.h
@@ -35,7 +35,7 @@ // Saves the app launch parameters to the full restore file. COMPONENT_EXPORT(FULL_RESTORE) -void SaveAppLaunchInfo(const base::FilePath& profile_dir, +void SaveAppLaunchInfo(const base::FilePath& profile_path, std::unique_ptr<AppLaunchInfo> app_launch_info); // Saves the window information to the full restore file.
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc index f8cd664..8c0d11a 100644 --- a/components/omnibox/common/omnibox_features.cc +++ b/components/omnibox/common/omnibox_features.cc
@@ -373,6 +373,13 @@ // necessary. const base::Feature kDefaultTypedNavigationsToHttps{ "OmniboxDefaultTypedNavigationsToHttps", base::FEATURE_DISABLED_BY_DEFAULT}; +// Parameter name used to look up the delay before falling back to the HTTP URL +// while trying an HTTPS URL. The parameter is treated as a TimeDelta, so the +// unit must be included in the value as well (e.g. 3s for 3 seconds). +// - If the HTTPS load finishes successfully during this time, the timer is +// cleared and no more work is done. +// - Otherwise, a new navigation to the the fallback HTTP URL is started. +const char kDefaultTypedNavigationsToHttpsTimeoutParam[] = "timeout"; // NOTE: while this is enabled by default, CCT visits are only tagged with the // necessary transition type if the intent launching CCT supplies the
diff --git a/components/omnibox/common/omnibox_features.h b/components/omnibox/common/omnibox_features.h index beeaa54..9f49392 100644 --- a/components/omnibox/common/omnibox_features.h +++ b/components/omnibox/common/omnibox_features.h
@@ -99,6 +99,7 @@ // Navigation experiments. extern const base::Feature kDefaultTypedNavigationsToHttps; +extern const char kDefaultTypedNavigationsToHttpsTimeoutParam[]; // Experiment to control whether visits from CCT are hidden. // TODO(https://crbug.com/1141501): this is for an experiment, and will be
diff --git a/components/password_manager/core/browser/password_form.cc b/components/password_manager/core/browser/password_form.cc index f0c74354..6c719c8 100644 --- a/components/password_manager/core/browser/password_form.cc +++ b/components/password_manager/core/browser/password_form.cc
@@ -173,11 +173,12 @@ PasswordForm& PasswordForm::operator=(PasswordForm&& form) = default; bool PasswordForm::IsPossibleChangePasswordForm() const { - return !new_password_element.empty(); + return !new_password_element_renderer_id.is_null(); } bool PasswordForm::IsPossibleChangePasswordFormWithoutUsername() const { - return IsPossibleChangePasswordForm() && username_element.empty(); + return IsPossibleChangePasswordForm() && + username_element_renderer_id.is_null(); } bool PasswordForm::HasUsernameElement() const {
diff --git a/components/password_manager/core/browser/password_manager_features_util.cc b/components/password_manager/core/browser/password_manager_features_util.cc index 981b3e41..db658c4 100644 --- a/components/password_manager/core/browser/password_manager_features_util.cc +++ b/components/password_manager/core/browser/password_manager_features_util.cc
@@ -259,6 +259,18 @@ GaiaIdHash::FromGaiaId(gaia_id)) .SetOptedIn(); + // Potentially also set the default store to the account one, based on a + // feature param. + bool save_to_account_store = base::GetFieldTrialParamByFeatureAsBool( + features::kEnablePasswordsAccountStorage, + features::kSaveToAccountStoreOnOptIn, + features::kSaveToAccountStoreOnOptInDefaultValue); + if (save_to_account_store) { + ScopedAccountStorageSettingsUpdate(pref_service, + GaiaIdHash::FromGaiaId(gaia_id)) + .SetDefaultStore(PasswordForm::Store::kAccountStore); + } + // Record the total number of (now) opted-in accounts. base::UmaHistogramExactLinear( "PasswordManager.AccountStorage.NumOptedInAccountsAfterOptIn",
diff --git a/components/password_manager/core/browser/password_manager_features_util_unittest.cc b/components/password_manager/core/browser/password_manager_features_util_unittest.cc index 7ca81e1..3000825 100644 --- a/components/password_manager/core/browser/password_manager_features_util_unittest.cc +++ b/components/password_manager/core/browser/password_manager_features_util_unittest.cc
@@ -289,6 +289,53 @@ EXPECT_TRUE(ShouldShowAccountStorageOptIn(&pref_service, &sync_service)); EXPECT_EQ(GetDefaultPasswordStore(&pref_service, &sync_service), PasswordForm::Store::kProfileStore); + + // After the user opts in, the default store should still be the profile one. + OptInToAccountStorage(&pref_service, &sync_service); + ASSERT_TRUE(IsOptedInForAccountStorage(&pref_service, &sync_service)); + EXPECT_EQ(GetDefaultPasswordStore(&pref_service, &sync_service), + PasswordForm::Store::kProfileStore); +} + +TEST(PasswordFeatureManagerUtil, SaveToAccountStoreOnOptInParam) { + base::test::ScopedFeatureList features; + features.InitAndEnableFeatureWithParameters( + features::kEnablePasswordsAccountStorage, + {{features::kSaveToProfileStoreByDefault, "true"}, + {features::kSaveToAccountStoreOnOptIn, "true"}}); + + TestingPrefServiceSimple pref_service; + pref_service.registry()->RegisterDictionaryPref( + prefs::kAccountStoragePerAccountSettings); + + CoreAccountInfo account; + account.email = "name@account.com"; + account.gaia = "name"; + account.account_id = CoreAccountId::FromGaiaId(account.gaia); + + // SyncService is running in transport mode. + syncer::TestSyncService sync_service; + sync_service.SetAuthenticatedAccountInfo(account); + sync_service.SetIsAuthenticatedAccountPrimary(false); + sync_service.SetDisableReasons({}); + sync_service.SetTransportState(syncer::SyncService::TransportState::ACTIVE); + ASSERT_FALSE(sync_service.IsSyncFeatureEnabled()); + + // By default, the user is not opted in. Since the + // |kSaveToProfileStoreByDefault| parameter is set, the default store should + // be the *profile* one. The opt-in for the account store should still show + // up, though. + ASSERT_FALSE(IsOptedInForAccountStorage(&pref_service, &sync_service)); + ASSERT_TRUE(ShouldShowAccountStorageOptIn(&pref_service, &sync_service)); + ASSERT_EQ(GetDefaultPasswordStore(&pref_service, &sync_service), + PasswordForm::Store::kProfileStore); + + // After the user opts in, the default store should change to the account one, + // based on the |kSaveToAccountStoreOnOptIn| param. + OptInToAccountStorage(&pref_service, &sync_service); + ASSERT_TRUE(IsOptedInForAccountStorage(&pref_service, &sync_service)); + EXPECT_EQ(GetDefaultPasswordStore(&pref_service, &sync_service), + PasswordForm::Store::kAccountStore); } TEST(PasswordFeatureManagerUtil, AccountStorageKeepSettingsOnlyForUsers) {
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc index 39061cb..511dd4ac 100644 --- a/components/password_manager/core/browser/password_manager_unittest.cc +++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -3768,6 +3768,47 @@ manager()->OnPasswordFormCleared(&driver_, form_data); } +// Similar test as above with fields that have empty names. +TEST_P(PasswordManagerTest, SubmissionDetectedOnClearedNamelessForm) { + constexpr base::char16 kEmptyName[] = STRING16_LITERAL(""); + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(features::kDetectFormSubmissionOnFormClear); + EXPECT_CALL(client_, IsSavingAndFillingEnabled).WillRepeatedly(Return(true)); + PasswordForm saved_match(MakeSavedForm()); + EXPECT_CALL(*store_, GetLogins) + .WillRepeatedly(WithArg<1>(InvokeConsumer(store_.get(), saved_match))); + + FormData form_data; + form_data.unique_renderer_id = FormRendererId(0); + form_data.url = GURL("http://www.google.com/a/LoginAuth"); + + FormFieldData old_password_field; + old_password_field.form_control_type = "password"; + old_password_field.unique_renderer_id = FieldRendererId(1); + old_password_field.name = kEmptyName; + old_password_field.value = ASCIIToUTF16("oldpass"); + form_data.fields.push_back(old_password_field); + + FormFieldData new_password_field; + new_password_field.form_control_type = "password"; + new_password_field.unique_renderer_id = FieldRendererId(2); + new_password_field.name = kEmptyName; + new_password_field.autocomplete_attribute = "new-password"; + form_data.fields.push_back(new_password_field); + + manager()->OnPasswordFormsParsed(&driver_, {form_data}); + + form_data.fields[0].value = ASCIIToUTF16("oldpass"); + form_data.fields[1].value = ASCIIToUTF16("newpass"); + + manager()->OnInformAboutUserInput(&driver_, form_data); + + std::unique_ptr<PasswordFormManagerForUI> form_manager_to_save; + EXPECT_CALL(client_, PromptUserToSaveOrUpdatePasswordPtr) + .WillOnce(WithArg<0>(SaveToScopedPtr(&form_manager_to_save))); + manager()->OnPasswordFormCleared(&driver_, form_data); +} + TEST_P(PasswordManagerTest, SubmissionDetectedOnClearedFormlessFields) { base::test::ScopedFeatureList feature_list; feature_list.InitAndEnableFeature(features::kDetectFormSubmissionOnFormClear); @@ -3830,6 +3871,63 @@ manager()->OnPasswordFormCleared(&driver_, form_data); } } + +// Similar test as above with fields that have empty names. +TEST_P(PasswordManagerTest, SubmissionDetectedOnClearedNameAndFormlessFields) { + constexpr base::char16 kEmptyName[] = STRING16_LITERAL(""); + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(features::kDetectFormSubmissionOnFormClear); + EXPECT_CALL(client_, IsSavingAndFillingEnabled).WillRepeatedly(Return(true)); + PasswordForm saved_match(MakeSavedForm()); + EXPECT_CALL(*store_, GetLogins) + .WillRepeatedly(WithArg<1>(InvokeConsumer(store_.get(), saved_match))); + + for (bool new_password_field_was_cleared : {true, false}) { + SCOPED_TRACE(testing::Message("#new password field was cleared = ") + << new_password_field_was_cleared); + + // Create FormData for a form with 1 password field and process it. + FormData form_data; + form_data.is_form_tag = false; + form_data.unique_renderer_id = FormRendererId(0); + form_data.url = GURL("http://www.google.com/a/LoginAuth"); + + FormFieldData old_password_field; + old_password_field.form_control_type = "password"; + old_password_field.unique_renderer_id = FieldRendererId(1); + old_password_field.name = kEmptyName; + old_password_field.value = ASCIIToUTF16("oldpass"); + form_data.fields.push_back(old_password_field); + + FormFieldData new_password_field; + new_password_field.form_control_type = "password"; + new_password_field.unique_renderer_id = FieldRendererId(2); + new_password_field.name = kEmptyName; + new_password_field.autocomplete_attribute = "new-password"; + form_data.fields.push_back(new_password_field); + + manager()->OnPasswordFormsParsed(&driver_, {form_data}); + + form_data.fields[0].value = ASCIIToUTF16("oldpass"); + form_data.fields[1].value = ASCIIToUTF16("newpass"); + + manager()->OnInformAboutUserInput(&driver_, form_data); + + form_data.fields[0].value.clear(); + if (new_password_field_was_cleared) + form_data.fields[1].value.clear(); + + std::unique_ptr<PasswordFormManagerForUI> form_manager_to_save; + if (new_password_field_was_cleared) { + EXPECT_CALL(client_, PromptUserToSaveOrUpdatePasswordPtr) + .WillOnce(WithArg<0>(SaveToScopedPtr(&form_manager_to_save))); + } else { + EXPECT_CALL(client_, PromptUserToSaveOrUpdatePasswordPtr).Times(0); + } + + manager()->OnPasswordFormCleared(&driver_, form_data); + } +} #endif // !defined(OS_IOS) TEST_P(PasswordManagerTest, IsFormManagerPendingPasswordUpdate) {
diff --git a/components/password_manager/core/common/password_manager_features.cc b/components/password_manager/core/common/password_manager_features.cc index 3142d87..f573051 100644 --- a/components/password_manager/core/common/password_manager_features.cc +++ b/components/password_manager/core/common/password_manager_features.cc
@@ -162,6 +162,13 @@ const bool kSaveToProfileStoreByDefaultDefaultValue = false; +// If set to true, Chrome will set the default store to the account store when +// the user opts in. This is mostly meaningful together with +// |kSaveToProfileStoreByDefault|. +const char kSaveToAccountStoreOnOptIn[] = "save_to_account_store_on_optin"; + +const bool kSaveToAccountStoreOnOptInDefaultValue = false; + } // namespace features } // namespace password_manager
diff --git a/components/password_manager/core/common/password_manager_features.h b/components/password_manager/core/common/password_manager_features.h index eb9623d..de830de 100644 --- a/components/password_manager/core/common/password_manager_features.h +++ b/components/password_manager/core/common/password_manager_features.h
@@ -62,6 +62,8 @@ extern const int kMaxMoveToAccountOffersForNonOptedInUserDefaultValue; extern const char kSaveToProfileStoreByDefault[]; extern const bool kSaveToProfileStoreByDefaultDefaultValue; +extern const char kSaveToAccountStoreOnOptIn[]; +extern const bool kSaveToAccountStoreOnOptInDefaultValue; } // namespace features
diff --git a/components/performance_manager/graph/process_node_impl.cc b/components/performance_manager/graph/process_node_impl.cc index 6f9fa066..d48a4e5 100644 --- a/components/performance_manager/graph/process_node_impl.cc +++ b/components/performance_manager/graph/process_node_impl.cc
@@ -10,6 +10,7 @@ #include "components/performance_manager/graph/frame_node_impl.h" #include "components/performance_manager/graph/graph_impl.h" #include "components/performance_manager/graph/page_node_impl.h" +#include "components/performance_manager/graph/worker_node_impl.h" #include "components/performance_manager/public/execution_context/execution_context_registry.h" #include "components/performance_manager/v8_memory/v8_context_tracker.h" @@ -249,6 +250,16 @@ return frames; } +base::flat_set<const WorkerNode*> ProcessNodeImpl::GetWorkerNodes() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + base::flat_set<const WorkerNode*> workers; + for (auto* worker_impl : worker_nodes_) { + const WorkerNode* worker = worker_impl; + workers.insert(worker); + } + return workers; +} + bool ProcessNodeImpl::GetMainThreadTaskLoadIsLow() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return main_thread_task_load_is_low();
diff --git a/components/performance_manager/graph/process_node_impl.h b/components/performance_manager/graph/process_node_impl.h index b801bbf..ea016dc4 100644 --- a/components/performance_manager/graph/process_node_impl.h +++ b/components/performance_manager/graph/process_node_impl.h
@@ -158,6 +158,7 @@ base::Optional<int32_t> GetExitStatus() const override; bool VisitFrameNodes(const FrameNodeVisitor& visitor) const override; base::flat_set<const FrameNode*> GetFrameNodes() const override; + base::flat_set<const WorkerNode*> GetWorkerNodes() const override; bool GetMainThreadTaskLoadIsLow() const override; uint64_t GetPrivateFootprintKb() const override; uint64_t GetResidentSetKb() const override;
diff --git a/components/performance_manager/public/graph/process_node.h b/components/performance_manager/public/graph/process_node.h index d48beda9..3375c39 100644 --- a/components/performance_manager/public/graph/process_node.h +++ b/components/performance_manager/public/graph/process_node.h
@@ -21,6 +21,7 @@ namespace performance_manager { class FrameNode; +class WorkerNode; class ProcessNodeObserver; class RenderProcessHostProxy; @@ -79,6 +80,10 @@ // calling this causes the set of nodes to be generated. virtual base::flat_set<const FrameNode*> GetFrameNodes() const = 0; + // Returns the set of worker nodes that are hosted in this process. Note that + // calling this causes the set of nodes to be generated. + virtual base::flat_set<const WorkerNode*> GetWorkerNodes() const = 0; + // Returns true if the main thread task load is low (below some threshold // of usage). See ProcessNodeObserver::OnMainThreadTaskLoadIsLow. virtual bool GetMainThreadTaskLoadIsLow() const = 0;
diff --git a/components/performance_manager/service_worker_context_adapter.cc b/components/performance_manager/service_worker_context_adapter.cc index c70d49c..f84c732 100644 --- a/components/performance_manager/service_worker_context_adapter.cc +++ b/components/performance_manager/service_worker_context_adapter.cc
@@ -131,10 +131,10 @@ return content::ServiceWorkerExternalRequestResult::kOk; } -void ServiceWorkerContextAdapter::CountExternalRequestsForTest( - const url::Origin& origin, - CountExternalRequestsCallback callback) { +size_t ServiceWorkerContextAdapter::CountExternalRequestsForTest( + const url::Origin& origin) { NOTIMPLEMENTED(); + return 0u; } bool ServiceWorkerContextAdapter::MaybeHasRegistrationForOrigin(
diff --git a/components/performance_manager/service_worker_context_adapter.h b/components/performance_manager/service_worker_context_adapter.h index 619bc3b..e7f0f900 100644 --- a/components/performance_manager/service_worker_context_adapter.h +++ b/components/performance_manager/service_worker_context_adapter.h
@@ -58,9 +58,7 @@ content::ServiceWorkerExternalRequestResult FinishedExternalRequest( int64_t service_worker_version_id, const std::string& request_uuid) override; - void CountExternalRequestsForTest( - const url::Origin& origin, - CountExternalRequestsCallback callback) override; + size_t CountExternalRequestsForTest(const url::Origin& origin) override; bool MaybeHasRegistrationForOrigin(const url::Origin& origin) override; void GetInstalledRegistrationOrigins( base::Optional<std::string> host_filter,
diff --git a/components/performance_manager/v8_memory/v8_detailed_memory.cc b/components/performance_manager/v8_memory/v8_detailed_memory.cc index 0ccfabe..be416e4 100644 --- a/components/performance_manager/v8_memory/v8_detailed_memory.cc +++ b/components/performance_manager/v8_memory/v8_detailed_memory.cc
@@ -469,43 +469,48 @@ // existing frame is likewise accured to unassociated usage. uint64_t unassociated_v8_bytes_used = 0; - // Create a mapping from token to per-frame usage for the merge below. - std::vector<std::pair<blink::LocalFrameToken, + // Create a mapping from token to execution context usage for the merge below. + std::vector<std::pair<blink::ExecutionContextToken, blink::mojom::PerContextV8MemoryUsagePtr>> tmp; for (auto& isolate : result->isolates) { for (auto& entry : isolate->contexts) { - if (entry->token.Is<blink::LocalFrameToken>()) { - tmp.emplace_back(entry->token.GetAs<blink::LocalFrameToken>(), - std::move(entry)); - } - // TODO(ulan): Handle WorkerFrameTokens here. + tmp.emplace_back(entry->token, std::move(entry)); } unassociated_v8_bytes_used += isolate->unassociated_bytes_used; } size_t found_frame_count = tmp.size(); - base::flat_map<blink::LocalFrameToken, + base::flat_map<blink::ExecutionContextToken, blink::mojom::PerContextV8MemoryUsagePtr> associated_memory(std::move(tmp)); // Validate that the frame tokens were all unique. If there are duplicates, // the map will arbitrarily drop all but one record per unique token. DCHECK_EQ(associated_memory.size(), found_frame_count); - base::flat_set<const FrameNode*> frame_nodes = process_node_->GetFrameNodes(); - for (const FrameNode* frame_node : frame_nodes) { - auto it = associated_memory.find(frame_node->GetFrameToken()); + std::vector<const execution_context::ExecutionContext*> execution_contexts; + for (auto* node : process_node_->GetFrameNodes()) { + execution_contexts.push_back( + execution_context::ExecutionContext::From(node)); + } + for (auto* node : process_node_->GetWorkerNodes()) { + execution_contexts.push_back( + execution_context::ExecutionContext::From(node)); + } + + for (const execution_context::ExecutionContext* ec : execution_contexts) { + auto it = associated_memory.find(ec->GetToken()); if (it == associated_memory.end()) { // No data for this node, clear any data associated with it. - ExecutionContextAttachedData::Destroy(frame_node); + ExecutionContextAttachedData::Destroy(ec); } else { - ExecutionContextAttachedData* frame_data = - ExecutionContextAttachedData::GetOrCreate(frame_node); - DCHECK_CALLED_ON_VALID_SEQUENCE(frame_data->sequence_checker_); + ExecutionContextAttachedData* ec_data = + ExecutionContextAttachedData::GetOrCreate(ec); + DCHECK_CALLED_ON_VALID_SEQUENCE(ec_data->sequence_checker_); - frame_data->data_available_ = true; - frame_data->data_.set_v8_bytes_used(it->second->bytes_used); + ec_data->data_available_ = true; + ec_data->data_.set_v8_bytes_used(it->second->bytes_used); // Zero out this datum as its usage has been consumed. // We avoid erase() here because it may take O(n) time. it->second.reset(); @@ -514,7 +519,7 @@ for (const auto& it : associated_memory) { if (it.second.is_null()) { - // Frame was already consumed. + // Execution context was already consumed. continue; } // Accrue the data for non-existent frames to unassociated bytes.
diff --git a/components/performance_manager/v8_memory/v8_detailed_memory_unittest.cc b/components/performance_manager/v8_memory/v8_detailed_memory_unittest.cc index 4b6e8289..b6892a7 100644 --- a/components/performance_manager/v8_memory/v8_detailed_memory_unittest.cc +++ b/components/performance_manager/v8_memory/v8_detailed_memory_unittest.cc
@@ -21,6 +21,7 @@ #include "components/performance_manager/graph/frame_node_impl.h" #include "components/performance_manager/graph/page_node_impl.h" #include "components/performance_manager/graph/process_node_impl.h" +#include "components/performance_manager/graph/worker_node_impl.h" #include "components/performance_manager/public/performance_manager.h" #include "components/performance_manager/public/render_process_host_id.h" #include "components/performance_manager/public/render_process_host_proxy.h" @@ -1920,6 +1921,50 @@ EXPECT_FALSE(weak_lifetime_test); } +TEST_F(V8DetailedMemoryDecoratorTest, DedicatedWorkers) { + V8DetailedMemoryRequest memory_request(kMinTimeBetweenRequests, graph()); + + MockV8DetailedMemoryReporter reporter; + + auto process = CreateNode<ProcessNodeImpl>( + content::PROCESS_TYPE_RENDERER, + RenderProcessHostProxy::CreateForTesting(kTestProcessID)); + + // Create a couple of frames with specified IDs. + auto page = CreateNode<PageNodeImpl>(); + + blink::LocalFrameToken frame_id = blink::LocalFrameToken(); + auto frame = CreateNode<FrameNodeImpl>(process.get(), page.get(), nullptr, 1, + 2, frame_id); + + blink::DedicatedWorkerToken worker_id = blink::DedicatedWorkerToken(); + auto worker = CreateNode<WorkerNodeImpl>( + WorkerNode::WorkerType::kDedicated, process.get(), + page->browser_context_id(), worker_id); + + worker->AddClientFrame(frame.get()); + { + auto data = NewPerProcessV8MemoryUsage(2); + AddIsolateMemoryUsage(frame_id, 1001u, data->isolates[0].get()); + AddIsolateMemoryUsage(worker_id, 1002u, data->isolates[1].get()); + ExpectBindAndRespondToQuery(&reporter, std::move(data)); + } + + task_env().RunUntilIdle(); + Mock::VerifyAndClearExpectations(&reporter); + + ASSERT_TRUE(V8DetailedMemoryExecutionContextData::ForFrameNode(frame.get())); + EXPECT_EQ(1001u, + V8DetailedMemoryExecutionContextData::ForFrameNode(frame.get()) + ->v8_bytes_used()); + ASSERT_TRUE( + V8DetailedMemoryExecutionContextData::ForWorkerNode(worker.get())); + EXPECT_EQ(1002u, + V8DetailedMemoryExecutionContextData::ForWorkerNode(worker.get()) + ->v8_bytes_used()); + worker->RemoveClientFrame(frame.get()); +} + } // namespace v8_memory } // namespace performance_manager
diff --git a/components/performance_manager/v8_memory/v8_memory_test_helpers.cc b/components/performance_manager/v8_memory/v8_memory_test_helpers.cc index cc48a97..eed1019 100644 --- a/components/performance_manager/v8_memory/v8_memory_test_helpers.cc +++ b/components/performance_manager/v8_memory/v8_memory_test_helpers.cc
@@ -353,18 +353,18 @@ return data; } -void AddIsolateMemoryUsage(const blink::LocalFrameToken& frame_token, +void AddIsolateMemoryUsage(blink::ExecutionContextToken token, uint64_t bytes_used, blink::mojom::PerIsolateV8MemoryUsage* isolate) { for (auto& entry : isolate->contexts) { - if (entry->token == blink::ExecutionContextToken(frame_token)) { + if (entry->token == token) { entry->bytes_used = bytes_used; return; } } auto context = blink::mojom::PerContextV8MemoryUsage::New(); - context->token = blink::ExecutionContextToken(frame_token); + context->token = token; context->bytes_used = bytes_used; isolate->contexts.push_back(std::move(context)); }
diff --git a/components/performance_manager/v8_memory/v8_memory_test_helpers.h b/components/performance_manager/v8_memory/v8_memory_test_helpers.h index 000865b..39271ae 100644 --- a/components/performance_manager/v8_memory/v8_memory_test_helpers.h +++ b/components/performance_manager/v8_memory/v8_memory_test_helpers.h
@@ -332,9 +332,9 @@ blink::mojom::PerProcessV8MemoryUsagePtr NewPerProcessV8MemoryUsage( size_t number_of_isolates); -// Finds the PerContextV8MemoryUsage in |isolate| whose token is |frame_token|, +// Finds the PerContextV8MemoryUsage in |isolate| whose token is |token|, // or creates it if it does not exist, and sets its bytes_used to |bytes_used|. -void AddIsolateMemoryUsage(const blink::LocalFrameToken& frame_token, +void AddIsolateMemoryUsage(blink::ExecutionContextToken token, uint64_t bytes_used, blink::mojom::PerIsolateV8MemoryUsage* isolate);
diff --git a/components/policy/core/common/BUILD.gn b/components/policy/core/common/BUILD.gn index ba65baa8..4c99709 100644 --- a/components/policy/core/common/BUILD.gn +++ b/components/policy/core/common/BUILD.gn
@@ -189,6 +189,18 @@ "//url", ] + if (chromeos_is_browser_only) { + sources += [ + "policy_loader_lacros.cc", + "policy_loader_lacros.h", + ] + deps += [ + "//chromeos/crosapi/mojom", + "//chromeos/lacros", + "//chromeos/startup:startup", + ] + } + allow_circular_includes_from = [ # Generated files use policy_details.h and policy_map.h from this target. # TODO(https://crbug.com/945868) - refactor so we don't have dep cycles.
diff --git a/components/policy/core/common/DEPS b/components/policy/core/common/DEPS index 0c358062..ef4d3b8c 100644 --- a/components/policy/core/common/DEPS +++ b/components/policy/core/common/DEPS
@@ -1,4 +1,7 @@ include_rules = [ + "+chromeos/crosapi", + "+chromeos/lacros", + "+chromeos/startup", "+chromeos/system", "+components/account_id", "-components/policy/core/browser",
diff --git a/components/policy/core/common/policy_loader_lacros.cc b/components/policy/core/common/policy_loader_lacros.cc new file mode 100644 index 0000000..3afd3cf0c --- /dev/null +++ b/components/policy/core/common/policy_loader_lacros.cc
@@ -0,0 +1,111 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/policy/core/common/policy_loader_lacros.h" + +#include <stddef.h> + +#include <algorithm> +#include <set> +#include <string> + +#include "base/bind.h" +#include "base/logging.h" +#include "base/stl_util.h" +#include "base/task/task_traits.h" +#include "base/task/thread_pool.h" +#include "base/time/time.h" +#include "chromeos/lacros/lacros_chrome_service_impl.h" +#include "chromeos/startup/startup.h" +#include "components/policy/core/common/cloud/cloud_policy_validator.h" +#include "components/policy/core/common/policy_bundle.h" +#include "components/policy/core/common/policy_proto_decoders.h" +#include "components/policy/proto/device_management_backend.pb.h" + +namespace policy { + +PolicyLoaderLacros::PolicyLoaderLacros( + scoped_refptr<base::SequencedTaskRunner> task_runner) + : AsyncPolicyLoader(task_runner), task_runner_(task_runner) {} + +PolicyLoaderLacros::~PolicyLoaderLacros() = default; + +void PolicyLoaderLacros::InitOnBackgroundThread() { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); +} + +std::unique_ptr<PolicyBundle> PolicyLoaderLacros::Load() { + std::unique_ptr<PolicyBundle> bundle = std::make_unique<PolicyBundle>(); + + crosapi::mojom::LacrosInitParamsPtr result; + const crosapi::mojom::LacrosInitParams* init_params; + auto* lacros_chrome_service = chromeos::LacrosChromeServiceImpl::Get(); + if (lacros_chrome_service) { + init_params = lacros_chrome_service->init_params(); + } else { + // On the first start of Lacros browser, the lacros_chrome_service is + // not initialized yet, so take the data directly from the file. This always + // happens on first start after user login, because policy data is loaded + // before the service is initialized. We cannot do other way, since there + // are other dependencies that create a cycle. The in-memory file is used + // to break the cycle. After that, if user reloads the policy the service + // is present. + // TODO(crbug.com/1114069): This code is duplicated in + // LacrosChromeServiceImpl. We could store the data in a static variable + // inside LacrosChromeServiceImpl and make a single static function to call. + base::Optional<std::string> content = chromeos::ReadStartupData(); + if (!content) { + LOG(ERROR) << "No content in file for init params"; + return bundle; + } + + if (!crosapi::mojom::LacrosInitParams::Deserialize( + content->data(), content->size(), &result)) { + LOG(ERROR) << "Failed to parse startup data"; + return bundle; + } + + init_params = result.get(); + } + + if (!init_params) { + LOG(ERROR) << "No init params"; + return bundle; + } + + if (!init_params->device_account_policy) { + LOG(ERROR) << "No policy data"; + return bundle; + } + + std::vector<uint8_t> data = init_params->device_account_policy.value(); + if (data.empty()) { + return bundle; + } + + auto policy = std::make_unique<enterprise_management::PolicyFetchResponse>(); + if (!policy->ParseFromString(std::string(data.begin(), data.end()))) { + LOG(ERROR) << "Failed to parse policy data"; + return bundle; + } + UserCloudPolicyValidator validator(std::move(policy), task_runner_); + validator.ValidatePayload(); + validator.RunValidation(); + + PolicyMap policy_map; + base::WeakPtr<CloudExternalDataManager> external_data_manager; + DecodeProtoFields(*(validator.payload()), external_data_manager, + PolicySource::POLICY_SOURCE_CLOUD, + PolicyScope::POLICY_SCOPE_USER, &policy_map); + bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) + .MergeFrom(policy_map); + last_modification_ = base::Time::Now(); + return bundle; +} + +base::Time PolicyLoaderLacros::LastModificationTime() { + return last_modification_; +} + +} // namespace policy
diff --git a/components/policy/core/common/policy_loader_lacros.h b/components/policy/core/common/policy_loader_lacros.h new file mode 100644 index 0000000..67ec66b --- /dev/null +++ b/components/policy/core/common/policy_loader_lacros.h
@@ -0,0 +1,48 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_POLICY_CORE_COMMON_POLICY_LOADER_LACROS_H_ +#define COMPONENTS_POLICY_CORE_COMMON_POLICY_LOADER_LACROS_H_ + +#include "base/memory/scoped_refptr.h" +#include "base/sequenced_task_runner.h" +#include "base/time/time.h" +#include "components/policy/core/common/async_policy_loader.h" + +namespace policy { + +// A policy loader for Lacros. The data is taken from Ash and the validatity of +// data is trusted, since they have been validated by Ash. +class POLICY_EXPORT PolicyLoaderLacros : public AsyncPolicyLoader { + public: + // Creates the policy loader, saving the task_runner internally. Later + // task_runner is used to have in sequence the process of policy parsing and + // validation. + explicit PolicyLoaderLacros( + scoped_refptr<base::SequencedTaskRunner> task_runner); + // Not copyable or movable + PolicyLoaderLacros(const PolicyLoaderLacros&) = delete; + PolicyLoaderLacros& operator=(const PolicyLoaderLacros&) = delete; + ~PolicyLoaderLacros() override; + + // AsyncPolicyLoader implementation. + // Verifies that it runs on correct thread. + void InitOnBackgroundThread() override; + // Loads the policy data from LacrosInitParams and populates it in the bundle + // that is returned. + std::unique_ptr<PolicyBundle> Load() override; + // Returns the last time the policy successfully loaded. + base::Time LastModificationTime() override; + + private: + // Task runner for running background jobs. + const scoped_refptr<base::SequencedTaskRunner> task_runner_; + + // The time of last modification. + base::Time last_modification_; +}; + +} // namespace policy + +#endif // COMPONENTS_POLICY_CORE_COMMON_POLICY_LOADER_LACROS_H_
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index eb46a56..de803a35 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -10939,6 +10939,7 @@ 'os_settings', 'camera', 'scanning', + 'web_store', ], }, }, @@ -10963,6 +10964,11 @@ 'value': 'scanning', 'caption': '''Scanning (supported since version 87)''', }, + { + 'name': 'web_store', + 'value': 'web_store', + 'caption': '''Web Store (supported since version 89)''', + }, ], 'supported_on': ['chrome_os:84-'], 'features': { @@ -10970,9 +10976,9 @@ 'dynamic_refresh': True, 'per_profile': False, }, - 'example_value': ['camera', 'browser_settings', 'os_settings', 'scanning'], + 'example_value': ['camera', 'browser_settings', 'os_settings', 'scanning', 'web_store'], 'id': 689, - 'caption': '''Configure the camera, browser settings, os settings, and scanning features to be disabled''', + 'caption': '''Configure the camera, browser settings, os settings, scanning and web store features to be disabled''', 'tags': [], 'desc': '''Allows you to set a list of <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> features to be disabled.
diff --git a/components/safe_browsing/core/browser/sync/BUILD.gn b/components/safe_browsing/core/browser/sync/BUILD.gn index 68a0503..60778a4 100644 --- a/components/safe_browsing/core/browser/sync/BUILD.gn +++ b/components/safe_browsing/core/browser/sync/BUILD.gn
@@ -8,6 +8,8 @@ sources = [ "safe_browsing_primary_account_token_fetcher.cc", "safe_browsing_primary_account_token_fetcher.h", + "sync_utils.cc", + "sync_utils.h", ] deps = [ @@ -15,19 +17,24 @@ "//components/safe_browsing/core/browser:token_fetcher", "//components/safe_browsing/core/common:thread_utils", "//components/signin/public/identity_manager", + "//components/sync/driver", "//google_apis", ] } source_set("unittests") { testonly = true - sources = [ "safe_browsing_primary_account_token_fetcher_unittest.cc" ] + sources = [ + "safe_browsing_primary_account_token_fetcher_unittest.cc", + "sync_utils_unittest.cc", + ] deps = [ ":sync", "//base/test:test_support", "//components/safe_browsing/core/common:test_support", "//components/signin/public/identity_manager:test_support", + "//components/sync/driver:test_support", "//testing/gtest", ] }
diff --git a/components/safe_browsing/core/browser/sync/sync_utils.cc b/components/safe_browsing/core/browser/sync/sync_utils.cc new file mode 100644 index 0000000..ad28be4 --- /dev/null +++ b/components/safe_browsing/core/browser/sync/sync_utils.cc
@@ -0,0 +1,50 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/safe_browsing/core/browser/sync/sync_utils.h" + +#include "components/signin/public/identity_manager/account_info.h" +#include "components/signin/public/identity_manager/consent_level.h" +#include "components/signin/public/identity_manager/identity_manager.h" +#include "components/sync/base/user_selectable_type.h" +#include "components/sync/driver/sync_service.h" +#include "components/sync/driver/sync_service_utils.h" +#include "components/sync/driver/sync_user_settings.h" + +namespace safe_browsing { + +// static +bool SyncUtils::IsPrimaryAccountSignedIn( + signin::IdentityManager* identity_manager) { + CoreAccountInfo primary_account_info = + identity_manager->GetPrimaryAccountInfo( + signin::ConsentLevel::kNotRequired); + return !primary_account_info.account_id.empty(); +} + +// static +bool SyncUtils::AreSigninAndSyncSetUpForSafeBrowsingTokenFetches( + syncer::SyncService* sync_service, + signin::IdentityManager* identity_manager, + bool user_has_enabled_enhanced_protection) { + // If the user has explicitly enabled enhanced protection and the primary + // account is available, no further conditions are needed. + if (user_has_enabled_enhanced_protection && + IsPrimaryAccountSignedIn(identity_manager)) { + return true; + } + + // Otherwise, check the status of sync: Safe browsing token fetches are + // enabled when the user is syncing their browsing history without a custom + // passphrase. + // NOTE: |sync_service| can be null in Incognito, and can also be set to null + // by a cmdline param. + return sync_service && + (syncer::GetUploadToGoogleState( + sync_service, syncer::ModelType::HISTORY_DELETE_DIRECTIVES) == + syncer::UploadState::ACTIVE) && + !sync_service->GetUserSettings()->IsUsingSecondaryPassphrase(); +} + +} // namespace safe_browsing
diff --git a/components/safe_browsing/core/browser/sync/sync_utils.h b/components/safe_browsing/core/browser/sync/sync_utils.h new file mode 100644 index 0000000..e0bd6917 --- /dev/null +++ b/components/safe_browsing/core/browser/sync/sync_utils.h
@@ -0,0 +1,39 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SAFE_BROWSING_CORE_BROWSER_SYNC_SYNC_UTILS_H_ +#define COMPONENTS_SAFE_BROWSING_CORE_BROWSER_SYNC_SYNC_UTILS_H_ + +namespace syncer { +class SyncService; +} + +namespace signin { +class IdentityManager; +} + +namespace safe_browsing { + +// This class implements sync and signin-related safe browsing utilities. +class SyncUtils { + public: + SyncUtils() = delete; + ~SyncUtils() = delete; + + // Returns true if signin and sync are configured such that access token + // fetches for safe browsing can be enabled. + static bool AreSigninAndSyncSetUpForSafeBrowsingTokenFetches( + syncer::SyncService* sync_service, + signin::IdentityManager* identity_manager, + bool user_has_enabled_enhanced_protection); + + private: + // Whether the primary account is signed in. Sync is not required. + static bool IsPrimaryAccountSignedIn( + signin::IdentityManager* identity_manager); +}; // class SyncUtils + +} // namespace safe_browsing + +#endif // COMPONENTS_SAFE_BROWSING_CORE_BROWSER_SYNC_SYNC_UTILS_H_
diff --git a/components/safe_browsing/core/browser/sync/sync_utils_unittest.cc b/components/safe_browsing/core/browser/sync/sync_utils_unittest.cc new file mode 100644 index 0000000..4d971e57 --- /dev/null +++ b/components/safe_browsing/core/browser/sync/sync_utils_unittest.cc
@@ -0,0 +1,113 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/safe_browsing/core/browser/sync/sync_utils.h" + +#include "components/safe_browsing/core/common/test_task_environment.h" +#include "components/signin/public/identity_manager/identity_test_environment.h" +#include "components/sync/driver/test_sync_service.h" +#include "testing/platform_test.h" + +namespace safe_browsing { + +class SyncUtilsTest : public PlatformTest { + public: + SyncUtilsTest() : task_environment_(CreateTestTaskEnvironment()) {} + + std::unique_ptr<base::test::TaskEnvironment> task_environment_; +}; + +TEST_F(SyncUtilsTest, AreSigninAndSyncSetUpForSafeBrowsingTokenFetches_Sync) { + std::unique_ptr<signin::IdentityTestEnvironment> identity_test_env = + std::make_unique<signin::IdentityTestEnvironment>(); + signin::IdentityManager* identity_manager = + identity_test_env->identity_manager(); + syncer::TestSyncService sync_service; + + // For the purposes of this test, IdentityManager has no primary account. + + // Sync is disabled. + sync_service.SetDisableReasons( + {syncer::SyncService::DISABLE_REASON_USER_CHOICE}); + sync_service.SetTransportState(syncer::SyncService::TransportState::DISABLED); + EXPECT_FALSE(SyncUtils::AreSigninAndSyncSetUpForSafeBrowsingTokenFetches( + &sync_service, identity_manager, + /* user_has_enabled_enhanced_protection=*/true)); + EXPECT_FALSE(SyncUtils::AreSigninAndSyncSetUpForSafeBrowsingTokenFetches( + &sync_service, identity_manager, + /* user_has_enabled_enhanced_protection=*/false)); + + // Sync is enabled. + sync_service.SetDisableReasons({}); + sync_service.SetTransportState(syncer::SyncService::TransportState::ACTIVE); + EXPECT_TRUE(SyncUtils::AreSigninAndSyncSetUpForSafeBrowsingTokenFetches( + &sync_service, identity_manager, + /* user_has_enabled_enhanced_protection=*/true)); + EXPECT_TRUE(SyncUtils::AreSigninAndSyncSetUpForSafeBrowsingTokenFetches( + &sync_service, identity_manager, + /* user_has_enabled_enhanced_protection=*/false)); + + // History sync is disabled. + sync_service.GetUserSettings()->SetSelectedTypes( + /* sync_everything */ false, {}); + EXPECT_FALSE(SyncUtils::AreSigninAndSyncSetUpForSafeBrowsingTokenFetches( + &sync_service, identity_manager, + /* user_has_enabled_enhanced_protection=*/true)); + EXPECT_FALSE(SyncUtils::AreSigninAndSyncSetUpForSafeBrowsingTokenFetches( + &sync_service, identity_manager, + /* user_has_enabled_enhanced_protection=*/false)); + + // Custom passphrase is enabled. + sync_service.GetUserSettings()->SetSelectedTypes( + false, {syncer::UserSelectableType::kHistory}); + sync_service.SetIsUsingSecondaryPassphrase(true); + EXPECT_FALSE(SyncUtils::AreSigninAndSyncSetUpForSafeBrowsingTokenFetches( + &sync_service, identity_manager, + /* user_has_enabled_enhanced_protection=*/true)); + EXPECT_FALSE(SyncUtils::AreSigninAndSyncSetUpForSafeBrowsingTokenFetches( + &sync_service, identity_manager, + /* user_has_enabled_enhanced_protection=*/false)); +} + +TEST_F(SyncUtilsTest, + AreSigninAndSyncSetUpForSafeBrowsingTokenFetches_IdentityManager) { + std::unique_ptr<signin::IdentityTestEnvironment> identity_test_env = + std::make_unique<signin::IdentityTestEnvironment>(); + signin::IdentityManager* identity_manager = + identity_test_env->identity_manager(); + syncer::TestSyncService sync_service; + + // For the purposes of this test, disable sync. + sync_service.SetDisableReasons( + {syncer::SyncService::DISABLE_REASON_USER_CHOICE}); + sync_service.SetTransportState(syncer::SyncService::TransportState::DISABLED); + sync_service.GetUserSettings()->SetSelectedTypes( + /* sync_everything */ false, {}); + + // If the user is not signed in, it should not be + // possible to perform URL lookups with tokens. + EXPECT_FALSE(SyncUtils::AreSigninAndSyncSetUpForSafeBrowsingTokenFetches( + &sync_service, identity_manager, + /* user_has_enabled_enhanced_protection=*/true)); + EXPECT_FALSE(SyncUtils::AreSigninAndSyncSetUpForSafeBrowsingTokenFetches( + &sync_service, identity_manager, + /* user_has_enabled_enhanced_protection=*/false)); + + // Enhanced protection is on and the user is signed in: it should be possible + // to perform URL lookups with tokens (even though the + // kRealTimeLookupEnabledWithToken feature and sync/history sync are + // disabled). + identity_test_env->MakeUnconsentedPrimaryAccountAvailable("test@example.com"); + EXPECT_TRUE(SyncUtils::AreSigninAndSyncSetUpForSafeBrowsingTokenFetches( + &sync_service, identity_manager, + /* user_has_enabled_enhanced_protection=*/true)); + + // Enhanced protection is *off* and the user is signed in: it should not be + // possible to perform URL lookups with tokens without sync being enabled. + EXPECT_FALSE(SyncUtils::AreSigninAndSyncSetUpForSafeBrowsingTokenFetches( + &sync_service, identity_manager, + /* user_has_enabled_enhanced_protection=*/false)); +} + +} // namespace safe_browsing
diff --git a/components/safe_browsing/core/realtime/BUILD.gn b/components/safe_browsing/core/realtime/BUILD.gn index f600bd8c..6a58ffb0 100644 --- a/components/safe_browsing/core/realtime/BUILD.gn +++ b/components/safe_browsing/core/realtime/BUILD.gn
@@ -15,8 +15,6 @@ "//components/safe_browsing/core:realtimeapi_proto", "//components/safe_browsing/core/common", "//components/safe_browsing/core/common:safe_browsing_prefs", - "//components/signin/public/identity_manager", - "//components/sync", "//components/unified_consent", "//components/user_prefs", "//components/variations/service",
diff --git a/components/safe_browsing/core/realtime/policy_engine.cc b/components/safe_browsing/core/realtime/policy_engine.cc index cffaf46..6666b75 100644 --- a/components/safe_browsing/core/realtime/policy_engine.cc +++ b/components/safe_browsing/core/realtime/policy_engine.cc
@@ -12,13 +12,6 @@ #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/safe_browsing/core/common/safebrowsing_constants.h" #include "components/safe_browsing/core/features.h" -#include "components/signin/public/identity_manager/account_info.h" -#include "components/signin/public/identity_manager/consent_level.h" -#include "components/signin/public/identity_manager/identity_manager.h" -#include "components/sync/base/user_selectable_type.h" -#include "components/sync/driver/sync_service.h" -#include "components/sync/driver/sync_service_utils.h" -#include "components/sync/driver/sync_user_settings.h" #include "components/unified_consent/pref_names.h" #include "components/user_prefs/user_prefs.h" #include "components/variations/service/variations_service.h" @@ -53,15 +46,6 @@ } // static -bool RealTimePolicyEngine::IsPrimaryAccountSignedIn( - signin::IdentityManager* identity_manager) { - CoreAccountInfo primary_account_info = - identity_manager->GetPrimaryAccountInfo( - signin::ConsentLevel::kNotRequired); - return !primary_account_info.account_id.empty(); -} - -// static bool RealTimePolicyEngine::CanPerformFullURLLookup( PrefService* pref_service, bool is_off_the_record, @@ -84,8 +68,7 @@ bool RealTimePolicyEngine::CanPerformFullURLLookupWithToken( PrefService* pref_service, bool is_off_the_record, - syncer::SyncService* sync_service, - signin::IdentityManager* identity_manager, + ClientConfiguredForTokenFetchesCallback client_callback, variations::VariationsService* variations_service) { if (!CanPerformFullURLLookup(pref_service, is_off_the_record, variations_service)) { @@ -100,23 +83,7 @@ return false; } - // If the user has explicitly enabled enhanced protection and the primary - // account is available, no further conditions are needed. - if (IsUserEpOptedIn(pref_service) && - IsPrimaryAccountSignedIn(identity_manager)) { - return true; - } - - // Otherwise, check the status of sync: Safe browsing token fetches are - // enabled when the user is syncing their browsing history without a custom - // passphrase. - // NOTE: |sync_service| can be null in Incognito, and can also be set to null - // by a cmdline param. - return sync_service && - (syncer::GetUploadToGoogleState( - sync_service, syncer::ModelType::HISTORY_DELETE_DIRECTIVES) == - syncer::UploadState::ACTIVE) && - !sync_service->GetUserSettings()->IsUsingSecondaryPassphrase(); + return std::move(client_callback).Run(IsUserEpOptedIn(pref_service)); } // static
diff --git a/components/safe_browsing/core/realtime/policy_engine.h b/components/safe_browsing/core/realtime/policy_engine.h index a94027bd..4252d04 100644 --- a/components/safe_browsing/core/realtime/policy_engine.h +++ b/components/safe_browsing/core/realtime/policy_engine.h
@@ -7,18 +7,11 @@ #include <string> +#include "base/callback.h" #include "build/build_config.h" class PrefService; -namespace syncer { -class SyncService; -} - -namespace signin { -class IdentityManager; -} - namespace variations { class VariationsService; } @@ -37,6 +30,12 @@ RealTimePolicyEngine() = delete; ~RealTimePolicyEngine() = delete; + // A callback via which the client of this component indicates whether they + // are configured to support token fetches. Used as part of + // CanPerformFullURLLookupWithToken(). + using ClientConfiguredForTokenFetchesCallback = + base::OnceCallback<bool(bool user_has_enabled_enhanced_protection)>; + // Return true if full URL lookups are enabled for |resource_type|. If // |can_rt_check_subresource_url| is set to false, return true only if // |resource_type| is |kMainFrame|. @@ -57,8 +56,7 @@ static bool CanPerformFullURLLookupWithToken( PrefService* pref_service, bool is_off_the_record, - syncer::SyncService* sync_service, - signin::IdentityManager* identity_manager, + ClientConfiguredForTokenFetchesCallback client_callback, variations::VariationsService* variations_service); static bool CanPerformEnterpriseFullURLLookup(const PrefService* pref_service, @@ -79,10 +77,6 @@ // Whether the user has opted-in to Enhanced Protection. static bool IsUserEpOptedIn(PrefService* pref_service); - // Whether the primary account is signed in. Sync is not required. - static bool IsPrimaryAccountSignedIn( - signin::IdentityManager* identity_manager); - friend class RealTimePolicyEngineTest; }; // class RealTimePolicyEngine
diff --git a/components/safe_browsing/core/realtime/policy_engine_unittest.cc b/components/safe_browsing/core/realtime/policy_engine_unittest.cc index 1dfe226..4227847 100644 --- a/components/safe_browsing/core/realtime/policy_engine_unittest.cc +++ b/components/safe_browsing/core/realtime/policy_engine_unittest.cc
@@ -10,8 +10,6 @@ #include "components/safe_browsing/core/common/safebrowsing_constants.h" #include "components/safe_browsing/core/common/test_task_environment.h" #include "components/safe_browsing/core/features.h" -#include "components/signin/public/identity_manager/identity_test_environment.h" -#include "components/sync/driver/test_sync_service.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "components/unified_consent/pref_names.h" #include "components/unified_consent/unified_consent_service.h" @@ -20,6 +18,15 @@ namespace safe_browsing { +// Used in tests of CanPerformFullURLLookupWithToken(). +bool AreTokenFetchesEnabledInClient(bool expected_ep_enabled_value, + bool return_value, + bool user_has_enabled_enhanced_protection) { + EXPECT_EQ(expected_ep_enabled_value, user_has_enabled_enhanced_protection); + + return return_value; +} + class RealTimePolicyEngineTest : public PlatformTest { public: RealTimePolicyEngineTest() : task_environment_(CreateTestTaskEnvironment()) {} @@ -41,10 +48,10 @@ bool CanPerformFullURLLookupWithToken( bool is_off_the_record, - syncer::SyncService* sync_service, - signin::IdentityManager* identity_manager) { + RealTimePolicyEngine::ClientConfiguredForTokenFetchesCallback + client_callback) { return RealTimePolicyEngine::CanPerformFullURLLookupWithToken( - &pref_service_, is_off_the_record, sync_service, identity_manager, + &pref_service_, is_off_the_record, std::move(client_callback), /*variations_service=*/nullptr); } @@ -106,26 +113,22 @@ TEST_F(RealTimePolicyEngineTest, TestCanPerformFullURLLookup_RTLookupForEpEnabled_WithTokenDisabled) { - std::unique_ptr<signin::IdentityTestEnvironment> identity_test_env = - std::make_unique<signin::IdentityTestEnvironment>(); - signin::IdentityManager* identity_manager = - identity_test_env->identity_manager(); - syncer::TestSyncService sync_service; - // User is signed in. - identity_test_env->MakeUnconsentedPrimaryAccountAvailable("test@example.com"); - pref_service_.SetBoolean(prefs::kSafeBrowsingEnhanced, true); { base::test::ScopedFeatureList feature_list; feature_list.InitAndEnableFeature(kEnhancedProtection); EXPECT_TRUE(CanPerformFullURLLookup(/* is_off_the_record */ false)); EXPECT_TRUE(CanPerformFullURLLookupWithToken( - /* is_off_the_record */ false, &sync_service, identity_manager)); + /* is_off_the_record */ false, + base::BindOnce(&AreTokenFetchesEnabledInClient, + /*expected_ep_enabled_value=*/true, + /*return_value=*/true))); } } -TEST_F(RealTimePolicyEngineTest, - TestCanPerformFullURLLookupWithToken_SyncControlled) { +TEST_F( + RealTimePolicyEngineTest, + TestCanPerformFullURLLookupWithToken_ClientControlledWithoutEnhancedProtection) { base::test::ScopedFeatureList feature_list; feature_list.InitWithFeatures( /* enabled_features */ {kRealTimeUrlLookupEnabled, @@ -134,71 +137,57 @@ pref_service_.SetUserPref( unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled, std::make_unique<base::Value>(true)); - std::unique_ptr<signin::IdentityTestEnvironment> identity_test_env = - std::make_unique<signin::IdentityTestEnvironment>(); - signin::IdentityManager* identity_manager = - identity_test_env->identity_manager(); - syncer::TestSyncService sync_service; - // Sync is disabled. - sync_service.SetDisableReasons( - {syncer::SyncService::DISABLE_REASON_USER_CHOICE}); - sync_service.SetTransportState(syncer::SyncService::TransportState::DISABLED); + // Token fetches are not configured in the client. EXPECT_FALSE(CanPerformFullURLLookupWithToken( - /* is_off_the_record */ false, &sync_service, identity_manager)); + /* is_off_the_record */ false, + base::BindOnce(&AreTokenFetchesEnabledInClient, + /*expected_ep_enabled_value=*/false, + /*return_value=*/false))); - // Sync is enabled. - sync_service.SetDisableReasons({}); - sync_service.SetTransportState(syncer::SyncService::TransportState::ACTIVE); + // Token fetches are configured in the client. EXPECT_TRUE(CanPerformFullURLLookupWithToken( - /* is_off_the_record */ false, &sync_service, identity_manager)); - - // History sync is disabled. - sync_service.GetUserSettings()->SetSelectedTypes( - /* sync_everything */ false, {}); - EXPECT_FALSE(CanPerformFullURLLookupWithToken( - /* is_off_the_record */ false, &sync_service, identity_manager)); - - // Custom passphrase is enabled. - sync_service.GetUserSettings()->SetSelectedTypes( - false, {syncer::UserSelectableType::kHistory}); - sync_service.SetIsUsingSecondaryPassphrase(true); - EXPECT_FALSE(CanPerformFullURLLookupWithToken( - /* is_off_the_record */ false, &sync_service, identity_manager)); + /* is_off_the_record */ false, + base::BindOnce(&AreTokenFetchesEnabledInClient, + /*expected_ep_enabled_value=*/false, + /*return_value=*/true))); } -TEST_F(RealTimePolicyEngineTest, - TestCanPerformFullURLLookupWithToken_EnhancedProtection) { +TEST_F( + RealTimePolicyEngineTest, + TestCanPerformFullURLLookupWithToken_ClientControlledWithEnhancedProtection) { base::test::ScopedFeatureList feature_list; feature_list.InitWithFeatures( /* enabled_features */ {kEnhancedProtection}, /* disabled_features */ {kRealTimeUrlLookupEnabledWithToken}); - std::unique_ptr<signin::IdentityTestEnvironment> identity_test_env = - std::make_unique<signin::IdentityTestEnvironment>(); - signin::IdentityManager* identity_manager = - identity_test_env->identity_manager(); - syncer::TestSyncService sync_service; - // For the purposes of this test, disable sync. - sync_service.SetDisableReasons( - {syncer::SyncService::DISABLE_REASON_USER_CHOICE}); - sync_service.SetTransportState(syncer::SyncService::TransportState::DISABLED); - sync_service.GetUserSettings()->SetSelectedTypes( - /* sync_everything */ false, {}); + // Enhanced protection is not enabled and the Finch feature is disabled: token + // fetches should be disallowed whether or not they are configured in the + // client. + EXPECT_FALSE(CanPerformFullURLLookupWithToken( + /* is_off_the_record */ false, + base::BindOnce(&AreTokenFetchesEnabledInClient, + /*expected_ep_enabled_value=*/false, + /*return_value=*/false))); + EXPECT_FALSE(CanPerformFullURLLookupWithToken( + /* is_off_the_record */ false, + base::BindOnce(&AreTokenFetchesEnabledInClient, + /*expected_ep_enabled_value=*/false, + /*return_value=*/true))); - // Enhanced protection is on but the user is not signed in: it should not be - // possible to perform URL lookups with tokens. + // With enhanced protection enabled, whether token fetches are allowed should + // be dependent on the configuration of the client pref_service_.SetBoolean(prefs::kSafeBrowsingEnhanced, true); EXPECT_FALSE(CanPerformFullURLLookupWithToken( - /* is_off_the_record */ false, &sync_service, identity_manager)); - - // Enhanced protection is on and the user is signed in: it should be possible - // to perform URL lookups with tokens (even though the - // kRealTimeLookupEnabledWithToken feature and sync/history sync are - // disabled). - identity_test_env->MakeUnconsentedPrimaryAccountAvailable("test@example.com"); + /* is_off_the_record */ false, + base::BindOnce(&AreTokenFetchesEnabledInClient, + /*expected_ep_enabled_value=*/true, + /*return_value=*/false))); EXPECT_TRUE(CanPerformFullURLLookupWithToken( - /* is_off_the_record */ false, &sync_service, identity_manager)); + /* is_off_the_record */ false, + base::BindOnce(&AreTokenFetchesEnabledInClient, + /*expected_ep_enabled_value=*/true, + /*return_value=*/true))); } TEST_F(RealTimePolicyEngineTest, TestCanPerformEnterpriseFullURLLookup) {
diff --git a/components/safe_browsing/core/realtime/url_lookup_service.cc b/components/safe_browsing/core/realtime/url_lookup_service.cc index 1c796a7..543a38db 100644 --- a/components/safe_browsing/core/realtime/url_lookup_service.cc +++ b/components/safe_browsing/core/realtime/url_lookup_service.cc
@@ -14,6 +14,7 @@ #include "components/prefs/pref_service.h" #include "components/safe_browsing/buildflags.h" #include "components/safe_browsing/core/browser/sync/safe_browsing_primary_account_token_fetcher.h" +#include "components/safe_browsing/core/browser/sync/sync_utils.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/safe_browsing/core/common/thread_utils.h" #include "components/safe_browsing/core/db/v4_protocol_manager_util.h" @@ -92,7 +93,10 @@ bool RealTimeUrlLookupService::CanPerformFullURLLookupWithToken() const { return RealTimePolicyEngine::CanPerformFullURLLookupWithToken( - pref_service_, is_off_the_record_, sync_service_, identity_manager_, + pref_service_, is_off_the_record_, + base::BindOnce( + &SyncUtils::AreSigninAndSyncSetUpForSafeBrowsingTokenFetches, + sync_service_, identity_manager_), variations_); }
diff --git a/components/signin/internal/identity_manager/gaia_cookie_manager_service_unittest.cc b/components/signin/internal/identity_manager/gaia_cookie_manager_service_unittest.cc index 2c298d65..bbe4939 100644 --- a/components/signin/internal/identity_manager/gaia_cookie_manager_service_unittest.cc +++ b/components/signin/internal/identity_manager/gaia_cookie_manager_service_unittest.cc
@@ -299,8 +299,8 @@ MockObserver observer(&helper); auto test_task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); - base::ScopedClosureRunner task_runner_ = - base::ThreadTaskRunnerHandle::OverrideForTesting(test_task_runner); + base::ThreadTaskRunnerHandleOverrideForTesting ttrh_override( + test_task_runner); EXPECT_CALL(helper, StartFetchingUbertoken()); EXPECT_CALL(helper, StartFetchingMergeSession()); @@ -323,8 +323,8 @@ base::HistogramTester histograms; auto test_task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); - base::ScopedClosureRunner task_runner_ = - base::ThreadTaskRunnerHandle::OverrideForTesting(test_task_runner); + base::ThreadTaskRunnerHandleOverrideForTesting ttrh_override( + test_task_runner); EXPECT_CALL(helper, StartFetchingUbertoken()); EXPECT_CALL(helper, StartFetchingMergeSession()).Times(2); @@ -917,8 +917,8 @@ MockObserver observer(&helper); auto test_task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); - base::ScopedClosureRunner task_runner_ = - base::ThreadTaskRunnerHandle::OverrideForTesting(test_task_runner); + base::ThreadTaskRunnerHandleOverrideForTesting ttrh_override( + test_task_runner); EXPECT_CALL(helper, StartFetchingListAccounts()).Times(3);
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc index 211d685..f13f837 100644 --- a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc +++ b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc
@@ -18,6 +18,7 @@ #include "components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h" #include "components/subresource_filter/content/browser/async_document_subresource_filter.h" #include "components/subresource_filter/content/browser/page_load_statistics.h" +#include "components/subresource_filter/content/browser/profile_interaction_manager.h" #include "components/subresource_filter/content/browser/subresource_filter_client.h" #include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.h" #include "components/subresource_filter/content/common/subresource_filter_messages.h" @@ -438,7 +439,7 @@ client_->GetSafeBrowsingDatabaseManager()) { throttles->push_back( std::make_unique<SubresourceFilterSafeBrowsingActivationThrottle>( - navigation_handle, client_.get(), + navigation_handle, client_->GetProfileInteractionManager(), content::GetIOThreadTaskRunner({}), client_->GetSafeBrowsingDatabaseManager())); }
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc index 2c725f2..a3e338e 100644 --- a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc +++ b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc
@@ -183,12 +183,6 @@ // SubresourceFilterClient: void ShowNotification() override { ++disallowed_notification_count_; } - mojom::ActivationLevel OnPageActivationComputed( - content::NavigationHandle* navigation_handle, - mojom::ActivationLevel effective_activation_level, - ActivationDecision* decision) override { - return effective_activation_level; - } void OnAdsViolationTriggered( content::RenderFrameHost* rfh, mojom::AdsViolation triggered_violation) override {} @@ -196,6 +190,10 @@ GetSafeBrowsingDatabaseManager() override { return database_manager_; } + subresource_filter::ProfileInteractionManager* GetProfileInteractionManager() + override { + return nullptr; + } void OnReloadRequested() override {} void CreateSafeBrowsingDatabaseManager() {
diff --git a/components/subresource_filter/content/browser/profile_interaction_manager.h b/components/subresource_filter/content/browser/profile_interaction_manager.h index 015ecf4..8081870c 100644 --- a/components/subresource_filter/content/browser/profile_interaction_manager.h +++ b/components/subresource_filter/content/browser/profile_interaction_manager.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_PROFILE_INTERACTION_MANAGER_H_ #define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_PROFILE_INTERACTION_MANAGER_H_ +#include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.h" #include "components/subresource_filter/core/common/activation_decision.h" #include "components/subresource_filter/core/mojom/subresource_filter.mojom.h" #include "content/public/browser/web_contents_observer.h" @@ -21,7 +22,9 @@ // Class that manages interaction between interaction between the // per-navigation/per-tab subresource filter objects (i.e., the throttles and // throttle manager) and the per-profile objects (e.g., content settings). -class ProfileInteractionManager : public content::WebContentsObserver { +class ProfileInteractionManager + : public content::WebContentsObserver, + public SubresourceFilterSafeBrowsingActivationThrottle::Delegate { public: ProfileInteractionManager(content::WebContents* web_contents, SubresourceFilterProfileContext* profile_context); @@ -43,19 +46,11 @@ void OnAdsViolationTriggered(content::RenderFrameHost* rfh, mojom::AdsViolation triggered_violation); - // Called when the initial activation decision has been computed by the - // safe browsing activation throttle. This object then applies any adjustments - // based on relevant state of the Profile (e.g., content settings). Returns - // the effective activation for this navigation. - // - // Note: |decision| is guaranteed to be non-nullptr, and can be modified by - // this method if any decision changes. - // - // Precondition: The navigation must be a main frame navigation. + // SubresourceFilterSafeBrowsingActivationThrottle::Delegate: mojom::ActivationLevel OnPageActivationComputed( content::NavigationHandle* navigation_handle, mojom::ActivationLevel initial_activation_level, - ActivationDecision* decision); + ActivationDecision* decision) override; private: // Unowned and must outlive this object.
diff --git a/components/subresource_filter/content/browser/subresource_filter_client.h b/components/subresource_filter/content/browser/subresource_filter_client.h index 2b4e80d..cdd3b9e 100644 --- a/components/subresource_filter/content/browser/subresource_filter_client.h +++ b/components/subresource_filter/content/browser/subresource_filter_client.h
@@ -6,15 +6,8 @@ #define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBRESOURCE_FILTER_CLIENT_H_ #include "base/memory/scoped_refptr.h" -#include "components/subresource_filter/content/browser/verified_ruleset_dealer.h" -#include "components/subresource_filter/core/common/activation_decision.h" #include "components/subresource_filter/core/mojom/subresource_filter.mojom.h" #include "content/public/browser/render_frame_host.h" -#include "content/public/browser/web_contents.h" - -namespace content { -class NavigationHandle; -} // namespace content namespace safe_browsing { class SafeBrowsingDatabaseManager; @@ -22,6 +15,8 @@ namespace subresource_filter { +class ProfileInteractionManager; + class SubresourceFilterClient { public: virtual ~SubresourceFilterClient() = default; @@ -30,20 +25,6 @@ // blocked. This method will be called at most once per main-frame navigation. virtual void ShowNotification() = 0; - // Called when the activation decision is otherwise completely computed by the - // subresource filter. At this point, the embedder still has a chance to - // alter the effective activation. Returns the effective activation for this - // navigation. - // - // Note: |decision| is guaranteed to be non-nullptr, and can be modified by - // the embedder if any decision changes. - // - // Precondition: The navigation must be a main frame navigation. - virtual mojom::ActivationLevel OnPageActivationComputed( - content::NavigationHandle* navigation_handle, - mojom::ActivationLevel initial_activation_level, - subresource_filter::ActivationDecision* decision) = 0; - // Called on the subresource filter client when an ads violation is detected. virtual void OnAdsViolationTriggered( content::RenderFrameHost* rfh, @@ -54,6 +35,14 @@ virtual const scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> GetSafeBrowsingDatabaseManager() = 0; + // Returns the ProfileInteractionManager instance associated with this + // client, or null if there is no such instance. + // TODO(crbug.com/1116095): Have ContentSubresourceFilterThrottleManager + // create and own this object internally once ChromeSubresourceFilterClient no + // longer calls into it, replacing this method with a getter for + // SubresourceFilterProfileContext. + virtual ProfileInteractionManager* GetProfileInteractionManager() = 0; + // Invoked when the user has requested a reload of a page with blocked ads // (e.g., via an infobar). virtual void OnReloadRequested() = 0;
diff --git a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.cc b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.cc index 3f444aa..6a6d09b 100644 --- a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.cc +++ b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.cc
@@ -17,7 +17,6 @@ #include "components/subresource_filter/content/browser/content_activation_list_utils.h" #include "components/subresource_filter/content/browser/devtools_interaction_tracker.h" #include "components/subresource_filter/content/browser/navigation_console_logger.h" -#include "components/subresource_filter/content/browser/subresource_filter_client.h" #include "components/subresource_filter/content/browser/subresource_filter_observer_manager.h" #include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.h" #include "components/subresource_filter/core/browser/subresource_filter_constants.h" @@ -64,7 +63,7 @@ SubresourceFilterSafeBrowsingActivationThrottle:: SubresourceFilterSafeBrowsingActivationThrottle( content::NavigationHandle* handle, - SubresourceFilterClient* client, + Delegate* delegate, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager) @@ -76,7 +75,7 @@ io_task_runner_, base::ThreadTaskRunnerHandle::Get()), base::OnTaskRunnerDeleter(io_task_runner_)), - client_(client) { + delegate_(delegate) { DCHECK(handle->IsInMainFrame()); CheckCurrentUrl(); @@ -205,9 +204,11 @@ activation_decision = ActivationDecision::FORCED_ACTIVATION; } - // Let the embedder get the last word when it comes to activation level. - activation_level = client_->OnPageActivationComputed( - navigation_handle(), activation_level, &activation_decision); + // Let the delegate adjust the activation decision if present. + if (delegate_) { + activation_level = delegate_->OnPageActivationComputed( + navigation_handle(), activation_level, &activation_decision); + } LogMetricsOnChecksComplete(selection.matched_list, activation_decision, activation_level);
diff --git a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.h b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.h index b3fc830..43e42b8 100644 --- a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.h +++ b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.h
@@ -26,8 +26,6 @@ namespace subresource_filter { -class SubresourceFilterClient; - // Enum representing a position in the redirect chain. These values are // persisted to logs. Entries should not be renumbered and numeric values should // never be reused. @@ -46,9 +44,32 @@ public base::SupportsWeakPtr< SubresourceFilterSafeBrowsingActivationThrottle> { public: + // Interface that allows the client of this class to adjust activation + // decisions if/as desired. + class Delegate { + public: + virtual ~Delegate() = default; + + // Called when the initial activation decision has been computed by the + // safe browsing activation throttle. Returns + // the effective activation for this navigation. + // + // Note: |decision| is guaranteed to be non-nullptr, and can be modified by + // this method if any decision changes. + // + // Precondition: The navigation must be a main frame navigation. + virtual mojom::ActivationLevel OnPageActivationComputed( + content::NavigationHandle* navigation_handle, + mojom::ActivationLevel initial_activation_level, + ActivationDecision* decision) = 0; + }; + + // |delegate| is allowed to be null, in which case the client creating this + // throttle will not be able to adjust activation decisions made by the + // throttle. SubresourceFilterSafeBrowsingActivationThrottle( content::NavigationHandle* handle, - SubresourceFilterClient* client, + Delegate* delegate, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager); @@ -110,8 +131,8 @@ base::OnTaskRunnerDeleter> database_client_; - // Must outlive this class. - SubresourceFilterClient* client_; + // May be null. If non-null, must outlive this class. + Delegate* delegate_; // Set to TimeTicks::Now() when the navigation is deferred in // WillProcessResponse. If deferral was not necessary, will remain null.
diff --git a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc index 08f1cc5..a86533d 100644 --- a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc +++ b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc
@@ -24,6 +24,7 @@ #include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h" #include "components/subresource_filter/content/browser/devtools_interaction_tracker.h" #include "components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h" +#include "components/subresource_filter/content/browser/profile_interaction_manager.h" #include "components/subresource_filter/content/browser/subresource_filter_client.h" #include "components/subresource_filter/content/browser/subresource_filter_observer_test_utils.h" #include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.h" @@ -69,11 +70,17 @@ "SubresourceFilter.PageLoad.ActivationList"; const char kSubresourceFilterActionsHistogram[] = "SubresourceFilter.Actions2"; -class MockSubresourceFilterClient : public SubresourceFilterClient { +class TestSafeBrowsingActivationThrottleDelegate + : public SubresourceFilterSafeBrowsingActivationThrottle::Delegate { public: - MockSubresourceFilterClient() = default; - ~MockSubresourceFilterClient() override = default; + TestSafeBrowsingActivationThrottleDelegate() = default; + ~TestSafeBrowsingActivationThrottleDelegate() override = default; + TestSafeBrowsingActivationThrottleDelegate( + const TestSafeBrowsingActivationThrottleDelegate&) = delete; + TestSafeBrowsingActivationThrottleDelegate& operator=( + const TestSafeBrowsingActivationThrottleDelegate&) = delete; + // SubresourceFilterSafeBrowsingActivationThrottle::Delegate: mojom::ActivationLevel OnPageActivationComputed( content::NavigationHandle* handle, mojom::ActivationLevel effective_level, @@ -88,15 +95,6 @@ return effective_level; } - MOCK_METHOD0(ShowNotification, void()); - MOCK_METHOD2(OnAdsViolationTriggered, - void(content::RenderFrameHost*, - subresource_filter::mojom::AdsViolation)); - MOCK_METHOD0( - GetSafeBrowsingDatabaseManager, - const scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>()); - MOCK_METHOD0(OnReloadRequested, void()); - void AllowlistInCurrentWebContents(const GURL& url) { ASSERT_TRUE(url.SchemeIsHTTPOrHTTPS()); allowlisted_hosts_.insert(url.host()); @@ -106,7 +104,25 @@ private: std::set<std::string> allowlisted_hosts_; +}; +class MockSubresourceFilterClient : public SubresourceFilterClient { + public: + MockSubresourceFilterClient() = default; + ~MockSubresourceFilterClient() override = default; + + MOCK_METHOD0(ShowNotification, void()); + MOCK_METHOD2(OnAdsViolationTriggered, + void(content::RenderFrameHost*, + subresource_filter::mojom::AdsViolation)); + MOCK_METHOD0( + GetSafeBrowsingDatabaseManager, + const scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>()); + MOCK_METHOD0(GetProfileInteractionManager, + subresource_filter::ProfileInteractionManager*()); + MOCK_METHOD0(OnReloadRequested, void()); + + private: DISALLOW_COPY_AND_ASSIGN(MockSubresourceFilterClient); }; @@ -213,7 +229,7 @@ if (navigation_handle->IsInMainFrame()) { navigation_handle->RegisterThrottleForTesting( std::make_unique<SubresourceFilterSafeBrowsingActivationThrottle>( - navigation_handle, client(), test_io_task_runner_, + navigation_handle, delegate(), test_io_task_runner_, fake_safe_browsing_database_)); } std::vector<std::unique_ptr<content::NavigationThrottle>> throttles; @@ -337,6 +353,7 @@ MockSubresourceFilterClient* client() { return client_; } + TestSafeBrowsingActivationThrottleDelegate* delegate() { return &delegate_; } base::TestMockTimeTaskRunner* test_io_task_runner() const { return test_io_task_runner_.get(); } @@ -352,6 +369,7 @@ testing::TestRulesetCreator test_ruleset_creator_; testing::TestRulesetPair test_ruleset_pair_; + TestSafeBrowsingActivationThrottleDelegate delegate_; std::unique_ptr<VerifiedRulesetDealer::Handle> ruleset_dealer_; std::unique_ptr<ContentSubresourceFilterThrottleManager> throttle_manager_; @@ -519,7 +537,7 @@ *observer()->GetPageActivationForLastCommittedLoad()); // Allowlisting occurs last, so the decision should still be DISABLED. - client()->AllowlistInCurrentWebContents(url); + delegate()->AllowlistInCurrentWebContents(url); SimulateNavigateAndCommit({url}, main_rfh()); EXPECT_EQ(mojom::ActivationLevel::kDisabled, *observer()->GetPageActivationForLastCommittedLoad()); @@ -792,7 +810,7 @@ EXPECT_EQ(test_data.expected_activation_level, *observer()->GetPageActivationForLastCommittedLoad()); if (test_data.url_matches_activation_list) { - client()->AllowlistInCurrentWebContents(test_url); + delegate()->AllowlistInCurrentWebContents(test_url); SimulateNavigateAndCommit({test_url}, main_rfh()); EXPECT_EQ(mojom::ActivationLevel::kDisabled, *observer()->GetPageActivationForLastCommittedLoad());
diff --git a/components/webapps/installable/installable_manager.h b/components/webapps/installable/installable_manager.h index 8b0b515..97d56750 100644 --- a/components/webapps/installable/installable_manager.h +++ b/components/webapps/installable/installable_manager.h
@@ -90,9 +90,6 @@ FRIEND_TEST_ALL_PREFIXES(InstallableManagerBrowserTest, ManagerBeginsInEmptyState); FRIEND_TEST_ALL_PREFIXES(InstallableManagerBrowserTest, ManagerInIncognito); - FRIEND_TEST_ALL_PREFIXES(InstallableManagerBrowserTest, CheckWebapp); - FRIEND_TEST_ALL_PREFIXES(InstallableManagerBrowserTest, - CheckLazyServiceWorkerPassesWhenWaiting); FRIEND_TEST_ALL_PREFIXES(InstallableManagerBrowserTest, CheckLazyServiceWorkerNoFetchHandlerFails); FRIEND_TEST_ALL_PREFIXES(InstallableManagerBrowserTest, @@ -101,6 +98,8 @@ CheckLazyServiceWorkerPassesWhenWaiting); FRIEND_TEST_ALL_PREFIXES(InstallableManagerOfflineCapabilityBrowserTest, CheckWebapp); + FRIEND_TEST_ALL_PREFIXES(InstallableManagerOfflineCapabilityBrowserTest, + CheckNotOfflineCapableStartUrl); using IconPurpose = blink::mojom::ManifestImageResource_Purpose;
diff --git a/content/browser/cookie_store/cookie_change_subscription.cc b/content/browser/cookie_store/cookie_change_subscription.cc index 6c73ba4..07b9b55 100644 --- a/content/browser/cookie_store/cookie_change_subscription.cc +++ b/content/browser/cookie_store/cookie_change_subscription.cc
@@ -167,11 +167,15 @@ break; } + // We assume that this is a same-site, same-party context. net::CookieOptions net_options; net_options.set_same_site_cookie_context( net::CookieOptions::SameSiteCookieContext::MakeInclusive()); net_options.set_same_party_cookie_context_type( net::CookieOptions::SamePartyCookieContextType::kSameParty); + // It doesn't matter which we choose here, since both SameParty and SameSite + // semantics should allow this access. But we make a choice to be explicit. + net_options.set_is_in_nontrivial_first_party_set(true); return cookie .IncludeForRequestURL(
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index b1bab00..3d3a24b 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -2557,7 +2557,7 @@ } void RenderFrameHostImpl::SwapIn() { - GetNavigationControl()->SwapIn(); + GetAssociatedLocalFrame()->SwapInImmediately(); } void RenderFrameHostImpl::Init() {
diff --git a/content/browser/service_worker/embedded_worker_test_helper.cc b/content/browser/service_worker/embedded_worker_test_helper.cc index 7873a1f..21cfacc 100644 --- a/content/browser/service_worker/embedded_worker_test_helper.cc +++ b/content/browser/service_worker/embedded_worker_test_helper.cc
@@ -43,12 +43,11 @@ base::MakeRefCounted<URLLoaderFactoryGetter>()) { scoped_refptr<base::SequencedTaskRunner> database_task_runner = base::ThreadTaskRunnerHandle::Get(); - wrapper_->InitOnCoreThread( - user_data_directory, std::move(database_task_runner), + wrapper_->InitInternal( + user_data_directory, /*quota_manager_proxy=*/nullptr, special_storage_policy, nullptr, - url_loader_factory_getter_.get(), - wrapper_->CreateNonNetworkPendingURLLoaderFactoryBundleForUpdateCheck( - browser_context_.get())); + url_loader_factory_getter_.get(), std::move(database_task_runner), + browser_context_.get()); wrapper_->process_manager()->SetProcessIdForTest(mock_render_process_id()); wrapper_->process_manager()->SetNewProcessIdForTest(new_render_process_id());
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc index 2d16df1..56bff13 100644 --- a/content/browser/service_worker/service_worker_browsertest.cc +++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -351,16 +351,15 @@ shell()->web_contents()->GetBrowserContext()); wrapper_ = static_cast<ServiceWorkerContextWrapper*>( partition->GetServiceWorkerContext()); - - RunOnCoreThread( - base::BindOnce(&self::SetUpOnCoreThread, base::Unretained(this))); } void TearDownOnMainThread() override { - base::RunLoop loop; - RunOnCoreThread(base::BindOnce(&self::TearDownOnCoreThread, - base::Unretained(this), loop.QuitClosure())); - loop.Run(); + // Flush remote storage control so that all pending callbacks are executed. + wrapper() + ->context() + ->registry() + ->GetRemoteStorageControl() + .FlushForTesting(); content::RunAllTasksUntilIdle(); wrapper_ = nullptr; } @@ -379,18 +378,6 @@ 1); } - virtual void SetUpOnCoreThread() {} - - virtual void TearDownOnCoreThread(base::OnceClosure callback) { - // Flush remote storage control so that all pending callbacks are executed. - wrapper() - ->context() - ->registry() - ->GetRemoteStorageControl() - .FlushForTesting(); - std::move(callback).Run(); - } - ServiceWorkerContextWrapper* wrapper() { return wrapper_.get(); } ServiceWorkerContext* public_context() { return wrapper(); }
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc index a9a4ebc6..eed3193 100644 --- a/content/browser/service_worker/service_worker_context_wrapper.cc +++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -28,7 +28,6 @@ #include "content/browser/service_worker/embedded_worker_status.h" #include "content/browser/service_worker/service_worker_container_host.h" #include "content/browser/service_worker/service_worker_host.h" -#include "content/browser/service_worker/service_worker_metrics.h" #include "content/browser/service_worker/service_worker_object_host.h" #include "content/browser/service_worker/service_worker_process_manager.h" #include "content/browser/service_worker/service_worker_quota_client.h" @@ -60,16 +59,16 @@ void WorkerStarted(ServiceWorkerContextWrapper::StatusCallback callback, blink::ServiceWorkerStatusCode status) { - DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); GetUIThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(std::move(callback), status)); } -void StartActiveWorkerOnCoreThread( +void DidFindRegistrationForStartActiveWorker( ServiceWorkerContextWrapper::StatusCallback callback, blink::ServiceWorkerStatusCode status, scoped_refptr<ServiceWorkerRegistration> registration) { - DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (status != blink::ServiceWorkerStatusCode::kOk || !registration->active_version()) { @@ -88,24 +87,12 @@ base::BindOnce(WorkerStarted, std::move(callback))); } -void SkipWaitingWorkerOnCoreThread( - blink::ServiceWorkerStatusCode status, - scoped_refptr<ServiceWorkerRegistration> registration) { - DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); - if (status != blink::ServiceWorkerStatusCode::kOk || - !registration->waiting_version()) - return; - - registration->waiting_version()->set_skip_waiting(true); - registration->ActivateWaitingVersionWhenReady(); -} - void DidStartWorker( scoped_refptr<ServiceWorkerVersion> version, ServiceWorkerContext::StartWorkerCallback info_callback, ServiceWorkerContext::StartWorkerFailureCallback error_callback, blink::ServiceWorkerStatusCode start_worker_status) { - DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (start_worker_status != blink::ServiceWorkerStatusCode::kOk) { std::move(error_callback).Run(start_worker_status); return; @@ -121,7 +108,7 @@ ServiceWorkerContext::StartWorkerFailureCallback failure_callback, blink::ServiceWorkerStatusCode service_worker_status, scoped_refptr<ServiceWorkerRegistration> registration) { - DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) { std::move(failure_callback).Run(service_worker_status); return; @@ -154,48 +141,42 @@ std::move(failure_callback))); } -void FinishRegistrationOnCoreThread( - ServiceWorkerContext::ResultCallback callback, - blink::ServiceWorkerStatusCode status, - const std::string& status_message, - int64_t registration_id) { - DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); - GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), - status == blink::ServiceWorkerStatusCode::kOk)); -} - -void FinishUnregistrationOnCoreThread( - ServiceWorkerContext::ResultCallback callback, - blink::ServiceWorkerStatusCode status) { - DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); - GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), - status == blink::ServiceWorkerStatusCode::kOk)); -} - -void MessageFinishedSending(ServiceWorkerContext::ResultCallback callback, - scoped_refptr<base::TaskRunner> callback_runner, - blink::ServiceWorkerStatusCode status) { - DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); - callback_runner->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), - status == blink::ServiceWorkerStatusCode::kOk)); -} - void RunOnceClosure(scoped_refptr<ServiceWorkerContextWrapper> ref_holder, base::OnceClosure task) { std::move(task).Run(); } +// Helper class to create a callback that takes blink::ServiceWorkerStatusCode +// as the first parameter and calls the original callback with a boolean of +// whether the status is blink::ServiceWorkerStatusCode::kOk or not. +class WrapResultCallbackToTakeStatusCode { + public: + explicit WrapResultCallbackToTakeStatusCode( + ServiceWorkerContext::ResultCallback callback) + : callback_(std::move(callback)) {} + + template <typename... Args> + operator base::OnceCallback<void(blink::ServiceWorkerStatusCode, Args...)>() { + return Take<Args...>(); + } + + private: + template <typename... Args> + base::OnceCallback<void(blink::ServiceWorkerStatusCode, Args...)> Take() { + return base::BindOnce( + [](ServiceWorkerContext::ResultCallback callback, + blink::ServiceWorkerStatusCode status, Args...) { + std::move(callback).Run(status == + blink::ServiceWorkerStatusCode::kOk); + }, + std::move(callback_)); + } + + ServiceWorkerContext::ResultCallback callback_; +}; + } // namespace -// static -void ServiceWorkerContextWrapper::RunOrPostTaskOnCoreThread( - const base::Location& location, - base::OnceClosure task) { - RunOrPostTaskOnThread(location, GetCoreThreadId(), std::move(task)); -} // static bool ServiceWorkerContext::ScopeMatches(const GURL& scope, const GURL& url) { @@ -254,23 +235,43 @@ scoped_refptr<base::SequencedTaskRunner> database_task_runner = base::ThreadPool::CreateSequencedTaskRunner( {base::MayBlock(), base::TaskShutdownBehavior::BLOCK_SHUTDOWN}); + InitInternal(user_data_directory, quota_manager_proxy, special_storage_policy, + blob_context, loader_factory_getter, + std::move(database_task_runner), + storage_partition_->browser_context()); +} + +void ServiceWorkerContextWrapper::InitInternal( + const base::FilePath& user_data_directory, + storage::QuotaManagerProxy* quota_manager_proxy, + storage::SpecialStoragePolicy* special_storage_policy, + ChromeBlobStorageContext* blob_context, + URLLoaderFactoryGetter* loader_factory_getter, + scoped_refptr<base::SequencedTaskRunner> database_task_runner, + BrowserContext* browser_context) { std::unique_ptr<blink::PendingURLLoaderFactoryBundle> non_network_pending_loader_factory_bundle_for_update_check; non_network_pending_loader_factory_bundle_for_update_check = CreateNonNetworkPendingURLLoaderFactoryBundleForUpdateCheck( - storage_partition_->browser_context()); + browser_context); - RunOrPostTaskOnCoreThread( - FROM_HERE, - base::BindOnce( - &ServiceWorkerContextWrapper::InitOnCoreThread, this, - user_data_directory, std::move(database_task_runner), - base::RetainedRef(quota_manager_proxy), - base::RetainedRef(special_storage_policy), - base::RetainedRef(blob_context), - base::RetainedRef(loader_factory_getter), - std::move( - non_network_pending_loader_factory_bundle_for_update_check))); + if (quota_manager_proxy) { + quota_manager_proxy->RegisterClient( + base::MakeRefCounted<ServiceWorkerQuotaClient>(this), + storage::QuotaClientType::kServiceWorker, + {blink::mojom::StorageType::kTemporary}); + } + + context_core_ = std::make_unique<ServiceWorkerContextCore>( + user_data_directory, std::move(database_task_runner), quota_manager_proxy, + special_storage_policy, loader_factory_getter, + std::move(non_network_pending_loader_factory_bundle_for_update_check), + core_observer_list_.get(), this); + + if (storage_partition_) { + context()->registry()->GetRegisteredOrigins(base::BindOnce( + &ServiceWorkerContextWrapper::DidGetRegisteredOrigins, this)); + } } void ServiceWorkerContextWrapper::Shutdown() { @@ -278,12 +279,11 @@ storage_partition_ = nullptr; process_manager_->Shutdown(); - - ShutdownOnCoreThread(); + context_core_.reset(); } void ServiceWorkerContextWrapper::DeleteAndStartOver() { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { // The context could be null due to system shutdown or restart failure. In // either case, we should not have to recover the system, so just return @@ -472,13 +472,7 @@ const GURL& script_url, const blink::mojom::ServiceWorkerRegistrationOptions& options, ResultCallback callback) { - if (!BrowserThread::CurrentlyOn(GetCoreThreadId())) { - base::PostTask( - FROM_HERE, {GetCoreThreadId()}, - base::BindOnce(&ServiceWorkerContextWrapper::RegisterServiceWorker, - this, script_url, options, std::move(callback))); - return; - } + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { GetUIThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(std::move(callback), false)); @@ -495,19 +489,14 @@ network::mojom::ReferrerPolicy::kDefault, /*outgoing_referrer=*/script_url, blink::mojom::InsecureRequestsPolicy::kDoNotUpgrade), - base::BindOnce(&FinishRegistrationOnCoreThread, std::move(callback))); + WrapResultCallbackToTakeStatusCode(std::move(callback))); } void ServiceWorkerContextWrapper::UnregisterServiceWorker( const GURL& scope, ResultCallback callback) { - if (!BrowserThread::CurrentlyOn(GetCoreThreadId())) { - base::PostTask( - FROM_HERE, {GetCoreThreadId()}, - base::BindOnce(&ServiceWorkerContextWrapper::UnregisterServiceWorker, - this, scope, std::move(callback))); - return; - } + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (!context_core_) { GetUIThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(std::move(callback), false)); @@ -516,14 +505,14 @@ context()->UnregisterServiceWorker( net::SimplifyUrlForRequest(scope), /*is_immediate=*/false, - base::BindOnce(&FinishUnregistrationOnCoreThread, std::move(callback))); + WrapResultCallbackToTakeStatusCode(std::move(callback))); } ServiceWorkerExternalRequestResult ServiceWorkerContextWrapper::StartingExternalRequest( int64_t service_worker_version_id, const std::string& request_uuid) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context()) return ServiceWorkerExternalRequestResult::kNullContext; scoped_refptr<ServiceWorkerVersion> version = @@ -537,7 +526,7 @@ ServiceWorkerContextWrapper::FinishedExternalRequest( int64_t service_worker_version_id, const std::string& request_uuid) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context()) return ServiceWorkerExternalRequestResult::kNullContext; scoped_refptr<ServiceWorkerVersion> version = @@ -547,14 +536,20 @@ return version->FinishExternalRequest(request_uuid); } -void ServiceWorkerContextWrapper::CountExternalRequestsForTest( - const url::Origin& origin, - CountExternalRequestsCallback callback) { +size_t ServiceWorkerContextWrapper::CountExternalRequestsForTest( + const url::Origin& origin) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - base::PostTask( - FROM_HERE, {GetCoreThreadId()}, - base::BindOnce(&ServiceWorkerContextWrapper::CountExternalRequests, this, - origin, std::move(callback))); + + std::vector<ServiceWorkerVersionInfo> live_version_info = + GetAllLiveVersionInfo(); + for (const ServiceWorkerVersionInfo& info : live_version_info) { + ServiceWorkerVersion* version = GetLiveVersion(info.version_id); + if (version && version->origin() == origin) { + return version->GetExternalRequestCountForTest(); // IN-TEST + } + } + + return 0u; } bool ServiceWorkerContextWrapper::MaybeHasRegistrationForOrigin( @@ -572,18 +567,19 @@ void ServiceWorkerContextWrapper::GetInstalledRegistrationOrigins( base::Optional<std::string> host_filter, GetInstalledRegistrationOriginsCallback callback) { - RunOrPostTaskOnCoreThread( - FROM_HERE, base::BindOnce(&ServiceWorkerContextWrapper:: - GetInstalledRegistrationOriginsOnCoreThread, - this, host_filter, std::move(callback), - base::ThreadTaskRunnerHandle::Get())); + RunOrPostTaskOnThread( + FROM_HERE, BrowserThread::UI, + base::BindOnce(&ServiceWorkerContextWrapper:: + GetInstalledRegistrationOriginsOnUIThread, + this, host_filter, std::move(callback), + base::ThreadTaskRunnerHandle::Get())); } -void ServiceWorkerContextWrapper::GetInstalledRegistrationOriginsOnCoreThread( +void ServiceWorkerContextWrapper::GetInstalledRegistrationOriginsOnUIThread( base::Optional<std::string> host_filter, GetInstalledRegistrationOriginsCallback callback, scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { task_runner_for_callback->PostTask( @@ -595,47 +591,37 @@ context()->registry()->GetRegisteredOrigins(base::BindOnce( &ServiceWorkerContextWrapper:: DidGetRegisteredOriginsForGetInstalledRegistrationOrigins, - host_filter, std::move(callback), task_runner_for_callback)); + host_filter, std::move(callback), std::move(task_runner_for_callback))); } void ServiceWorkerContextWrapper::GetAllOriginsInfo( GetUsageInfoCallback callback) { - RunOrPostTaskOnCoreThread( - FROM_HERE, - base::BindOnce( - &ServiceWorkerContextWrapper::GetAllOriginsInfoOnCoreThread, this, - std::move(callback), base::ThreadTaskRunnerHandle::Get())); -} - -void ServiceWorkerContextWrapper::GetAllOriginsInfoOnCoreThread( - GetUsageInfoCallback callback, - scoped_refptr<base::TaskRunner> callback_runner) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { - callback_runner->PostTask( + base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), std::vector<StorageUsageInfo>())); return; } context()->registry()->GetAllRegistrationsInfos(base::BindOnce( &ServiceWorkerContextWrapper::DidGetAllRegistrationsForGetAllOrigins, - this, base::TimeTicks::Now(), std::move(callback), - std::move(callback_runner))); + this, std::move(callback))); } void ServiceWorkerContextWrapper::DeleteForOrigin(const url::Origin& origin, ResultCallback callback) { - RunOrPostTaskOnCoreThread( - FROM_HERE, - base::BindOnce(&ServiceWorkerContextWrapper::DeleteForOriginOnCoreThread, + RunOrPostTaskOnThread( + FROM_HERE, BrowserThread::UI, + base::BindOnce(&ServiceWorkerContextWrapper::DeleteForOriginOnUIThread, this, origin, std::move(callback), base::ThreadTaskRunnerHandle::Get())); } -void ServiceWorkerContextWrapper::DeleteForOriginOnCoreThread( +void ServiceWorkerContextWrapper::DeleteForOriginOnUIThread( const url::Origin& origin, ResultCallback callback, scoped_refptr<base::TaskRunner> callback_runner) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { callback_runner->PostTask(FROM_HERE, base::BindOnce(std::move(callback), false)); @@ -657,16 +643,17 @@ void ServiceWorkerContextWrapper::PerformStorageCleanup( base::OnceClosure callback) { - RunOrPostTaskOnCoreThread( - FROM_HERE, + RunOrPostTaskOnThread( + FROM_HERE, BrowserThread::UI, base::BindOnce( - &ServiceWorkerContextWrapper::PerformStorageCleanupOnCoreThread, this, + &ServiceWorkerContextWrapper::PerformStorageCleanupOnUIThread, this, std::move(callback), base::ThreadTaskRunnerHandle::Get())); } -void ServiceWorkerContextWrapper::PerformStorageCleanupOnCoreThread( +void ServiceWorkerContextWrapper::PerformStorageCleanupOnUIThread( base::OnceClosure callback, scoped_refptr<base::TaskRunner> callback_runner) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { callback_runner->PostTask(FROM_HERE, std::move(callback)); return; @@ -682,61 +669,41 @@ void ServiceWorkerContextWrapper::CheckHasServiceWorker( const GURL& url, CheckHasServiceWorkerCallback callback) { - if (!BrowserThread::CurrentlyOn(GetCoreThreadId())) { - base::PostTask( - FROM_HERE, {GetCoreThreadId()}, - base::BindOnce(&ServiceWorkerContextWrapper::CheckHasServiceWorker, - this, url, std::move(callback))); - return; - } + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (!context_core_) { - GetUIThreadTaskRunner({})->PostTask( + base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), ServiceWorkerCapability::NO_SERVICE_WORKER)); return; } - context()->CheckHasServiceWorker( - net::SimplifyUrlForRequest(url), - base::BindOnce(&ServiceWorkerContextWrapper::DidCheckHasServiceWorker, - this, std::move(callback))); + context()->CheckHasServiceWorker(net::SimplifyUrlForRequest(url), + std::move(callback)); } void ServiceWorkerContextWrapper::CheckOfflineCapability( const GURL& url, CheckOfflineCapabilityCallback callback) { - if (!BrowserThread::CurrentlyOn(GetCoreThreadId())) { - base::PostTask( - FROM_HERE, {GetCoreThreadId()}, - base::BindOnce(&ServiceWorkerContextWrapper::CheckOfflineCapability, - this, url, std::move(callback))); - return; - } + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (!context_core_) { - GetUIThreadTaskRunner({})->PostTask( + base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), OfflineCapability::kUnsupported, blink::mojom::kInvalidServiceWorkerRegistrationId)); return; } - context()->CheckOfflineCapability( - net::SimplifyUrlForRequest(url), - base::BindOnce(&ServiceWorkerContextWrapper::DidCheckOfflineCapability, - this, std::move(callback))); + context()->CheckOfflineCapability(net::SimplifyUrlForRequest(url), + std::move(callback)); } void ServiceWorkerContextWrapper::ClearAllServiceWorkersForTest( base::OnceClosure callback) { - if (!BrowserThread::CurrentlyOn(GetCoreThreadId())) { - base::PostTask( - FROM_HERE, {GetCoreThreadId()}, - base::BindOnce( - &ServiceWorkerContextWrapper::ClearAllServiceWorkersForTest, this, - std::move(callback))); - return; - } + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { - GetUIThreadTaskRunner({})->PostTask(FROM_HERE, std::move(callback)); + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + std::move(callback)); return; } context_core_->ClearAllServiceWorkersForTest(std::move(callback)); @@ -746,7 +713,7 @@ const GURL& scope, StartWorkerCallback info_callback, StartWorkerFailureCallback failure_callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); FindRegistrationForScopeImpl( scope, /*include_installing_version=*/true, base::BindOnce(&FoundRegistrationForStartWorker, std::move(info_callback), @@ -757,26 +724,32 @@ const GURL& scope, blink::TransferableMessage message, ResultCallback result_callback) { - RunOrPostTaskOnCoreThread( - FROM_HERE, + RunOrPostTaskOnThread( + FROM_HERE, BrowserThread::UI, base::BindOnce(&ServiceWorkerContextWrapper:: - StartServiceWorkerAndDispatchMessageOnCoreThread, + StartServiceWorkerAndDispatchMessageOnUIThread, this, scope, std::move(message), - std::move(result_callback), - base::ThreadTaskRunnerHandle::Get())); + base::BindOnce( + [](ResultCallback callback, + scoped_refptr<base::TaskRunner> callback_runner, + bool success) { + callback_runner->PostTask( + FROM_HERE, + base::BindOnce(std::move(callback), success)); + }, + std::move(result_callback), + base::ThreadTaskRunnerHandle::Get()))); } void ServiceWorkerContextWrapper:: - StartServiceWorkerAndDispatchMessageOnCoreThread( + StartServiceWorkerAndDispatchMessageOnUIThread( const GURL& scope, blink::TransferableMessage message, - ResultCallback result_callback, - scoped_refptr<base::TaskRunner> callback_runner) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + ResultCallback result_callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { - callback_runner->PostTask( - FROM_HERE, base::BindOnce(std::move(result_callback), false)); + std::move(result_callback).Run(/*success=*/false); return; } @@ -784,23 +757,20 @@ net::SimplifyUrlForRequest(scope), false /* include_installing_version */, base::BindOnce( &ServiceWorkerContextWrapper::DidFindRegistrationForMessageDispatch, - this, std::move(message), scope, std::move(result_callback), - std::move(callback_runner))); + this, std::move(message), scope, std::move(result_callback))); } void ServiceWorkerContextWrapper::DidFindRegistrationForMessageDispatch( blink::TransferableMessage message, const GURL& source_origin, ResultCallback result_callback, - scoped_refptr<base::TaskRunner> callback_runner, blink::ServiceWorkerStatusCode service_worker_status, scoped_refptr<ServiceWorkerRegistration> registration) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) { LOG(WARNING) << "No registration available, status: " << static_cast<int>(service_worker_status); - callback_runner->PostTask( - FROM_HERE, base::BindOnce(std::move(result_callback), false)); + std::move(result_callback).Run(/*success=*/false); return; } registration->active_version()->StartWorker( @@ -808,7 +778,7 @@ base::BindOnce( &ServiceWorkerContextWrapper::DidStartServiceWorkerForMessageDispatch, this, std::move(message), source_origin, registration, - std::move(result_callback), std::move(callback_runner))); + std::move(result_callback))); } void ServiceWorkerContextWrapper::DidStartServiceWorkerForMessageDispatch( @@ -816,12 +786,10 @@ const GURL& source_origin, scoped_refptr<ServiceWorkerRegistration> registration, ResultCallback result_callback, - scoped_refptr<base::TaskRunner> callback_runner, blink::ServiceWorkerStatusCode status) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (status != blink::ServiceWorkerStatusCode::kOk) { - callback_runner->PostTask( - FROM_HERE, base::BindOnce(std::move(result_callback), false)); + std::move(result_callback).Run(/*success=*/false); return; } @@ -839,8 +807,7 @@ int request_id = version->StartRequest( ServiceWorkerMetrics::EventType::MESSAGE, - base::BindOnce(&MessageFinishedSending, std::move(result_callback), - std::move(callback_runner))); + WrapResultCallbackToTakeStatusCode(std::move(result_callback))); version->endpoint()->DispatchExtendableMessageEvent( std::move(event), version->CreateSimpleEventCallback(request_id)); } @@ -852,27 +819,30 @@ "document_url", document_url.spec()); DCHECK_CURRENTLY_ON(BrowserThread::UI); - RunOrPostTaskOnCoreThread( - FROM_HERE, + auto callback_with_recording_metrics = base::BindOnce( + [](StartServiceWorkerForNavigationHintCallback callback, + StartServiceWorkerForNavigationHintResult result) { + ServiceWorkerMetrics::RecordStartServiceWorkerForNavigationHintResult( + result); + std::move(callback).Run(result); + }, + std::move(callback)); + + if (!context_core_) { + std::move(callback_with_recording_metrics) + .Run(StartServiceWorkerForNavigationHintResult::FAILED); + return; + } + context_core_->registry()->FindRegistrationForClientUrl( + net::SimplifyUrlForRequest(document_url), base::BindOnce( - &ServiceWorkerContextWrapper:: - StartServiceWorkerForNavigationHintOnCoreThread, - this, document_url, - base::BindOnce(&ServiceWorkerContextWrapper:: - RecordStartServiceWorkerForNavigationHintResult, - this, std::move(callback)))); + &ServiceWorkerContextWrapper::DidFindRegistrationForNavigationHint, + this, std::move(callback_with_recording_metrics))); } void ServiceWorkerContextWrapper::StopAllServiceWorkersForOrigin( const url::Origin& origin) { - if (!BrowserThread::CurrentlyOn(GetCoreThreadId())) { - base::PostTask( - FROM_HERE, {GetCoreThreadId()}, - base::BindOnce( - &ServiceWorkerContextWrapper::StopAllServiceWorkersForOrigin, this, - origin)); - return; - } + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_.get()) { return; } @@ -886,11 +856,21 @@ void ServiceWorkerContextWrapper::StopAllServiceWorkers( base::OnceClosure callback) { - RunOrPostTaskOnCoreThread( - FROM_HERE, - base::BindOnce( - &ServiceWorkerContextWrapper::StopAllServiceWorkersOnCoreThread, this, - std::move(callback), base::ThreadTaskRunnerHandle::Get())); + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (!context_core_.get()) { + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + std::move(callback)); + return; + } + + std::vector<ServiceWorkerVersionInfo> live_versions = GetAllLiveVersionInfo(); + base::RepeatingClosure barrier = + base::BarrierClosure(live_versions.size(), std::move(callback)); + for (const ServiceWorkerVersionInfo& info : live_versions) { + ServiceWorkerVersion* version = GetLiveVersion(info.version_id); + DCHECK(version); + version->StopWorker(barrier); + } } const base::flat_map<int64_t, ServiceWorkerRunningInfo>& @@ -900,7 +880,7 @@ ServiceWorkerRegistration* ServiceWorkerContextWrapper::GetLiveRegistration( int64_t registration_id) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) return nullptr; return context_core_->GetLiveRegistration(registration_id); @@ -908,7 +888,7 @@ ServiceWorkerVersion* ServiceWorkerContextWrapper::GetLiveVersion( int64_t version_id) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) return nullptr; return context_core_->GetLiveVersion(version_id); @@ -916,7 +896,7 @@ std::vector<ServiceWorkerRegistrationInfo> ServiceWorkerContextWrapper::GetAllLiveRegistrationInfo() { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) return std::vector<ServiceWorkerRegistrationInfo>(); return context_core_->GetAllLiveRegistrationInfo(); @@ -924,7 +904,7 @@ std::vector<ServiceWorkerVersionInfo> ServiceWorkerContextWrapper::GetAllLiveVersionInfo() { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) return std::vector<ServiceWorkerVersionInfo>(); return context_core_->GetAllLiveVersionInfo(); @@ -933,39 +913,20 @@ void ServiceWorkerContextWrapper::HasMainFrameWindowClient( const GURL& origin, BoolCallback callback) const { - RunOrPostTaskOnCoreThread( - FROM_HERE, - base::BindOnce( - &ServiceWorkerContextWrapper::HasMainFrameWindowClientOnCoreThread, - this, origin, std::move(callback), - base::ThreadTaskRunnerHandle::Get())); -} + DCHECK_CURRENTLY_ON(BrowserThread::UI); -void ServiceWorkerContextWrapper::HasMainFrameWindowClientOnCoreThread( - const GURL& origin, - BoolCallback callback, - scoped_refptr<base::TaskRunner> callback_runner) const { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); if (!context_core_) { - callback_runner->PostTask(FROM_HERE, - base::BindOnce(std::move(callback), false)); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), false)); return; } - context_core_->HasMainFrameWindowClient( - origin, - base::BindOnce( - [](BoolCallback callback, - scoped_refptr<base::TaskRunner> callback_runner, bool result) { - callback_runner->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), result)); - }, - std::move(callback), std::move(callback_runner))); + context_core_->HasMainFrameWindowClient(origin, std::move(callback)); } std::unique_ptr<std::vector<GlobalFrameRoutingId>> ServiceWorkerContextWrapper::GetWindowClientFrameRoutingIds( const GURL& origin) const { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); std::unique_ptr<std::vector<GlobalFrameRoutingId>> frame_routing_ids( new std::vector<GlobalFrameRoutingId>()); @@ -988,7 +949,7 @@ void ServiceWorkerContextWrapper::FindReadyRegistrationForClientUrl( const GURL& client_url, FindRegistrationCallback callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort, nullptr); @@ -1004,7 +965,7 @@ void ServiceWorkerContextWrapper::FindReadyRegistrationForScope( const GURL& scope, FindRegistrationCallback callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort, nullptr); @@ -1021,7 +982,7 @@ void ServiceWorkerContextWrapper::FindRegistrationForScope( const GURL& scope, FindRegistrationCallback callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); const bool include_installing_version = true; FindRegistrationForScopeImpl(scope, include_installing_version, std::move(callback)); @@ -1031,7 +992,7 @@ int64_t registration_id, const url::Origin& origin, FindRegistrationCallback callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort, nullptr); @@ -1047,7 +1008,7 @@ void ServiceWorkerContextWrapper::FindReadyRegistrationForIdOnly( int64_t registration_id, FindRegistrationCallback callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort, nullptr); @@ -1062,29 +1023,13 @@ void ServiceWorkerContextWrapper::GetAllRegistrations( GetRegistrationsInfosCallback callback) { - RunOrPostTaskOnCoreThread( - FROM_HERE, - base::BindOnce( - &ServiceWorkerContextWrapper::GetAllRegistrationsOnCoreThread, this, - base::BindOnce( - [](GetRegistrationsInfosCallback callback, - scoped_refptr<base::TaskRunner> callback_runner, - blink::ServiceWorkerStatusCode status, - const std::vector<ServiceWorkerRegistrationInfo>& - registrations) { - callback_runner->PostTask( - FROM_HERE, - base::BindOnce(std::move(callback), status, registrations)); - }, - std::move(callback), base::ThreadTaskRunnerHandle::Get()))); -} - -void ServiceWorkerContextWrapper::GetAllRegistrationsOnCoreThread( - GetRegistrationsInfosCallback callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { - std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort, - std::vector<ServiceWorkerRegistrationInfo>()); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(std::move(callback), + blink::ServiceWorkerStatusCode::kErrorAbort, + std::vector<ServiceWorkerRegistrationInfo>())); return; } context_core_->registry()->GetAllRegistrationsInfos(std::move(callback)); @@ -1093,10 +1038,10 @@ void ServiceWorkerContextWrapper::GetStorageUsageForOrigin( const url::Origin& origin, GetStorageUsageForOriginCallback callback) { - RunOrPostTaskOnCoreThread( - FROM_HERE, + RunOrPostTaskOnThread( + FROM_HERE, BrowserThread::UI, base::BindOnce( - &ServiceWorkerContextWrapper::GetStorageUsageForOriginOnCoreThread, + &ServiceWorkerContextWrapper::GetStorageUsageForOriginOnUIThread, this, origin, base::BindOnce( [](GetStorageUsageForOriginCallback callback, @@ -1109,10 +1054,10 @@ std::move(callback), base::ThreadTaskRunnerHandle::Get()))); } -void ServiceWorkerContextWrapper::GetStorageUsageForOriginOnCoreThread( +void ServiceWorkerContextWrapper::GetStorageUsageForOriginOnUIThread( const url::Origin& origin, GetStorageUsageForOriginCallback callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort, 0); return; @@ -1124,7 +1069,7 @@ void ServiceWorkerContextWrapper::GetRegistrationsForOrigin( const url::Origin& origin, GetRegistrationsCallback callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, @@ -1141,11 +1086,11 @@ int64_t registration_id, const std::vector<std::string>& keys, GetUserDataCallback callback) { - RunOrPostTaskOnCoreThread( - FROM_HERE, + RunOrPostTaskOnThread( + FROM_HERE, BrowserThread::UI, base::BindOnce( - &ServiceWorkerContextWrapper::GetRegistrationUserDataOnCoreThread, - this, registration_id, keys, + &ServiceWorkerContextWrapper::GetRegistrationUserDataOnUIThread, this, + registration_id, keys, base::BindOnce( [](GetUserDataCallback callback, scoped_refptr<base::TaskRunner> callback_runner, @@ -1158,11 +1103,11 @@ std::move(callback), base::ThreadTaskRunnerHandle::Get()))); } -void ServiceWorkerContextWrapper::GetRegistrationUserDataOnCoreThread( +void ServiceWorkerContextWrapper::GetRegistrationUserDataOnUIThread( int64_t registration_id, const std::vector<std::string>& keys, GetUserDataCallback callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { std::move(callback).Run(std::vector<std::string>(), blink::ServiceWorkerStatusCode::kErrorAbort); @@ -1176,11 +1121,11 @@ int64_t registration_id, const std::string& key_prefix, GetUserDataCallback callback) { - RunOrPostTaskOnCoreThread( - FROM_HERE, + RunOrPostTaskOnThread( + FROM_HERE, BrowserThread::UI, base::BindOnce( &ServiceWorkerContextWrapper:: - GetRegistrationUserDataByKeyPrefixOnCoreThread, + GetRegistrationUserDataByKeyPrefixOnUIThread, this, registration_id, key_prefix, base::BindOnce( [](GetUserDataCallback callback, @@ -1194,12 +1139,11 @@ std::move(callback), base::ThreadTaskRunnerHandle::Get()))); } -void ServiceWorkerContextWrapper:: - GetRegistrationUserDataByKeyPrefixOnCoreThread( - int64_t registration_id, - const std::string& key_prefix, - GetUserDataCallback callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); +void ServiceWorkerContextWrapper::GetRegistrationUserDataByKeyPrefixOnUIThread( + int64_t registration_id, + const std::string& key_prefix, + GetUserDataCallback callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { std::move(callback).Run(std::vector<std::string>(), blink::ServiceWorkerStatusCode::kErrorAbort); @@ -1213,11 +1157,11 @@ int64_t registration_id, const std::string& key_prefix, GetUserKeysAndDataCallback callback) { - RunOrPostTaskOnCoreThread( - FROM_HERE, + RunOrPostTaskOnThread( + FROM_HERE, BrowserThread::UI, base::BindOnce( &ServiceWorkerContextWrapper:: - GetRegistrationUserKeysAndDataByKeyPrefixOnCoreThread, + GetRegistrationUserKeysAndDataByKeyPrefixOnUIThread, this, registration_id, key_prefix, base::BindOnce( [](GetUserKeysAndDataCallback callback, @@ -1232,11 +1176,11 @@ } void ServiceWorkerContextWrapper:: - GetRegistrationUserKeysAndDataByKeyPrefixOnCoreThread( + GetRegistrationUserKeysAndDataByKeyPrefixOnUIThread( int64_t registration_id, const std::string& key_prefix, GetUserKeysAndDataCallback callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort, base::flat_map<std::string, std::string>()); @@ -1251,10 +1195,10 @@ const url::Origin& origin, const std::vector<std::pair<std::string, std::string>>& key_value_pairs, StatusCallback callback) { - RunOrPostTaskOnCoreThread( - FROM_HERE, + RunOrPostTaskOnThread( + FROM_HERE, BrowserThread::UI, base::BindOnce( - &ServiceWorkerContextWrapper::StoreRegistrationUserDataOnCoreThread, + &ServiceWorkerContextWrapper::StoreRegistrationUserDataOnUIThread, this, registration_id, origin, key_value_pairs, base::BindOnce( [](StatusCallback callback, @@ -1266,12 +1210,12 @@ std::move(callback), base::ThreadTaskRunnerHandle::Get()))); } -void ServiceWorkerContextWrapper::StoreRegistrationUserDataOnCoreThread( +void ServiceWorkerContextWrapper::StoreRegistrationUserDataOnUIThread( int64_t registration_id, const url::Origin& origin, const std::vector<std::pair<std::string, std::string>>& key_value_pairs, StatusCallback callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort); return; @@ -1284,10 +1228,10 @@ int64_t registration_id, const std::vector<std::string>& keys, StatusCallback callback) { - RunOrPostTaskOnCoreThread( - FROM_HERE, + RunOrPostTaskOnThread( + FROM_HERE, BrowserThread::UI, base::BindOnce( - &ServiceWorkerContextWrapper::ClearRegistrationUserDataOnCoreThread, + &ServiceWorkerContextWrapper::ClearRegistrationUserDataOnUIThread, this, registration_id, keys, base::BindOnce( [](StatusCallback callback, @@ -1299,11 +1243,11 @@ std::move(callback), base::ThreadTaskRunnerHandle::Get()))); } -void ServiceWorkerContextWrapper::ClearRegistrationUserDataOnCoreThread( +void ServiceWorkerContextWrapper::ClearRegistrationUserDataOnUIThread( int64_t registration_id, const std::vector<std::string>& keys, StatusCallback callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort); return; @@ -1316,11 +1260,11 @@ int64_t registration_id, const std::vector<std::string>& key_prefixes, StatusCallback callback) { - RunOrPostTaskOnCoreThread( - FROM_HERE, + RunOrPostTaskOnThread( + FROM_HERE, BrowserThread::UI, base::BindOnce( &ServiceWorkerContextWrapper:: - ClearRegistrationUserDataByKeyPrefixesOnCoreThread, + ClearRegistrationUserDataByKeyPrefixesOnUIThread, this, registration_id, key_prefixes, base::BindOnce( [](StatusCallback callback, @@ -1333,11 +1277,11 @@ } void ServiceWorkerContextWrapper:: - ClearRegistrationUserDataByKeyPrefixesOnCoreThread( + ClearRegistrationUserDataByKeyPrefixesOnUIThread( int64_t registration_id, const std::vector<std::string>& key_prefixes, StatusCallback callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort); return; @@ -1349,11 +1293,11 @@ void ServiceWorkerContextWrapper::GetUserDataForAllRegistrations( const std::string& key, GetUserDataForAllRegistrationsCallback callback) { - RunOrPostTaskOnCoreThread( - FROM_HERE, + RunOrPostTaskOnThread( + FROM_HERE, BrowserThread::UI, base::BindOnce( &ServiceWorkerContextWrapper:: - GetUserDataForAllRegistrationsOnCoreThread, + GetUserDataForAllRegistrationsOnUIThread, this, key, base::BindOnce( [](GetUserDataForAllRegistrationsCallback callback, @@ -1367,10 +1311,10 @@ std::move(callback), base::ThreadTaskRunnerHandle::Get()))); } -void ServiceWorkerContextWrapper::GetUserDataForAllRegistrationsOnCoreThread( +void ServiceWorkerContextWrapper::GetUserDataForAllRegistrationsOnUIThread( const std::string& key, GetUserDataForAllRegistrationsCallback callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { std::move(callback).Run(std::vector<std::pair<int64_t, std::string>>(), blink::ServiceWorkerStatusCode::kErrorAbort); @@ -1383,11 +1327,11 @@ void ServiceWorkerContextWrapper::GetUserDataForAllRegistrationsByKeyPrefix( const std::string& key_prefix, GetUserDataForAllRegistrationsCallback callback) { - RunOrPostTaskOnCoreThread( - FROM_HERE, + RunOrPostTaskOnThread( + FROM_HERE, BrowserThread::UI, base::BindOnce( &ServiceWorkerContextWrapper:: - GetUserDataForAllRegistrationsByKeyPrefixOnCoreThread, + GetUserDataForAllRegistrationsByKeyPrefixOnUIThread, this, key_prefix, base::BindOnce( [](GetUserDataForAllRegistrationsCallback callback, @@ -1402,10 +1346,10 @@ } void ServiceWorkerContextWrapper:: - GetUserDataForAllRegistrationsByKeyPrefixOnCoreThread( + GetUserDataForAllRegistrationsByKeyPrefixOnUIThread( const std::string& key_prefix, GetUserDataForAllRegistrationsCallback callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { std::move(callback).Run(std::vector<std::pair<int64_t, std::string>>(), blink::ServiceWorkerStatusCode::kErrorAbort); @@ -1418,11 +1362,11 @@ void ServiceWorkerContextWrapper::ClearUserDataForAllRegistrationsByKeyPrefix( const std::string& key_prefix, StatusCallback callback) { - RunOrPostTaskOnCoreThread( - FROM_HERE, + RunOrPostTaskOnThread( + FROM_HERE, BrowserThread::UI, base::BindOnce( &ServiceWorkerContextWrapper:: - ClearUserDataForAllRegistrationsByKeyPrefixOnCoreThread, + ClearUserDataForAllRegistrationsByKeyPrefixOnUIThread, this, key_prefix, base::BindOnce( [](StatusCallback callback, @@ -1435,10 +1379,10 @@ } void ServiceWorkerContextWrapper:: - ClearUserDataForAllRegistrationsByKeyPrefixOnCoreThread( + ClearUserDataForAllRegistrationsByKeyPrefixOnUIThread( const std::string& key_prefix, StatusCallback callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort); return; @@ -1450,47 +1394,38 @@ void ServiceWorkerContextWrapper::StartActiveServiceWorker( const GURL& scope, StatusCallback callback) { - if (!BrowserThread::CurrentlyOn(GetCoreThreadId())) { - base::PostTask( - FROM_HERE, {GetCoreThreadId()}, - base::BindOnce(&ServiceWorkerContextWrapper::StartActiveServiceWorker, - this, scope, std::move(callback))); - return; - } + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { - GetUIThreadTaskRunner({})->PostTask( + base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), blink::ServiceWorkerStatusCode::kErrorAbort)); return; } context_core_->registry()->FindRegistrationForScope( net::SimplifyUrlForRequest(scope), - base::BindOnce(&StartActiveWorkerOnCoreThread, std::move(callback))); + base::BindOnce(&DidFindRegistrationForStartActiveWorker, + std::move(callback))); } void ServiceWorkerContextWrapper::SkipWaitingWorker(const GURL& scope) { - if (!BrowserThread::CurrentlyOn(GetCoreThreadId())) { - base::PostTask( - FROM_HERE, {GetCoreThreadId()}, - base::BindOnce(&ServiceWorkerContextWrapper::SkipWaitingWorker, this, - scope)); - return; - } + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) return; context_core_->registry()->FindRegistrationForScope( net::SimplifyUrlForRequest(scope), - base::BindOnce(&SkipWaitingWorkerOnCoreThread)); + base::BindOnce([](blink::ServiceWorkerStatusCode status, + scoped_refptr<ServiceWorkerRegistration> registration) { + if (status != blink::ServiceWorkerStatusCode::kOk || + !registration->waiting_version()) + return; + + registration->waiting_version()->set_skip_waiting(true); + registration->ActivateWaitingVersionWhenReady(); + })); } void ServiceWorkerContextWrapper::UpdateRegistration(const GURL& scope) { - if (!BrowserThread::CurrentlyOn(GetCoreThreadId())) { - base::PostTask( - FROM_HERE, {GetCoreThreadId()}, - base::BindOnce(&ServiceWorkerContextWrapper::UpdateRegistration, this, - scope)); - return; - } + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) return; context_core_->registry()->FindRegistrationForScope( @@ -1501,13 +1436,7 @@ void ServiceWorkerContextWrapper::SetForceUpdateOnPageLoad( bool force_update_on_page_load) { - if (!BrowserThread::CurrentlyOn(GetCoreThreadId())) { - base::PostTask( - FROM_HERE, {GetCoreThreadId()}, - base::BindOnce(&ServiceWorkerContextWrapper::SetForceUpdateOnPageLoad, - this, force_update_on_page_load)); - return; - } + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) return; context_core_->set_force_update_on_page_load(force_update_on_page_load); @@ -1537,42 +1466,11 @@ core_observer_list_->RemoveObserver(identifiability_metrics_.get()); } -void ServiceWorkerContextWrapper::InitOnCoreThread( - const base::FilePath& user_data_directory, - scoped_refptr<base::SequencedTaskRunner> database_task_runner, - storage::QuotaManagerProxy* quota_manager_proxy, - storage::SpecialStoragePolicy* special_storage_policy, - ChromeBlobStorageContext* blob_context, - URLLoaderFactoryGetter* loader_factory_getter, - std::unique_ptr<blink::PendingURLLoaderFactoryBundle> - non_network_pending_loader_factory_bundle_for_update_check) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); - DCHECK(!context_core_); - - if (quota_manager_proxy) { - quota_manager_proxy->RegisterClient( - base::MakeRefCounted<ServiceWorkerQuotaClient>(this), - storage::QuotaClientType::kServiceWorker, - {blink::mojom::StorageType::kTemporary}); - } - - context_core_ = std::make_unique<ServiceWorkerContextCore>( - user_data_directory, std::move(database_task_runner), quota_manager_proxy, - special_storage_policy, loader_factory_getter, - std::move(non_network_pending_loader_factory_bundle_for_update_check), - core_observer_list_.get(), this); - - if (storage_partition_) { - context()->registry()->GetRegisteredOrigins(base::BindOnce( - &ServiceWorkerContextWrapper::DidGetRegisteredOrigins, this)); - } -} - void ServiceWorkerContextWrapper::FindRegistrationForScopeImpl( const GURL& scope, bool include_installing_version, FindRegistrationCallback callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!context_core_) { std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort, nullptr); @@ -1585,17 +1483,12 @@ include_installing_version, std::move(callback))); } -void ServiceWorkerContextWrapper::ShutdownOnCoreThread() { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); - context_core_.reset(); -} - void ServiceWorkerContextWrapper::DidFindRegistrationForFindImpl( bool include_installing_version, FindRegistrationCallback callback, blink::ServiceWorkerStatusCode status, scoped_refptr<ServiceWorkerRegistration> registration) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (status != blink::ServiceWorkerStatusCode::kOk) { std::move(callback).Run(status, nullptr); return; @@ -1635,7 +1528,7 @@ void ServiceWorkerContextWrapper::OnStatusChangedForFindReadyRegistration( FindRegistrationCallback callback, scoped_refptr<ServiceWorkerRegistration> registration) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); scoped_refptr<ServiceWorkerVersion> active_version = registration->active_version(); if (!active_version || @@ -1649,7 +1542,7 @@ void ServiceWorkerContextWrapper::DidDeleteAndStartOver( blink::ServiceWorkerStatusCode status) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (status != blink::ServiceWorkerStatusCode::kOk) { context_core_.reset(); return; @@ -1660,12 +1553,10 @@ } void ServiceWorkerContextWrapper::DidGetAllRegistrationsForGetAllOrigins( - base::TimeTicks start_time, GetUsageInfoCallback callback, - scoped_refptr<base::TaskRunner> callback_runner, blink::ServiceWorkerStatusCode status, const std::vector<ServiceWorkerRegistrationInfo>& registrations) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); std::vector<StorageUsageInfo> usage_infos; std::map<GURL, StorageUsageInfo> origins; @@ -1687,36 +1578,14 @@ usage_infos.push_back(origin_info_pair.second); } - ServiceWorkerMetrics::RecordGetAllOriginsInfoTime(base::TimeTicks::Now() - - start_time); - - callback_runner->PostTask(FROM_HERE, - base::BindOnce(std::move(callback), usage_infos)); + std::move(callback).Run(usage_infos); } -void ServiceWorkerContextWrapper::DidCheckHasServiceWorker( - CheckHasServiceWorkerCallback callback, - ServiceWorkerCapability capability) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); - - GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), capability)); -} - -void ServiceWorkerContextWrapper::DidCheckOfflineCapability( - CheckOfflineCapabilityCallback callback, - OfflineCapability capability, - int64_t registration_id) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); - GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, - base::BindOnce(std::move(callback), capability, registration_id)); -} void ServiceWorkerContextWrapper::DidFindRegistrationForUpdate( blink::ServiceWorkerStatusCode status, scoped_refptr<ServiceWorkerRegistration> registration) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (status != blink::ServiceWorkerStatusCode::kOk) return; @@ -1732,54 +1601,13 @@ true /* force_bypass_cache */); } -void ServiceWorkerContextWrapper::CountExternalRequests( - const url::Origin& origin, - CountExternalRequestsCallback callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); - - std::vector<ServiceWorkerVersionInfo> live_version_info = - GetAllLiveVersionInfo(); - size_t pending_external_request_count = 0; - for (const ServiceWorkerVersionInfo& info : live_version_info) { - ServiceWorkerVersion* version = GetLiveVersion(info.version_id); - if (version && version->origin() == origin) { - pending_external_request_count = - version->GetExternalRequestCountForTest(); - break; - } - } - - GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, - base::BindOnce(std::move(callback), pending_external_request_count)); -} - -void ServiceWorkerContextWrapper:: - StartServiceWorkerForNavigationHintOnCoreThread( - const GURL& document_url, - StartServiceWorkerForNavigationHintCallback callback) { - TRACE_EVENT1("ServiceWorker", - "StartServiceWorkerForNavigationHintOnCoreThread", - "document_url", document_url.spec()); - DCHECK_CURRENTLY_ON(GetCoreThreadId()); - if (!context_core_) { - std::move(callback).Run(StartServiceWorkerForNavigationHintResult::FAILED); - return; - } - context_core_->registry()->FindRegistrationForClientUrl( - net::SimplifyUrlForRequest(document_url), - base::BindOnce( - &ServiceWorkerContextWrapper::DidFindRegistrationForNavigationHint, - this, std::move(callback))); -} - void ServiceWorkerContextWrapper::DidFindRegistrationForNavigationHint( StartServiceWorkerForNavigationHintCallback callback, blink::ServiceWorkerStatusCode status, scoped_refptr<ServiceWorkerRegistration> registration) { TRACE_EVENT1("ServiceWorker", "DidFindRegistrationForNavigationHint", "status", blink::ServiceWorkerStatusToString(status)); - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!registration) { DCHECK_NE(status, blink::ServiceWorkerStatusCode::kOk); std::move(callback).Run(StartServiceWorkerForNavigationHintResult:: @@ -1817,46 +1645,16 @@ blink::ServiceWorkerStatusCode code) { TRACE_EVENT2("ServiceWorker", "DidStartServiceWorkerForNavigationHint", "url", scope.spec(), "code", blink::ServiceWorkerStatusToString(code)); - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); + std::move(callback).Run( code == blink::ServiceWorkerStatusCode::kOk ? StartServiceWorkerForNavigationHintResult::STARTED : StartServiceWorkerForNavigationHintResult::FAILED); } -void ServiceWorkerContextWrapper:: - RecordStartServiceWorkerForNavigationHintResult( - StartServiceWorkerForNavigationHintCallback callback, - StartServiceWorkerForNavigationHintResult result) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); - ServiceWorkerMetrics::RecordStartServiceWorkerForNavigationHintResult(result); - GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), result)); -} - -void ServiceWorkerContextWrapper::StopAllServiceWorkersOnCoreThread( - base::OnceClosure callback, - scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); - if (!context_core_.get()) { - task_runner_for_callback->PostTask(FROM_HERE, std::move(callback)); - return; - } - std::vector<ServiceWorkerVersionInfo> live_versions = GetAllLiveVersionInfo(); - base::RepeatingClosure barrier = base::BarrierClosure( - live_versions.size(), - base::BindOnce( - base::IgnoreResult(&base::SingleThreadTaskRunner::PostTask), - std::move(task_runner_for_callback), FROM_HERE, std::move(callback))); - for (const ServiceWorkerVersionInfo& info : live_versions) { - ServiceWorkerVersion* version = GetLiveVersion(info.version_id); - DCHECK(version); - version->StopWorker(base::BindOnce(barrier)); - } -} - ServiceWorkerContextCore* ServiceWorkerContextWrapper::context() { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); + DCHECK_CURRENTLY_ON(BrowserThread::UI); return context_core_.get(); } @@ -1884,33 +1682,12 @@ return factory_bundle; } -void ServiceWorkerContextWrapper::GetLoaderFactoryForUpdateCheck( - const GURL& scope, - base::OnceCallback<void(scoped_refptr<network::SharedURLLoaderFactory>)> - callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); - - RunOrPostTaskOnThread( - FROM_HERE, BrowserThread::UI, - base::BindOnce( - &ServiceWorkerContextWrapper::SetUpLoaderFactoryForUpdateCheckOnUI, - this, scope, std::move(callback))); -} - -void ServiceWorkerContextWrapper::SetUpLoaderFactoryForUpdateCheckOnUI( - const GURL& scope, - base::OnceCallback<void(scoped_refptr<network::SharedURLLoaderFactory>)> - callback) { +scoped_refptr<network::SharedURLLoaderFactory> +ServiceWorkerContextWrapper::GetLoaderFactoryForUpdateCheck(const GURL& scope) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!storage_partition()) { - RunOrPostTaskOnThread( - FROM_HERE, GetCoreThreadId(), - base::BindOnce( - &ServiceWorkerContextWrapper::DidSetUpLoaderFactoryForUpdateCheck, - this, mojo::NullRemote(), mojo::NullReceiver(), - /* bypass_redirect_checks=*/false, std::move(callback))); - return; + return nullptr; } mojo::PendingRemote<network::mojom::URLLoaderFactory> remote; @@ -1938,28 +1715,6 @@ storage_partition()); } - RunOrPostTaskOnThread( - FROM_HERE, GetCoreThreadId(), - base::BindOnce( - &ServiceWorkerContextWrapper::DidSetUpLoaderFactoryForUpdateCheck, - this, std::move(remote), std::move(pending_receiver), - bypass_redirect_checks, std::move(callback))); -} - -void ServiceWorkerContextWrapper::DidSetUpLoaderFactoryForUpdateCheck( - mojo::PendingRemote<network::mojom::URLLoaderFactory> remote, - mojo::PendingReceiver<network::mojom::URLLoaderFactory> pending_receiver, - bool bypass_redirect_checks, - base::OnceCallback<void(scoped_refptr<network::SharedURLLoaderFactory>)> - callback) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); - - // Return nullptr if preparation on the UI thread failed. - if (!remote) { - std::move(callback).Run(nullptr); - return; - } - // Set up a Mojo connection to the network loader factory if it's not been // created yet. if (pending_receiver) { @@ -1980,10 +1735,8 @@ static_cast<blink::PendingURLLoaderFactoryBundle*>( loader_factory_bundle_info.get()) ->set_bypass_redirect_checks(bypass_redirect_checks); - scoped_refptr<network::SharedURLLoaderFactory> loader_factory = - network::SharedURLLoaderFactory::Create( - std::move(loader_factory_bundle_info)); - std::move(callback).Run(std::move(loader_factory)); + return network::SharedURLLoaderFactory::Create( + std::move(loader_factory_bundle_info)); } void ServiceWorkerContextWrapper::WaitForRegistrationsInitializedForTest() { @@ -1997,17 +1750,6 @@ void ServiceWorkerContextWrapper::DidGetRegisteredOrigins( const std::vector<url::Origin>& origins) { - DCHECK_CURRENTLY_ON(GetCoreThreadId()); - GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, - base::BindOnce( - &ServiceWorkerContextWrapper::InitializeRegisteredOriginsOnUI, this, - origins)); -} - -void ServiceWorkerContextWrapper::InitializeRegisteredOriginsOnUI( - const std::vector<url::Origin>& origins) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); registered_origins_.insert(origins.begin(), origins.end()); registrations_initialized_ = true; if (on_registrations_initialized_)
diff --git a/content/browser/service_worker/service_worker_context_wrapper.h b/content/browser/service_worker/service_worker_context_wrapper.h index 38f56fa..26f1fa3 100644 --- a/content/browser/service_worker/service_worker_context_wrapper.h +++ b/content/browser/service_worker/service_worker_context_wrapper.h
@@ -52,9 +52,15 @@ // A refcounted wrapper class for ServiceWorkerContextCore. Higher level content // lib classes keep references to this class on multiple threads. The inner core -// instance is strictly single threaded (this is called the "core thread") and -// is not refcounted. The core object is what is used internally by service -// worker classes. +// instance is strictly single threaded (on the UI thread) and is not +// refcounted. The core object is what is used internally by service worker +// classes. +// +// All the methods are expected to be called on the UI thread. +// Some of the methods are exceptionally allowed to be called on any threads, +// but it's now discouraged. +// TODO(https://crbug.com/1161153): Disallow methods to be called on any +// threads. class CONTENT_EXPORT ServiceWorkerContextWrapper : public ServiceWorkerContext, public ServiceWorkerContextCoreObserver, @@ -82,9 +88,6 @@ explicit ServiceWorkerContextWrapper(BrowserContext* browser_context); - static void RunOrPostTaskOnCoreThread(const base::Location& location, - base::OnceClosure task); - // Init and Shutdown are for use on the UI thread when the profile, // storagepartition is being setup and torn down. void Init(const base::FilePath& user_data_directory, @@ -95,8 +98,7 @@ void Shutdown(); // Deletes all files on disk and restarts the system asynchronously. This - // leaves the system in a disabled state until it's done. This should be - // called on the core thread. + // leaves the system in a disabled state until it's done. void DeleteAndStartOver(); // The StoragePartition should only be used on the UI thread. @@ -105,10 +107,8 @@ void set_storage_partition(StoragePartitionImpl* storage_partition); - // UI thread. BrowserContext* browser_context(); - // The process manager can be used on either UI or IO. ServiceWorkerProcessManager* process_manager() { return process_manager_.get(); } @@ -162,9 +162,7 @@ ServiceWorkerExternalRequestResult FinishedExternalRequest( int64_t service_worker_version_id, const std::string& request_uuid) override; - void CountExternalRequestsForTest( - const url::Origin& origin, - CountExternalRequestsCallback callback) override; + size_t CountExternalRequestsForTest(const url::Origin& origin) override; bool MaybeHasRegistrationForOrigin(const url::Origin& origin) override; void GetInstalledRegistrationOrigins( base::Optional<std::string> host_filter, @@ -195,18 +193,15 @@ const base::flat_map<int64_t, ServiceWorkerRunningInfo>& GetRunningServiceWorkerInfos() override; - // These methods must only be called from the core thread. ServiceWorkerRegistration* GetLiveRegistration(int64_t registration_id); ServiceWorkerVersion* GetLiveVersion(int64_t version_id); std::vector<ServiceWorkerRegistrationInfo> GetAllLiveRegistrationInfo(); std::vector<ServiceWorkerVersionInfo> GetAllLiveVersionInfo(); - // May be called from any thread, and the callback is called on that thread. void HasMainFrameWindowClient(const GURL& origin, BoolCallback callback) const; - // Returns all frame routing ids for the given |origin|. Must be called on the - // core thread. + // Returns all frame routing ids for the given |origin|. std::unique_ptr<std::vector<GlobalFrameRoutingId>> GetWindowClientFrameRoutingIds(const GURL& origin) const; @@ -220,7 +215,6 @@ // version, activates the waiting version and runs |callback| when it is // activated. // - // Must be called on the core thread, and |callback| is called on that thread. // There is no guarantee for whether the callback is called synchronously or // asynchronously. void FindReadyRegistrationForClientUrl(const GURL& client_url, @@ -236,7 +230,6 @@ // version, activates the waiting version and runs |callback| when it is // activated. // - // Must be called on the core thread, and |callback| is called on that thread. // There is no guarantee for whether the callback is called synchronously or // asynchronously. void FindReadyRegistrationForScope(const GURL& scope, @@ -258,9 +251,8 @@ // version, activates the waiting version and runs |callback| when it is // activated. // - // Must be called on the core thread, and the callback is called on that - // thread. There is no guarantee about whether the callback is called - // asynchronously or synchronously. + // There is no guarantee about whether the callback is called asynchronously + // or synchronously. void FindReadyRegistrationForId(int64_t registration_id, const url::Origin& origin, FindRegistrationCallback callback); @@ -279,15 +271,17 @@ // version, activates the waiting version and runs |callback| when it is // activated. // - // Must be called on the core thread, and the callback is called on that - // thread. There is no guarantee about whether the callback is called - // synchronously or asynchronously. + // There is no guarantee about whether the callback is called synchronously or + // asynchronously. void FindReadyRegistrationForIdOnly(int64_t registration_id, FindRegistrationCallback callback); + void GetAllRegistrations(GetRegistrationsInfosCallback callback); + // These can be called from any thread, and the callback is called on that // thread. - void GetAllRegistrations(GetRegistrationsInfosCallback callback); + // TODO(https://crbug.com/1161153): Make these methods called only on the UI + // thread. void GetRegistrationUserData(int64_t registration_id, const std::vector<std::string>& keys, GetUserDataCallback callback); @@ -328,24 +322,19 @@ // Returns a list of ServiceWorkerRegistration for |origin|. The list includes // stored registrations and installing (not stored yet) registrations. - // Must be called on the core thread, and the callback is called on that - // thread. This restriction is because the callback gets pointers to live - // registrations, which live on the core thread. void GetRegistrationsForOrigin(const url::Origin& origin, GetRegistrationsCallback callback); - // This function can be called from any thread, but the callback will always - // be called on the UI thread. // Fails with kErrorNotFound if there is no active registration for the given // scope. It means that there is no registration at all or that the // registration doesn't have an active version yet (which is the case for // installing service workers). void StartActiveServiceWorker(const GURL& scope, StatusCallback callback); - // These methods can be called from any thread. void SkipWaitingWorker(const GURL& scope); void UpdateRegistration(const GURL& scope); void SetForceUpdateOnPageLoad(bool force_update_on_page_load); + // Different from AddObserver/RemoveObserver(ServiceWorkerContextObserver*). // But we must keep the same name, or else base::ScopedObserver breaks. void AddObserver(ServiceWorkerContextCoreObserver* observer); @@ -353,23 +342,18 @@ bool is_incognito() const { return is_incognito_; } - // The core context is only for use on the IO thread. // Can be null before/during init, during/after shutdown, and after // DeleteAndStartOver fails. ServiceWorkerContextCore* context(); - // This method waits for service worker registrations to be initialized on the - // UI thread, and depends on |on_registrations_initialized_| and - // |registrations_initialized_| which are called in - // InitializeRegisteredOriginsOnUI(). + // This method waits for service worker registrations to be initialized, and + // depends on |on_registrations_initialized_| and |registrations_initialized_| + // which are called in InitializeRegisteredOrigins(). void WaitForRegistrationsInitializedForTest(); - // This must be called on the core thread, and the |callback| also runs on - // the core thread which can be called with nullptr on failure. - void GetLoaderFactoryForUpdateCheck( - const GURL& scope, - base::OnceCallback<void(scoped_refptr<network::SharedURLLoaderFactory>)> - callback); + // Returns nullptr on failure. + scoped_refptr<network::SharedURLLoaderFactory> GetLoaderFactoryForUpdateCheck( + const GURL& scope); private: friend class BackgroundSyncManagerTest; @@ -386,16 +370,16 @@ ~ServiceWorkerContextWrapper() override; - void InitOnCoreThread( + // Init() with a custom database task runner and BrowserContext. Explicitly + // called from EmbeddedWorkerTestHelper. + void InitInternal( const base::FilePath& user_data_directory, - scoped_refptr<base::SequencedTaskRunner> database_task_runner, storage::QuotaManagerProxy* quota_manager_proxy, storage::SpecialStoragePolicy* special_storage_policy, ChromeBlobStorageContext* blob_context, - URLLoaderFactoryGetter* url_loader_factory_getter, - std::unique_ptr<blink::PendingURLLoaderFactoryBundle> - non_network_pending_loader_factory_bundle_for_update_check); - void ShutdownOnCoreThread(); + URLLoaderFactoryGetter* loader_factory_getter, + scoped_refptr<base::SequencedTaskRunner> database_task_runner, + BrowserContext* browser_context); // If |include_installing_version| is true, |callback| is called if there is // an installing version with no waiting or active version. @@ -415,25 +399,14 @@ void DidDeleteAndStartOver(blink::ServiceWorkerStatusCode status); void DidGetAllRegistrationsForGetAllOrigins( - base::TimeTicks start_time, GetUsageInfoCallback callback, - scoped_refptr<base::TaskRunner> callback_runner, blink::ServiceWorkerStatusCode status, const std::vector<ServiceWorkerRegistrationInfo>& registrations); - void DidCheckHasServiceWorker(CheckHasServiceWorkerCallback callback, - content::ServiceWorkerCapability status); - void DidCheckOfflineCapability(CheckOfflineCapabilityCallback callback, - content::OfflineCapability status, - int64_t registration_id); - void DidFindRegistrationForUpdate( blink::ServiceWorkerStatusCode status, scoped_refptr<content::ServiceWorkerRegistration> registration); - void CountExternalRequests(const url::Origin& origin, - CountExternalRequestsCallback callback); - void DidFindRegistrationForNavigationHint( StartServiceWorkerForNavigationHintCallback callback, blink::ServiceWorkerStatusCode status, @@ -452,7 +425,6 @@ blink::TransferableMessage message, const GURL& source_origin, ResultCallback result_callback, - scoped_refptr<base::TaskRunner> callback_runner, blink::ServiceWorkerStatusCode service_worker_status, scoped_refptr<ServiceWorkerRegistration> registration); @@ -461,7 +433,6 @@ const GURL& source_origin, scoped_refptr<ServiceWorkerRegistration> registration, ServiceWorkerContext::ResultCallback result_callback, - scoped_refptr<base::TaskRunner> callback_runner, blink::ServiceWorkerStatusCode service_worker_status); // Called when ServiceWorkerImportedScriptUpdateCheck is enabled. @@ -485,11 +456,9 @@ base::OnceCallback<void(scoped_refptr<network::SharedURLLoaderFactory>)> callback); - // These methods are used as a callback for GetRegisteredOrigins when - // initialising on the core thread, so registered origins can be tracked - // on the UI thread as well. + // This is used as a callback of GetRegisteredOrigins when initialising to + // store a list of origins that have registered service workers. void DidGetRegisteredOrigins(const std::vector<url::Origin>& origins); - void InitializeRegisteredOriginsOnUI(const std::vector<url::Origin>& origins); static void DidGetRegisteredOriginsForGetInstalledRegistrationOrigins( base::Optional<std::string> host_filter, @@ -497,71 +466,55 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_callback, const std::vector<url::Origin>& origins); - // Temporary for crbug.com/824858. - void GetAllOriginsInfoOnCoreThread( - GetUsageInfoCallback callback, - scoped_refptr<base::TaskRunner> callback_runner); - void PerformStorageCleanupOnCoreThread( + // Temporary for https://crbug.com/1161153. + void PerformStorageCleanupOnUIThread( base::OnceClosure callback, scoped_refptr<base::TaskRunner> callback_runner); - void StartServiceWorkerAndDispatchMessageOnCoreThread( + void StartServiceWorkerAndDispatchMessageOnUIThread( const GURL& scope, blink::TransferableMessage message, - ResultCallback result_callback, - scoped_refptr<base::TaskRunner> callback_runner); - void DeleteForOriginOnCoreThread( + ResultCallback result_callback); + void DeleteForOriginOnUIThread( const url::Origin& origin, ResultCallback callback, scoped_refptr<base::TaskRunner> callback_runner); - void HasMainFrameWindowClientOnCoreThread( - const GURL& origin, - BoolCallback callback, - scoped_refptr<base::TaskRunner> callback_runner) const; - void GetAllRegistrationsOnCoreThread(GetRegistrationsInfosCallback callback); - void GetRegistrationUserDataOnCoreThread(int64_t registration_id, - const std::vector<std::string>& keys, - GetUserDataCallback callback); - void GetRegistrationUserDataByKeyPrefixOnCoreThread( + void GetRegistrationUserDataOnUIThread(int64_t registration_id, + const std::vector<std::string>& keys, + GetUserDataCallback callback); + void GetRegistrationUserDataByKeyPrefixOnUIThread( int64_t registration_id, const std::string& key_prefix, GetUserDataCallback callback); - void GetRegistrationUserKeysAndDataByKeyPrefixOnCoreThread( + void GetRegistrationUserKeysAndDataByKeyPrefixOnUIThread( int64_t registration_id, const std::string& key_prefix, GetUserKeysAndDataCallback callback); - void StoreRegistrationUserDataOnCoreThread( + void StoreRegistrationUserDataOnUIThread( int64_t registration_id, const url::Origin& origin, const std::vector<std::pair<std::string, std::string>>& key_value_pairs, StatusCallback callback); - void ClearRegistrationUserDataOnCoreThread( - int64_t registration_id, - const std::vector<std::string>& keys, - StatusCallback callback); - void ClearRegistrationUserDataByKeyPrefixesOnCoreThread( + void ClearRegistrationUserDataOnUIThread(int64_t registration_id, + const std::vector<std::string>& keys, + StatusCallback callback); + void ClearRegistrationUserDataByKeyPrefixesOnUIThread( int64_t registration_id, const std::vector<std::string>& key_prefixes, StatusCallback callback); - void GetUserDataForAllRegistrationsOnCoreThread( + void GetUserDataForAllRegistrationsOnUIThread( const std::string& key, GetUserDataForAllRegistrationsCallback callback); - void GetUserDataForAllRegistrationsByKeyPrefixOnCoreThread( + void GetUserDataForAllRegistrationsByKeyPrefixOnUIThread( const std::string& key_prefix, GetUserDataForAllRegistrationsCallback callback); - void ClearUserDataForAllRegistrationsByKeyPrefixOnCoreThread( + void ClearUserDataForAllRegistrationsByKeyPrefixOnUIThread( const std::string& key_prefix, StatusCallback callback); - void StartServiceWorkerForNavigationHintOnCoreThread( - const GURL& document_url, - StartServiceWorkerForNavigationHintCallback callback); - void StopAllServiceWorkersOnCoreThread( - base::OnceClosure callback, - scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_callback); - void GetInstalledRegistrationOriginsOnCoreThread( + void GetInstalledRegistrationOriginsOnUIThread( base::Optional<std::string> host_filter, GetInstalledRegistrationOriginsCallback callback, scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_callback); - void GetStorageUsageForOriginOnCoreThread( + void GetStorageUsageForOriginOnUIThread( const url::Origin& origin, GetStorageUsageForOriginCallback callback); @@ -577,7 +530,6 @@ observer_list_; const std::unique_ptr<ServiceWorkerProcessManager> process_manager_; - // Cleared in ShutdownOnCoreThread(): std::unique_ptr<ServiceWorkerContextCore> context_core_; // Initialized in Init(); true if the user data directory is empty.
diff --git a/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc b/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc index fe85f03..b6763487 100644 --- a/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc +++ b/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc
@@ -206,6 +206,9 @@ base::Optional<SubresourceLoaderParams> ServiceWorkerMainResourceLoaderInterceptor:: MaybeCreateSubresourceLoaderParams() { + if (!handle_) { + return base::nullopt; + } base::WeakPtr<ServiceWorkerContainerHost> container_host = handle_->container_host();
diff --git a/content/browser/service_worker/service_worker_metrics.cc b/content/browser/service_worker/service_worker_metrics.cc index bc69de06..9f77049 100644 --- a/content/browser/service_worker/service_worker_metrics.cc +++ b/content/browser/service_worker/service_worker_metrics.cc
@@ -569,8 +569,4 @@ } } -void ServiceWorkerMetrics::RecordGetAllOriginsInfoTime(base::TimeDelta time) { - base::UmaHistogramMediumTimes("ServiceWorker.GetAllOriginsInfoTime", time); -} - } // namespace content
diff --git a/content/browser/service_worker/service_worker_metrics.h b/content/browser/service_worker/service_worker_metrics.h index 5df034e..a81d49a 100644 --- a/content/browser/service_worker/service_worker_metrics.h +++ b/content/browser/service_worker/service_worker_metrics.h
@@ -242,8 +242,6 @@ blink::ServiceWorkerStatusCode status, base::TimeDelta duration); - static void RecordGetAllOriginsInfoTime(base::TimeDelta time); - private: DISALLOW_IMPLICIT_CONSTRUCTORS(ServiceWorkerMetrics); };
diff --git a/content/browser/service_worker/service_worker_register_job.cc b/content/browser/service_worker/service_worker_register_job.cc index b25c66d8..00048ba6 100644 --- a/content/browser/service_worker/service_worker_register_job.cc +++ b/content/browser/service_worker/service_worker_register_job.cc
@@ -336,39 +336,6 @@ return !skip_script_comparison_; } -void ServiceWorkerRegisterJob::TriggerUpdateCheck( - scoped_refptr<network::SharedURLLoaderFactory> loader_factory) { - DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); - - if (!loader_factory) { - // We can't continue with update checking appropriately without - // |loader_factory|. Null |loader_factory| means that the storage partition - // was not available probably because it's shutting down. - // This terminates the current job (|this|). - Complete(blink::ServiceWorkerStatusCode::kErrorAbort, - ServiceWorkerConsts::kShutdownErrorMessage); - return; - } - - ServiceWorkerVersion* version_to_update = registration()->GetNewestVersion(); - base::TimeDelta time_since_last_check = - base::Time::Now() - registration()->last_update_check(); - std::vector<storage::mojom::ServiceWorkerResourceRecordPtr> resources; - version_to_update->script_cache_map()->GetResources(&resources); - int64_t script_resource_id = - version_to_update->script_cache_map()->LookupResourceId(script_url_); - DCHECK_NE(script_resource_id, blink::mojom::kInvalidServiceWorkerResourceId); - - update_checker_ = std::make_unique<ServiceWorkerUpdateChecker>( - std::move(resources), script_url_, script_resource_id, version_to_update, - std::move(loader_factory), force_bypass_cache_, - registration()->update_via_cache(), time_since_last_check, context_, - outside_fetch_client_settings_object_.Clone()); - update_checker_->Start( - base::BindOnce(&ServiceWorkerRegisterJob::OnUpdateCheckFinished, - weak_factory_.GetWeakPtr())); -} - void ServiceWorkerRegisterJob::OnUpdateCheckFinished( ServiceWorkerSingleScriptUpdateChecker::Result result, std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker::FailureInfo> @@ -518,10 +485,35 @@ return; } - // This will start the update check after loader factory is retrieved. - context_->wrapper()->GetLoaderFactoryForUpdateCheck( - scope_, base::BindOnce(&ServiceWorkerRegisterJob::TriggerUpdateCheck, - weak_factory_.GetWeakPtr())); + scoped_refptr<network::SharedURLLoaderFactory> loader_factory = + context_->wrapper()->GetLoaderFactoryForUpdateCheck(scope_); + if (!loader_factory) { + // We can't continue with update checking appropriately without + // |loader_factory|. Null |loader_factory| means that the storage partition + // was not available probably because it's shutting down. + // This terminates the current job (|this|). + Complete(blink::ServiceWorkerStatusCode::kErrorAbort, + ServiceWorkerConsts::kShutdownErrorMessage); + return; + } + + ServiceWorkerVersion* version_to_update = registration()->GetNewestVersion(); + base::TimeDelta time_since_last_check = + base::Time::Now() - registration()->last_update_check(); + std::vector<storage::mojom::ServiceWorkerResourceRecordPtr> resources; + version_to_update->script_cache_map()->GetResources(&resources); + int64_t script_resource_id = + version_to_update->script_cache_map()->LookupResourceId(script_url_); + DCHECK_NE(script_resource_id, blink::mojom::kInvalidServiceWorkerResourceId); + + update_checker_ = std::make_unique<ServiceWorkerUpdateChecker>( + std::move(resources), script_url_, script_resource_id, version_to_update, + std::move(loader_factory), force_bypass_cache_, + registration()->update_via_cache(), time_since_last_check, context_, + outside_fetch_client_settings_object_.Clone()); + update_checker_->Start( + base::BindOnce(&ServiceWorkerRegisterJob::OnUpdateCheckFinished, + weak_factory_.GetWeakPtr())); } void ServiceWorkerRegisterJob::OnStartWorkerFinished(
diff --git a/content/browser/service_worker/service_worker_register_job.h b/content/browser/service_worker/service_worker_register_job.h index d01452ab..f8f6aae8 100644 --- a/content/browser/service_worker/service_worker_register_job.h +++ b/content/browser/service_worker/service_worker_register_job.h
@@ -115,8 +115,6 @@ scoped_refptr<ServiceWorkerRegistration> registration); bool IsUpdateCheckNeeded() const; - void TriggerUpdateCheck( - scoped_refptr<network::SharedURLLoaderFactory> loader_factory); // Refer ServiceWorkerUpdateChecker::UpdateStatusCallback for the meaning of // the parameters.
diff --git a/content/browser/worker_host/worker_script_loader.cc b/content/browser/worker_host/worker_script_loader.cc index 488671b0..720c6d9 100644 --- a/content/browser/worker_host/worker_script_loader.cc +++ b/content/browser/worker_host/worker_script_loader.cc
@@ -118,6 +118,12 @@ DCHECK(!completed_); DCHECK(interceptor); + if (!service_worker_handle_) { + // The DedicatedWorkerHost or SharedWorkerHost is already destroyed. + Abort(); + return; + } + // Create SubresourceLoaderParams for intercepting subresource requests and // populating the "controller" field in ServiceWorkerContainer. This can be // null if the interceptor is not interested in this request.
diff --git a/content/child/child_process_sandbox_support_impl_mac.cc b/content/child/child_process_sandbox_support_impl_mac.cc index 55ece81f..20fa9f5 100644 --- a/content/child/child_process_sandbox_support_impl_mac.cc +++ b/content/child/child_process_sandbox_support_impl_mac.cc
@@ -59,8 +59,9 @@ out_descriptor); } -SkColor WebSandboxSupportMac::GetSystemColor(blink::MacSystemColorID color_id, - blink::ColorScheme color_scheme) { +SkColor WebSandboxSupportMac::GetSystemColor( + blink::MacSystemColorID color_id, + blink::mojom::ColorScheme color_scheme) { if (!color_map_.IsValid()) { DLOG(ERROR) << "GetSystemColor does not have a valid color_map_"; return SK_ColorMAGENTA; @@ -69,10 +70,11 @@ "Light and dark color scheme system colors loaded."); base::span<const SkColor> color_map = color_map_.GetMemoryAsSpan<SkColor>( blink::kMacSystemColorIDCount * blink::kMacSystemColorSchemeCount); - base::span<const SkColor> color_map_for_scheme = color_map.subspan( - color_scheme == blink::ColorScheme::kDark ? blink::kMacSystemColorIDCount - : 0, - blink::kMacSystemColorIDCount); + base::span<const SkColor> color_map_for_scheme = + color_map.subspan(color_scheme == blink::mojom::ColorScheme::kDark + ? blink::kMacSystemColorIDCount + : 0, + blink::kMacSystemColorIDCount); return color_map_for_scheme[static_cast<size_t>(color_id)]; }
diff --git a/content/child/child_process_sandbox_support_impl_mac.h b/content/child/child_process_sandbox_support_impl_mac.h index 1456f46..96c9cbc 100644 --- a/content/child/child_process_sandbox_support_impl_mac.h +++ b/content/child/child_process_sandbox_support_impl_mac.h
@@ -29,7 +29,7 @@ base::ScopedCFTypeRef<CTFontDescriptorRef>* out_descriptor, uint32_t* font_id) override; SkColor GetSystemColor(blink::MacSystemColorID color_id, - blink::ColorScheme color_scheme) override; + blink::mojom::ColorScheme color_scheme) override; private: void OnGotSystemColors(base::ReadOnlySharedMemoryRegion region);
diff --git a/content/child/webthemeengine_impl_android.cc b/content/child/webthemeengine_impl_android.cc index 0696ab7..a6be4c16 100644 --- a/content/child/webthemeengine_impl_android.cc +++ b/content/child/webthemeengine_impl_android.cc
@@ -10,7 +10,6 @@ #include "skia/ext/platform_canvas.h" #include "ui/native_theme/native_theme.h" -using blink::ColorScheme; using blink::WebThemeEngine; namespace content { @@ -156,7 +155,7 @@ WebThemeEngine::State state, const gfx::Rect& rect, const WebThemeEngine::ExtraParams* extra_params, - blink::ColorScheme color_scheme) { + blink::mojom::ColorScheme color_scheme) { ui::NativeTheme::ExtraParams native_theme_extra_params; GetNativeThemeExtraParams( part, state, extra_params, &native_theme_extra_params);
diff --git a/content/child/webthemeengine_impl_android.h b/content/child/webthemeengine_impl_android.h index 06cc7b8..aff6b7c 100644 --- a/content/child/webthemeengine_impl_android.h +++ b/content/child/webthemeengine_impl_android.h
@@ -21,7 +21,7 @@ blink::WebThemeEngine::State state, const gfx::Rect& rect, const blink::WebThemeEngine::ExtraParams* extra_params, - blink::ColorScheme color_scheme) override; + blink::mojom::ColorScheme color_scheme) override; blink::ForcedColors GetForcedColors() const override; void SetForcedColors(const blink::ForcedColors forced_colors) override; };
diff --git a/content/child/webthemeengine_impl_conversions.cc b/content/child/webthemeengine_impl_conversions.cc index 84509d4..fa3747b 100644 --- a/content/child/webthemeengine_impl_conversions.cc +++ b/content/child/webthemeengine_impl_conversions.cc
@@ -84,11 +84,11 @@ } ui::NativeTheme::ColorScheme NativeColorScheme( - blink::ColorScheme color_scheme) { + blink::mojom::ColorScheme color_scheme) { switch (color_scheme) { - case blink::ColorScheme::kLight: + case blink::mojom::ColorScheme::kLight: return ui::NativeTheme::ColorScheme::kLight; - case blink::ColorScheme::kDark: + case blink::mojom::ColorScheme::kDark: return ui::NativeTheme::ColorScheme::kDark; } }
diff --git a/content/child/webthemeengine_impl_conversions.h b/content/child/webthemeengine_impl_conversions.h index 88858bc..92f7826f 100644 --- a/content/child/webthemeengine_impl_conversions.h +++ b/content/child/webthemeengine_impl_conversions.h
@@ -22,7 +22,7 @@ blink::WebThemeEngine::State state); CONTENT_EXPORT ui::NativeTheme::ColorScheme NativeColorScheme( - blink::ColorScheme color_scheme); + blink::mojom::ColorScheme color_scheme); CONTENT_EXPORT ui::NativeTheme::SystemThemeColor NativeSystemThemeColor( blink::WebThemeEngine::SystemThemeColor theme_color);
diff --git a/content/child/webthemeengine_impl_default.cc b/content/child/webthemeengine_impl_default.cc index 836fa111..312bc84 100644 --- a/content/child/webthemeengine_impl_default.cc +++ b/content/child/webthemeengine_impl_default.cc
@@ -10,9 +10,9 @@ #include "ui/native_theme/native_theme.h" #include "ui/native_theme/overlay_scrollbar_constants_aura.h" -using blink::ColorScheme; using blink::WebScrollbarOverlayColorTheme; using blink::WebThemeEngine; +using blink::mojom::ColorScheme; namespace content { namespace { @@ -185,7 +185,7 @@ WebThemeEngine::State state, const gfx::Rect& rect, const WebThemeEngine::ExtraParams* extra_params, - blink::ColorScheme color_scheme) { + blink::mojom::ColorScheme color_scheme) { ui::NativeTheme::ExtraParams native_theme_extra_params; GetNativeThemeExtraParams( part, state, extra_params, &native_theme_extra_params);
diff --git a/content/child/webthemeengine_impl_default.h b/content/child/webthemeengine_impl_default.h index 91715b8c..9da412ed 100644 --- a/content/child/webthemeengine_impl_default.h +++ b/content/child/webthemeengine_impl_default.h
@@ -22,7 +22,7 @@ blink::WebThemeEngine::State state, const gfx::Rect& rect, const blink::WebThemeEngine::ExtraParams* extra_params, - blink::ColorScheme color_scheme) override; + blink::mojom::ColorScheme color_scheme) override; void GetOverlayScrollbarStyle( blink::WebThemeEngine::ScrollbarStyle*) override; bool SupportsNinePatch(Part part) const override;
diff --git a/content/child/webthemeengine_impl_mac.cc b/content/child/webthemeengine_impl_mac.cc index d442351..009f761 100644 --- a/content/child/webthemeengine_impl_mac.cc +++ b/content/child/webthemeengine_impl_mac.cc
@@ -14,7 +14,7 @@ WebThemeEngine::State state, const gfx::Rect& rect, const WebThemeEngine::ExtraParams* extra_params, - blink::ColorScheme color_scheme) { + blink::mojom::ColorScheme color_scheme) { if (IsScrollbarPart(part)) { PaintMacScrollBarParts(canvas, part, state, rect, extra_params, color_scheme); @@ -44,7 +44,7 @@ WebThemeEngine::State state, const gfx::Rect& rect, const WebThemeEngine::ExtraParams* extra_params, - blink::ColorScheme color_scheme) { + blink::mojom::ColorScheme color_scheme) { ui::NativeTheme::ExtraParams native_theme_extra_params; native_theme_extra_params.scrollbar_extra.is_hovering = extra_params->scrollbar_extra.is_hovering;
diff --git a/content/child/webthemeengine_impl_mac.h b/content/child/webthemeengine_impl_mac.h index 6a3aac0..64b17c7 100644 --- a/content/child/webthemeengine_impl_mac.h +++ b/content/child/webthemeengine_impl_mac.h
@@ -18,7 +18,7 @@ blink::WebThemeEngine::State state, const gfx::Rect& rect, const blink::WebThemeEngine::ExtraParams* extra_params, - blink::ColorScheme color_scheme) override; + blink::mojom::ColorScheme color_scheme) override; static bool IsScrollbarPart(WebThemeEngine::Part part); static void PaintMacScrollBarParts( @@ -27,7 +27,7 @@ WebThemeEngine::State state, const gfx::Rect& rect, const WebThemeEngine::ExtraParams* extra_params, - blink::ColorScheme color_scheme); + blink::mojom::ColorScheme color_scheme); }; } // namespace content
diff --git a/content/child/webthemeengine_impl_unittest.cc b/content/child/webthemeengine_impl_unittest.cc index 45c2598d..45bf16a6 100644 --- a/content/child/webthemeengine_impl_unittest.cc +++ b/content/child/webthemeengine_impl_unittest.cc
@@ -97,8 +97,8 @@ } TEST(WebThemeEngineTest, NativeColorScheme) { - std::vector<blink::ColorScheme> blink_inputs = {blink::ColorScheme::kLight, - blink::ColorScheme::kDark}; + std::vector<blink::mojom::ColorScheme> blink_inputs = { + blink::mojom::ColorScheme::kLight, blink::mojom::ColorScheme::kDark}; std::vector<ui::NativeTheme::ColorScheme> native_theme_outputs = { ui::NativeTheme::ColorScheme::kLight,
diff --git a/content/common/frame.mojom b/content/common/frame.mojom index 5a31b87..d14891f 100644 --- a/content/common/frame.mojom +++ b/content/common/frame.mojom
@@ -208,15 +208,6 @@ // all possible. SetWantErrorMessageStackTrace(); - // Requests that a provisional RenderFrame swap itself into the frame tree, - // replacing the RenderFrameProxy that it is associated with. This is used - // with remote-to-local frame navigations when the RenderFrameProxy - // corresponds to a non-live (crashed) frame. In that case, the browser - // process will send this message as part of an early commit to stop showing - // the sad iframe without waiting for the provisional RenderFrame's navigation - // to commit. - SwapIn(); - // Unload this RenderFrame and replace it by a RenderFrameProxy, so the frame // can navigate to a document rendered by a different process. The unload can // fail if the RenderFrame is currently detached (it was removed from the
diff --git a/content/public/browser/service_worker_context.h b/content/public/browser/service_worker_context.h index 8db242d..47abbd1 100644 --- a/content/public/browser/service_worker_context.h +++ b/content/public/browser/service_worker_context.h
@@ -64,6 +64,12 @@ // See service_worker_context_wrapper.cc for the implementation // of ServiceWorkerContext and ServiceWorkerContextWrapper (the // primary implementation of this abstract class). +// +// All methods are basically expected to be called on the UI thread. +// Currently, only two methods are allowed to be called on any threads but it's +// discouraged. +// TODO(https://crbug.com/1161153): Disallow methods to be called on any +// threads. class CONTENT_EXPORT ServiceWorkerContext { public: using ResultCallback = base::OnceCallback<void(bool success)>; @@ -81,9 +87,6 @@ base::OnceCallback<void(OfflineCapability capability, int64_t registration_id)>; - using CountExternalRequestsCallback = - base::OnceCallback<void(size_t external_request_count)>; - using StartServiceWorkerForNavigationHintCallback = base::OnceCallback<void( StartServiceWorkerForNavigationHintResult result)>; @@ -93,6 +96,8 @@ using StartWorkerFailureCallback = base::OnceCallback<void(blink::ServiceWorkerStatusCode status_code)>; + // Returns BrowserThread::UI always. + // TODO(https://crbug.com/1138155): Remove this. static content::BrowserThread::ID GetCoreThreadId(); // Returns true if |url| is within the service worker |scope|. @@ -105,7 +110,6 @@ ServiceWorkerContext* service_worker_context, base::OnceClosure task); - // Observer methods are always dispatched on the UI thread. virtual void AddObserver(ServiceWorkerContextObserver* observer) = 0; virtual void RemoveObserver(ServiceWorkerContextObserver* observer) = 0; @@ -118,9 +122,6 @@ // * Fetching |script_url| fails. // * |script_url| fails to parse or its top-level execution fails. // * Something unexpected goes wrong, like a renderer crash or a full disk. - // - // This function can be called from any thread, but the callback will always - // be called on the UI thread. virtual void RegisterServiceWorker( const GURL& script_url, const blink::mojom::ServiceWorkerRegistrationOptions& options, @@ -133,9 +134,6 @@ // Unregistration can fail if: // * No registration exists for |scope|. // * Something unexpected goes wrong, like a renderer crash. - // - // This function can be called from any thread, but the callback will always - // be called on the UI thread. virtual void UnregisterServiceWorker(const GURL& scope, ResultCallback callback) = 0; @@ -147,8 +145,6 @@ // calls FinishedExternalRequest(). This ensures that content/ does not // shut the worker down while embedder is expecting the worker to be kept // alive. - // - // Must be called from the core thread. virtual ServiceWorkerExternalRequestResult StartingExternalRequest( int64_t service_worker_version_id, const std::string& request_uuid) = 0; @@ -157,18 +153,14 @@ const std::string& request_uuid) = 0; // Returns the pending external request count for the worker with the - // specified |origin| via |callback|. Must be called from the UI thread. The - // callback is called on the UI thread. - virtual void CountExternalRequestsForTest( - const url::Origin& origin, - CountExternalRequestsCallback callback) = 0; + // specified |origin|. + virtual size_t CountExternalRequestsForTest(const url::Origin& origin) = 0; // Whether |origin| has any registrations. Uninstalling and uninstalled // registrations do not cause this to return true, that is, only registrations // with status ServiceWorkerRegistration::Status::kIntact are considered, such // as even if the corresponding live registrations may still exist. Also, // returns true if it doesn't know (registrations are not yet initialized). - // Must be called on the UI thread. virtual bool MaybeHasRegistrationForOrigin(const url::Origin& origin) = 0; // Returns a set of origins which have at least one stored registration. @@ -181,14 +173,13 @@ base::Optional<std::string> host_filter, GetInstalledRegistrationOriginsCallback callback) = 0; - // May be called from any thread, and the callback is called on that thread. virtual void GetAllOriginsInfo(GetUsageInfoCallback callback) = 0; - // This function can be called from any thread, and the callback is called - // on that thread. Deletes all registrations in the origin and clears all - // service workers belonging to the registrations. All clients controlled by - // those service workers will lose their controllers immediately after this - // operation. + // Deletes all registrations in the origin and clears all service workers + // belonging to the registrations. All clients controlled by those service + // workers will lose their controllers immediately after this operation. + // This function can be called from any thread, and the callback is called on + // that thread. virtual void DeleteForOrigin(const url::Origin& origin_url, ResultCallback callback) = 0; @@ -203,9 +194,6 @@ // Service Worker registration matching |url|. In case the service // worker is being installed as of calling this method, it will wait for the // installation to finish before coming back with the result. - // - // This function can be called from any thread, but the callback will always - // be called on the UI thread. virtual void CheckHasServiceWorker( const GURL& url, CheckHasServiceWorkerCallback callback) = 0; @@ -214,9 +202,6 @@ // event. Returns OfflineCapability::kSupported and the registration id if // the response's status code is 200. // - // This function can be called from any thread, but the callback will always - // be called on the UI thread. - // // TODO(hayato): Re-visit to integrate this function with // |ServiceWorkerContext::CheckHasServiceWorker|. virtual void CheckOfflineCapability( @@ -226,9 +211,6 @@ // Stops all running service workers and unregisters all service worker // registrations. This method is used in web tests to make sure that the // existing service worker will not affect the succeeding tests. - // - // This function can be called from any thread, but the callback will always - // be called on the UI thread. virtual void ClearAllServiceWorkersForTest(base::OnceClosure callback) = 0; // Starts the active worker of the registration for the given |scope|. If @@ -237,9 +219,8 @@ // successful, otherwise |failure_callback| is passed information about the // error. // - // Must be called on the core thread, and the callback is called on that - // thread. There is no guarantee about whether the callback is called - // synchronously or asynchronously. + // There is no guarantee about whether the callback is called synchronously or + // asynchronously. virtual void StartWorkerForScope( const GURL& scope, StartWorkerCallback info_callback, @@ -257,26 +238,18 @@ ResultCallback result_callback) = 0; // Starts the service worker for |document_url|. Called when a navigation to - // that URL is predicted to occur soon. Must be called from the UI thread. The - // |callback| will always be called on the UI thread. + // that URL is predicted to occur soon. virtual void StartServiceWorkerForNavigationHint( const GURL& document_url, StartServiceWorkerForNavigationHintCallback callback) = 0; // Stops all running workers on the given |origin|. - // - // This function can be called from any thread. virtual void StopAllServiceWorkersForOrigin(const url::Origin& origin) = 0; // Stops all running service workers. - // - // This function can be called from any thread. - // |callback| is called on the caller's thread. virtual void StopAllServiceWorkers(base::OnceClosure callback) = 0; // Gets info about all running workers. - // - // Must be called on the UI thread. The callback is called on the UI thread. virtual const base::flat_map<int64_t /* version_id */, ServiceWorkerRunningInfo>& GetRunningServiceWorkerInfos() = 0;
diff --git a/content/public/test/fake_local_frame.cc b/content/public/test/fake_local_frame.cc index 7169507e..c6784136 100644 --- a/content/public/test/fake_local_frame.cc +++ b/content/public/test/fake_local_frame.cc
@@ -45,6 +45,8 @@ void FakeLocalFrame::AddInspectorIssue( blink::mojom::InspectorIssueInfoPtr info) {} +void FakeLocalFrame::SwapInImmediately() {} + void FakeLocalFrame::CheckCompleted() {} void FakeLocalFrame::StopLoading() {}
diff --git a/content/public/test/fake_local_frame.h b/content/public/test/fake_local_frame.h index bd58a30..d9c48a7 100644 --- a/content/public/test/fake_local_frame.h +++ b/content/public/test/fake_local_frame.h
@@ -49,6 +49,7 @@ const std::string& message, bool discard_duplicates) override; void AddInspectorIssue(blink::mojom::InspectorIssueInfoPtr info) override; + void SwapInImmediately() override; void CheckCompleted() override; void StopLoading() override; void Collapse(bool collapsed) override;
diff --git a/content/public/test/fake_service_worker_context.cc b/content/public/test/fake_service_worker_context.cc index 45257b5..1945153 100644 --- a/content/public/test/fake_service_worker_context.cc +++ b/content/public/test/fake_service_worker_context.cc
@@ -50,10 +50,10 @@ NOTREACHED(); return ServiceWorkerExternalRequestResult::kWorkerNotFound; } -void FakeServiceWorkerContext::CountExternalRequestsForTest( - const url::Origin& origin, - CountExternalRequestsCallback callback) { +size_t FakeServiceWorkerContext::CountExternalRequestsForTest( + const url::Origin& origin) { NOTREACHED(); + return 0u; } bool FakeServiceWorkerContext::MaybeHasRegistrationForOrigin( const url::Origin& origin) {
diff --git a/content/public/test/fake_service_worker_context.h b/content/public/test/fake_service_worker_context.h index 560ff20f..02b3995 100644 --- a/content/public/test/fake_service_worker_context.h +++ b/content/public/test/fake_service_worker_context.h
@@ -45,9 +45,7 @@ ServiceWorkerExternalRequestResult FinishedExternalRequest( int64_t service_worker_version_id, const std::string& request_uuid) override; - void CountExternalRequestsForTest( - const url::Origin& origin, - CountExternalRequestsCallback callback) override; + size_t CountExternalRequestsForTest(const url::Origin& origin) override; bool MaybeHasRegistrationForOrigin(const url::Origin& origin) override; void GetInstalledRegistrationOrigins( base::Optional<std::string> host_filter,
diff --git a/content/renderer/media/android/stream_texture_proxy_unittest.cc b/content/renderer/media/android/stream_texture_proxy_unittest.cc index 74e03d6f..6d74e789 100644 --- a/content/renderer/media/android/stream_texture_proxy_unittest.cc +++ b/content/renderer/media/android/stream_texture_proxy_unittest.cc
@@ -39,8 +39,7 @@ public: StreamTextureProxyTest() : task_runner_(base::MakeRefCounted<base::TestSimpleTaskRunner>()), - thread_task_runner_handle_override_( - base::ThreadTaskRunnerHandle::OverrideForTesting(task_runner_)), + thread_task_runner_handle_override_(task_runner_), channel_(base::MakeRefCounted<TestGpuChannelHost>()) {} ~StreamTextureProxyTest() override { channel_ = nullptr; } @@ -59,7 +58,8 @@ protected: scoped_refptr<base::TestSimpleTaskRunner> task_runner_; - base::ScopedClosureRunner thread_task_runner_handle_override_; + base::ThreadTaskRunnerHandleOverrideForTesting + thread_task_runner_handle_override_; scoped_refptr<TestGpuChannelHost> channel_; };
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index b42f671..8d9b4417 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -1154,6 +1154,13 @@ std::move(in->remote)); } +std::string GetUniqueNameOfWebFrame(WebFrame* web_frame) { + if (web_frame->IsWebLocalFrame()) + return RenderFrameImpl::FromWebFrame(web_frame)->unique_name(); + return RenderFrameProxy::FromWebFrame(web_frame->ToWebRemoteFrame()) + ->unique_name(); +} + } // namespace RenderFrameImpl::AssertNavigationCommits::AssertNavigationCommits( @@ -1714,13 +1721,17 @@ agent_scheduling_group, render_view, routing_id, std::move(browser_interface_broker), devtools_frame_token); render_frame->InitializeBlameContext(nullptr); - render_frame->previous_routing_id_ = previous_routing_id; web_frame = blink::WebLocalFrame::CreateProvisional( render_frame, render_frame->blink_interface_registry_.get(), frame_token, previous_web_frame, replicated_state.frame_policy, WebString::FromUTF8(replicated_state.name)); - // The new |web_frame| is a main frame iff the proxy's frame was. + // The new |web_frame| is a main frame iff the previous frame was. DCHECK_EQ(!previous_web_frame->Parent(), !web_frame->Parent()); + // Clone the current unique name so web tests that log frame unique names + // output something meaningful. At `SwapIn()` time, the unique name will be + // updated to the latest value. + render_frame->unique_name_helper_.set_propagated_name( + GetUniqueNameOfWebFrame(previous_web_frame)); } CHECK(render_view); @@ -1965,7 +1976,6 @@ in_frame_tree_(false), render_view_(params.render_view), routing_id_(params.routing_id), - previous_routing_id_(MSG_ROUTING_NONE), selection_text_offset_(0), selection_range_(gfx::Range::InvalidRange()), render_accessibility_manager_( @@ -2588,10 +2598,6 @@ return base::Value(); } -void RenderFrameImpl::SwapIn() { - SwapInInternal(); -} - void RenderFrameImpl::SnapshotAccessibilityTree( uint32_t ax_mode, SnapshotAccessibilityTreeCallback callback) { @@ -4102,15 +4108,6 @@ "id", routing_id_, "url", GetLoadingUrl().possibly_invalid_spec()); - bool is_provisional_frame = previous_routing_id_ != MSG_ROUTING_NONE; - if (is_provisional_frame) { - // If this is a provisional frame associated with a proxy (i.e., a frame - // created for a remote-to-local navigation), swap it into the frame tree - // now. - if (!SwapInInternal()) - return; - } - // Generate a new embedding token on each document change. GetWebFrame()->SetEmbeddingToken(base::UnguessableToken::Create()); @@ -5237,38 +5234,17 @@ return blink::mojom::CommitResult::Ok; } -std::string RenderFrameImpl::GetPreviousFrameUniqueName() { - DCHECK(!in_frame_tree_); - - RenderFrameProxy* previous_proxy = - RenderFrameProxy::FromRoutingID(previous_routing_id_); - RenderFrameImpl* previous_frame = - RenderFrameImpl::FromRoutingID(previous_routing_id_); - - // The |previous_proxy| or the |previous_frame| should always exist. - // If it was detached while the provisional LocalFrame was being navigated, - // the provisional frame would've been cleaned up by - // RenderFrameProxy::FrameDetached. - // See https://crbug.com/526304 and https://crbug.com/568676 for context. - CHECK_NE(!!previous_proxy, !!previous_frame); - - if (previous_proxy) - return previous_proxy->unique_name(); - return previous_frame->unique_name(); -} - -bool RenderFrameImpl::SwapInInternal() { - CHECK_NE(previous_routing_id_, MSG_ROUTING_NONE); +bool RenderFrameImpl::SwapIn(WebFrame* previous_web_frame) { CHECK(!in_frame_tree_); - unique_name_helper_.set_propagated_name(GetPreviousFrameUniqueName()); + // The unique name can still change in `WebFrame::Swap()` below (due to JS + // changing the browsing context name), but in practice, this seems to be good + // enough. + unique_name_helper_.set_propagated_name( + GetUniqueNameOfWebFrame(previous_web_frame)); - // Note: Calling swap() will detach and delete |previous_frame|, so do not - // reference it after this. - WebFrame* previous_web_frame = ResolveWebFrame(previous_routing_id_); - - // With RenderDocument it's possible for the frame to be deleted as a side - // effect of JS event handlers called during swap. + // Swapping out a frame can dispatch JS event handlers, causing `this` to be + // deleted. bool is_main_frame = is_main_frame_; if (!previous_web_frame->Swap(frame_)) { // Main frames should always swap successfully because there is no parent @@ -5277,7 +5253,8 @@ return false; } - previous_routing_id_ = MSG_ROUTING_NONE; + // `previous_web_frame` is now detached, and should no longer be referenced. + in_frame_tree_ = true; // If this is the main frame going from a remote frame to a local frame,
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index f55598f..306e88f 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -522,7 +522,6 @@ int32_t world_id, JavaScriptExecuteRequestInIsolatedWorldCallback callback) override; void SetWantErrorMessageStackTrace() override; - void SwapIn() override; void Unload(int proxy_routing_id, bool is_loading, const FrameReplicationState& replicated_frame_state, @@ -602,6 +601,7 @@ void WillSendSubmitEvent(const blink::WebFormElement& form) override; void DidCreateDocumentLoader( blink::WebDocumentLoader* document_loader) override; + bool SwapIn(blink::WebFrame* previous_web_frame) override; void DidCommitNavigation( blink::WebHistoryCommitType commit_type, bool should_reset_browser_interface_broker, @@ -800,11 +800,6 @@ bool IsLocalRoot() const; const RenderFrameImpl* GetLocalRoot() const; - // Gets the unique_name() of the frame being replaced by this frame, when - // it is a provisional frame. Invalid to call on frames that are already - // attached to the frame tree. - std::string GetPreviousFrameUniqueName(); - private: friend class RenderFrameImplTest; friend class RenderFrameObserver; @@ -884,14 +879,6 @@ void AddObserver(RenderFrameObserver* observer); void RemoveObserver(RenderFrameObserver* observer); - // Swaps the current frame into the frame tree, replacing the - // RenderFrameProxy it is associated with. Return value indicates whether - // the swap operation succeeded. This should only be used for provisional - // frames associated with a proxy, while the proxy is still in the frame tree. - // If the associated proxy has been detached before this is called, this - // returns false and aborts the swap. - bool SwapInInternal(); - // Checks whether accessibility support for this frame is currently enabled. bool IsAccessibilityEnabled() const; @@ -1211,13 +1198,6 @@ RenderViewImpl* render_view_; const int routing_id_; - // If this RenderFrame was created to replace a previous object, this will - // store its routing id. The previous object can be: - // - A RenderFrame. This requires RenderDocument to be enabled. - // - A RenderFrameProxy. - // At commit time, the two objects will be swapped and the old one cleared. - int previous_routing_id_; - // Keeps track of which future subframes the browser process has history items // for during a history navigation, as well as whether those items are for // about:blank. The renderer process should ask the browser for history items
diff --git a/content/renderer/service_worker/service_worker_subresource_loader.cc b/content/renderer/service_worker/service_worker_subresource_loader.cc index 2b919092..6d9fafd 100644 --- a/content/renderer/service_worker/service_worker_subresource_loader.cc +++ b/content/renderer/service_worker/service_worker_subresource_loader.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/callback.h" #include "base/command_line.h" +#include "base/debug/crash_logging.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/optional.h" @@ -479,6 +480,7 @@ return; } response_head_->encoded_data_length = 0; + received_redirect_for_bug1162035_ = true; url_loader_client_->OnReceiveRedirect(*redirect_info_, response_head_.Clone()); TransitionToStatus(Status::kSentRedirect); @@ -684,7 +686,18 @@ "https://crbug.com/845683"; DCHECK(!new_url.has_value()) << "Redirect with modified url was not " "supported yet. crbug.com/845683"; - DCHECK(redirect_info_); + + // TODO(crbug.com/1162035): Replace with a DCHECK or early return when + // the bug is understood. + if (!redirect_info_) { + SCOPED_CRASH_KEY_NUMBER("bug1162035", "follow_status", + static_cast<int>(status_)); + SCOPED_CRASH_KEY_BOOL("bug1162035", "received_redirect", + received_redirect_for_bug1162035_); + SCOPED_CRASH_KEY_BOOL("bug1162035", "followed_redirect", + followed_redirect_for_bug1162035_); + CHECK(false); + } bool should_clear_upload = false; net::RedirectUtil::UpdateHttpRequest( @@ -707,6 +720,7 @@ // Restart the request. TransitionToStatus(Status::kNotStarted); redirect_info_.reset(); + followed_redirect_for_bug1162035_ = true; response_callback_receiver_.reset(); StartRequest(resource_request_); } @@ -858,25 +872,31 @@ } void ServiceWorkerSubresourceLoader::TransitionToStatus(Status new_status) { -#if DCHECK_IS_ON() + // TODO(crbug.com/1162035): Remove once the bug is understood and replace + // the CHECKs below to DCHECKs. + SCOPED_CRASH_KEY_NUMBER("bug1162035", "transition_old", + static_cast<int>(status_)); + SCOPED_CRASH_KEY_NUMBER("bug1162035", "transition_new", + static_cast<int>(new_status)); + switch (new_status) { case Status::kNotStarted: - DCHECK_EQ(status_, Status::kSentRedirect); + CHECK_EQ(status_, Status::kSentRedirect); break; case Status::kStarted: - DCHECK_EQ(status_, Status::kNotStarted); + CHECK_EQ(status_, Status::kNotStarted); break; case Status::kSentRedirect: - DCHECK_EQ(status_, Status::kStarted); + CHECK_EQ(status_, Status::kStarted); break; case Status::kSentHeader: - DCHECK_EQ(status_, Status::kStarted); + CHECK_EQ(status_, Status::kStarted); break; case Status::kSentBody: - DCHECK_EQ(status_, Status::kSentHeader); + CHECK_EQ(status_, Status::kSentHeader); break; case Status::kCompleted: - DCHECK( + CHECK( // Network fallback before interception. status_ == Status::kNotStarted || // Network fallback after interception. @@ -887,7 +907,6 @@ status_ == Status::kSentBody); break; } -#endif // DCHECK_IS_ON() status_ = new_status; }
diff --git a/content/renderer/service_worker/service_worker_subresource_loader.h b/content/renderer/service_worker/service_worker_subresource_loader.h index fc5a133..636b37e 100644 --- a/content/renderer/service_worker/service_worker_subresource_loader.h +++ b/content/renderer/service_worker/service_worker_subresource_loader.h
@@ -206,6 +206,11 @@ blink::mojom::ServiceWorkerFetchEventTimingPtr fetch_event_timing_; network::mojom::FetchResponseSource response_source_; + // For debugging crbug.com/1162035. Set to true after a redirect is + // received/followed. + bool received_redirect_for_bug1162035_ = false; + bool followed_redirect_for_bug1162035_ = false; + base::WeakPtrFactory<ServiceWorkerSubresourceLoader> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(ServiceWorkerSubresourceLoader);
diff --git a/content/web_test/renderer/web_frame_test_proxy.cc b/content/web_test/renderer/web_frame_test_proxy.cc index 0c52cd9..6ad2e410 100644 --- a/content/web_test/renderer/web_frame_test_proxy.cc +++ b/content/web_test/renderer/web_frame_test_proxy.cc
@@ -280,13 +280,7 @@ } std::string WebFrameTestProxy::GetFrameNameForWebTests() { - // If the frame is provisional, use the name of the frame it will replace in - // the tree, as the provisional frame has no name until swap. The name isn't - // moved onto the provisional frame until swap because it may change in the - // meantime, but this grabs the value it currently is, which is good enough - // for tests. - return blink::UniqueNameHelper::ExtractStableNameForTesting( - in_frame_tree() ? unique_name() : GetPreviousFrameUniqueName()); + return blink::UniqueNameHelper::ExtractStableNameForTesting(unique_name()); } std::string WebFrameTestProxy::GetFrameDescriptionForWebTests() {
diff --git a/extensions/browser/event_router_unittest.cc b/extensions/browser/event_router_unittest.cc index 31a67f7..89f49381 100644 --- a/extensions/browser/event_router_unittest.cc +++ b/extensions/browser/event_router_unittest.cc
@@ -20,7 +20,6 @@ #include "extensions/browser/extensions_test.h" #include "extensions/common/extension_builder.h" #include "extensions/common/extension_messages.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" #include "testing/gtest/include/gtest/gtest.h" using base::DictionaryValue; @@ -383,7 +382,6 @@ true /** did_enqueue */); ExpectHistogramCounts(7, 3, 2, 2, 2, 0); - ScopedWorkerBasedExtensionsChannel current_channel_override; scoped_refptr<const Extension> service_worker_extension = CreateServiceWorkerExtension(); router.ReportEvent(events::HistogramValue::FOR_TEST,
diff --git a/extensions/common/BUILD.gn b/extensions/common/BUILD.gn index 0c5e7e9..b7e5b49 100644 --- a/extensions/common/BUILD.gn +++ b/extensions/common/BUILD.gn
@@ -422,8 +422,6 @@ "api/extension_action/action_info_test_util.h", "file_test_util.cc", "file_test_util.h", - "scoped_worker_based_extensions_channel.cc", - "scoped_worker_based_extensions_channel.h", ] deps = [
diff --git a/extensions/common/extension_builder_unittest.cc b/extensions/common/extension_builder_unittest.cc index 29b18c47..6319fe7 100644 --- a/extensions/common/extension_builder_unittest.cc +++ b/extensions/common/extension_builder_unittest.cc
@@ -13,7 +13,6 @@ #include "extensions/common/manifest_handlers/content_scripts_handler.h" #include "extensions/common/manifest_handlers/externally_connectable.h" #include "extensions/common/permissions/permissions_data.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" #include "extensions/common/user_script.h" #include "extensions/common/value_builder.h" #include "testing/gmock/include/gmock/gmock.h" @@ -122,9 +121,6 @@ EXPECT_FALSE(BackgroundInfo::IsServiceWorkerBased(extension.get())); } { - // TODO(crbug.com/853378): Remove this when we open up support for - // service workers. - ScopedWorkerBasedExtensionsChannel current_channel_override; scoped_refptr<const Extension> extension = ExtensionBuilder("service worker") .SetBackgroundContext(
diff --git a/extensions/common/features/simple_feature_unittest.cc b/extensions/common/features/simple_feature_unittest.cc index f2d467b..e771b54 100644 --- a/extensions/common/features/simple_feature_unittest.cc +++ b/extensions/common/features/simple_feature_unittest.cc
@@ -24,7 +24,6 @@ #include "extensions/common/features/feature_session_type.h" #include "extensions/common/manifest.h" #include "extensions/common/manifest_handlers/background_info.h" -#include "extensions/common/scoped_worker_based_extensions_channel.h" #include "extensions/common/switches.h" #include "extensions/common/value_builder.h" #include "testing/gtest/include/gtest/gtest.h" @@ -1035,8 +1034,6 @@ } TEST(SimpleFeatureUnitTest, DisallowForServiceWorkers) { - ScopedWorkerBasedExtensionsChannel worker_channel_override; - SimpleFeature feature; feature.set_name("somefeature"); feature.set_contexts({Feature::BLESSED_EXTENSION_CONTEXT});
diff --git a/extensions/common/scoped_worker_based_extensions_channel.cc b/extensions/common/scoped_worker_based_extensions_channel.cc deleted file mode 100644 index ba74d40..0000000 --- a/extensions/common/scoped_worker_based_extensions_channel.cc +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "extensions/common/scoped_worker_based_extensions_channel.h" - -#include "extensions/common/constants.h" - -namespace extensions { - -ScopedWorkerBasedExtensionsChannel::ScopedWorkerBasedExtensionsChannel() - : worker_based_extensions_channel_( - extension_misc::kMinChannelForServiceWorkerBasedExtension) {} -ScopedWorkerBasedExtensionsChannel::~ScopedWorkerBasedExtensionsChannel() = - default; - -} // namespace extensions
diff --git a/extensions/common/scoped_worker_based_extensions_channel.h b/extensions/common/scoped_worker_based_extensions_channel.h deleted file mode 100644 index ceee4ba9..0000000 --- a/extensions/common/scoped_worker_based_extensions_channel.h +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef EXTENSIONS_COMMON_SCOPED_WORKER_BASED_EXTENSIONS_CHANNEL_H_ -#define EXTENSIONS_COMMON_SCOPED_WORKER_BASED_EXTENSIONS_CHANNEL_H_ - -#include "extensions/common/features/feature_channel.h" - -namespace extensions { - -// Sets the current channel so that Service Worker based extensions are enabled -// and also and extension APIs from those Service Workers are enabled. -// -// Note: It is important to set this override early in tests so that the -// channel change is visible to renderers running with service workers. -class ScopedWorkerBasedExtensionsChannel { - public: - ScopedWorkerBasedExtensionsChannel(); - ScopedWorkerBasedExtensionsChannel( - const ScopedWorkerBasedExtensionsChannel&) = delete; - ScopedWorkerBasedExtensionsChannel& operator=( - const ScopedWorkerBasedExtensionsChannel&) = delete; - ~ScopedWorkerBasedExtensionsChannel(); - - private: - ScopedCurrentChannel worker_based_extensions_channel_; -}; - -} // namespace extensions - -#endif // EXTENSIONS_COMMON_SCOPED_WORKER_BASED_EXTENSIONS_CHANNEL_H_
diff --git a/gin/BUILD.gn b/gin/BUILD.gn index 4fa8514..dfc59c1 100644 --- a/gin/BUILD.gn +++ b/gin/BUILD.gn
@@ -75,10 +75,6 @@ defines = [ "GIN_IMPLEMENTATION" ] - if (use_perfetto_client_library) { - defines += [ "V8_USE_PERFETTO" ] - } - public_deps = [ "//base", "//v8",
diff --git a/gpu/ipc/client/command_buffer_proxy_impl_unittest.cc b/gpu/ipc/client/command_buffer_proxy_impl_unittest.cc index 229d81b..c9a3db0 100644 --- a/gpu/ipc/client/command_buffer_proxy_impl_unittest.cc +++ b/gpu/ipc/client/command_buffer_proxy_impl_unittest.cc
@@ -61,8 +61,7 @@ public: CommandBufferProxyImplTest() : task_runner_(base::MakeRefCounted<base::TestSimpleTaskRunner>()), - thread_task_runner_handle_override_( - base::ThreadTaskRunnerHandle::OverrideForTesting(task_runner_)), + thread_task_runner_handle_override_(task_runner_), channel_(base::MakeRefCounted<TestGpuChannelHost>(&sink_)) {} ~CommandBufferProxyImplTest() override { @@ -97,7 +96,8 @@ protected: IPC::TestSink sink_; scoped_refptr<base::TestSimpleTaskRunner> task_runner_; - base::ScopedClosureRunner thread_task_runner_handle_override_; + base::ThreadTaskRunnerHandleOverrideForTesting + thread_task_runner_handle_override_; scoped_refptr<TestGpuChannelHost> channel_; };
diff --git a/ios/chrome/browser/ui/alert_view/alert_view_controller.mm b/ios/chrome/browser/ui/alert_view/alert_view_controller.mm index 1538693..fd34467 100644 --- a/ios/chrome/browser/ui/alert_view/alert_view_controller.mm +++ b/ios/chrome/browser/ui/alert_view/alert_view_controller.mm
@@ -144,7 +144,8 @@ self.contentView = [[UIView alloc] init]; self.contentView.accessibilityIdentifier = self.alertAccessibilityIdentifier; self.contentView.clipsToBounds = YES; - self.contentView.backgroundColor = UIColor.cr_systemBackgroundColor; + self.contentView.backgroundColor = + [UIColor colorNamed:kPrimaryBackgroundColor]; self.contentView.layer.cornerRadius = kCornerRadius; self.contentView.layer.shadowOffset = CGSizeMake(kShadowOffsetX, kShadowOffsetY); @@ -294,7 +295,8 @@ } stackHolder.layer.borderWidth = 1.0 / [UIScreen mainScreen].scale; stackHolder.clipsToBounds = YES; - stackHolder.backgroundColor = UIColor.cr_secondarySystemBackgroundColor; + stackHolder.backgroundColor = + [UIColor colorNamed:kSecondaryBackgroundColor]; stackHolder.translatesAutoresizingMaskIntoConstraints = NO; self.textFieldStackHolder = stackHolder;
diff --git a/ios/chrome/browser/ui/authentication/signin/user_signin/gradient_view.mm b/ios/chrome/browser/ui/authentication/signin/user_signin/gradient_view.mm index 44cb6fd..220c77a 100644 --- a/ios/chrome/browser/ui/authentication/signin/user_signin/gradient_view.mm +++ b/ios/chrome/browser/ui/authentication/signin/user_signin/gradient_view.mm
@@ -5,7 +5,7 @@ #import "ios/chrome/browser/ui/authentication/signin/user_signin/gradient_view.h" #import "base/mac/foundation_util.h" -#import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" +#import "ios/chrome/common/ui/colors/semantic_color_names.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -53,8 +53,9 @@ [CATransaction setDisableActions:YES]; self.gradientLayer.colors = @[ - (id)[UIColor.cr_systemBackgroundColor colorWithAlphaComponent:0].CGColor, - (id)UIColor.cr_systemBackgroundColor.CGColor, + (id)[[UIColor colorNamed:kPrimaryBackgroundColor] colorWithAlphaComponent:0] + .CGColor, + (id)[UIColor colorNamed:kPrimaryBackgroundColor].CGColor, ]; [CATransaction commit]; }
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 c93c77f..90ad96b 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
@@ -12,7 +12,6 @@ #import "ios/chrome/browser/ui/authentication/signin/user_signin/gradient_view.h" #import "ios/chrome/browser/ui/util/rtl_geometry.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" -#import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" #import "ios/chrome/common/ui/util/constraints_ui_util.h" #import "ios/chrome/common/ui/util/pointer_interaction_util.h" @@ -307,7 +306,7 @@ #pragma mark - Properties - (UIColor*)systemBackgroundColor { - return UIColor.cr_systemBackgroundColor; + return [UIColor colorNamed:kPrimaryBackgroundColor]; } - (NSString*)confirmationButtonTitle {
diff --git a/ios/chrome/browser/ui/authentication/unified_consent/identity_picker_view.mm b/ios/chrome/browser/ui/authentication/unified_consent/identity_picker_view.mm index 538e5e1..6d8ccf65 100644 --- a/ios/chrome/browser/ui/authentication/unified_consent/identity_picker_view.mm +++ b/ios/chrome/browser/ui/authentication/unified_consent/identity_picker_view.mm
@@ -12,6 +12,7 @@ #import "ios/chrome/browser/ui/authentication/unified_consent/unified_consent_constants.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" +#import "ios/chrome/common/ui/colors/semantic_color_names.h" #import "ios/chrome/common/ui/util/constraints_ui_util.h" #import "ios/chrome/common/ui/util/pointer_interaction_util.h" @@ -47,7 +48,7 @@ if (self) { self.accessibilityIdentifier = kIdentityPickerViewIdentifier; self.layer.cornerRadius = kIdentityPickerViewRadius; - self.backgroundColor = UIColor.cr_secondarySystemBackgroundColor; + self.backgroundColor = [UIColor colorNamed:kSecondaryBackgroundColor]; // Adding view elements inside. // Ink view. _rippleView = [[MDCRippleView alloc] initWithFrame:CGRectZero];
diff --git a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm index 1f2f4900..10c7f11 100644 --- a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm +++ b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm
@@ -193,7 +193,7 @@ // Separator. UIView* separator = [[UIView alloc] initWithFrame:CGRectZero]; separator.translatesAutoresizingMaskIntoConstraints = NO; - separator.backgroundColor = UIColor.cr_secondarySystemBackgroundColor; + separator.backgroundColor = [UIColor colorNamed:kSecondaryBackgroundColor]; [container addSubview:separator]; // Customize label.
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_navigation_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_navigation_controller.mm index f09595a..7cd5405d 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_navigation_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_navigation_controller.mm
@@ -6,7 +6,7 @@ #import "ios/chrome/browser/ui/bookmarks/bookmark_ui_constants.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" -#import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" +#import "ios/chrome/common/ui/colors/semantic_color_names.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -16,7 +16,7 @@ - (void)viewDidLoad { [super viewDidLoad]; - self.view.backgroundColor = UIColor.cr_systemBackgroundColor; + self.view.backgroundColor = [UIColor colorNamed:kPrimaryBackgroundColor]; self.navigationBar.accessibilityIdentifier = kBookmarkNavigationBarIdentifier; }
diff --git a/ios/chrome/browser/ui/collection_view/collection_view_controller.mm b/ios/chrome/browser/ui/collection_view/collection_view_controller.mm index efe8c6ee..a62dbb3 100644 --- a/ios/chrome/browser/ui/collection_view/collection_view_controller.mm +++ b/ios/chrome/browser/ui/collection_view/collection_view_controller.mm
@@ -13,7 +13,7 @@ #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" #import "ios/chrome/browser/ui/material_components/chrome_app_bar_view_controller.h" #import "ios/chrome/browser/ui/material_components/utils.h" -#import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" +#import "ios/chrome/common/ui/colors/semantic_color_names.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -65,9 +65,10 @@ } // Suport dark mode. - self.collectionView.backgroundColor = UIColor.cr_systemGroupedBackgroundColor; + self.collectionView.backgroundColor = + [UIColor colorNamed:kGroupedPrimaryBackgroundColor]; self.styler.cellBackgroundColor = - UIColor.cr_secondarySystemGroupedBackgroundColor; + [UIColor colorNamed:kGroupedSecondaryBackgroundColor]; } - (void)contentSizeCategoryDidChange:(id)sender {
diff --git a/ios/chrome/browser/ui/fancy_ui/primary_action_button.mm b/ios/chrome/browser/ui/fancy_ui/primary_action_button.mm index 29a07fc..a87ae86 100644 --- a/ios/chrome/browser/ui/fancy_ui/primary_action_button.mm +++ b/ios/chrome/browser/ui/fancy_ui/primary_action_button.mm
@@ -5,7 +5,6 @@ #import "ios/chrome/browser/ui/fancy_ui/primary_action_button.h" #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h" -#import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" #import "ios/chrome/common/ui/util/pointer_interaction_util.h" @@ -43,7 +42,7 @@ } #endif // defined(__IPHONE_13_4) - UIColor* hintColor = UIColor.cr_systemBackgroundColor; + UIColor* hintColor = [UIColor colorNamed:kPrimaryBackgroundColor]; UIColor* inkColor = [UIColor colorWithWhite:1 alpha:0.2f]; UIColor* backgroundColor = [UIColor colorNamed:kBlueColor]; UIColor* disabledColor = [UIColor colorNamed:kDisabledTintColor];
diff --git a/ios/chrome/browser/ui/first_run/static_file_view_controller.mm b/ios/chrome/browser/ui/first_run/static_file_view_controller.mm index 68958ff..b61597a 100644 --- a/ios/chrome/browser/ui/first_run/static_file_view_controller.mm +++ b/ios/chrome/browser/ui/first_run/static_file_view_controller.mm
@@ -13,7 +13,7 @@ #import "ios/chrome/browser/ui/icons/chrome_icon.h" #import "ios/chrome/browser/ui/material_components/utils.h" #include "ios/chrome/browser/ui/util/rtl_geometry.h" -#import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" +#import "ios/chrome/common/ui/colors/semantic_color_names.h" #import "ios/web/common/web_view_creation_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -70,7 +70,7 @@ cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0]; [_webView loadRequest:request]; - [_webView setBackgroundColor:UIColor.cr_systemBackgroundColor]; + [_webView setBackgroundColor:[UIColor colorNamed:kPrimaryBackgroundColor]]; [self.view addSubview:_webView]; ConfigureAppBarViewControllerWithCardStyle(_appBarViewController);
diff --git a/ios/chrome/browser/ui/material_components/utils.mm b/ios/chrome/browser/ui/material_components/utils.mm index bee7e27..b9c6a6d 100644 --- a/ios/chrome/browser/ui/material_components/utils.mm +++ b/ios/chrome/browser/ui/material_components/utils.mm
@@ -15,6 +15,7 @@ #include "base/mac/foundation_util.h" #import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" +#import "ios/chrome/common/ui/colors/semantic_color_names.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -44,7 +45,7 @@ viewController.headerView.shiftBehavior = MDCFlexibleHeaderShiftBehaviorDisabled; viewController.headerView.backgroundColor = - UIColor.cr_secondarySystemBackgroundColor; + [UIColor colorNamed:kSecondaryBackgroundColor]; viewController.navigationBar.tintColor = UIColor.cr_labelColor; viewController.navigationBar.titleAlignment = MDCNavigationBarTitleAlignmentLeading;
diff --git a/ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_table_view_controller.mm b/ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_table_view_controller.mm index 31fdb75c..46a28fc 100644 --- a/ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_table_view_controller.mm +++ b/ios/chrome/browser/ui/send_tab_to_self/send_tab_to_self_table_view_controller.mm
@@ -19,7 +19,6 @@ #include "ios/chrome/browser/ui/table_view/cells/table_view_url_item.h" #import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" -#import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" #include "ios/chrome/grit/ios_strings.h" #include "ui/base/l10n/l10n_util.h" @@ -82,8 +81,9 @@ - (void)viewDidLoad { [super viewDidLoad]; - self.view.backgroundColor = UIColor.cr_systemBackgroundColor; - self.styler.cellBackgroundColor = UIColor.cr_systemBackgroundColor; + self.view.backgroundColor = [UIColor colorNamed:kPrimaryBackgroundColor]; + self.styler.cellBackgroundColor = + [UIColor colorNamed:kPrimaryBackgroundColor]; self.tableView.sectionHeaderHeight = 0; self.tableView.sectionFooterHeight = 0; [self.tableView
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_view_controller.mm b/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_view_controller.mm index 0868e19..11c78c05 100644 --- a/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_view_controller.mm +++ b/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_view_controller.mm
@@ -15,7 +15,6 @@ #import "ios/chrome/browser/ui/table_view/chrome_table_view_controller.h" #import "ios/chrome/browser/ui/table_view/table_view_utils.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" -#import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" #include "ios/chrome/grit/ios_strings.h" #include "ui/base/l10n/l10n_util_mac.h" @@ -87,7 +86,8 @@ - (void)viewDidLoad { [super viewDidLoad]; - self.view.backgroundColor = UIColor.cr_systemGroupedBackgroundColor; + self.view.backgroundColor = + [UIColor colorNamed:kGroupedPrimaryBackgroundColor]; self.tableView.accessibilityIdentifier = kAddCreditCardViewID; self.navigationItem.title = l10n_util::GetNSString(
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.mm b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.mm index 2e822f9..e45bdec 100644 --- a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.mm
@@ -139,10 +139,10 @@ if (!base::FeatureList::IsEnabled(kSettingsRefresh)) { self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; - self.styler.cellBackgroundColor = UIColor.cr_systemBackgroundColor; - self.styler.tableViewBackgroundColor = UIColor.cr_systemBackgroundColor; self.tableView.accessibilityIdentifier = kClearBrowsingDataViewAccessibilityIdentifier; + self.styler.tableViewBackgroundColor = + [UIColor colorNamed:kPrimaryBackgroundColor]; self.tableView.backgroundColor = self.styler.tableViewBackgroundColor; // TableView configuration
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/time_range_selector_table_view_controller.mm b/ios/chrome/browser/ui/settings/clear_browsing_data/time_range_selector_table_view_controller.mm index 7002d7d..09d8f10 100644 --- a/ios/chrome/browser/ui/settings/clear_browsing_data/time_range_selector_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/clear_browsing_data/time_range_selector_table_view_controller.mm
@@ -15,6 +15,7 @@ #import "ios/chrome/browser/ui/table_view/table_view_utils.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" +#import "ios/chrome/common/ui/colors/semantic_color_names.h" #include "ios/chrome/grit/ios_strings.h" #include "ui/base/l10n/l10n_util_mac.h" @@ -78,7 +79,8 @@ - (void)viewDidLoad { [super viewDidLoad]; if (!base::FeatureList::IsEnabled(kSettingsRefresh)) { - self.styler.tableViewBackgroundColor = UIColor.cr_systemBackgroundColor; + self.styler.tableViewBackgroundColor = + [UIColor colorNamed:kPrimaryBackgroundColor]; self.tableView.backgroundColor = self.styler.tableViewBackgroundColor; } [self loadModel];
diff --git a/ios/chrome/browser/ui/settings/settings_navigation_controller.mm b/ios/chrome/browser/ui/settings/settings_navigation_controller.mm index befb055..7fa7884 100644 --- a/ios/chrome/browser/ui/settings/settings_navigation_controller.mm +++ b/ios/chrome/browser/ui/settings/settings_navigation_controller.mm
@@ -25,7 +25,6 @@ #include "ios/chrome/browser/ui/ui_feature_flags.h" #include "ios/chrome/browser/ui/util/ui_util.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" -#import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" #import "ios/chrome/common/ui/util/constraints_ui_util.h" #include "ios/chrome/grit/ios_strings.h" @@ -289,7 +288,7 @@ - (void)viewDidLoad { [super viewDidLoad]; - self.view.backgroundColor = UIColor.cr_systemBackgroundColor; + self.view.backgroundColor = [UIColor colorNamed:kPrimaryBackgroundColor]; if (base::FeatureList::IsEnabled(kSettingsRefresh)) { self.navigationBar.translucent = NO;
diff --git a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm index 29cbff5..f20c692 100644 --- a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm
@@ -117,7 +117,7 @@ - (void)viewDidLoad { if (!base::FeatureList::IsEnabled(kSettingsRefresh)) { self.styler.tableViewBackgroundColor = - UIColor.cr_systemGroupedBackgroundColor; + [UIColor colorNamed:kGroupedPrimaryBackgroundColor]; } UIBarButtonItem* flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace @@ -128,7 +128,7 @@ [super viewDidLoad]; self.styler.cellBackgroundColor = - UIColor.cr_secondarySystemGroupedBackgroundColor; + [UIColor colorNamed:kGroupedSecondaryBackgroundColor]; self.styler.cellTitleColor = UIColor.cr_labelColor; self.tableView.estimatedSectionHeaderHeight = kEstimatedHeaderFooterHeight; self.tableView.estimatedRowHeight = kSettingsCellDefaultHeight;
diff --git a/ios/chrome/browser/ui/table_view/chrome_table_view_styler.mm b/ios/chrome/browser/ui/table_view/chrome_table_view_styler.mm index fb2725c..6ee04a2 100644 --- a/ios/chrome/browser/ui/table_view/chrome_table_view_styler.mm +++ b/ios/chrome/browser/ui/table_view/chrome_table_view_styler.mm
@@ -6,7 +6,6 @@ #include "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" -#import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -20,9 +19,10 @@ if (base::FeatureList::IsEnabled(kSettingsRefresh)) { _tableViewBackgroundColor = [UIColor colorNamed:kSecondaryBackgroundColor]; - _cellBackgroundColor = UIColor.cr_secondarySystemGroupedBackgroundColor; + _cellBackgroundColor = + [UIColor colorNamed:kGroupedSecondaryBackgroundColor]; } else { - _tableViewBackgroundColor = UIColor.cr_systemBackgroundColor; + _tableViewBackgroundColor = [UIColor colorNamed:kPrimaryBackgroundColor]; } } return self;
diff --git a/ios/chrome/browser/ui/table_view/table_view_navigation_controller.mm b/ios/chrome/browser/ui/table_view/table_view_navigation_controller.mm index 416f3ef..08c4369 100644 --- a/ios/chrome/browser/ui/table_view/table_view_navigation_controller.mm +++ b/ios/chrome/browser/ui/table_view/table_view_navigation_controller.mm
@@ -8,7 +8,6 @@ #import "ios/chrome/browser/ui/table_view/chrome_table_view_controller.h" #import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" -#import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -43,9 +42,10 @@ self.toolbar.barTintColor = [UIColor colorNamed:kSecondaryBackgroundColor]; self.view.backgroundColor = [UIColor colorNamed:kSecondaryBackgroundColor]; } else { - self.navigationBar.barTintColor = UIColor.cr_systemBackgroundColor; - self.toolbar.barTintColor = UIColor.cr_systemBackgroundColor; - self.view.backgroundColor = UIColor.cr_systemBackgroundColor; + self.navigationBar.barTintColor = + [UIColor colorNamed:kPrimaryBackgroundColor]; + self.toolbar.barTintColor = [UIColor colorNamed:kPrimaryBackgroundColor]; + self.view.backgroundColor = [UIColor colorNamed:kPrimaryBackgroundColor]; } }
diff --git a/ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h b/ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h index c4026725..e95226e 100644 --- a/ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h +++ b/ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h
@@ -13,16 +13,6 @@ // TODO (crbug.com/981889): Remove along with iOS 12. @interface UIColor (CRSemanticColors) -// System Background Color -@property(class, nonatomic, readonly) UIColor* cr_systemBackgroundColor; -@property(class, nonatomic, readonly) - UIColor* cr_secondarySystemBackgroundColor; - -// System Grouped Background Colors -@property(class, nonatomic, readonly) UIColor* cr_systemGroupedBackgroundColor; -@property(class, nonatomic, readonly) - UIColor* cr_secondarySystemGroupedBackgroundColor; - // Label Colors @property(class, nonatomic, readonly) UIColor* cr_labelColor; @property(class, nonatomic, readonly) UIColor* cr_secondaryLabelColor;
diff --git a/ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.mm b/ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.mm index 39ced8a..70f20f4 100644 --- a/ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.mm +++ b/ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.mm
@@ -10,42 +10,6 @@ @implementation UIColor (CRSemanticColors) -#pragma mark - System Background Colors - -+ (UIColor*)cr_systemBackgroundColor { - if (@available(iOS 13, *)) { - return UIColor.systemBackgroundColor; - } - return UIColor.whiteColor; -} - -+ (UIColor*)cr_secondarySystemBackgroundColor { - if (@available(iOS 13, *)) { - return UIColor.secondarySystemBackgroundColor; - } - // This is the value for secondarySystemBackgroundColor in light mode. - return [UIColor colorWithRed:244 / (CGFloat)0xFF - green:244 / (CGFloat)0xFF - blue:248 / (CGFloat)0xFF - alpha:1]; -} - -#pragma mark - System Grouped Background Colors - -+ (UIColor*)cr_systemGroupedBackgroundColor { - if (@available(iOS 13, *)) { - return UIColor.systemGroupedBackgroundColor; - } - return UIColor.groupTableViewBackgroundColor; -} - -+ (UIColor*)cr_secondarySystemGroupedBackgroundColor { - if (@available(iOS 13, *)) { - return UIColor.secondarySystemGroupedBackgroundColor; - } - return UIColor.whiteColor; -} - #pragma mark - Label Colors + (UIColor*)cr_labelColor {
diff --git a/ios/chrome/common/ui/colors/resources/BUILD.gn b/ios/chrome/common/ui/colors/resources/BUILD.gn index c6935c0..59ca80c 100644 --- a/ios/chrome/common/ui/colors/resources/BUILD.gn +++ b/ios/chrome/common/ui/colors/resources/BUILD.gn
@@ -27,9 +27,12 @@ ":grey_700_color", ":grey_800_color", ":grey_900_color", + ":grouped_primary_background_color", + ":grouped_secondary_background_color", ":mdc_ink_color", ":mdc_secondary_ink_color", ":placeholder_image_tint_color", + ":primary_background_color", ":red_color", ":red_dark_color", ":scrim_background_color", @@ -223,3 +226,15 @@ colorset("secondary_background_color") { sources = [ "secondary_background_color.colorset/Contents.json" ] } + +colorset("primary_background_color") { + sources = [ "primary_background_color.colorset/Contents.json" ] +} + +colorset("grouped_secondary_background_color") { + sources = [ "grouped_secondary_background_color.colorset/Contents.json" ] +} + +colorset("grouped_primary_background_color") { + sources = [ "grouped_primary_background_color.colorset/Contents.json" ] +}
diff --git a/ios/chrome/common/ui/colors/resources/grouped_primary_background_color.colorset/Contents.json b/ios/chrome/common/ui/colors/resources/grouped_primary_background_color.colorset/Contents.json new file mode 100644 index 0000000..f1f5bfa --- /dev/null +++ b/ios/chrome/common/ui/colors/resources/grouped_primary_background_color.colorset/Contents.json
@@ -0,0 +1,38 @@ +{ + "info": { + "version": 1, + "author": "xcode" + }, + "colors": [ + { + "idiom": "universal", + "color": { + "color-space": "display-p3", + "components": { + "red": "0xF1", + "alpha": "1.000", + "blue": "0xF4", + "green": "0xF3" + } + } + }, + { + "idiom": "universal", + "appearances": [ + { + "appearance": "luminosity", + "value": "dark" + } + ], + "color": { + "color-space": "display-p3", + "components": { + "red": "0x20", + "alpha": "1.000", + "blue": "0x24", + "green": "0x21" + } + } + } + ] +} \ No newline at end of file
diff --git a/ios/chrome/common/ui/colors/resources/grouped_secondary_background_color.colorset/Contents.json b/ios/chrome/common/ui/colors/resources/grouped_secondary_background_color.colorset/Contents.json new file mode 100644 index 0000000..0d5ff736 --- /dev/null +++ b/ios/chrome/common/ui/colors/resources/grouped_secondary_background_color.colorset/Contents.json
@@ -0,0 +1,38 @@ +{ + "info": { + "version": 1, + "author": "xcode" + }, + "colors": [ + { + "idiom": "universal", + "color": { + "color-space": "display-p3", + "components": { + "red": "0xFF", + "alpha": "1.000", + "blue": "0xFF", + "green": "0xFF" + } + } + }, + { + "idiom": "universal", + "appearances": [ + { + "appearance": "luminosity", + "value": "dark" + } + ], + "color": { + "color-space": "display-p3", + "components": { + "red": "0x35", + "alpha": "1.000", + "blue": "0x39", + "green": "0x37" + } + } + } + ] +} \ No newline at end of file
diff --git a/ios/chrome/common/ui/colors/resources/primary_background_color.colorset/Contents.json b/ios/chrome/common/ui/colors/resources/primary_background_color.colorset/Contents.json new file mode 100644 index 0000000..a66621c8 --- /dev/null +++ b/ios/chrome/common/ui/colors/resources/primary_background_color.colorset/Contents.json
@@ -0,0 +1,38 @@ +{ + "info": { + "version": 1, + "author": "xcode" + }, + "colors": [ + { + "idiom": "universal", + "color": { + "color-space": "display-p3", + "components": { + "red": "0xFF", + "alpha": "1.000", + "blue": "0xFF", + "green": "0xFF" + } + } + }, + { + "idiom": "universal", + "appearances": [ + { + "appearance": "luminosity", + "value": "dark" + } + ], + "color": { + "color-space": "display-p3", + "components": { + "red": "0x20", + "alpha": "1.000", + "blue": "0x24", + "green": "0x21" + } + } + } + ] +} \ No newline at end of file
diff --git a/ios/chrome/common/ui/colors/semantic_color_names.h b/ios/chrome/common/ui/colors/semantic_color_names.h index ce13cb6..d66f212 100644 --- a/ios/chrome/common/ui/colors/semantic_color_names.h +++ b/ios/chrome/common/ui/colors/semantic_color_names.h
@@ -14,6 +14,10 @@ extern NSString* const kDisabledTintColor; // Background color used in the rounded squares behind favicons. extern NSString* const kFaviconBackgroundColor; +// Primary grouped background color. +extern NSString* const kGroupedPrimaryBackgroundColor; +// Secondary grouped background color. +extern NSString* const kGroupedSecondaryBackgroundColor; // Ink color for an MDC button. extern NSString* const kMDCInkColor; // Ink color for a secondary style MDC button (button with transparent @@ -21,6 +25,8 @@ extern NSString* const kMDCSecondaryInkColor; // Color used to tint placeholder images and icons. extern NSString* const kPlaceholderImageTintColor; +// Primary background color. +extern NSString* const kPrimaryBackgroundColor; extern NSString* const kScrimBackgroundColor; // Secondary background color. extern NSString* const kSecondaryBackgroundColor;
diff --git a/ios/chrome/common/ui/colors/semantic_color_names.mm b/ios/chrome/common/ui/colors/semantic_color_names.mm index 74d8960..22d8e42 100644 --- a/ios/chrome/common/ui/colors/semantic_color_names.mm +++ b/ios/chrome/common/ui/colors/semantic_color_names.mm
@@ -13,9 +13,14 @@ NSString* const kCloseButtonColor = @"close_button_color"; NSString* const kDisabledTintColor = @"disabled_tint_color"; NSString* const kFaviconBackgroundColor = @"favicon_background_color"; +NSString* const kGroupedPrimaryBackgroundColor = + @"grouped_primary_background_color"; +NSString* const kGroupedSecondaryBackgroundColor = + @"grouped_secondary_background_color"; NSString* const kMDCInkColor = @"mdc_ink_color"; NSString* const kMDCSecondaryInkColor = @"mdc_secondary_ink_color"; NSString* const kPlaceholderImageTintColor = @"placeholder_image_tint_color"; +NSString* const kPrimaryBackgroundColor = @"primary_background_color"; NSString* const kScrimBackgroundColor = @"scrim_background_color"; NSString* const kSecondaryBackgroundColor = @"secondary_background_color"; NSString* const kSeparatorColor = @"separator_color";
diff --git a/ios/web/js_messaging/BUILD.gn b/ios/web/js_messaging/BUILD.gn index 7466714..bae4756 100644 --- a/ios/web/js_messaging/BUILD.gn +++ b/ios/web/js_messaging/BUILD.gn
@@ -37,10 +37,30 @@ ] } +source_set("java_script_feature") { + configs += [ "//build/config/compiler:enable_arc" ] + deps = [ + ":js_messaging", + "//base", + "//ios/web/public", + "//ios/web/public/js_messaging", + "//ios/web/web_state/ui:wk_web_view_configuration_provider_header", + ] + + sources = [ + "java_script_content_world.h", + "java_script_content_world.mm", + "java_script_feature.mm", + "java_script_feature_manager.h", + "java_script_feature_manager.mm", + ] +} + source_set("unittests") { configs += [ "//build/config/compiler:enable_arc" ] testonly = true deps = [ + ":java_script_feature", ":js_messaging", "//base", "//base/test:test_support", @@ -56,6 +76,8 @@ sources = [ "crw_js_window_id_manager_unittest.mm", "crw_wk_script_message_router_unittest.mm", + "java_script_content_world_unittest.mm", + "java_script_feature_unittest.mm", "page_script_util_unittest.mm", "web_frame_impl_unittest.mm", "web_frame_util_unittest.mm",
diff --git a/ios/web/js_messaging/java_script_content_world.h b/ios/web/js_messaging/java_script_content_world.h new file mode 100644 index 0000000..ea092c8f --- /dev/null +++ b/ios/web/js_messaging/java_script_content_world.h
@@ -0,0 +1,63 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_WEB_JS_MESSAGING_JAVA_SCRIPT_CONTENT_WORLD_H_ +#define IOS_WEB_JS_MESSAGING_JAVA_SCRIPT_CONTENT_WORLD_H_ + +#include <set> + +#import <WebKit/WebKit.h> + +namespace web { + +class JavaScriptFeature; + +// Represents a content world which can be configured with a given set of +// JavaScriptFeatures. An isolated world prevents the loaded web page’s +// JavaScript from interacting with the browser's feature JavaScript. This can +// improve the security and robustness of the feature JavaScript. +class JavaScriptContentWorld { + public: + ~JavaScriptContentWorld(); + JavaScriptContentWorld(const JavaScriptContentWorld&) = delete; + + // Creates a content world for features which will interact with the page + // content world shared by the webpage's JavaScript. + explicit JavaScriptContentWorld( + WKUserContentController* user_content_controller); + +#if defined(__IPHONE_14_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 + // Creates a content world for features which will interact with the given + // |content_world|. + JavaScriptContentWorld(WKUserContentController* user_content_controller, + WKContentWorld* content_world) + API_AVAILABLE(ios(14.0)); +#endif // defined(__IPHONE14_0) + + // Adds |feature| by configuring the feature scripts and communication + // callbacks. + void AddFeature(const JavaScriptFeature* feature); + + // Returns true if and only if |feature| has been added to this content world. + bool HasFeature(const JavaScriptFeature* feature); + + private: + // The features which have already been configured for |content_world_|. + std::set<const JavaScriptFeature*> features_; + + // The associated user content controller for configuring injected scripts and + // communication. + WKUserContentController* user_content_controller_ = nil; + +#if defined(__IPHONE_14_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 + // The associated WKContentWorld. May be null which represents the main world + // which the page content itself uses. (The same content world can also be + // represented by [WKContentWorld pageWorld] on iOS 14 and later.) + WKContentWorld* content_world_ API_AVAILABLE(ios(14.0)) = nullptr; +#endif // defined(__IPHONE14_0) +}; + +} // namespace web + +#endif // IOS_WEB_JS_MESSAGING_JAVA_SCRIPT_CONTENT_WORLD_H_
diff --git a/ios/web/js_messaging/java_script_content_world.mm b/ios/web/js_messaging/java_script_content_world.mm new file mode 100644 index 0000000..60047e2 --- /dev/null +++ b/ios/web/js_messaging/java_script_content_world.mm
@@ -0,0 +1,109 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/web/js_messaging/java_script_content_world.h" + +#include "base/check_op.h" +#include "base/notreached.h" +#include "ios/web/public/js_messaging/java_script_feature.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace web { + +namespace { + +WKUserScriptInjectionTime InjectionTimeToWKUserScriptInjectionTime( + JavaScriptFeature::FeatureScript::InjectionTime injection_time) { + switch (injection_time) { + case JavaScriptFeature::FeatureScript::InjectionTime::kDocumentStart: + return WKUserScriptInjectionTimeAtDocumentStart; + case JavaScriptFeature::FeatureScript::InjectionTime::kDocumentEnd: + return WKUserScriptInjectionTimeAtDocumentEnd; + } + NOTREACHED(); + return WKUserScriptInjectionTimeAtDocumentStart; +} + +} // namespace + +JavaScriptContentWorld::JavaScriptContentWorld( + WKUserContentController* user_content_controller) + : user_content_controller_(user_content_controller) {} + +#if defined(__IPHONE_14_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 +JavaScriptContentWorld::JavaScriptContentWorld( + WKUserContentController* user_content_controller, + WKContentWorld* content_world) + : user_content_controller_(user_content_controller), + content_world_(content_world) {} +#endif // defined(__IPHONE14_0) + +JavaScriptContentWorld::~JavaScriptContentWorld() {} + +bool JavaScriptContentWorld::HasFeature(const JavaScriptFeature* feature) { + return features_.find(feature) != features_.end(); +} + +void JavaScriptContentWorld::AddFeature(const JavaScriptFeature* feature) { + if (HasFeature(feature)) { + // |feature| has already been added to this content world. + return; + } + +#if defined(__IPHONE_14_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 + if (@available(iOS 14, *)) { + // Ensure |feature| supports this content world. + if (content_world_ && content_world_ != WKContentWorld.pageWorld) { + DCHECK_EQ(feature->GetSupportedContentWorld(), + JavaScriptFeature::ContentWorld::kAnyContentWorld); + } + } +#endif // defined(__IPHONE14_0) + + features_.insert(feature); + + // Add dependent features first. + for (const JavaScriptFeature* dep_feature : feature->GetDependentFeatures()) { + AddFeature(dep_feature); + } + + // Setup user scripts. + for (const JavaScriptFeature::FeatureScript& feature_script : + feature->GetScripts()) { + WKUserScriptInjectionTime injection_time = + InjectionTimeToWKUserScriptInjectionTime( + feature_script.GetInjectionTime()); + + bool main_frame_only = + feature_script.GetTargetFrames() != + JavaScriptFeature::FeatureScript::TargetFrames::kAllFrames; + + WKUserScript* user_script = nil; +#if defined(__IPHONE_14_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 + if (@available(iOS 14, *)) { + if (content_world_) { + user_script = [[WKUserScript alloc] + initWithSource:feature_script.GetScriptString() + injectionTime:injection_time + forMainFrameOnly:main_frame_only + inContentWorld:content_world_]; + } + } +#endif // defined(__IPHONE14_0) + + if (!user_script) { + user_script = + [[WKUserScript alloc] initWithSource:feature_script.GetScriptString() + injectionTime:injection_time + forMainFrameOnly:main_frame_only]; + } + + [user_content_controller_ addUserScript:user_script]; + } +} + +} // namespace web
diff --git a/ios/web/js_messaging/java_script_content_world_unittest.mm b/ios/web/js_messaging/java_script_content_world_unittest.mm new file mode 100644 index 0000000..2cb638e6 --- /dev/null +++ b/ios/web/js_messaging/java_script_content_world_unittest.mm
@@ -0,0 +1,44 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/web/js_messaging/java_script_content_world.h" + +#import "ios/web/public/js_messaging/java_script_feature.h" +#import "testing/gtest_mac.h" +#import "testing/platform_test.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +typedef PlatformTest JavaScriptContentWorldTest; + +// Tests adding a JavaScriptFeature to a JavaScriptContentWorld. +TEST_F(JavaScriptContentWorldTest, AddFeature) { + WKUserContentController* user_content_controller = + [[WKUserContentController alloc] init]; + web::JavaScriptContentWorld world(user_content_controller); + + const web::JavaScriptFeature& feature = web::JavaScriptFeature( + web::JavaScriptFeature::ContentWorld::kAnyContentWorld, {}); + world.AddFeature(&feature); + EXPECT_TRUE(world.HasFeature(&feature)); +} + +// Tests adding a JavaScriptFeature to a specific JavaScriptContentWorld. +TEST_F(JavaScriptContentWorldTest, AddFeatureToSpecificWKContentWorld) { +#if defined(__IPHONE_14_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 + if (@available(iOS 14, *)) { + WKUserContentController* user_content_controller = + [[WKUserContentController alloc] init]; + web::JavaScriptContentWorld world(user_content_controller, + [WKContentWorld defaultClientWorld]); + + const web::JavaScriptFeature& feature = web::JavaScriptFeature( + web::JavaScriptFeature::ContentWorld::kAnyContentWorld, {}); + world.AddFeature(&feature); + EXPECT_TRUE(world.HasFeature(&feature)); + } +#endif // defined(__IPHONE14_0) +}
diff --git a/ios/web/js_messaging/java_script_feature.mm b/ios/web/js_messaging/java_script_feature.mm new file mode 100644 index 0000000..ec40110 --- /dev/null +++ b/ios/web/js_messaging/java_script_feature.mm
@@ -0,0 +1,103 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ios/web/public/js_messaging/java_script_feature.h" + +#import <Foundation/Foundation.h> + +#include "base/bind.h" +#import "base/strings/sys_string_conversions.h" +#import "ios/web/js_messaging/java_script_content_world.h" +#import "ios/web/js_messaging/java_script_feature_manager.h" +#include "ios/web/js_messaging/page_script_util.h" +#include "ios/web/js_messaging/web_frame_impl.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { + +// Returns a JavaScript safe string based on |script_filename|. This is used as +// a unique identifier for a given script and passed to +// |MakeScriptInjectableOnce| which ensures JS isn't executed multiple times due +// to duplicate injection. +NSString* InjectionTokenForScript(NSString* script_filename) { + NSMutableCharacterSet* validCharacters = + [NSMutableCharacterSet alphanumericCharacterSet]; + [validCharacters addCharactersInString:@"$_"]; + NSCharacterSet* invalidCharacters = validCharacters.invertedSet; + NSString* token = + [script_filename stringByTrimmingCharactersInSet:invalidCharacters]; + DCHECK_GT(token.length, 0ul); + return token; +} + +} // namespace + +namespace web { + +#pragma mark - JavaScriptFeature::FeatureScript + +JavaScriptFeature::FeatureScript +JavaScriptFeature::FeatureScript::CreateWithFilename( + const std::string& filename, + InjectionTime injection_time, + TargetFrames target_frames) { + return JavaScriptFeature::FeatureScript(filename, injection_time, + target_frames); +} + +JavaScriptFeature::FeatureScript::FeatureScript(const std::string& filename, + InjectionTime injection_time, + TargetFrames target_frames) + : script_filename_(filename), + injection_time_(injection_time), + target_frames_(target_frames) {} + +JavaScriptFeature::FeatureScript::~FeatureScript() = default; + +NSString* JavaScriptFeature::FeatureScript::GetScriptString() const { + NSString* script_filename = base::SysUTF8ToNSString(script_filename_); + NSString* injection_token = InjectionTokenForScript(script_filename); + return MakeScriptInjectableOnce(injection_token, + GetPageScript(script_filename)); +} + +#pragma mark - JavaScriptFeature + +JavaScriptFeature::JavaScriptFeature(ContentWorld supported_world) + : supported_world_(supported_world) {} + +JavaScriptFeature::JavaScriptFeature( + ContentWorld supported_world, + std::vector<const FeatureScript> feature_scripts) + : supported_world_(supported_world), scripts_(feature_scripts) {} + +JavaScriptFeature::JavaScriptFeature( + ContentWorld supported_world, + std::vector<const FeatureScript> feature_scripts, + std::vector<const JavaScriptFeature*> dependent_features) + : supported_world_(supported_world), + scripts_(feature_scripts), + dependent_features_(dependent_features) {} + +JavaScriptFeature::~JavaScriptFeature() = default; + +JavaScriptFeature::ContentWorld JavaScriptFeature::GetSupportedContentWorld() + const { + return supported_world_; +} + +const std::vector<const JavaScriptFeature::FeatureScript> +JavaScriptFeature::GetScripts() const { + return scripts_; +} + +const std::vector<const JavaScriptFeature*> +JavaScriptFeature::GetDependentFeatures() const { + return dependent_features_; +} + +} // namespace web
diff --git a/ios/web/js_messaging/java_script_feature_manager.h b/ios/web/js_messaging/java_script_feature_manager.h new file mode 100644 index 0000000..a957065 --- /dev/null +++ b/ios/web/js_messaging/java_script_feature_manager.h
@@ -0,0 +1,57 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_WEB_JS_MESSAGING_JAVA_SCRIPT_FEATURE_MANAGER_H_ +#define IOS_WEB_JS_MESSAGING_JAVA_SCRIPT_FEATURE_MANAGER_H_ + +#include <memory> +#include <vector> + +#include "base/supports_user_data.h" +#import "ios/web/js_messaging/java_script_content_world.h" + +@class WKUserContentController; + +namespace web { + +class BrowserState; +class JavaScriptFeature; + +// Configures JavaScriptFeatures for |browser_state|. The features will be +// added to either |page_content_world_| or |isolated_world_| based on +// JavaScriptFeature::GetSupportedContentWorld() and the operating system of the +// user's device (which determines if isolated worlds are supported). +class JavaScriptFeatureManager : public base::SupportsUserData::Data { + public: + ~JavaScriptFeatureManager() override; + + // Returns the JavaScriptFeatureManager associated with |browser_state.| + // If a JavaScriptFeatureManager does not already exist, one will be created + // and associated with |browser_state|. |browser_state| must not be null. + static JavaScriptFeatureManager* FromBrowserState( + BrowserState* browser_state); + + // Configures |features| on |user_content_controller_| by adding user scripts + // and script message handlers. + // NOTE: |page_content_world_| and |isolated_world_| will be recreated. + void ConfigureFeatures(std::vector<JavaScriptFeature*> features); + + JavaScriptFeatureManager(const JavaScriptFeatureManager&) = delete; + JavaScriptFeatureManager& operator=(const JavaScriptFeatureManager&) = delete; + + private: + JavaScriptFeatureManager(WKUserContentController* user_content_controller); + + WKUserContentController* user_content_controller_ = nullptr; + + // The content world shared with the page content JavaScript. + std::unique_ptr<JavaScriptContentWorld> page_content_world_; + // A content world isolated from the page content JavaScript for application + // JavaScript execution. + std::unique_ptr<JavaScriptContentWorld> isolated_world_; +}; + +} // namespace web + +#endif // IOS_WEB_JS_MESSAGING_JAVA_SCRIPT_FEATURE_MANAGER_H_
diff --git a/ios/web/js_messaging/java_script_feature_manager.mm b/ios/web/js_messaging/java_script_feature_manager.mm new file mode 100644 index 0000000..8ee5888a --- /dev/null +++ b/ios/web/js_messaging/java_script_feature_manager.mm
@@ -0,0 +1,76 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/web/js_messaging/java_script_feature_manager.h" + +#import <WebKit/WebKit.h> + +#include "base/ios/ios_util.h" +#import "ios/web/public/browser_state.h" +#import "ios/web/public/js_messaging/java_script_feature.h" +#import "ios/web/web_state/ui/wk_web_view_configuration_provider.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { + +// Key used to associate a JavaScriptFeatureManager instances with a +// BrowserState. +const char kWebJavaScriptFeatureManagerKeyName[] = + "web_java_script_feature_manager"; + +} // namespace + +namespace web { + +JavaScriptFeatureManager::JavaScriptFeatureManager( + WKUserContentController* user_content_controller) + : user_content_controller_(user_content_controller) {} +JavaScriptFeatureManager::~JavaScriptFeatureManager() {} + +JavaScriptFeatureManager* JavaScriptFeatureManager::FromBrowserState( + BrowserState* browser_state) { + DCHECK(browser_state); + + JavaScriptFeatureManager* feature_manager = + static_cast<JavaScriptFeatureManager*>( + browser_state->GetUserData(kWebJavaScriptFeatureManagerKeyName)); + if (!feature_manager) { + WKWebViewConfigurationProvider& configuration_provider = + WKWebViewConfigurationProvider::FromBrowserState(browser_state); + WKUserContentController* user_content_controller = + configuration_provider.GetWebViewConfiguration().userContentController; + feature_manager = new JavaScriptFeatureManager(user_content_controller); + browser_state->SetUserData(kWebJavaScriptFeatureManagerKeyName, + base::WrapUnique(feature_manager)); + } + return feature_manager; +} + +void JavaScriptFeatureManager::ConfigureFeatures( + std::vector<JavaScriptFeature*> features) { + page_content_world_ = + std::make_unique<JavaScriptContentWorld>(user_content_controller_); + +#if defined(__IPHONE_14_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 + if (@available(iOS 14, *)) { + isolated_world_ = std::make_unique<JavaScriptContentWorld>( + user_content_controller_, WKContentWorld.defaultClientWorld); + } +#endif // defined(__IPHONE14_0) + + for (JavaScriptFeature* feature : features) { + if (isolated_world_ && + feature->GetSupportedContentWorld() == + JavaScriptFeature::ContentWorld::kAnyContentWorld) { + isolated_world_->AddFeature(feature); + } else { + page_content_world_->AddFeature(feature); + } + } +} + +} // namespace web
diff --git a/ios/web/js_messaging/java_script_feature_unittest.mm b/ios/web/js_messaging/java_script_feature_unittest.mm new file mode 100644 index 0000000..97f2be643 --- /dev/null +++ b/ios/web/js_messaging/java_script_feature_unittest.mm
@@ -0,0 +1,103 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/web/public/js_messaging/java_script_feature.h" + +#import "testing/gtest_mac.h" +#import "testing/platform_test.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +typedef PlatformTest JavaScriptFeatureTest; + +// Tests the creation of FeatureScripts. +TEST_F(JavaScriptFeatureTest, CreateFeatureScript) { + auto document_start_injection_time = + web::JavaScriptFeature::FeatureScript::InjectionTime::kDocumentStart; + auto target_frames_all = + web::JavaScriptFeature::FeatureScript::TargetFrames::kAllFrames; + auto feature_script = + web::JavaScriptFeature::FeatureScript::CreateWithFilename( + "base_js", document_start_injection_time, target_frames_all); + + EXPECT_EQ(document_start_injection_time, feature_script.GetInjectionTime()); + EXPECT_EQ(target_frames_all, feature_script.GetTargetFrames()); + EXPECT_TRUE([feature_script.GetScriptString() containsString:@"__gCrWeb"]); + + auto document_end_injection_time = + web::JavaScriptFeature::FeatureScript::InjectionTime::kDocumentEnd; + auto target_frames_main = + web::JavaScriptFeature::FeatureScript::TargetFrames::kMainFrame; + auto feature_script2 = + web::JavaScriptFeature::FeatureScript::CreateWithFilename( + "common_js", document_end_injection_time, target_frames_main); + + EXPECT_EQ(document_end_injection_time, feature_script2.GetInjectionTime()); + EXPECT_EQ(target_frames_main, feature_script2.GetTargetFrames()); + EXPECT_TRUE( + [feature_script2.GetScriptString() containsString:@"__gCrWeb.common"]); +} + +// Tests creating a JavaScriptFeature. +TEST_F(JavaScriptFeatureTest, CreateFeature) { + auto document_start_injection_time = + web::JavaScriptFeature::FeatureScript::InjectionTime::kDocumentStart; + auto target_frames_all = + web::JavaScriptFeature::FeatureScript::TargetFrames::kAllFrames; + const web::JavaScriptFeature::FeatureScript feature_script = + web::JavaScriptFeature::FeatureScript::CreateWithFilename( + "base_js", document_start_injection_time, target_frames_all); + + auto any_content_world = + web::JavaScriptFeature::ContentWorld::kAnyContentWorld; + web::JavaScriptFeature feature(any_content_world, {feature_script}); + + EXPECT_EQ(any_content_world, feature.GetSupportedContentWorld()); + EXPECT_EQ(0ul, feature.GetDependentFeatures().size()); + + auto feature_scripts = feature.GetScripts(); + ASSERT_EQ(1ul, feature_scripts.size()); + EXPECT_NSEQ(feature_script.GetScriptString(), + feature_scripts[0].GetScriptString()); +} + +// Tests creating a JavaScriptFeature which relies on a dependent feature. +TEST_F(JavaScriptFeatureTest, CreateFeatureWithDependentFeature) { + auto document_start_injection_time = + web::JavaScriptFeature::FeatureScript::InjectionTime::kDocumentStart; + auto target_frames_all = + web::JavaScriptFeature::FeatureScript::TargetFrames::kAllFrames; + const web::JavaScriptFeature::FeatureScript dependent_feature_script = + web::JavaScriptFeature::FeatureScript::CreateWithFilename( + "base_js", document_start_injection_time, target_frames_all); + + auto document_end_injection_time = + web::JavaScriptFeature::FeatureScript::InjectionTime::kDocumentEnd; + auto target_frames_main = + web::JavaScriptFeature::FeatureScript::TargetFrames::kMainFrame; + const web::JavaScriptFeature::FeatureScript feature_script = + web::JavaScriptFeature::FeatureScript::CreateWithFilename( + "common_js", document_end_injection_time, target_frames_main); + + auto page_content_world = + web::JavaScriptFeature::ContentWorld::kPageContentWorld; + web::JavaScriptFeature dependent_feature(page_content_world, + {dependent_feature_script}); + web::JavaScriptFeature feature(page_content_world, {feature_script}, + {&dependent_feature}); + EXPECT_EQ(page_content_world, feature.GetSupportedContentWorld()); + + auto feature_scripts = feature.GetScripts(); + ASSERT_EQ(1ul, feature_scripts.size()); + auto dependent_features = feature.GetDependentFeatures(); + ASSERT_EQ(1ul, dependent_features.size()); + auto dependent_feature_scripts = dependent_features[0]->GetScripts(); + ASSERT_EQ(1ul, dependent_feature_scripts.size()); + EXPECT_NSEQ(feature_script.GetScriptString(), + feature_scripts[0].GetScriptString()); + EXPECT_NSEQ(dependent_feature_script.GetScriptString(), + dependent_feature_scripts[0].GetScriptString()); +}
diff --git a/ios/web/js_messaging/page_script_util.h b/ios/web/js_messaging/page_script_util.h index 280e81f..ba17052 100644 --- a/ios/web/js_messaging/page_script_util.h +++ b/ios/web/js_messaging/page_script_util.h
@@ -15,6 +15,20 @@ // bundled resource file with the given name (excluding extension). NSString* GetPageScript(NSString* script_file_name); +// Make sure that script is injected only once. For example, content of +// WKUserScript can be injected into the same page multiple times +// without notifying WKNavigationDelegate (e.g. after window.document.write +// JavaScript call). Injecting the script multiple times invalidates the +// __gCrWeb.windowId variable and will break the ability to send messages from +// JS to the native code. Wrapping injected script into "if (!injected)" check +// prevents multiple injections into the same page. |script_identifier| should +// identify the script being injected in order to enforce the injection of +// |script| to only once. +// NOTE: |script_identifier| will be used as the suffix for a JavaScript var, so +// it must adhere to JavaScript var naming rules. +NSString* MakeScriptInjectableOnce(NSString* script_identifier, + NSString* script); + // Returns an autoreleased string containing the JavaScript to be injected into // the main frame of the web view as early as possible. NSString* GetDocumentStartScriptForMainFrame(BrowserState* browser_state);
diff --git a/ios/web/js_messaging/page_script_util.mm b/ios/web/js_messaging/page_script_util.mm index 1176af3..68777aa 100644 --- a/ios/web/js_messaging/page_script_util.mm +++ b/ios/web/js_messaging/page_script_util.mm
@@ -18,29 +18,6 @@ namespace { -// Make sure that script is injected only once. For example, content of -// WKUserScript can be injected into the same page multiple times -// without notifying WKNavigationDelegate (e.g. after window.document.write -// JavaScript call). Injecting the script multiple times invalidates the -// __gCrWeb.windowId variable and will break the ability to send messages from -// JS to the native code. Wrapping injected script into "if (!injected)" check -// prevents multiple injections into the same page. |script_identifier| should -// identify the script being injected in order to enforce the injection of -// |script| to only once. -// NOTE: |script_identifier| will be used as the prefix for a JavaScript var, so -// it must adhere to JavaScript var naming rules. -NSString* MakeScriptInjectableOnce(NSString* script_identifier, - NSString* script) { - NSString* kOnceWrapperTemplate = - @"if (typeof %@ === 'undefined') { var %@ = true; %%@ }"; - NSString* injected_var_name = - [NSString stringWithFormat:@"%@_injected", script_identifier]; - NSString* once_wrapper = - [NSString stringWithFormat:kOnceWrapperTemplate, injected_var_name, - injected_var_name]; - return [NSString stringWithFormat:once_wrapper, script]; -} - // Returns a string with \ and ' escaped. // This is used instead of GetQuotedJSONString because that will convert // UTF-16 to UTF-8, which can cause problems when injecting scripts depending @@ -72,6 +49,18 @@ return content; } +NSString* MakeScriptInjectableOnce(NSString* script_identifier, + NSString* script) { + NSString* kOnceWrapperTemplate = + @"if (typeof %@ === 'undefined') { var %@ = true; %%@ }"; + NSString* injected_var_name = + [NSString stringWithFormat:@"_injected_%@", script_identifier]; + NSString* once_wrapper = + [NSString stringWithFormat:kOnceWrapperTemplate, injected_var_name, + injected_var_name]; + return [NSString stringWithFormat:once_wrapper, script]; +} + NSString* GetDocumentStartScriptForMainFrame(BrowserState* browser_state) { DCHECK(GetWebClient()); NSString* embedder_page_script =
diff --git a/ios/web/js_messaging/page_script_util_unittest.mm b/ios/web/js_messaging/page_script_util_unittest.mm index dcf6579..f92c1d5 100644 --- a/ios/web/js_messaging/page_script_util_unittest.mm +++ b/ios/web/js_messaging/page_script_util_unittest.mm
@@ -24,6 +24,20 @@ using base::test::ios::WaitUntilConditionOrTimeout; using base::test::ios::kWaitForPageLoadTimeout; +namespace { + +void AddSharedScriptsToWebView(WKWebView* web_view) { + // Scripts must be all injected at once because as soon as __gCrWeb exists, + // injection is assumed to be done and __gCrWeb.message is used. + NSString* scripts = [NSString + stringWithFormat:@"%@; %@; %@", web::test::GetPageScript(@"base_js"), + web::test::GetPageScript(@"common_js"), + web::test::GetPageScript(@"message_js")]; + web::test::ExecuteJavaScript(web_view, scripts); +} + +} // namespace + namespace web { namespace { @@ -37,10 +51,26 @@ } }; +// Tests that |MakeScriptInjectableOnce| prevents a script from being injected +// twice. +TEST_F(PageScriptUtilTest, MakeScriptInjectableOnce) { + WKWebView* web_view = BuildWKWebView(CGRectZero, GetBrowserState()); + NSString* identifier = @"script_id"; + + test::ExecuteJavaScript( + web_view, MakeScriptInjectableOnce(identifier, @"var value = 1;")); + EXPECT_NSEQ(@(1), test::ExecuteJavaScript(web_view, @"value")); + + test::ExecuteJavaScript(web_view, + MakeScriptInjectableOnce(identifier, @"value = 2;")); + EXPECT_NSEQ(@(1), test::ExecuteJavaScript(web_view, @"value")); +} + // Tests that WKWebView early page script is a valid script that injects global // __gCrWeb object. TEST_F(PageScriptUtilTest, WKWebViewEarlyPageScript) { WKWebView* web_view = BuildWKWebView(CGRectZero, GetBrowserState()); + AddSharedScriptsToWebView(web_view); test::ExecuteJavaScript( web_view, GetDocumentStartScriptForAllFrames(GetBrowserState())); EXPECT_NSEQ(@"object", test::ExecuteJavaScript(web_view, @"typeof __gCrWeb")); @@ -50,6 +80,7 @@ TEST_F(PageScriptUtilTest, WKEmbedderScript) { GetWebClient()->SetEarlyPageScript(@"__gCrEmbedder = {};"); WKWebView* web_view = BuildWKWebView(CGRectZero, GetBrowserState()); + AddSharedScriptsToWebView(web_view); test::ExecuteJavaScript( web_view, GetDocumentStartScriptForAllFrames(GetBrowserState())); test::ExecuteJavaScript(
diff --git a/ios/web/public/js_messaging/BUILD.gn b/ios/web/public/js_messaging/BUILD.gn index 4ce249f..f884da7 100644 --- a/ios/web/public/js_messaging/BUILD.gn +++ b/ios/web/public/js_messaging/BUILD.gn
@@ -10,6 +10,7 @@ ] sources = [ + "java_script_feature.h", "web_frame.h", "web_frame_user_data.h", "web_frame_util.h",
diff --git a/ios/web/public/js_messaging/java_script_feature.h b/ios/web/public/js_messaging/java_script_feature.h new file mode 100644 index 0000000..b1049ef1 --- /dev/null +++ b/ios/web/public/js_messaging/java_script_feature.h
@@ -0,0 +1,105 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_WEB_PUBLIC_JS_MESSAGING_JAVA_SCRIPT_FEATURE_H_ +#define IOS_WEB_PUBLIC_JS_MESSAGING_JAVA_SCRIPT_FEATURE_H_ + +#include <string> +#include <vector> + +@class NSString; + +namespace web { + +// Describes a feature implemented in Javascript and native<->JS communication +// (if any). It is intended to be instantiated directly for simple features +// requiring injection only, but should subclassed into feature specific classes +// to handle JS<->native communication. +// NOTE: As implemented within //ios/web, JavaScriptFeature instances holds no +// state itself and can be used application-wide across browser states. However, +// this is not guaranteed of JavaScriptFeature subclasses. +class JavaScriptFeature { + public: + // The content world which this feature supports. + // NOTE: Features should use kAnyContentWorld whenever possible to allow for + // isolation between the feature and the loaded webpage JavaScript. + enum class ContentWorld { + // Represents any content world. + kAnyContentWorld = 0, + // Represents the page content world which is shared by the JavaScript of + // the webpage. This value should only be used if the feature provides + // JavaScript which needs to be accessible to the client JavaScript. For + // example, JavaScript polyfills. + kPageContentWorld, + }; + + // A script to be injected into webpage frames which support this feature. + class FeatureScript { + public: + // The time at which this script will be injected into the page. + enum class InjectionTime { + kDocumentStart = 0, + kDocumentEnd, + }; + + // The frames which this script will be injected into. + enum class TargetFrames { + kAllFrames = 0, + kMainFrame, + }; + + // Creates a FeatureScript with the script file from the application bundle + // with |filename| to be injected at |injection_time| into |target_frames|. + static FeatureScript CreateWithFilename(const std::string& filename, + InjectionTime injection_time, + TargetFrames target_frames); + + // Returns the JavaScript string of the script with |script_filename_|. + NSString* GetScriptString() const; + + InjectionTime GetInjectionTime() const { return injection_time_; } + TargetFrames GetTargetFrames() const { return target_frames_; } + + ~FeatureScript(); + + private: + FeatureScript(const std::string& filename, + InjectionTime injection_time, + TargetFrames target_frames); + + std::string script_filename_; + InjectionTime injection_time_; + TargetFrames target_frames_; + }; + + JavaScriptFeature(ContentWorld supported_world, + std::vector<const FeatureScript> feature_scripts); + JavaScriptFeature(ContentWorld supported_world, + std::vector<const FeatureScript> feature_scripts, + std::vector<const JavaScriptFeature*> dependent_features); + virtual ~JavaScriptFeature(); + + // Returns the supported content world for this feature. + ContentWorld GetSupportedContentWorld() const; + + // Returns a vector of scripts used by this feature. + virtual const std::vector<const FeatureScript> GetScripts() const; + // Returns a vector of features which this one depends upon being available. + virtual const std::vector<const JavaScriptFeature*> GetDependentFeatures() + const; + + JavaScriptFeature(const JavaScriptFeature&) = delete; + + protected: + explicit JavaScriptFeature(ContentWorld supported_world); + + private: + ContentWorld supported_world_; + std::vector<const FeatureScript> scripts_; + std::vector<const JavaScriptFeature*> dependent_features_; +}; + +} // namespace web + +#endif // IOS_WEB_PUBLIC_JS_MESSAGING_JAVA_SCRIPT_FEATURE_H_
diff --git a/ios/web/web_state/ui/BUILD.gn b/ios/web/web_state/ui/BUILD.gn index 6c03c00..7fbb38d 100644 --- a/ios/web/web_state/ui/BUILD.gn +++ b/ios/web/web_state/ui/BUILD.gn
@@ -117,7 +117,14 @@ configs += [ "//build/config/compiler:enable_arc" ] } +source_set("wk_web_view_configuration_provider_header") { + deps = [ "//base" ] + sources = [ "wk_web_view_configuration_provider.h" ] + configs += [ "//build/config/compiler:enable_arc" ] +} + source_set("wk_web_view_configuration_provider") { + public_deps = [ ":wk_web_view_configuration_provider_header" ] deps = [ "//base", "//components/safe_browsing/core:features", @@ -134,7 +141,6 @@ "wk_content_rule_list_provider.mm", "wk_content_rule_list_util.h", "wk_content_rule_list_util.mm", - "wk_web_view_configuration_provider.h", "wk_web_view_configuration_provider.mm", "wk_web_view_configuration_provider_observer.h", ]
diff --git a/media/capture/video/chromeos/camera_app_device_bridge_impl.cc b/media/capture/video/chromeos/camera_app_device_bridge_impl.cc index e71efb4..77b0675 100644 --- a/media/capture/video/chromeos/camera_app_device_bridge_impl.cc +++ b/media/capture/video/chromeos/camera_app_device_bridge_impl.cc
@@ -39,6 +39,11 @@ camera_info_getter_ = std::move(camera_info_getter); } +void CameraAppDeviceBridgeImpl::SetVirtualDeviceController( + VirtualDeviceController virtual_device_controller) { + virtual_device_controller_ = std::move(virtual_device_controller); +} + void CameraAppDeviceBridgeImpl::UnsetCameraInfoGetter() { camera_info_getter_ = {}; } @@ -81,4 +86,12 @@ std::move(callback).Run(is_supported_); } +void CameraAppDeviceBridgeImpl::SetMultipleStreamsEnabled( + const std::string& device_id, + bool enabled, + SetMultipleStreamsEnabledCallback callback) { + virtual_device_controller_.Run(device_id, enabled); + std::move(callback).Run(true); +} + } // namespace media
diff --git a/media/capture/video/chromeos/camera_app_device_bridge_impl.h b/media/capture/video/chromeos/camera_app_device_bridge_impl.h index 42a1972d..f388166 100644 --- a/media/capture/video/chromeos/camera_app_device_bridge_impl.h +++ b/media/capture/video/chromeos/camera_app_device_bridge_impl.h
@@ -21,6 +21,8 @@ public: using CameraInfoGetter = base::RepeatingCallback<cros::mojom::CameraInfoPtr(const std::string&)>; + using VirtualDeviceController = + base::RepeatingCallback<void(const std::string&, bool)>; CameraAppDeviceBridgeImpl(); @@ -37,6 +39,9 @@ void UnsetCameraInfoGetter(); + void SetVirtualDeviceController( + VirtualDeviceController virtual_device_controller); + CameraAppDeviceImpl* GetCameraAppDevice(const std::string& device_id); // cros::mojom::CameraAppDeviceBridge implementations. @@ -45,6 +50,11 @@ void IsSupported(IsSupportedCallback callback) override; + void SetMultipleStreamsEnabled( + const std::string& device_id, + bool enabled, + SetMultipleStreamsEnabledCallback callback) override; + private: CameraAppDeviceImpl* CreateCameraAppDevice(const std::string& device_id); @@ -52,6 +62,8 @@ CameraInfoGetter camera_info_getter_; + VirtualDeviceController virtual_device_controller_; + mojo::ReceiverSet<cros::mojom::CameraAppDeviceBridge> receivers_; base::flat_map<std::string, std::unique_ptr<media::CameraAppDeviceImpl>> @@ -62,4 +74,4 @@ } // namespace media -#endif // MEDIA_CAPTURE_VIDEO_CHROMEOS_CAMERA_APP_DEVICE_BRIDGE_IMPL_H_ \ No newline at end of file +#endif // MEDIA_CAPTURE_VIDEO_CHROMEOS_CAMERA_APP_DEVICE_BRIDGE_IMPL_H_
diff --git a/media/capture/video/chromeos/camera_app_device_provider_impl.cc b/media/capture/video/chromeos/camera_app_device_provider_impl.cc index 0cca221..53defd2 100644 --- a/media/capture/video/chromeos/camera_app_device_provider_impl.cc +++ b/media/capture/video/chromeos/camera_app_device_provider_impl.cc
@@ -54,4 +54,27 @@ bridge_->IsSupported(std::move(callback)); } -} // namespace media \ No newline at end of file +void CameraAppDeviceProviderImpl::SetMultipleStreamsEnabled( + const std::string& source_id, + bool enabled, + SetMultipleStreamsEnabledCallback callback) { + mapping_callback_.Run( + source_id, + media::BindToCurrentLoop(base::BindOnce( + &CameraAppDeviceProviderImpl::SetMultipleStreamsEnabledWithDeviceId, + weak_ptr_factory_.GetWeakPtr(), enabled, std::move(callback)))); +} + +void CameraAppDeviceProviderImpl::SetMultipleStreamsEnabledWithDeviceId( + bool enabled, + SetMultipleStreamsEnabledCallback callback, + const base::Optional<std::string>& device_id) { + if (!device_id.has_value()) { + std::move(callback).Run(false); + return; + } + + bridge_->SetMultipleStreamsEnabled(*device_id, enabled, std::move(callback)); +} + +} // namespace media
diff --git a/media/capture/video/chromeos/camera_app_device_provider_impl.h b/media/capture/video/chromeos/camera_app_device_provider_impl.h index 615d6bdba..6bf036e 100644 --- a/media/capture/video/chromeos/camera_app_device_provider_impl.h +++ b/media/capture/video/chromeos/camera_app_device_provider_impl.h
@@ -32,12 +32,21 @@ void GetCameraAppDevice(const std::string& source_id, GetCameraAppDeviceCallback callback) override; void IsSupported(IsSupportedCallback callback) override; + void SetMultipleStreamsEnabled( + const std::string& device_id, + bool enabled, + SetMultipleStreamsEnabledCallback callback) override; private: void GetCameraAppDeviceWithDeviceId( GetCameraAppDeviceCallback callback, const base::Optional<std::string>& device_id); + void SetMultipleStreamsEnabledWithDeviceId( + bool enable, + SetMultipleStreamsEnabledCallback callback, + const base::Optional<std::string>& device_id); + mojo::Remote<cros::mojom::CameraAppDeviceBridge> bridge_; DeviceIdMappingCallback mapping_callback_; @@ -51,4 +60,4 @@ } // namespace media -#endif // MEDIA_CAPTURE_VIDEO_CHROMEOS_CAMERA_APP_DEVICE_PROVIDER_IMPL_H_ \ No newline at end of file +#endif // MEDIA_CAPTURE_VIDEO_CHROMEOS_CAMERA_APP_DEVICE_PROVIDER_IMPL_H_
diff --git a/media/capture/video/chromeos/camera_hal_delegate.cc b/media/capture/video/chromeos/camera_hal_delegate.cc index 903c535..b4b8cd48 100644 --- a/media/capture/video/chromeos/camera_hal_delegate.cc +++ b/media/capture/video/chromeos/camera_hal_delegate.cc
@@ -19,6 +19,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" #include "base/strings/string_split.h" +#include "base/strings/string_util.h" #include "base/system/system_monitor.h" #include "base/unguessable_token.h" #include "media/capture/video/chromeos/camera_app_device_bridge_impl.h" @@ -33,6 +34,7 @@ namespace { constexpr int32_t kDefaultFps = 30; +constexpr char kVirtualPrefix[] = "VIRTUAL_"; constexpr base::TimeDelta kEventWaitTimeoutSecs = base::TimeDelta::FromSeconds(1); @@ -196,7 +198,8 @@ auto* delegate = GetVCDDelegate(task_runner_for_screen_observer, device_descriptor, camera_app_device_bridge); - return std::make_unique<VideoCaptureDeviceChromeOSHalv3>(delegate); + return std::make_unique<VideoCaptureDeviceChromeOSHalv3>(delegate, + device_descriptor); } void CameraHalDelegate::GetSupportedFormats( @@ -292,6 +295,7 @@ { base::AutoLock info_lock(camera_info_lock_); base::AutoLock id_map_lock(device_id_to_camera_id_lock_); + base::AutoLock virtual_lock(enable_virtual_device_lock_); for (const auto& it : camera_info_) { int camera_id = it.first; const cros::mojom::CameraInfoPtr& camera_info = it.second; @@ -339,6 +343,12 @@ // Mojo validates the input parameters for us so we don't need to // worry about malformed values. } + case cros::mojom::CameraFacing::CAMERA_FACING_VIRTUAL_BACK: + case cros::mojom::CameraFacing::CAMERA_FACING_VIRTUAL_FRONT: + case cros::mojom::CameraFacing::CAMERA_FACING_VIRTUAL_EXTERNAL: + // |camera_info_| should not have these facing types. + LOG(ERROR) << "Invalid facing type: " << camera_info->facing; + break; } auto* vid = get_vendor_string("com.google.usb.vendorId"); auto* pid = get_vendor_string("com.google.usb.productId"); @@ -350,9 +360,20 @@ devices_info.emplace_back(desc); GetSupportedFormats(camera_info_[camera_id], &devices_info.back().supported_formats); + + // Create a virtual device when multiple streams are enabled. + if (enable_virtual_device_[camera_id]) { + desc.facing = VideoFacingMode::MEDIA_VIDEO_FACING_NONE; + desc.device_id = + std::string(kVirtualPrefix) + base::NumberToString(camera_id); + desc.set_display_name("Virtual Camera"); + device_id_to_camera_id_[desc.device_id] = camera_id; + devices_info.emplace_back(desc); + GetSupportedFormats(camera_info_[camera_id], + &devices_info.back().supported_formats); + } } } - // TODO(shik): Report external camera first when lid is closed. // TODO(jcliang): Remove this after JS API supports query camera facing // (http://crbug.com/543997). @@ -410,7 +431,36 @@ if (it == camera_info_.end()) { return {}; } - return it->second.Clone(); + auto info = it->second.Clone(); + if (base::StartsWith(device_id, std::string(kVirtualPrefix))) { + switch (it->second->facing) { + case cros::mojom::CameraFacing::CAMERA_FACING_BACK: + info->facing = cros::mojom::CameraFacing::CAMERA_FACING_VIRTUAL_BACK; + break; + case cros::mojom::CameraFacing::CAMERA_FACING_FRONT: + info->facing = cros::mojom::CameraFacing::CAMERA_FACING_VIRTUAL_FRONT; + break; + case cros::mojom::CameraFacing::CAMERA_FACING_EXTERNAL: + info->facing = + cros::mojom::CameraFacing::CAMERA_FACING_VIRTUAL_EXTERNAL; + break; + default: + break; + } + } + return info; +} + +void CameraHalDelegate::EnableVirtualDevice(const std::string& device_id, + bool enable) { + if (base::StartsWith(device_id, std::string(kVirtualPrefix))) { + return; + } + auto camera_id = GetCameraIdFromDeviceId(device_id); + if (camera_id != -1) { + base::AutoLock lock(enable_virtual_device_lock_); + enable_virtual_device_[camera_id] = enable; + } } const VendorTagInfo* CameraHalDelegate::GetVendorTagInfoByName(
diff --git a/media/capture/video/chromeos/camera_hal_delegate.h b/media/capture/video/chromeos/camera_hal_delegate.h index a5f7a29..267b45a 100644 --- a/media/capture/video/chromeos/camera_hal_delegate.h +++ b/media/capture/video/chromeos/camera_hal_delegate.h
@@ -93,6 +93,8 @@ const VendorTagInfo* GetVendorTagInfoByName(const std::string& full_name); + void EnableVirtualDevice(const std::string& device_id, bool enable); + private: friend class base::RefCountedThreadSafe<CameraHalDelegate>; @@ -193,6 +195,10 @@ base::Lock device_id_to_camera_id_lock_; std::map<std::string, int> device_id_to_camera_id_ GUARDED_BY(device_id_to_camera_id_lock_); + // A virtual device is enabled/disabled for camera id. + base::Lock enable_virtual_device_lock_; + base::flat_map<int, bool> enable_virtual_device_ + GUARDED_BY(enable_virtual_device_lock_); SEQUENCE_CHECKER(sequence_checker_); @@ -214,6 +220,7 @@ // information of vendor tags. Bound to |ipc_task_runner_|. VendorTagOpsDelegate vendor_tag_ops_delegate_; + // A map from camera id to corresponding delegate instance. base::flat_map<int, std::unique_ptr<VideoCaptureDeviceChromeOSDelegate>> vcd_delegate_map_;
diff --git a/media/capture/video/chromeos/mojom/camera_app.mojom b/media/capture/video/chromeos/mojom/camera_app.mojom index 7bc0da4..59df9f82 100644 --- a/media/capture/video/chromeos/mojom/camera_app.mojom +++ b/media/capture/video/chromeos/mojom/camera_app.mojom
@@ -53,6 +53,11 @@ // and camera app. Currently only devices running camera HAL v3 support this // feature. IsSupported() => (bool is_supported); + + // Add/Remove a virtual device for recording stream according to |enabled|. + // The virtual device has the same config as |device_id| except facing + // attribute. + SetMultipleStreamsEnabled(string device_id, bool enabled) => (bool success); }; // Inner interface that used to communicate between browser process (Remote) and @@ -68,6 +73,11 @@ // and camera app. Currently only devices running camera HAL v3 support this // feature. IsSupported() => (bool is_supported); + + // Add/Remove a virtual device for recording stream according to |enabled|. + // The virtual device has the same config as |device_id| except facing + // attribute. + SetMultipleStreamsEnabled(string device_id, bool enabled) => (bool success); }; // Interface for communication between Chrome Camera App (Remote) and camera
diff --git a/media/capture/video/chromeos/mojom/camera_common.mojom b/media/capture/video/chromeos/mojom/camera_common.mojom index 0547429..f26bcd9 100644 --- a/media/capture/video/chromeos/mojom/camera_common.mojom +++ b/media/capture/video/chromeos/mojom/camera_common.mojom
@@ -13,6 +13,9 @@ CAMERA_FACING_BACK = 0, CAMERA_FACING_FRONT = 1, CAMERA_FACING_EXTERNAL = 2, + CAMERA_FACING_VIRTUAL_BACK = 3, + CAMERA_FACING_VIRTUAL_FRONT = 4, + CAMERA_FACING_VIRTUAL_EXTERNAL = 5, }; struct CameraResourceCost {
diff --git a/media/capture/video/chromeos/video_capture_device_chromeos_halv3.cc b/media/capture/video/chromeos/video_capture_device_chromeos_halv3.cc index 7e24d63a4..d7dc818 100644 --- a/media/capture/video/chromeos/video_capture_device_chromeos_halv3.cc +++ b/media/capture/video/chromeos/video_capture_device_chromeos_halv3.cc
@@ -4,13 +4,21 @@ #include "media/capture/video/chromeos/video_capture_device_chromeos_halv3.h" +#include "base/strings/string_util.h" #include "media/capture/video/chromeos/video_capture_device_chromeos_delegate.h" namespace media { +constexpr char kVirtualPrefix[] = "VIRTUAL_"; + VideoCaptureDeviceChromeOSHalv3::VideoCaptureDeviceChromeOSHalv3( - VideoCaptureDeviceChromeOSDelegate* delegate) - : vcd_delegate_(delegate), client_type_(ClientType::kPreviewClient) {} + VideoCaptureDeviceChromeOSDelegate* delegate, + const VideoCaptureDeviceDescriptor& vcd_descriptor) + : vcd_delegate_(delegate) { + client_type_ = base::StartsWith(vcd_descriptor.device_id, kVirtualPrefix) + ? ClientType::kVideoClient + : ClientType::kPreviewClient; +} VideoCaptureDeviceChromeOSHalv3::~VideoCaptureDeviceChromeOSHalv3() { vcd_delegate_->Shutdown();
diff --git a/media/capture/video/chromeos/video_capture_device_chromeos_halv3.h b/media/capture/video/chromeos/video_capture_device_chromeos_halv3.h index fde6525..5c5188a82 100644 --- a/media/capture/video/chromeos/video_capture_device_chromeos_halv3.h +++ b/media/capture/video/chromeos/video_capture_device_chromeos_halv3.h
@@ -19,8 +19,9 @@ class CAPTURE_EXPORT VideoCaptureDeviceChromeOSHalv3 final : public VideoCaptureDevice { public: - explicit VideoCaptureDeviceChromeOSHalv3( - VideoCaptureDeviceChromeOSDelegate* delegate); + VideoCaptureDeviceChromeOSHalv3( + VideoCaptureDeviceChromeOSDelegate* delegate, + const VideoCaptureDeviceDescriptor& vcd_descriptor); ~VideoCaptureDeviceChromeOSHalv3() final;
diff --git a/media/capture/video/chromeos/video_capture_device_factory_chromeos.cc b/media/capture/video/chromeos/video_capture_device_factory_chromeos.cc index be6c8138..97b6d909 100644 --- a/media/capture/video/chromeos/video_capture_device_factory_chromeos.cc +++ b/media/capture/video/chromeos/video_capture_device_factory_chromeos.cc
@@ -95,6 +95,9 @@ camera_app_device_bridge_->SetCameraInfoGetter( base::BindRepeating(&CameraHalDelegate::GetCameraInfoFromDeviceId, base::Unretained(camera_hal_delegate_.get()))); + camera_app_device_bridge_->SetVirtualDeviceController( + base::BindRepeating(&CameraHalDelegate::EnableVirtualDevice, + base::Unretained(camera_hal_delegate_.get()))); } return true; }
diff --git a/media/cast/sender/video_encoder_unittest.cc b/media/cast/sender/video_encoder_unittest.cc index e566564..ad0827619 100644 --- a/media/cast/sender/video_encoder_unittest.cc +++ b/media/cast/sender/video_encoder_unittest.cc
@@ -40,8 +40,7 @@ protected: VideoEncoderTest() : task_runner_(new FakeSingleThreadTaskRunner(&testing_clock_)), - thread_task_runner_override_reverter_( - base::ThreadTaskRunnerHandle::OverrideForTesting(task_runner_)), + task_runner_handle_override_(task_runner_), cast_environment_(new CastEnvironment(&testing_clock_, task_runner_, task_runner_, @@ -194,7 +193,7 @@ base::SimpleTestTickClock testing_clock_; const scoped_refptr<FakeSingleThreadTaskRunner> task_runner_; - base::ScopedClosureRunner thread_task_runner_override_reverter_; + base::ThreadTaskRunnerHandleOverrideForTesting task_runner_handle_override_; const scoped_refptr<CastEnvironment> cast_environment_; FrameSenderConfig video_config_; std::unique_ptr<FakeVideoEncodeAcceleratorFactory> vea_factory_;
diff --git a/media/gpu/video_encode_accelerator_tests.cc b/media/gpu/video_encode_accelerator_tests.cc index ef671bb..ae92230 100644 --- a/media/gpu/video_encode_accelerator_tests.cc +++ b/media/gpu/video_encode_accelerator_tests.cc
@@ -333,8 +333,14 @@ // Check if there is no keyframe except the first frame. EXPECT_EQ(encoder->GetEventCount(VideoEncoder::kKeyFrame), 1u); encoder->ForceKeyFrame(); - // Check if the |middle_frame|+1-th frame is keyframe. - encoder->EncodeUntil(VideoEncoder::kBitstreamReady, middle_frame + 1u); + // Since kFrameReleased and kBitstreamReady events are asynchronous, the + // number of bitstreams being processed is unknown. We check keyframe request + // is applied by seeing if there is a keyframe in a few frames after + // requested. 10 is arbitrarily chosen. + constexpr size_t kKeyFrameRequestWindow = 10u; + encoder->EncodeUntil(VideoEncoder::kBitstreamReady, + std::min(middle_frame + kKeyFrameRequestWindow, + config.num_frames_to_encode)); EXPECT_TRUE(encoder->WaitUntilIdle()); EXPECT_EQ(encoder->GetEventCount(VideoEncoder::kKeyFrame), 2u);
diff --git a/media/renderers/paint_canvas_video_renderer.cc b/media/renderers/paint_canvas_video_renderer.cc index f4d4428..6565908e 100644 --- a/media/renderers/paint_canvas_video_renderer.cc +++ b/media/renderers/paint_canvas_video_renderer.cc
@@ -254,10 +254,10 @@ texture_info.fFormat = GL_RGBA8_OES; GrBackendTexture backend_texture(size.width(), size.height(), GrMipMapped::kNo, texture_info); - return SkImage::MakeFromAdoptedTexture( + return SkImage::MakeFromTexture( raster_context_provider->GrContext(), backend_texture, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kPremul_SkAlphaType, - color_space.ToSkColorSpace()); + color_space.ToSkColorSpace(), nullptr, nullptr); } void VideoFrameCopyTextureOrSubTexture(gpu::gles2::GLES2Interface* gl, @@ -912,7 +912,7 @@ const bool need_rotation = video_transformation.rotation != VIDEO_ROTATION_0; const bool need_scaling = - dest_rect.size() != gfx::SizeF(video_frame->visible_rect().size()); + dest_rect.size() != gfx::SizeF(image.width(), image.height()); const bool need_translation = !dest_rect.origin().IsOrigin(); // TODO(tmathmeyer): apply horizontal / vertical mirroring if needed. bool need_transform = need_rotation || need_scaling || need_translation; @@ -943,13 +943,10 @@ rotated_dest_size = gfx::SizeF(rotated_dest_size.height(), rotated_dest_size.width()); } - canvas->scale(SkFloatToScalar(rotated_dest_size.width() / - video_frame->visible_rect().width()), - SkFloatToScalar(rotated_dest_size.height() / - video_frame->visible_rect().height())); - canvas->translate( - -SkFloatToScalar(video_frame->visible_rect().width() * 0.5f), - -SkFloatToScalar(video_frame->visible_rect().height() * 0.5f)); + canvas->scale(SkFloatToScalar(rotated_dest_size.width() / image.width()), + SkFloatToScalar(rotated_dest_size.height() / image.height())); + canvas->translate(-SkFloatToScalar(image.width() * 0.5f), + -SkFloatToScalar(image.height() * 0.5f)); } SkImageInfo info; @@ -968,15 +965,7 @@ const size_t offset = info.computeOffset(origin.x(), origin.y(), row_bytes); void* const pixels_offset = reinterpret_cast<char*>(pixels) + offset; ConvertVideoFrameToRGBPixels(video_frame.get(), pixels_offset, row_bytes); - } else if (video_frame->HasTextures()) { - DCHECK_EQ(video_frame->coded_size(), - gfx::Size(image.width(), image.height())); - canvas->drawImageRect(image, gfx::RectToSkRect(video_frame->visible_rect()), - dest, &video_flags, - SkCanvas::kStrict_SrcRectConstraint); } else { - DCHECK_EQ(video_frame->visible_rect().size(), - gfx::Size(image.width(), image.height())); canvas->drawImage(image, 0, 0, &video_flags); } @@ -1709,6 +1698,8 @@ DCHECK(!source_mailbox.IsZero()); DCHECK(source_texture); auto* ri = raster_context_provider->RasterInterface(); + if (!texture_ownership_in_skia) + ri->DeleteGpuRasterTexture(source_texture); if (!wraps_video_frame_texture) { gpu::SyncToken sync_token; ri->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData()); @@ -1718,7 +1709,9 @@ } bool PaintCanvasVideoRenderer::Cache::Recycle() { - DCHECK(!wraps_video_frame_texture); + if (!texture_ownership_in_skia) + return true; + if (!paint_image.HasExclusiveTextureAccess()) return false; @@ -1728,6 +1721,7 @@ paint_image = cc::PaintImage(); // We need a new texture ID because skia will destroy the previous one with // the SkImage. + texture_ownership_in_skia = false; source_texture = 0; return true; } @@ -1773,6 +1767,7 @@ } else { cache_.emplace(video_frame->unique_id()); auto* sii = raster_context_provider->SharedImageInterface(); + // TODO(nazabris): Sort out what to do when GLES2 is needed but the // cached shared image is created without it. uint32_t flags = @@ -1788,6 +1783,8 @@ ri->WaitSyncTokenCHROMIUM( sii->GenUnverifiedSyncToken().GetConstData()); } + + DCHECK(!cache_->texture_ownership_in_skia); if (video_frame->NumTextures() == 1) { auto frame_mailbox = SynchronizeVideoFrameSingleMailbox(ri, video_frame.get()); @@ -1828,10 +1825,35 @@ cache_->raster_context_provider = raster_context_provider; cache_->coded_size = video_frame->coded_size(); cache_->visible_rect = video_frame->visible_rect(); - + GrDirectContext* direct = + GrAsDirectContext(raster_context_provider->GrContext()); + sk_sp<SkImage> source_subset = source_image->makeSubset( + gfx::RectToSkIRect(cache_->visible_rect), direct); + if (source_subset) { + // We use the flushPendingGrContextIO = true so we can flush any pending + // GPU work on the GrContext to ensure that skia exectues the work for + // generating the subset and it can be safely destroyed. + GrBackendTexture image_backend = + source_image->getBackendTexture(/*flushPendingGrContextIO*/ true); + GrBackendTexture subset_backend = + source_subset->getBackendTexture(/*flushPendingGrContextIO*/ true); +#if DCHECK_IS_ON() + GrGLTextureInfo backend_info; + if (image_backend.getGLTextureInfo(&backend_info)) + DCHECK_EQ(backend_info.fID, cache_->source_texture); +#endif + if (subset_backend.isValid() && + subset_backend.isSameTexture(image_backend)) { + cache_->texture_ownership_in_skia = true; + source_subset = SkImage::MakeFromAdoptedTexture( + cache_->raster_context_provider->GrContext(), image_backend, + kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, + kPremul_SkAlphaType, source_image->imageInfo().refColorSpace()); + } + } paint_image_builder.set_texture_backing( sk_sp<VideoTextureBacking>(new VideoTextureBacking( - std::move(source_image), raster_context_provider)), + std::move(source_subset), raster_context_provider)), cc::PaintImage::GetNextContentId()); } else { cache_.emplace(video_frame->unique_id());
diff --git a/media/renderers/paint_canvas_video_renderer.h b/media/renderers/paint_canvas_video_renderer.h index a422e23..943cc37 100644 --- a/media/renderers/paint_canvas_video_renderer.h +++ b/media/renderers/paint_canvas_video_renderer.h
@@ -239,6 +239,9 @@ // (if true), or to an allocated shared image (if false). bool wraps_video_frame_texture = false; + // Whether the texture pointed by |paint_image| is owned by skia or not. + bool texture_ownership_in_skia = false; + // Used to allow recycling of the previous shared image. This requires that // no external users have access to this resource via SkImage. Returns true // if the existing resource can be recycled.
diff --git a/net/cookies/cookie_options.cc b/net/cookies/cookie_options.cc index 2553b07..874a506 100644 --- a/net/cookies/cookie_options.cc +++ b/net/cookies/cookie_options.cc
@@ -66,6 +66,7 @@ options.set_do_not_update_access_time(); options.set_same_party_cookie_context_type( SamePartyCookieContextType::kSameParty); + options.set_is_in_nontrivial_first_party_set(true); return options; }
diff --git a/net/cookies/cookie_options.h b/net/cookies/cookie_options.h index b36614e0..992dde9 100644 --- a/net/cookies/cookie_options.h +++ b/net/cookies/cookie_options.h
@@ -155,6 +155,13 @@ } uint32_t full_party_context_size() const { return full_party_context_size_; } + void set_is_in_nontrivial_first_party_set(bool is_member) { + is_in_nontrivial_first_party_set_ = is_member; + } + bool is_in_nontrivial_first_party_set() const { + return is_in_nontrivial_first_party_set_; + } + // Convenience method for where you need a CookieOptions that will // work for getting/setting all types of cookies, including HttpOnly and // SameSite cookies. Also specifies not to update the access time, because @@ -174,6 +181,13 @@ // The size of the isolation_info.party_context plus the top-frame site. // Stored for logging purposes. uint32_t full_party_context_size_ = 0; + // Whether the site requesting cookie access (as opposed to e.g. the + // `site_for_cookies`) is a member (or owner) of a nontrivial First-Party + // Set. + // This is included here temporarily, for the purpose of ignoring SameParty + // for sites that are not participating in the Origin Trial. + // TODO(https://crbug.com/1163990): remove this field. + bool is_in_nontrivial_first_party_set_ = false; }; } // namespace net
diff --git a/net/cookies/cookie_util.cc b/net/cookies/cookie_util.cc index b051c2b..04ae883b 100644 --- a/net/cookies/cookie_util.cc +++ b/net/cookies/cookie_util.cc
@@ -612,8 +612,10 @@ CookieSamePartyStatus GetSamePartyStatus(const CanonicalCookie& cookie, const CookieOptions& options) { - if (!IsFirstPartySetsEnabled() || !cookie.IsSameParty()) + if (!IsFirstPartySetsEnabled() || !cookie.IsSameParty() || + !options.is_in_nontrivial_first_party_set()) { return CookieSamePartyStatus::kNoSamePartyEnforcement; + } switch (options.same_party_cookie_context_type()) { case CookieOptions::SamePartyCookieContextType::kCrossParty:
diff --git a/net/cookies/cookie_util_unittest.cc b/net/cookies/cookie_util_unittest.cc index 4271b0c..34df85f0 100644 --- a/net/cookies/cookie_util_unittest.cc +++ b/net/cookies/cookie_util_unittest.cc
@@ -8,6 +8,10 @@ #include "base/callback.h" #include "base/strings/string_split.h" #include "base/test/bind.h" +#include "base/test/scoped_feature_list.h" +#include "base/time/time.h" +#include "net/base/features.h" +#include "net/cookies/cookie_constants.h" #include "net/cookies/cookie_util.h" #include "testing/gtest/include/gtest/gtest.h" @@ -1267,6 +1271,175 @@ EXPECT_TRUE(result_out); } +TEST(CookieUtilTest, GetSamePartyStatus_NotInSet) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kFirstPartySets); + CookieOptions options; + options.set_is_in_nontrivial_first_party_set(false); + + for (bool same_party : {false, true}) { + for (bool secure : {false, true}) { + for (bool httponly : {false, true}) { + for (CookieSameSite same_site : { + CookieSameSite::NO_RESTRICTION, + CookieSameSite::LAX_MODE, + CookieSameSite::STRICT_MODE, + CookieSameSite::UNSPECIFIED, + }) { + for (CookieOptions::SamePartyCookieContextType party_context_type : { + CookieOptions::SamePartyCookieContextType::kCrossParty, + CookieOptions::SamePartyCookieContextType::kSameParty, + }) { + base::Time now = base::Time::Now(); + std::unique_ptr<CanonicalCookie> cookie = + CanonicalCookie::CreateUnsafeCookieForTesting( + "cookie", "tasty", "example.test", "/", now, now, now, + secure, httponly, same_site, + CookiePriority::COOKIE_PRIORITY_DEFAULT, same_party); + + options.set_same_party_cookie_context_type(party_context_type); + EXPECT_EQ(CookieSamePartyStatus::kNoSamePartyEnforcement, + cookie_util::GetSamePartyStatus(*cookie, options)); + } + } + } + } + } +} + +TEST(CookieUtilTest, GetSamePartyStatus_FeatureDisabled) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndDisableFeature(features::kFirstPartySets); + CookieOptions options; + options.set_is_in_nontrivial_first_party_set(true); + + for (bool same_party : {false, true}) { + for (bool secure : {false, true}) { + for (bool httponly : {false, true}) { + for (CookieSameSite same_site : { + CookieSameSite::NO_RESTRICTION, + CookieSameSite::LAX_MODE, + CookieSameSite::STRICT_MODE, + CookieSameSite::UNSPECIFIED, + }) { + for (CookieOptions::SamePartyCookieContextType party_context_type : { + CookieOptions::SamePartyCookieContextType::kCrossParty, + CookieOptions::SamePartyCookieContextType::kSameParty, + }) { + base::Time now = base::Time::Now(); + std::unique_ptr<CanonicalCookie> cookie = + CanonicalCookie::CreateUnsafeCookieForTesting( + "cookie", "tasty", "example.test", "/", now, now, now, + secure, httponly, same_site, + CookiePriority::COOKIE_PRIORITY_DEFAULT, same_party); + + options.set_same_party_cookie_context_type(party_context_type); + EXPECT_EQ(CookieSamePartyStatus::kNoSamePartyEnforcement, + cookie_util::GetSamePartyStatus(*cookie, options)); + } + } + } + } + } +} + +TEST(CookieUtilTest, GetSamePartyStatus_NotSameParty) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kFirstPartySets); + CookieOptions options; + options.set_is_in_nontrivial_first_party_set(true); + + for (bool secure : {false, true}) { + for (bool httponly : {false, true}) { + for (CookieSameSite same_site : { + CookieSameSite::NO_RESTRICTION, + CookieSameSite::LAX_MODE, + CookieSameSite::STRICT_MODE, + CookieSameSite::UNSPECIFIED, + }) { + for (CookieOptions::SamePartyCookieContextType party_context_type : { + CookieOptions::SamePartyCookieContextType::kCrossParty, + CookieOptions::SamePartyCookieContextType::kSameParty, + }) { + base::Time now = base::Time::Now(); + std::unique_ptr<CanonicalCookie> cookie = + CanonicalCookie::CreateUnsafeCookieForTesting( + "cookie", "tasty", "example.test", "/", now, now, now, secure, + httponly, same_site, CookiePriority::COOKIE_PRIORITY_DEFAULT, + false /* same_party */); + + options.set_same_party_cookie_context_type(party_context_type); + EXPECT_EQ(CookieSamePartyStatus::kNoSamePartyEnforcement, + cookie_util::GetSamePartyStatus(*cookie, options)); + } + } + } + } +} + +TEST(CookieUtilTest, GetSamePartyStatus_SamePartySemantics) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kFirstPartySets); + CookieOptions options; + options.set_is_in_nontrivial_first_party_set(true); + + // Note: some SameParty cookie configurations (e.g. non-Secure cookies) are + // skipped, because they are invalid. + for (bool httponly : {false, true}) { + for (CookieSameSite same_site : { + CookieSameSite::NO_RESTRICTION, + CookieSameSite::LAX_MODE, + CookieSameSite::UNSPECIFIED, + }) { + for (CookieOptions::SameSiteCookieContext::ContextType same_site_context : + { + CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE, + CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX, + CookieOptions::SameSiteCookieContext::ContextType:: + SAME_SITE_LAX_METHOD_UNSAFE, + CookieOptions::SameSiteCookieContext::ContextType:: + SAME_SITE_STRICT, + }) { + for (CookieOptions::SameSiteCookieContext::ContextType + schemeful_same_site_context : + { + CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE, + CookieOptions::SameSiteCookieContext::ContextType:: + SAME_SITE_LAX, + CookieOptions::SameSiteCookieContext::ContextType:: + SAME_SITE_LAX_METHOD_UNSAFE, + CookieOptions::SameSiteCookieContext::ContextType:: + SAME_SITE_STRICT, + }) { + if (same_site_context < schemeful_same_site_context) + continue; + options.set_same_site_cookie_context( + CookieOptions::SameSiteCookieContext( + same_site_context, schemeful_same_site_context)); + + base::Time now = base::Time::Now(); + std::unique_ptr<CanonicalCookie> cookie = + CanonicalCookie::CreateUnsafeCookieForTesting( + "cookie", "tasty", "example.test", "/", now, now, now, + true /* secure */, httponly, same_site, + CookiePriority::COOKIE_PRIORITY_DEFAULT, + true /* same_party */); + + options.set_same_party_cookie_context_type( + CookieOptions::SamePartyCookieContextType::kCrossParty); + EXPECT_EQ(CookieSamePartyStatus::kEnforceSamePartyExclude, + cookie_util::GetSamePartyStatus(*cookie, options)); + + options.set_same_party_cookie_context_type( + CookieOptions::SamePartyCookieContextType::kSameParty); + EXPECT_EQ(CookieSamePartyStatus::kEnforceSamePartyInclude, + cookie_util::GetSamePartyStatus(*cookie, options)); + } + } + } + } +} + } // namespace } // namespace net
diff --git a/net/dns/host_resolver_manager_unittest.cc b/net/dns/host_resolver_manager_unittest.cc index 6d0aa18f..563035d2 100644 --- a/net/dns/host_resolver_manager_unittest.cc +++ b/net/dns/host_resolver_manager_unittest.cc
@@ -2224,8 +2224,8 @@ // Override the current thread task runner, so we can simulate the passage of // time and avoid any actual sleeps. auto test_task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); - base::ScopedClosureRunner task_runner_override_scoped_cleanup = - base::ThreadTaskRunnerHandle::OverrideForTesting(test_task_runner); + base::ThreadTaskRunnerHandleOverrideForTesting task_runner_handle_override( + test_task_runner); // Resolve "host1". ResolveHostResponseHelper response(resolver_->CreateRequest( @@ -2265,8 +2265,8 @@ // number of retries used is 4 rather than something higher. TEST_F(HostResolverManagerTest, DefaultMaxRetryAttempts) { auto test_task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); - base::ScopedClosureRunner task_runner_override_scoped_cleanup = - base::ThreadTaskRunnerHandle::OverrideForTesting(test_task_runner); + base::ThreadTaskRunnerHandleOverrideForTesting task_runner_handle_override( + test_task_runner); // Instantiate a ResolverProc that will block all incoming requests. auto resolver_proc = base::MakeRefCounted<LookupAttemptHostResolverProc>( @@ -2982,8 +2982,8 @@ // Override the current thread task runner, so we can simulate the passage of // time to trigger the timeout. auto test_task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); - base::ScopedClosureRunner task_runner_override_scoped_cleanup = - base::ThreadTaskRunnerHandle::OverrideForTesting(test_task_runner); + base::ThreadTaskRunnerHandleOverrideForTesting task_runner_handle_override( + test_task_runner); HostResolver::ResolveHostParameters parameters; parameters.source = HostResolverSource::MULTICAST_DNS; @@ -3021,8 +3021,8 @@ // Override the current thread task runner, so we can simulate the passage of // time to trigger the timeout. auto test_task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); - base::ScopedClosureRunner task_runner_override_scoped_cleanup = - base::ThreadTaskRunnerHandle::OverrideForTesting(test_task_runner); + base::ThreadTaskRunnerHandleOverrideForTesting task_runner_handle_override( + test_task_runner); HostResolver::ResolveHostParameters parameters; parameters.dns_query_type = DnsQueryType::A; @@ -3067,8 +3067,8 @@ // Override the current thread task runner, so we can simulate the passage of // time to trigger the timeout. auto test_task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); - base::ScopedClosureRunner task_runner_override_scoped_cleanup = - base::ThreadTaskRunnerHandle::OverrideForTesting(test_task_runner); + base::ThreadTaskRunnerHandleOverrideForTesting task_runner_handle_override( + test_task_runner); HostResolver::ResolveHostParameters parameters; parameters.source = HostResolverSource::MULTICAST_DNS;
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index b327383..dec89f6 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc
@@ -156,7 +156,8 @@ net::CookieOptions CreateCookieOptions( net::CookieOptions::SameSiteCookieContext same_site_context, net::CookieOptions::SamePartyCookieContextType same_party_context, - const net::IsolationInfo& isolation_info) { + const net::IsolationInfo& isolation_info, + bool is_in_nontrivial_first_party_set) { net::CookieOptions options; options.set_return_excluded_cookies(); options.set_include_httponly(); @@ -167,6 +168,8 @@ options.set_full_party_context_size(isolation_info.party_context()->size() + 1); } + options.set_is_in_nontrivial_first_party_set( + is_in_nontrivial_first_party_set); return options; } @@ -179,13 +182,13 @@ // IsolationInfo. But that might not be true for other embedders yet // (including cast, WebView, etc). Also not sure about iOS. net::CookieOptions::SamePartyCookieContextType ComputeSamePartyContext( - const GURL& request_url, + const net::SchemefulSite& request_site, const net::IsolationInfo& isolation_info, const net::CookieAccessDelegate* cookie_access_delegate) { if (!isolation_info.IsEmpty() && isolation_info.party_context().has_value() && cookie_access_delegate && cookie_access_delegate->IsContextSamePartyWithSite( - net::SchemefulSite(request_url), + request_site, isolation_info.network_isolation_key().GetTopFrameSite().value(), isolation_info.party_context().value())) { return net::CookieOptions::SamePartyCookieContextType::kSameParty; @@ -573,11 +576,19 @@ request_->method(), request_->url(), request_->site_for_cookies(), request_->initiator(), force_ignore_site_for_cookies); + net::SchemefulSite request_site(request_->url()); + + const CookieAccessDelegate* delegate = + cookie_store->cookie_access_delegate(); + CookieOptions::SamePartyCookieContextType same_party_context = - ComputeSamePartyContext(request_->url(), request_->isolation_info(), - cookie_store->cookie_access_delegate()); + ComputeSamePartyContext(request_site, request_->isolation_info(), + delegate); + bool is_in_nontrivial_first_party_set = + delegate && delegate->IsInNontrivialFirstPartySet(request_site); CookieOptions options = CreateCookieOptions( - same_site_context, same_party_context, request_->isolation_info()); + same_site_context, same_party_context, request_->isolation_info(), + is_in_nontrivial_first_party_set); cookie_store->GetCookieListWithOptionsAsync( request_->url(), options, @@ -716,12 +727,17 @@ request_->url(), request_->site_for_cookies(), request_->initiator(), force_ignore_site_for_cookies); + const CookieAccessDelegate* delegate = cookie_store->cookie_access_delegate(); + net::SchemefulSite request_site(request_->url()); CookieOptions::SamePartyCookieContextType same_party_context = - ComputeSamePartyContext(request_->url(), request_->isolation_info(), - cookie_store->cookie_access_delegate()); + ComputeSamePartyContext(request_site, request_->isolation_info(), + delegate); + bool is_in_nontrivial_first_party_set = + delegate && delegate->IsInNontrivialFirstPartySet(request_site); CookieOptions options = CreateCookieOptions( - same_site_context, same_party_context, request_->isolation_info()); + same_site_context, same_party_context, request_->isolation_info(), + is_in_nontrivial_first_party_set); // Set all cookies, without waiting for them to be set. Any subsequent // read will see the combined result of all cookie operation.
diff --git a/pdf/document_metadata.h b/pdf/document_metadata.h index 82d00ac..e1ad46d 100644 --- a/pdf/document_metadata.h +++ b/pdf/document_metadata.h
@@ -30,8 +30,8 @@ // dictionary (see section 14.3.3 "Document Information Dictionary" of the ISO // 32000-1 standard), as well as other properties about the file. // TODO(crbug.com/93619): Finish adding information dictionary fields like -// |keywords|, |creation_date|, and |mod_date|. Also add fields like -// |size_bytes|, |is_encrypted|, and |is_linearized|. +// `keywords`, `creation_date`, and `mod_date`. Also add fields like +// `size_bytes` and `is_encrypted`. struct DocumentMetadata { DocumentMetadata(); DocumentMetadata(const DocumentMetadata&) = delete; @@ -41,6 +41,9 @@ // Version of the document PdfVersion version = PdfVersion::kUnknown; + // Whether the document is optimized by linearization. + bool linearized = false; + // The document's title. std::string title;
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc index 3bb90f3..465d70da 100644 --- a/pdf/pdfium/pdfium_engine.cc +++ b/pdf/pdfium/pdfium_engine.cc
@@ -674,13 +674,13 @@ if (!fpdf_availability()) { document_->file_access().m_FileLen = doc_loader_->GetDocumentSize(); document_->CreateFPDFAvailability(); - DCHECK(fpdf_availability()); + // Currently engine does not deal efficiently with some non-linearized // files. // See http://code.google.com/p/chromium/issues/detail?id=59400 // To improve user experience we download entire file for non-linearized // PDF. - if (FPDFAvail_IsLinearized(fpdf_availability()) != PDF_LINEARIZED) { + if (!IsLinearized()) { // Wait complete document. process_when_pending_request_complete_ = false; document_->ResetFPDFAvailability(); @@ -2752,9 +2752,8 @@ pending_pages_.clear(); size_t new_page_count = FPDF_GetPageCount(doc()); - bool doc_complete = doc_loader_->IsDocumentComplete(); - bool is_linear = - FPDFAvail_IsLinearized(fpdf_availability()) == PDF_LINEARIZED; + const bool doc_complete = doc_loader_->IsDocumentComplete(); + const bool is_linear = IsLinearized(); for (size_t i = 0; i < new_page_count; ++i) { // Get page availability. If |document_loaded_| == true and the page is not // new, then the page has been constructed already. Get page availability @@ -2805,12 +2804,10 @@ void PDFiumEngine::LoadBody() { DCHECK(doc()); - DCHECK(fpdf_availability()); if (doc_loader_->IsDocumentComplete()) { LoadForm(); - } else if (FPDFAvail_IsLinearized(fpdf_availability()) == PDF_LINEARIZED && - FPDF_GetPageCount(doc()) == 1) { - // If we have only one page we should load form first, bacause it is may be + } else if (IsLinearized() && FPDF_GetPageCount(doc()) == 1) { + // If we have only one page we should load form first, because it may be an // XFA document. And after loading form the page count and its contents may // be changed. LoadForm(); @@ -2865,6 +2862,11 @@ } } +bool PDFiumEngine::IsLinearized() { + DCHECK(fpdf_availability()); + return FPDFAvail_IsLinearized(fpdf_availability()) == PDF_LINEARIZED; +} + void PDFiumEngine::CalculateVisiblePages() { // Early return if the PDF isn't being loaded or if we don't have the document // info yet. The latter is important because otherwise as the PDF is being @@ -3948,8 +3950,10 @@ void PDFiumEngine::LoadDocumentMetadata() { DCHECK(document_loaded_); - // Document information dictionary entries doc_metadata_.version = GetDocumentVersion(); + doc_metadata_.linearized = IsLinearized(); + + // Document information dictionary entries doc_metadata_.title = GetTrimmedMetadataByField("Title"); doc_metadata_.author = GetTrimmedMetadataByField("Author"); doc_metadata_.subject = GetTrimmedMetadataByField("Subject");
diff --git a/pdf/pdfium/pdfium_engine.h b/pdf/pdfium/pdfium_engine.h index 2bbdba1..448b012f 100644 --- a/pdf/pdfium/pdfium_engine.h +++ b/pdf/pdfium/pdfium_engine.h
@@ -302,6 +302,9 @@ void LoadForm(); + // Checks whether the document is optimized by linearization. + bool IsLinearized(); + // Calculates which pages should be displayed right now. void CalculateVisiblePages();
diff --git a/pdf/pdfium/pdfium_engine_unittest.cc b/pdf/pdfium/pdfium_engine_unittest.cc index f6c27b1..f6a47b3 100644 --- a/pdf/pdfium/pdfium_engine_unittest.cc +++ b/pdf/pdfium/pdfium_engine_unittest.cc
@@ -349,6 +349,7 @@ const DocumentMetadata& doc_metadata = engine->GetDocumentMetadata(); EXPECT_EQ(PdfVersion::k1_7, doc_metadata.version); + EXPECT_FALSE(doc_metadata.linearized); EXPECT_EQ("Sample PDF Document Info", doc_metadata.title); EXPECT_EQ("Chromium Authors", doc_metadata.author); EXPECT_EQ("Testing", doc_metadata.subject); @@ -365,6 +366,7 @@ const DocumentMetadata& doc_metadata = engine->GetDocumentMetadata(); EXPECT_EQ(PdfVersion::k1_7, doc_metadata.version); + EXPECT_FALSE(doc_metadata.linearized); EXPECT_THAT(doc_metadata.title, IsEmpty()); EXPECT_THAT(doc_metadata.author, IsEmpty()); EXPECT_THAT(doc_metadata.subject, IsEmpty()); @@ -372,6 +374,14 @@ EXPECT_THAT(doc_metadata.producer, IsEmpty()); } +TEST_F(PDFiumEngineTest, GetLinearizedDocumentMetadata) { + NiceMock<MockTestClient> client; + std::unique_ptr<PDFiumEngine> engine = + InitializeEngine(&client, FILE_PATH_LITERAL("linearized.pdf")); + ASSERT_TRUE(engine); + EXPECT_TRUE(engine->GetDocumentMetadata().linearized); +} + TEST_F(PDFiumEngineTest, GetBadPdfVersion) { NiceMock<MockTestClient> client; std::unique_ptr<PDFiumEngine> engine =
diff --git a/services/device/usb/usb_device_handle_win.cc b/services/device/usb/usb_device_handle_win.cc index 208f2e0..b2c6316 100644 --- a/services/device/usb/usb_device_handle_win.cc +++ b/services/device/usb/usb_device_handle_win.cc
@@ -222,8 +222,8 @@ // Aborting requests may run or destroy callbacks holding the last reference // to this object so hold a reference for the rest of this method. scoped_refptr<UsbDeviceHandleWin> self(this); - while (!requests_.empty()) - requests_.begin()->second->Abort(); + for (const auto& request : requests_) + request->Abort(); device_ = nullptr; } @@ -995,15 +995,19 @@ auto request = std::make_unique<Request>( handle, interface ? interface->info->interface_number : -1); Request* request_ptr = request.get(); - requests_[request_ptr] = std::move(request); + requests_.push_back(std::move(request)); return request_ptr; } std::unique_ptr<UsbDeviceHandleWin::Request> UsbDeviceHandleWin::UnlinkRequest( UsbDeviceHandleWin::Request* request_ptr) { - auto it = requests_.find(request_ptr); + auto it = std::find_if( + requests_.begin(), requests_.end(), + [request_ptr](const std::unique_ptr<Request>& request) -> bool { + return request.get() == request_ptr; + }); DCHECK(it != requests_.end()); - std::unique_ptr<Request> request = std::move(it->second); + std::unique_ptr<Request> request = std::move(*it); requests_.erase(it); return request; } @@ -1085,7 +1089,13 @@ buffer = nullptr; bytes_transferred = 0; - status = UsbTransferStatus::TRANSFER_ERROR; + switch (win32_result) { + case ERROR_REQUEST_ABORTED: + status = UsbTransferStatus::CANCELLED; + break; + default: + status = UsbTransferStatus::TRANSFER_ERROR; + } } DCHECK_NE(request->interface_number(), -1);
diff --git a/services/device/usb/usb_device_handle_win.h b/services/device/usb/usb_device_handle_win.h index a07bc7b..8fc499e 100644 --- a/services/device/usb/usb_device_handle_win.h +++ b/services/device/usb/usb_device_handle_win.h
@@ -5,6 +5,7 @@ #ifndef SERVICES_DEVICE_USB_USB_DEVICE_HANDLE_WIN_H_ #define SERVICES_DEVICE_USB_USB_DEVICE_HANDLE_WIN_H_ +#include <list> #include <map> #include <memory> #include <vector> @@ -206,7 +207,7 @@ std::map<uint8_t, Interface> interfaces_; std::map<uint8_t, Endpoint> endpoints_; - std::map<Request*, std::unique_ptr<Request>> requests_; + std::list<std::unique_ptr<Request>> requests_; // Control transfers which are waiting for a function handle to be ready. std::vector<OpenInterfaceCallback> ep0_ready_callbacks_;
diff --git a/services/network/cookie_manager_unittest.cc b/services/network/cookie_manager_unittest.cc index 9578723..fa66ec7 100644 --- a/services/network/cookie_manager_unittest.cc +++ b/services/network/cookie_manager_unittest.cc
@@ -316,6 +316,7 @@ net::CookieOptions::SameSiteCookieContext::MakeInclusive()); options.set_same_party_cookie_context_type( net::CookieOptions::SamePartyCookieContextType::kSameParty); + options.set_is_in_nontrivial_first_party_set(true); if (can_modify_httponly) options.set_include_httponly(); @@ -873,55 +874,114 @@ net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/true), "https", true)); - // Retrieve only unrestricted cookies. SameParty cookies are excluded, and - // non-SameSite=None cookies are excluded. - net::CookieOptions options; - options.set_return_excluded_cookies(); - ASSERT_EQ(net::CookieOptions::SamePartyCookieContextType::kCrossParty, - options.same_party_cookie_context_type()); - ASSERT_EQ( - net::CookieOptions::SameSiteCookieContext( - net::CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE), - options.same_site_cookie_context()); - const GURL cookie_url("https://foo_host.com/with/path"); - EXPECT_THAT(service_wrapper()->GetCookieList(cookie_url, options), - UnorderedElementsAre(CookieWithName("nonSameParty-None"))); - EXPECT_THAT( - service_wrapper()->GetExcludedCookieList(cookie_url, options), - UnorderedElementsAre(CookieAccessWithName("SameParty-Unspecified"), - CookieAccessWithName("SameParty-None"), - CookieAccessWithName("SameParty-Lax"), - CookieAccessWithName("nonSameParty-Unspecified"), - CookieAccessWithName("nonSameParty-Lax"))); + // Verify that sites in a First-Party Set get SameParty semantics. + { + net::CookieOptions options; + options.set_return_excluded_cookies(); + options.set_is_in_nontrivial_first_party_set(true); + ASSERT_EQ(net::CookieOptions::SamePartyCookieContextType::kCrossParty, + options.same_party_cookie_context_type()); + ASSERT_EQ( + net::CookieOptions::SameSiteCookieContext( + net::CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE), + options.same_site_cookie_context()); - // In a same-party, cross-site context, SameParty cookies should be included, - // and non-SameParty cookies should be excluded based on SameSite value. - options.set_same_party_cookie_context_type( - net::CookieOptions::SamePartyCookieContextType::kSameParty); - EXPECT_THAT(service_wrapper()->GetCookieList(cookie_url, options), - UnorderedElementsAre(CookieWithName("SameParty-Unspecified"), - CookieWithName("SameParty-None"), - CookieWithName("SameParty-Lax"), - CookieWithName("nonSameParty-None"))); - EXPECT_THAT( - service_wrapper()->GetExcludedCookieList(cookie_url, options), - UnorderedElementsAre(CookieAccessWithName("nonSameParty-Unspecified"), - CookieAccessWithName("nonSameParty-Lax"))); + // Retrieve only unrestricted cookies. SameParty cookies are excluded, and + // non-SameSite=None cookies are excluded. + EXPECT_THAT(service_wrapper()->GetCookieList(cookie_url, options), + UnorderedElementsAre(CookieWithName("nonSameParty-None"))); - // In a same-party, same-site context, all cookies should be included. - options.set_same_site_cookie_context( - net::CookieOptions::SameSiteCookieContext::MakeInclusive()); - EXPECT_THAT(service_wrapper()->GetCookieList(cookie_url, options), - UnorderedElementsAre(CookieWithName("SameParty-Unspecified"), - CookieWithName("SameParty-None"), - CookieWithName("SameParty-Lax"), - CookieWithName("nonSameParty-Unspecified"), - CookieWithName("nonSameParty-None"), - CookieWithName("nonSameParty-Lax"))); - EXPECT_THAT(service_wrapper()->GetExcludedCookieList(cookie_url, options), - IsEmpty()); + EXPECT_THAT( + service_wrapper()->GetExcludedCookieList(cookie_url, options), + UnorderedElementsAre(CookieAccessWithName("SameParty-Unspecified"), + CookieAccessWithName("SameParty-None"), + CookieAccessWithName("SameParty-Lax"), + CookieAccessWithName("nonSameParty-Unspecified"), + CookieAccessWithName("nonSameParty-Lax"))); + + // In a same-party, cross-site context, SameParty cookies should be + // included, and non-SameParty cookies should be excluded based on SameSite + // value. + options.set_same_party_cookie_context_type( + net::CookieOptions::SamePartyCookieContextType::kSameParty); + EXPECT_THAT(service_wrapper()->GetCookieList(cookie_url, options), + UnorderedElementsAre(CookieWithName("SameParty-Unspecified"), + CookieWithName("SameParty-None"), + CookieWithName("SameParty-Lax"), + CookieWithName("nonSameParty-None"))); + EXPECT_THAT( + service_wrapper()->GetExcludedCookieList(cookie_url, options), + UnorderedElementsAre(CookieAccessWithName("nonSameParty-Unspecified"), + CookieAccessWithName("nonSameParty-Lax"))); + + // In a same-party, same-site context, all cookies should be included. + options.set_same_site_cookie_context( + net::CookieOptions::SameSiteCookieContext::MakeInclusive()); + EXPECT_THAT(service_wrapper()->GetCookieList(cookie_url, options), + UnorderedElementsAre(CookieWithName("SameParty-Unspecified"), + CookieWithName("SameParty-None"), + CookieWithName("SameParty-Lax"), + CookieWithName("nonSameParty-Unspecified"), + CookieWithName("nonSameParty-None"), + CookieWithName("nonSameParty-Lax"))); + EXPECT_THAT(service_wrapper()->GetExcludedCookieList(cookie_url, options), + IsEmpty()); + } + + // Now verify that sites not in a First-Party Set ignore SameParty and fall + // back to SameSite semantics instead. + { + net::CookieOptions options; + options.set_return_excluded_cookies(); + // Default, but set for explicitness. + options.set_is_in_nontrivial_first_party_set(false); + ASSERT_EQ(net::CookieOptions::SamePartyCookieContextType::kCrossParty, + options.same_party_cookie_context_type()); + ASSERT_EQ( + net::CookieOptions::SameSiteCookieContext( + net::CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE), + options.same_site_cookie_context()); + + // Cross-party, cross-site. + EXPECT_THAT(service_wrapper()->GetCookieList(cookie_url, options), + UnorderedElementsAre(CookieWithName("SameParty-None"), + CookieWithName("nonSameParty-None"))); + + EXPECT_THAT( + service_wrapper()->GetExcludedCookieList(cookie_url, options), + UnorderedElementsAre(CookieAccessWithName("SameParty-Unspecified"), + CookieAccessWithName("SameParty-Lax"), + CookieAccessWithName("nonSameParty-Unspecified"), + CookieAccessWithName("nonSameParty-Lax"))); + + // Same-party, cross-site. + options.set_same_party_cookie_context_type( + net::CookieOptions::SamePartyCookieContextType::kSameParty); + EXPECT_THAT(service_wrapper()->GetCookieList(cookie_url, options), + UnorderedElementsAre(CookieWithName("SameParty-None"), + CookieWithName("nonSameParty-None"))); + EXPECT_THAT( + service_wrapper()->GetExcludedCookieList(cookie_url, options), + UnorderedElementsAre(CookieAccessWithName("SameParty-Unspecified"), + CookieAccessWithName("SameParty-Lax"), + CookieAccessWithName("nonSameParty-Unspecified"), + CookieAccessWithName("nonSameParty-Lax"))); + + // Same-party, same-site. + options.set_same_site_cookie_context( + net::CookieOptions::SameSiteCookieContext::MakeInclusive()); + EXPECT_THAT(service_wrapper()->GetCookieList(cookie_url, options), + UnorderedElementsAre(CookieWithName("SameParty-Unspecified"), + CookieWithName("SameParty-None"), + CookieWithName("SameParty-Lax"), + CookieWithName("nonSameParty-Unspecified"), + CookieWithName("nonSameParty-None"), + CookieWithName("nonSameParty-Lax"))); + EXPECT_THAT(service_wrapper()->GetExcludedCookieList(cookie_url, options), + IsEmpty()); + } } TEST_F(CookieManagerTest, GetCookieListAccessTime) {
diff --git a/services/network/public/cpp/cookie_manager_mojom_traits.cc b/services/network/public/cpp/cookie_manager_mojom_traits.cc index 9be0ce2..da81027 100644 --- a/services/network/public/cpp/cookie_manager_mojom_traits.cc +++ b/services/network/public/cpp/cookie_manager_mojom_traits.cc
@@ -382,6 +382,9 @@ cookie_options->set_full_party_context_size( mojo_options.full_party_context_size()); + cookie_options->set_is_in_nontrivial_first_party_set( + mojo_options.is_in_nontrivial_first_party_set()); + return true; }
diff --git a/services/network/public/cpp/cookie_manager_mojom_traits.h b/services/network/public/cpp/cookie_manager_mojom_traits.h index 0fbf44dd..d8cd73f 100644 --- a/services/network/public/cpp/cookie_manager_mojom_traits.h +++ b/services/network/public/cpp/cookie_manager_mojom_traits.h
@@ -129,6 +129,10 @@ return o.full_party_context_size(); } + static bool is_in_nontrivial_first_party_set(const net::CookieOptions& o) { + return o.is_in_nontrivial_first_party_set(); + } + static bool Read(network::mojom::CookieOptionsDataView mojo_options, net::CookieOptions* cookie_options); };
diff --git a/services/network/public/cpp/cookie_manager_mojom_traits_unittest.cc b/services/network/public/cpp/cookie_manager_mojom_traits_unittest.cc index fb0620106..6164206 100644 --- a/services/network/public/cpp/cookie_manager_mojom_traits_unittest.cc +++ b/services/network/public/cpp/cookie_manager_mojom_traits_unittest.cc
@@ -326,6 +326,8 @@ EXPECT_FALSE(least_trusted.return_excluded_cookies()); least_trusted.set_return_excluded_cookies(); // differ from default. least_trusted.set_full_party_context_size(10u); + least_trusted.set_is_in_nontrivial_first_party_set( + true); // differ from default. EXPECT_TRUE(mojo::test::SerializeAndDeserialize<mojom::CookieOptions>( least_trusted, copy)); @@ -338,6 +340,7 @@ EXPECT_EQ(net::CookieOptions::SamePartyCookieContextType::kCrossParty, copy.same_party_cookie_context_type()); EXPECT_EQ(10u, copy.full_party_context_size()); + EXPECT_TRUE(copy.is_in_nontrivial_first_party_set()); } { @@ -348,6 +351,7 @@ very_trusted.set_same_party_cookie_context_type( net::CookieOptions::SamePartyCookieContextType::kSameParty); very_trusted.set_full_party_context_size(1u); + very_trusted.set_is_in_nontrivial_first_party_set(true); EXPECT_TRUE(mojo::test::SerializeAndDeserialize<mojom::CookieOptions>( very_trusted, copy)); @@ -358,6 +362,7 @@ EXPECT_EQ(net::CookieOptions::SamePartyCookieContextType::kSameParty, copy.same_party_cookie_context_type()); EXPECT_EQ(1u, copy.full_party_context_size()); + EXPECT_TRUE(copy.is_in_nontrivial_first_party_set()); } }
diff --git a/services/network/public/mojom/cookie_manager.mojom b/services/network/public/mojom/cookie_manager.mojom index ceec3f6..c736353 100644 --- a/services/network/public/mojom/cookie_manager.mojom +++ b/services/network/public/mojom/cookie_manager.mojom
@@ -130,6 +130,8 @@ // The size of the isolation_info.party_context plus the top-frame site for // logging purposes. uint32 full_party_context_size = 0; + // Whether the site is a member of a nontrivial First-Party Set. + bool is_in_nontrivial_first_party_set = false; }; // See net/cookies/canonical_cookie.{h,cc} for documentation.
diff --git a/third_party/blink/public/common/BUILD.gn b/third_party/blink/public/common/BUILD.gn index 9edade2..1b409bc 100644 --- a/third_party/blink/public/common/BUILD.gn +++ b/third_party/blink/public/common/BUILD.gn
@@ -69,7 +69,6 @@ "client_hints/client_hints.h", "context_menu_data/edit_flags.h", "context_menu_data/input_field_type.h", - "css/color_scheme.h", "css/forced_colors.h", "css/navigation_controls.h", "css/page_orientation.h",
diff --git a/third_party/blink/public/common/css/color_scheme.h b/third_party/blink/public/common/css/color_scheme.h deleted file mode 100644 index 3ea04a9f..0000000 --- a/third_party/blink/public/common/css/color_scheme.h +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_CSS_COLOR_SCHEME_H_ -#define THIRD_PARTY_BLINK_PUBLIC_COMMON_CSS_COLOR_SCHEME_H_ - -namespace blink { - -// This is the color scheme for rendering web content. The color scheme affects -// the UA style sheet (setting the text color to white instead of black on the -// root element for kDark), the frame backdrop color (black instead of white for -// kDark), theming form controls and scrollbars, etc. -enum ColorScheme { - kLight = 1, - kDark = 2, -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_CSS_COLOR_SCHEME_H_
diff --git a/third_party/blink/public/common/frame/frame_owner_properties_mojom_traits.h b/third_party/blink/public/common/frame/frame_owner_properties_mojom_traits.h deleted file mode 100644 index 76907d7..0000000 --- a/third_party/blink/public/common/frame/frame_owner_properties_mojom_traits.h +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_FRAME_FRAME_OWNER_PROPERTIES_MOJOM_TRAITS_H_ -#define THIRD_PARTY_BLINK_PUBLIC_COMMON_FRAME_FRAME_OWNER_PROPERTIES_MOJOM_TRAITS_H_ - -#include "mojo/public/cpp/bindings/enum_traits.h" -#include "third_party/blink/public/common/common_export.h" -#include "third_party/blink/public/common/css/color_scheme.h" -#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-shared.h" - -namespace mojo { - -template <> -struct BLINK_COMMON_EXPORT - EnumTraits<blink::mojom::ColorScheme, ::blink::ColorScheme> { - static blink::mojom::ColorScheme ToMojom(::blink::ColorScheme color_scheme) { - switch (color_scheme) { - case ::blink::ColorScheme::kLight: - return blink::mojom::ColorScheme::kLight; - case ::blink::ColorScheme::kDark: - return blink::mojom::ColorScheme::kDark; - } - NOTREACHED(); - return blink::mojom::ColorScheme::kLight; - } - static bool FromMojom(blink::mojom::ColorScheme input, - ::blink::ColorScheme* out) { - switch (input) { - case blink::mojom::ColorScheme::kLight: - *out = ::blink::ColorScheme::kLight; - return true; - case blink::mojom::ColorScheme::kDark: - *out = ::blink::ColorScheme::kDark; - return true; - } - return false; - } -}; - -} // namespace mojo - -#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_FRAME_FRAME_OWNER_PROPERTIES_MOJOM_TRAITS_H_
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn index ea7cd9f..135ade3b 100644 --- a/third_party/blink/public/mojom/BUILD.gn +++ b/third_party/blink/public/mojom/BUILD.gn
@@ -212,6 +212,7 @@ public_deps = [ ":android_mojo_bindings", ":authenticator_test_mojo_bindings", + ":color_scheme_mojo_bindings", ":mojom_mhtml_load_result", ":script_type_mojo_bindings", ":web_feature_mojo_bindings", @@ -415,17 +416,6 @@ { types = [ { - mojom = "blink.mojom.ColorScheme" - cpp = "::blink::ColorScheme" - copyable_pass_by_value = true - }, - ] - traits_headers = [ "//third_party/blink/public/common/frame/frame_owner_properties_mojom_traits.h" ] - traits_public_deps = [ "//third_party/blink/public/common:headers" ] - }, - { - types = [ - { mojom = "blink.mojom.WebPreferences" cpp = "::blink::web_pref::WebPreferences" }, @@ -838,6 +828,7 @@ public_deps = [ ":android_mojo_bindings", + ":color_scheme_mojo_bindings", ":mojom_platform", ":script_type_mojo_bindings", ":web_feature_mojo_bindings", @@ -1309,6 +1300,23 @@ export_header_blink = "third_party/blink/renderer/platform/platform_export.h" } +mojom("color_scheme_mojo_bindings") { + generate_java = true + visibility_blink = [ + "//third_party/blink/public/mojom:mojom_core_blink", + "//third_party/blink/public/mojom:mojom_platform_blink", + "//third_party/blink/renderer/core:prerequisites", + "//third_party/blink/renderer/modules", + "//third_party/blink/renderer/platform", + ] + + sources = [ "frame/color_scheme.mojom" ] + + export_class_attribute = "BLINK_COMMON_EXPORT" + export_define = "BLINK_COMMON_IMPLEMENTATION=1" + export_header = "third_party/blink/public/common/common_export.h" +} + mojom("mobile_metrics") { sources = [ "mobile_metrics/mobile_friendliness.mojom" ] cpp_typemaps = [
diff --git a/third_party/blink/public/mojom/frame/color_scheme.mojom b/third_party/blink/public/mojom/frame/color_scheme.mojom new file mode 100644 index 0000000..d4f3f3c --- /dev/null +++ b/third_party/blink/public/mojom/frame/color_scheme.mojom
@@ -0,0 +1,10 @@ +// 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 blink.mojom; + +enum ColorScheme { + kLight, + kDark, +};
diff --git a/third_party/blink/public/mojom/frame/frame.mojom b/third_party/blink/public/mojom/frame/frame.mojom index 4d307db..dfc7ea9 100644 --- a/third_party/blink/public/mojom/frame/frame.mojom +++ b/third_party/blink/public/mojom/frame/frame.mojom
@@ -513,6 +513,14 @@ // doing so via console messages. AddInspectorIssue(InspectorIssueInfo info); + // Requests that a provisional frame swap itself into the frame tree, + // immediately replacing the RemoteFrame that it is associated with. Normally, + // this swap happens when the navigation commits in the provisional frame. + // However, if the RemoteFrame corresponds to a crashed (and non-live) frame, + // the browser will immediately call this method to stop showing the sad + // iframe without having to wait for the navigation to commit. + SwapInImmediately(); + // Sent to a frame when one of its remote children finishes loading, so that // the frame can update its loading state. CheckCompleted();
diff --git a/third_party/blink/public/mojom/frame/frame_owner_properties.mojom b/third_party/blink/public/mojom/frame/frame_owner_properties.mojom index aeb9f5ce..c6f9ef1d 100644 --- a/third_party/blink/public/mojom/frame/frame_owner_properties.mojom +++ b/third_party/blink/public/mojom/frame/frame_owner_properties.mojom
@@ -5,11 +5,7 @@ module blink.mojom; import "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom"; - -enum ColorScheme { - kLight, - kDark, -}; +import "third_party/blink/public/mojom/frame/color_scheme.mojom"; struct FrameOwnerProperties { // Browsing context container's name
diff --git a/third_party/blink/public/platform/mac/web_sandbox_support.h b/third_party/blink/public/platform/mac/web_sandbox_support.h index a91384b7..0dbe483 100644 --- a/third_party/blink/public/platform/mac/web_sandbox_support.h +++ b/third_party/blink/public/platform/mac/web_sandbox_support.h
@@ -32,8 +32,8 @@ #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MAC_WEB_SANDBOX_SUPPORT_H_ #include "base/mac/scoped_cftyperef.h" -#include "third_party/blink/public/common/css/color_scheme.h" #include "third_party/blink/public/common/sandbox_support/sandbox_support_mac.h" +#include "third_party/blink/public/mojom/frame/color_scheme.mojom-shared.h" #include "third_party/skia/include/core/SkColor.h" typedef struct CGFont* CGFontRef; @@ -57,7 +57,7 @@ uint32_t* font_id) = 0; // Returns the system's preferred value for a named color. - virtual SkColor GetSystemColor(MacSystemColorID, ColorScheme) = 0; + virtual SkColor GetSystemColor(MacSystemColorID, mojom::ColorScheme) = 0; }; } // namespace blink
diff --git a/third_party/blink/public/platform/web_theme_engine.h b/third_party/blink/public/platform/web_theme_engine.h index 97a07fd..8873bdf 100644 --- a/third_party/blink/public/platform/web_theme_engine.h +++ b/third_party/blink/public/platform/web_theme_engine.h
@@ -34,8 +34,8 @@ #include "base/optional.h" #include "base/time/time.h" #include "build/build_config.h" -#include "third_party/blink/public/common/css/color_scheme.h" #include "third_party/blink/public/common/css/forced_colors.h" +#include "third_party/blink/public/mojom/frame/color_scheme.mojom-shared.h" #include "third_party/blink/public/platform/web_scrollbar_overlay_color_theme.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/geometry/rect.h" @@ -189,7 +189,7 @@ struct ScrollbarExtraParams { bool is_hovering; bool is_overlay; - ColorScheme scrollbar_theme; + mojom::ColorScheme scrollbar_theme; ScrollbarOrientation orientation; }; #endif @@ -246,7 +246,7 @@ State, const gfx::Rect&, const ExtraParams*, - blink::ColorScheme) {} + blink::mojom::ColorScheme) {} virtual base::Optional<SkColor> GetSystemColor( SystemThemeColor system_theme) const {
diff --git a/third_party/blink/public/web/web_frame_owner_properties.h b/third_party/blink/public/web/web_frame_owner_properties.h index 150fdd6..bc8a70072 100644 --- a/third_party/blink/public/web/web_frame_owner_properties.h +++ b/third_party/blink/public/web/web_frame_owner_properties.h
@@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_FRAME_OWNER_PROPERTIES_H_ #define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_FRAME_OWNER_PROPERTIES_H_ -#include "third_party/blink/public/common/css/color_scheme.h" +#include "third_party/blink/public/mojom/frame/color_scheme.mojom-shared.h" #include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-shared.h" #include "third_party/blink/public/platform/web_string.h" @@ -19,7 +19,7 @@ bool allow_fullscreen{false}; bool allow_payment_request{false}; bool is_display_none{false}; - ColorScheme color_scheme{ColorScheme::kLight}; + mojom::ColorScheme color_scheme{mojom::ColorScheme::kLight}; WebString required_csp; public: @@ -33,7 +33,7 @@ bool allow_fullscreen, bool allow_payment_request, bool is_display_none, - ColorScheme color_scheme, + mojom::ColorScheme color_scheme, const WebString& required_csp) : name(name), scrollbar_mode(scrollbar_mode),
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h index 03bbdf9d..d20c4427 100644 --- a/third_party/blink/public/web/web_local_frame_client.h +++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -335,6 +335,16 @@ // datasource will become the provisional datasource for the frame. virtual void DidCreateDocumentLoader(WebDocumentLoader*) {} + // A navigation is about to commit in a new frame that is still provisional + // (i.e. not swapped into the frame tree). Implementations should perform any + // bookkeeping work to sync the state of the previous frame and the new frame + // and use `WebFrame::Swap()` to swap in the new frame. + // + // The return value should be the return value of `WebFrame::Swap()`, which + // returns false if the navigation should not proceed due to the frame being + // removed from the frame tree by JS while swapping it in, or true otherwise. + virtual bool SwapIn(WebFrame* previous_frame) { return false; } + // The navigation has been committed, as a result of // WebNavigationControl::CommitNavigation call. The newly created document // is committed to the frame, the encoding of the response body is known,
diff --git a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.h b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.h index f23c503..27f175f3 100644 --- a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.h +++ b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.h
@@ -71,6 +71,7 @@ v8::Context::AbortScriptExecutionCallback callback); private: + // LocalWindowProxy overrides: bool IsLocal() const override { return true; } void Initialize() override; void DisposeContext(Lifecycle next_status, FrameReuseStatus) override;
diff --git a/third_party/blink/renderer/bindings/core/v8/remote_window_proxy.h b/third_party/blink/renderer/bindings/core/v8/remote_window_proxy.h index 0841c42..a8b9818 100644 --- a/third_party/blink/renderer/bindings/core/v8/remote_window_proxy.h +++ b/third_party/blink/renderer/bindings/core/v8/remote_window_proxy.h
@@ -48,6 +48,9 @@ RemoteWindowProxy(v8::Isolate*, RemoteFrame&, scoped_refptr<DOMWrapperWorld>); private: + friend class WindowProxyManager; + + // WindowProxy overrides: void Initialize() override; void DisposeContext(Lifecycle next_status, FrameReuseStatus) override; @@ -62,6 +65,11 @@ void SetupWindowPrototypeChain(); }; +template <> +struct DowncastTraits<RemoteWindowProxy> { + static bool AllowFrom(const WindowProxy& proxy) { return !proxy.IsLocal(); } +}; + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_REMOTE_WINDOW_PROXY_H_
diff --git a/third_party/blink/renderer/bindings/core/v8/window_proxy.cc b/third_party/blink/renderer/bindings/core/v8/window_proxy.cc index 32e5a75..8e590ff 100644 --- a/third_party/blink/renderer/bindings/core/v8/window_proxy.cc +++ b/third_party/blink/renderer/bindings/core/v8/window_proxy.cc
@@ -95,9 +95,9 @@ lifecycle_ == Lifecycle::kGlobalObjectIsDetached); // Make sure the global object was detached from the proxy by calling - // clearForNavigation(). + // ClearForSwap(). DLOG_IF(FATAL, is_global_object_attached_) - << "Context not detached by calling clearForNavigation()"; + << "Context not detached by calling ClearForSwap()"; v8::Local<v8::Object> global_proxy = global_proxy_.NewLocal(isolate_); global_proxy_.Clear(); @@ -109,6 +109,10 @@ CHECK(global_proxy_.IsEmpty()); global_proxy_.Set(isolate_, global_proxy); + // The global proxy was transferred from a previous WindowProxy, so the state + // should be detached, not uninitialized. This ensures that it will be + // properly reinitialized when needed, e.g. by `UpdateDocument()`. + lifecycle_ = Lifecycle::kGlobalObjectIsDetached; } // Create a new environment and setup the global object.
diff --git a/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc b/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc index 1032a80..373a0ef6c 100644 --- a/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc +++ b/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc
@@ -4,8 +4,12 @@ #include "third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h" +#include "third_party/blink/renderer/bindings/core/v8/local_window_proxy.h" +#include "third_party/blink/renderer/bindings/core/v8/remote_window_proxy.h" +#include "third_party/blink/renderer/core/frame/remote_frame.h" #include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h" #include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace blink { @@ -58,14 +62,22 @@ for (const auto& entry : global_proxies) WindowProxyMaybeUninitialized(*entry.first)->SetGlobalProxy(entry.second); - // Initialize the window proxies now, to re-establish the connection between - // the global object and the v8::Context. This is really only needed for a - // RemoteDOMWindow, since it has no scripting environment of its own. - // Without this, existing script references to a swapped in RemoteDOMWindow - // would be broken until that RemoteDOMWindow was vended again through an - // interface like window.frames. - for (const auto& entry : global_proxies) - WindowProxyMaybeUninitialized(*entry.first)->InitializeIfNeeded(); + // Any transferred global proxies must now be reinitialized to ensure any + // preexisting JS references to global proxies don't break. + + // For local frames, the global proxies cannot be reinitialized yet. Blink is + // in the midst of committing a navigation and swapping in the new frame. + // Instead, the global proxies will be reinitialized after this via a call to + // `UpdateDocument()` when the new `Document` is installed: this will happen + // before committing the navigation completes and yields back to the event + // loop. + if (frame_type_ == FrameType::kLocal) + return; + + for (const auto& entry : global_proxies) { + To<RemoteWindowProxy>(WindowProxyMaybeUninitialized(*entry.first)) + ->Initialize(); + } } void WindowProxyManager::ResetIsolatedWorldsForTesting() { @@ -125,20 +137,17 @@ MainWorldProxyMaybeUninitialized()->UpdateDocument(); for (auto& entry : isolated_worlds_) { - auto* isolated_window_proxy = - static_cast<LocalWindowProxy*>(entry.value.Get()); - isolated_window_proxy->UpdateDocument(); + To<LocalWindowProxy>(entry.value.Get())->UpdateDocument(); } } void LocalWindowProxyManager::UpdateSecurityOrigin( const SecurityOrigin* security_origin) { - static_cast<LocalWindowProxy*>(window_proxy_.Get()) + To<LocalWindowProxy>(window_proxy_.Get()) ->UpdateSecurityOrigin(security_origin); for (auto& entry : isolated_worlds_) { - auto* isolated_window_proxy = - static_cast<LocalWindowProxy*>(entry.value.Get()); + auto* isolated_window_proxy = To<LocalWindowProxy>(entry.value.Get()); scoped_refptr<SecurityOrigin> isolated_security_origin = isolated_window_proxy->World().IsolatedWorldSecurityOrigin( security_origin->AgentClusterId()); @@ -154,9 +163,7 @@ ->SetAbortScriptExecution(callback); for (auto& entry : isolated_worlds_) { - auto* isolated_window_proxy = - static_cast<LocalWindowProxy*>(entry.value.Get()); - isolated_window_proxy->SetAbortScriptExecution(callback); + To<LocalWindowProxy>(entry.value.Get())->SetAbortScriptExecution(callback); } }
diff --git a/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h b/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h index 53e1fd7..eb810cf9b 100644 --- a/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h +++ b/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h
@@ -31,9 +31,10 @@ void ClearForSwap(); void ClearForV8MemoryPurge(); - // Global proxies are passed in a vector to maintain their order: global proxy - // object for the main world is always first. This is needed to prevent bugs - // like https://crbug.com/700077 . + // Helpers used to transfer global proxies from the previous frame to the new + // frame when swapping frames. Global proxies are passed in a vector to ensure + // the main world is always processed first. This is needed to prevent bugs + // like https://crbug.com/700077. using GlobalProxyVector = Vector<std::pair<DOMWrapperWorld*, v8::Local<v8::Object>>>; void CORE_EXPORT ReleaseGlobalProxies(GlobalProxyVector&);
diff --git a/third_party/blink/renderer/controller/performance_manager/renderer_resource_coordinator_impl_test.cc b/third_party/blink/renderer/controller/performance_manager/renderer_resource_coordinator_impl_test.cc index 4d5ec06..92185a64 100644 --- a/third_party/blink/renderer/controller/performance_manager/renderer_resource_coordinator_impl_test.cc +++ b/third_party/blink/renderer/controller/performance_manager/renderer_resource_coordinator_impl_test.cc
@@ -209,7 +209,8 @@ ¤t_v8_context_token), iframe_attribution_matcher)); } - main_frame->FirstChild()->Swap(local_frame); + // Committing a navigation in the provisional frame swaps it in. + frame_test_helpers::LoadFrame(local_frame, "data:text/html,"); mock_process_coordination_unit_->VerifyExpectations(); // Local -> Local @@ -224,7 +225,8 @@ ¤t_v8_context_token), iframe_attribution_matcher)); } - main_frame->FirstChild()->Swap(new_local_frame); + // Committing a navigation in the provisional frame swaps it in. + frame_test_helpers::LoadFrame(new_local_frame, "data:text/html,"); mock_process_coordination_unit_->VerifyExpectations(); // Local -> Remote
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn index 4310ee3..b9e8f4e2d73 100644 --- a/third_party/blink/renderer/core/BUILD.gn +++ b/third_party/blink/renderer/core/BUILD.gn
@@ -125,6 +125,7 @@ "//services/service_manager/public/cpp", "//skia", "//third_party/angle:translator", + "//third_party/blink/public/mojom:color_scheme_mojo_bindings", "//third_party/blink/public/mojom:mojom_broadcastchannel_bindings_blink", "//third_party/blink/renderer/bindings/core/v8:bindings_core_v8_generated", "//third_party/blink/renderer/bindings/core/v8:generated",
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5 index 1e4dca11..f57b9b0 100644 --- a/third_party/blink/renderer/core/css/css_properties.json5 +++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -1898,7 +1898,7 @@ property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "InitialValue"], style_builder_custom_functions: ["initial", "inherit", "value"], inherited: true, - include_paths: ["third_party/blink/public/common/css/color_scheme.h"], + include_paths: ["third_party/blink/public/mojom/frame/color_scheme.mojom-blink.h"], type_name: "Vector<AtomicString>", default_value: "Vector<AtomicString, 0>()", field_template: "external",
diff --git a/third_party/blink/renderer/core/css/parser/css_parser.cc b/third_party/blink/renderer/core/css/parser/css_parser.cc index 8ac3af1..24e43759 100644 --- a/third_party/blink/renderer/core/css/parser/css_parser.cc +++ b/third_party/blink/renderer/core/css/parser/css_parser.cc
@@ -280,7 +280,7 @@ bool CSSParser::ParseSystemColor(Color& color, const String& color_string, - ColorScheme color_scheme) { + mojom::blink::ColorScheme color_scheme) { CSSValueID id = CssValueKeywordID(color_string); if (!StyleColor::IsSystemColor(id)) return false;
diff --git a/third_party/blink/renderer/core/css/parser/css_parser.h b/third_party/blink/renderer/core/css/parser/css_parser.h index 99a926f..9277f458 100644 --- a/third_party/blink/renderer/core/css/parser/css_parser.h +++ b/third_party/blink/renderer/core/css/parser/css_parser.h
@@ -6,7 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_PARSER_H_ #include <memory> -#include "third_party/blink/public/common/css/color_scheme.h" +#include "third_party/blink/public/mojom/frame/color_scheme.mojom-blink-forward.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/core/css/css_property_value_set.h" @@ -103,7 +103,9 @@ // The color will only be changed when string contains a valid CSS color, so // callers can set it to a default color and ignore the boolean result. static bool ParseColor(Color&, const String&, bool strict = false); - static bool ParseSystemColor(Color&, const String&, ColorScheme color_scheme); + static bool ParseSystemColor(Color&, + const String&, + mojom::blink::ColorScheme color_scheme); static void ParseSheetForInspector(const CSSParserContext*, StyleSheetContents*,
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc index 8aa2d4db..6e41b3b 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc +++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -1928,8 +1928,9 @@ if (value_id == CSSValueID::kCurrentcolor) return value; if (StyleColor::IsColorKeyword(value_id)) { - ColorScheme scheme = - state ? state->Style()->UsedColorScheme() : ColorScheme::kLight; + mojom::blink::ColorScheme scheme = + state ? state->Style()->UsedColorScheme() + : mojom::blink::ColorScheme::kLight; Color color = document.GetTextLinkColors().ColorFromCSSValue( value, Color(), scheme, false); return *cssvalue::CSSColorValue::Create(color.Rgb());
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc b/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc index 4023f26..6be1002 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc
@@ -215,7 +215,7 @@ if (const auto* pair = DynamicTo<CSSLightDarkValuePair>(value)) { if (!property.IsInherited()) Style()->SetHasNonInheritedLightDarkValue(); - if (Style()->UsedColorScheme() == ColorScheme::kLight) + if (Style()->UsedColorScheme() == mojom::blink::ColorScheme::kLight) return pair->First(); return pair->Second(); }
diff --git a/third_party/blink/renderer/core/css/style_color.cc b/third_party/blink/renderer/core/css/style_color.cc index b62e67c..0a9dab2 100644 --- a/third_party/blink/renderer/core/css/style_color.cc +++ b/third_party/blink/renderer/core/css/style_color.cc
@@ -10,7 +10,7 @@ namespace blink { Color StyleColor::Resolve(Color current_color, - ColorScheme color_scheme, + mojom::blink::ColorScheme color_scheme, bool is_forced_color) const { if (IsCurrentColor()) return current_color; @@ -21,7 +21,7 @@ } Color StyleColor::ResolveWithAlpha(Color current_color, - ColorScheme color_scheme, + mojom::blink::ColorScheme color_scheme, int alpha, bool is_forced_color) const { Color color = Resolve(current_color, color_scheme, is_forced_color); @@ -29,7 +29,7 @@ } Color StyleColor::ColorFromKeyword(CSSValueID keyword, - ColorScheme color_scheme) { + mojom::blink::ColorScheme color_scheme) { if (const char* value_name = getValueName(keyword)) { if (const NamedColor* named_color = FindColor(value_name, static_cast<wtf_size_t>(strlen(value_name))))
diff --git a/third_party/blink/renderer/core/css/style_color.h b/third_party/blink/renderer/core/css/style_color.h index 8a0b6ca..4cab8f2 100644 --- a/third_party/blink/renderer/core/css/style_color.h +++ b/third_party/blink/renderer/core/css/style_color.h
@@ -31,7 +31,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_COLOR_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_COLOR_H_ -#include "third_party/blink/public/common/css/color_scheme.h" +#include "third_party/blink/public/mojom/frame/color_scheme.mojom-blink-forward.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/css_value_keywords.h" #include "third_party/blink/renderer/platform/graphics/color.h" @@ -74,7 +74,7 @@ // TODO(1081945): Once CSSSystemColorComputeToSelf is enabled, we can remove // |is_forced_color|. Color Resolve(Color current_color, - ColorScheme color_scheme, + mojom::blink::ColorScheme color_scheme, bool is_forced_color = false) const; // Resolve and override the resolved color's alpha channel as specified by @@ -82,7 +82,7 @@ // TODO(1081945): Once CSSSystemColorComputeToSelf is enabled, we can remove // |is_forced_color|. Color ResolveWithAlpha(Color current_color, - ColorScheme color_scheme, + mojom::blink::ColorScheme color_scheme, int alpha, bool is_forced_color = false) const; @@ -90,7 +90,8 @@ return EffectiveColorKeyword() == CSSValueID::kInvalid; } - static Color ColorFromKeyword(CSSValueID, ColorScheme color_scheme); + static Color ColorFromKeyword(CSSValueID, + mojom::blink::ColorScheme color_scheme); static bool IsColorKeyword(CSSValueID); static bool IsSystemColor(CSSValueID);
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index 0e6b81b..7ec6c361 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -29,6 +29,7 @@ #include "third_party/blink/renderer/core/css/style_engine.h" +#include "third_party/blink/public/mojom/frame/color_scheme.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_theme_engine.h" #include "third_party/blink/renderer/core/css/counter_style_map.h" @@ -111,7 +112,8 @@ : document_(&document), is_html_import_(document.IsHTMLImport()), document_style_sheet_collection_( - MakeGarbageCollected<DocumentStyleSheetCollection>(document)) { + MakeGarbageCollected<DocumentStyleSheetCollection>(document)), + owner_color_scheme_(mojom::blink::ColorScheme::kLight) { if (document.GetFrame()) { // We don't need to create CSSFontSelector for imported document or // HTMLTemplateElement's document, because those documents have no frame. @@ -2272,18 +2274,20 @@ // view's base background color in order to match the root element color- // scheme. See spec: // https://drafts.csswg.org/css-color-adjust/#color-scheme-effect - ColorScheme root_color_scheme = ColorScheme::kLight; + mojom::blink::ColorScheme root_color_scheme = + mojom::blink::ColorScheme::kLight; if (auto* root_element = GetDocument().documentElement()) { if (const ComputedStyle* style = root_element->GetComputedStyle()) root_color_scheme = style->UsedColorSchemeForInitialColors(); else if (SupportsDarkColorScheme()) - root_color_scheme = ColorScheme::kDark; + root_color_scheme = mojom::blink::ColorScheme::kDark; } - color_scheme_background_ = root_color_scheme == ColorScheme::kLight - ? Color::kWhite - : Color(0x12, 0x12, 0x12); + color_scheme_background_ = + root_color_scheme == mojom::blink::ColorScheme::kLight + ? Color::kWhite + : Color(0x12, 0x12, 0x12); if (GetDocument().IsInMainFrame()) { - if (root_color_scheme == ColorScheme::kDark) { + if (root_color_scheme == mojom::blink::ColorScheme::kDark) { use_color_adjust_background = LocalFrameView::UseColorAdjustBackground::kIfBaseNotTransparent; } @@ -2300,7 +2304,7 @@ color_scheme_changed); } -void StyleEngine::SetOwnerColorScheme(ColorScheme color_scheme) { +void StyleEngine::SetOwnerColorScheme(mojom::blink::ColorScheme color_scheme) { DCHECK(!GetDocument().IsInMainFrame()); if (owner_color_scheme_ == color_scheme) return; @@ -2310,7 +2314,7 @@ void StyleEngine::UpdateForcedBackgroundColor() { forced_background_color_ = LayoutTheme::GetTheme().SystemColor( - CSSValueID::kCanvas, ColorScheme::kLight); + CSSValueID::kCanvas, mojom::blink::ColorScheme::kLight); } Color StyleEngine::ColorAdjustBackgroundColor() const {
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h index 647ec315..5cf889c 100644 --- a/third_party/blink/renderer/core/css/style_engine.h +++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -159,8 +159,10 @@ void WatchedSelectorsChanged(); void InitialStyleChanged(); void ColorSchemeChanged(); - void SetOwnerColorScheme(ColorScheme); - ColorScheme GetOwnerColorScheme() const { return owner_color_scheme_; } + void SetOwnerColorScheme(mojom::blink::ColorScheme); + mojom::blink::ColorScheme GetOwnerColorScheme() const { + return owner_color_scheme_; + } void InitialViewportChanged(); void ViewportRulesChanged(); void HtmlImportAddedOrRemoved(); @@ -666,7 +668,7 @@ // embedding document. If the color-scheme of the owner element and the root // element in the embedded document differ, use a solid backdrop color instead // of the default transparency of an iframe. - ColorScheme owner_color_scheme_{ColorScheme::kLight}; + mojom::blink::ColorScheme owner_color_scheme_; // The color of the canvas backdrop for the used color-scheme. Color color_scheme_background_;
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc index aac42901..896b68a2 100644 --- a/third_party/blink/renderer/core/css/style_engine_test.cc +++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -2402,7 +2402,7 @@ color_scheme_helper.SetForcedColors(GetDocument(), ForcedColors::kActive); UpdateAllLifecyclePhases(); Color system_background_color = LayoutTheme::GetTheme().SystemColor( - CSSValueID::kCanvas, ColorScheme::kLight); + CSSValueID::kCanvas, mojom::blink::ColorScheme::kLight); EXPECT_EQ(system_background_color, GetDocument().View()->BaseBackgroundColor()); @@ -2420,7 +2420,7 @@ UpdateAllLifecyclePhases(); EXPECT_EQ( - ColorScheme::kLight, + mojom::blink::ColorScheme::kLight, GetDocument().documentElement()->GetComputedStyle()->UsedColorScheme()); GetDocument().GetPage()->SetMediaFeatureOverride("prefers-color-scheme", @@ -2428,7 +2428,7 @@ UpdateAllLifecyclePhases(); EXPECT_EQ( - ColorScheme::kDark, + mojom::blink::ColorScheme::kDark, GetDocument().documentElement()->GetComputedStyle()->UsedColorScheme()); } @@ -2984,7 +2984,7 @@ EXPECT_EQ(Color::kWhite, root->GetComputedStyle()->VisitedDependentColor( GetCSSPropertyColor())); - EXPECT_EQ(ColorScheme::kDark, + EXPECT_EQ(mojom::blink::ColorScheme::kDark, root->GetComputedStyle()->UsedColorSchemeForInitialColors()); EXPECT_EQ(MakeRGB(255, 0, 0), body->GetComputedStyle()->VisitedDependentColor( GetCSSPropertyColor())); @@ -2993,7 +2993,7 @@ GetDocument().GetFrame()->StartPrinting(page_size, page_size, 1); EXPECT_EQ(Color::kBlack, root->GetComputedStyle()->VisitedDependentColor( GetCSSPropertyColor())); - EXPECT_EQ(ColorScheme::kLight, + EXPECT_EQ(mojom::blink::ColorScheme::kLight, root->GetComputedStyle()->UsedColorSchemeForInitialColors()); EXPECT_EQ(MakeRGB(0, 128, 0), body->GetComputedStyle()->VisitedDependentColor( GetCSSPropertyColor())); @@ -3001,7 +3001,7 @@ GetDocument().GetFrame()->EndPrinting(); EXPECT_EQ(Color::kWhite, root->GetComputedStyle()->VisitedDependentColor( GetCSSPropertyColor())); - EXPECT_EQ(ColorScheme::kDark, + EXPECT_EQ(mojom::blink::ColorScheme::kDark, root->GetComputedStyle()->UsedColorSchemeForInitialColors()); EXPECT_EQ(MakeRGB(255, 0, 0), body->GetComputedStyle()->VisitedDependentColor( GetCSSPropertyColor())); @@ -3492,14 +3492,14 @@ To<HTMLIFrameElement>(GetDocument().getElementById("frame")); auto* frame_document = frame_element->contentDocument(); ASSERT_TRUE(frame_document); - EXPECT_EQ(ColorScheme::kDark, + EXPECT_EQ(mojom::blink::ColorScheme::kDark, frame_document->GetStyleEngine().GetOwnerColorScheme()); frame_element->SetInlineStyleProperty(CSSPropertyID::kColorScheme, "light"); test::RunPendingTasks(); Compositor().BeginFrame(); - EXPECT_EQ(ColorScheme::kLight, + EXPECT_EQ(mojom::blink::ColorScheme::kLight, frame_document->GetStyleEngine().GetOwnerColorScheme()); }
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index bb5f422..3640d73 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -4034,6 +4034,9 @@ parser_->StopParsing(); if (load_event_progress_ == kLoadEventNotRun || + // TODO(dcheng): We should consider if we can make this conditional check + // stronger with a DCHECK() that this isn't called if the unload event is + // already complete. load_event_progress_ > kUnloadEventInProgress) { return; } @@ -5703,7 +5706,7 @@ int margin_height, mojom::blink::ScrollbarMode scrollbar_mode, bool is_display_none, - ColorScheme color_scheme) { + mojom::blink::ColorScheme color_scheme) { DCHECK(GetFrame() && GetFrame()->Owner()); FrameOwner* owner = GetFrame()->Owner();
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index b9afdd1..8e818cd 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h
@@ -42,6 +42,7 @@ #include "third_party/blink/public/common/metrics/document_update_reason.h" #include "third_party/blink/public/mojom/feature_policy/document_policy_feature.mojom-blink-forward.h" #include "third_party/blink/public/mojom/federated_learning/floc.mojom-blink-forward.h" +#include "third_party/blink/public/mojom/frame/color_scheme.mojom-blink-forward.h" #include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h" #include "third_party/blink/public/mojom/permissions/permission.mojom-blink-forward.h" #include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink-forward.h" @@ -992,7 +993,7 @@ int margin_height, mojom::blink::ScrollbarMode, bool is_display_none, - ColorScheme color_scheme); + mojom::blink::ColorScheme color_scheme); String title() const { return title_; } void setTitle(const String&);
diff --git a/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc b/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc index 4a388fa..81ae8f6 100644 --- a/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc +++ b/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc
@@ -182,12 +182,17 @@ return nullptr; } else if (first_letter_text_layout_object->IsInline() && !first_letter_text_layout_object->SlowFirstChild()) { - LayoutObject* next_sibling = - first_letter_text_layout_object->NextSibling(); - first_letter_text_layout_object = - next_sibling - ? next_sibling - : first_letter_text_layout_object->Parent()->NextSibling(); + if (LayoutObject* next_sibling = + first_letter_text_layout_object->NextSibling()) { + first_letter_text_layout_object = next_sibling; + continue; + } + LayoutObject* parent = first_letter_text_layout_object->Parent(); + if (parent && parent != parent_layout_object) { + first_letter_text_layout_object = parent->NextSibling(); + continue; + } + return nullptr; } else { first_letter_text_layout_object = first_letter_text_layout_object->SlowFirstChild();
diff --git a/third_party/blink/renderer/core/dom/first_letter_pseudo_element_test.cc b/third_party/blink/renderer/core/dom/first_letter_pseudo_element_test.cc index 3090df5..1d380f4 100644 --- a/third_party/blink/renderer/core/dom/first_letter_pseudo_element_test.cc +++ b/third_party/blink/renderer/core/dom/first_letter_pseudo_element_test.cc
@@ -4,17 +4,32 @@ #include "third_party/blink/renderer/core/dom/first_letter_pseudo_element.h" -#include <gtest/gtest.h> +#include "third_party/blink/renderer/core/testing/page_test_base.h" namespace blink { -class FirstLetterPseudoElementTest : public testing::Test {}; +class FirstLetterPseudoElementTest : public PageTestBase {}; TEST_F(FirstLetterPseudoElementTest, DoesNotBreakEmoji) { const UChar emoji[] = {0xD83D, 0xDE31, 0}; EXPECT_EQ(2u, FirstLetterPseudoElement::FirstLetterLength(emoji)); } +// http://crbug.com/1161370 +TEST_F(FirstLetterPseudoElementTest, EmptySpanOnly) { + InsertStyleElement("p::first-letter { color: red; }"); + SetBodyContent("<div><p id=sample><b></b></p>abc</div>"); + Element& sample = *GetElementById("sample"); + // Call Element::RebuildFirstLetterLayoutTree() + sample.setAttribute(html_names::kContenteditableAttr, "true"); + const PseudoElement* const first_letter = + sample.GetPseudoElement(kPseudoIdFirstLetter); + // We should not have ::first-letter pseudo element because <p> has no text. + // See |FirstLetterPseudoElement::FirstLetterTextLayoutObject()| should + // return nullptr during rebuilding layout tree. + EXPECT_FALSE(first_letter); +} + TEST_F(FirstLetterPseudoElementTest, UnicodePairBreaking) { const UChar test_string[] = {0xD800, 0xDD00, 'A', 0xD800, 0xDD00, 0xD800, 0xDD00, 'B', 0};
diff --git a/third_party/blink/renderer/core/dom/text_link_colors.cc b/third_party/blink/renderer/core/dom/text_link_colors.cc index aa3bf1ac..2cb600b 100644 --- a/third_party/blink/renderer/core/dom/text_link_colors.cc +++ b/third_party/blink/renderer/core/dom/text_link_colors.cc
@@ -29,6 +29,7 @@ #include "third_party/blink/renderer/core/dom/text_link_colors.h" +#include "third_party/blink/public/mojom/frame/color_scheme.mojom-blink.h" #include "third_party/blink/renderer/core/css/css_color_value.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" #include "third_party/blink/renderer/core/css/css_light_dark_value_pair.h" @@ -60,11 +61,16 @@ has_custom_text_color_ = true; } -Color TextLinkColors::TextColor(ColorScheme color_scheme) const { +Color TextLinkColors::TextColor() const { + return TextColor(mojom::blink::ColorScheme::kLight); +} + +Color TextLinkColors::TextColor(mojom::blink::ColorScheme color_scheme) const { return has_custom_text_color_ ? text_color_ - : color_scheme == ColorScheme::kLight ? Color::kBlack - : Color::kWhite; + : color_scheme == mojom::blink::ColorScheme::kLight + ? Color::kBlack + : Color::kWhite; } void TextLinkColors::SetLinkColor(const Color& color) { @@ -72,11 +78,17 @@ has_custom_link_color_ = true; } -const Color& TextLinkColors::LinkColor(ColorScheme color_scheme) const { +const Color& TextLinkColors::LinkColor() const { + return LinkColor(mojom::blink::ColorScheme::kLight); +} + +const Color& TextLinkColors::LinkColor( + mojom::blink::ColorScheme color_scheme) const { return has_custom_link_color_ ? link_color_ - : color_scheme == ColorScheme::kLight ? kDefaultLinkColorLight - : kDefaultLinkColorDark; + : color_scheme == mojom::blink::ColorScheme::kLight + ? kDefaultLinkColorLight + : kDefaultLinkColorDark; } void TextLinkColors::SetVisitedLinkColor(const Color& color) { @@ -84,11 +96,17 @@ has_custom_visited_link_color_ = true; } -const Color& TextLinkColors::VisitedLinkColor(ColorScheme color_scheme) const { - return has_custom_visited_link_color_ ? visited_link_color_ - : color_scheme == ColorScheme::kLight - ? kDefaultVisitedLinkColorLight - : kDefaultVisitedLinkColorDark; +const Color& TextLinkColors::VisitedLinkColor() const { + return VisitedLinkColor(mojom::blink::ColorScheme::kLight); +} + +const Color& TextLinkColors::VisitedLinkColor( + mojom::blink::ColorScheme color_scheme) const { + return has_custom_visited_link_color_ + ? visited_link_color_ + : color_scheme == mojom::blink::ColorScheme::kLight + ? kDefaultVisitedLinkColorLight + : kDefaultVisitedLinkColorDark; } void TextLinkColors::SetActiveLinkColor(const Color& color) { @@ -96,23 +114,30 @@ has_custom_active_link_color_ = true; } -const Color& TextLinkColors::ActiveLinkColor(ColorScheme color_scheme) const { - return has_custom_active_link_color_ ? active_link_color_ - : color_scheme == ColorScheme::kLight - ? kDefaultActiveLinkColorLight - : kDefaultActiveLinkColorDark; +const Color& TextLinkColors::ActiveLinkColor() const { + return ActiveLinkColor(mojom::blink::ColorScheme::kLight); +} + +const Color& TextLinkColors::ActiveLinkColor( + mojom::blink::ColorScheme color_scheme) const { + return has_custom_active_link_color_ + ? active_link_color_ + : color_scheme == mojom::blink::ColorScheme::kLight + ? kDefaultActiveLinkColorLight + : kDefaultActiveLinkColorDark; } Color TextLinkColors::ColorFromCSSValue(const CSSValue& value, Color current_color, - ColorScheme color_scheme, + mojom::blink::ColorScheme color_scheme, bool for_visited_link) const { if (auto* color_value = DynamicTo<cssvalue::CSSColorValue>(value)) return color_value->Value(); if (auto* pair = DynamicTo<CSSLightDarkValuePair>(value)) { const CSSValue& color_value = - color_scheme == ColorScheme::kLight ? pair->First() : pair->Second(); + color_scheme == mojom::blink::ColorScheme::kLight ? pair->First() + : pair->Second(); return ColorFromCSSValue(color_value, current_color, color_scheme, for_visited_link); }
diff --git a/third_party/blink/renderer/core/dom/text_link_colors.h b/third_party/blink/renderer/core/dom/text_link_colors.h index 14efed8a..055ae99 100644 --- a/third_party/blink/renderer/core/dom/text_link_colors.h +++ b/third_party/blink/renderer/core/dom/text_link_colors.h
@@ -30,7 +30,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_TEXT_LINK_COLORS_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_TEXT_LINK_COLORS_H_ -#include "third_party/blink/public/common/css/color_scheme.h" +#include "third_party/blink/public/mojom/frame/color_scheme.mojom-blink-forward.h" #include "third_party/blink/renderer/platform/graphics/color.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" @@ -47,13 +47,15 @@ TextLinkColors& operator=(const TextLinkColors&) = delete; void SetTextColor(const Color& color); - Color TextColor(ColorScheme color_scheme = ColorScheme::kLight) const; + Color TextColor() const; + Color TextColor(mojom::blink::ColorScheme color_scheme) const; - const Color& LinkColor(ColorScheme color_scheme = ColorScheme::kLight) const; - const Color& VisitedLinkColor( - ColorScheme color_scheme = ColorScheme::kLight) const; - const Color& ActiveLinkColor( - ColorScheme color_scheme = ColorScheme::kLight) const; + const Color& LinkColor() const; + const Color& LinkColor(mojom::blink::ColorScheme color_scheme) const; + const Color& VisitedLinkColor() const; + const Color& VisitedLinkColor(mojom::blink::ColorScheme color_scheme) const; + const Color& ActiveLinkColor() const; + const Color& ActiveLinkColor(mojom::blink::ColorScheme color_scheme) const; void SetLinkColor(const Color& color); void SetVisitedLinkColor(const Color& color); void SetActiveLinkColor(const Color& color); @@ -62,7 +64,7 @@ void ResetActiveLinkColor() { has_custom_active_link_color_ = false; } Color ColorFromCSSValue(const CSSValue&, Color current_color, - ColorScheme color_scheme, + mojom::blink::ColorScheme color_scheme, bool for_visited_link = false) const; private:
diff --git a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc index 1110c224..eb962ab2 100644 --- a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc +++ b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
@@ -356,7 +356,8 @@ bool in_forced_colors_mode = popup_client_->OwnerElement().GetDocument().InForcedColorsMode(); page_->GetSettings().SetPreferredColorScheme( - style->UsedColorScheme() == ColorScheme::kDark && !in_forced_colors_mode + style->UsedColorScheme() == mojom::blink::ColorScheme::kDark && + !in_forced_colors_mode ? mojom::blink::PreferredColorScheme::kDark : mojom::blink::PreferredColorScheme::kLight); }
diff --git a/third_party/blink/renderer/core/exported/web_view_test.cc b/third_party/blink/renderer/core/exported/web_view_test.cc index 64589ed..a7c7f66 100644 --- a/third_party/blink/renderer/core/exported/web_view_test.cc +++ b/third_party/blink/renderer/core/exported/web_view_test.cc
@@ -593,7 +593,7 @@ UpdateAllLifecyclePhases(); Color system_background_color = LayoutTheme::GetTheme().SystemColor( - CSSValueID::kCanvas, ColorScheme::kLight); + CSSValueID::kCanvas, mojom::blink::ColorScheme::kLight); EXPECT_EQ(system_background_color, frame_view->BaseBackgroundColor()); color_scheme_helper.SetForcedColors(*(web_view->GetPage()),
diff --git a/third_party/blink/renderer/core/frame/frame.cc b/third_party/blink/renderer/core/frame/frame.cc index 0d5d1bf..9305b576 100644 --- a/third_party/blink/renderer/core/frame/frame.cc +++ b/third_party/blink/renderer/core/frame/frame.cc
@@ -542,11 +542,10 @@ } bool Frame::Swap(WebFrame* new_web_frame) { + DCHECK(IsAttached()); + using std::swap; - // TODO(dcheng): This should not be reachable. Reaching this implies `Swap()` - // is being called on an already-detached frame which should never happen... - if (!IsAttached()) - return false; + // Important: do not cache frame tree pointers (e.g. `previous_sibling_`, // `next_sibling_`, `first_child_`, `last_child_`) here. It is possible for // `Detach()` to mutate the frame tree and cause cached values to become
diff --git a/third_party/blink/renderer/core/frame/frame_owner.h b/third_party/blink/renderer/core/frame/frame_owner.h index 163493e..00c4bcf 100644 --- a/third_party/blink/renderer/core/frame/frame_owner.h +++ b/third_party/blink/renderer/core/frame/frame_owner.h
@@ -4,6 +4,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FRAME_OWNER_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FRAME_OWNER_H_ +#include "third_party/blink/public/mojom/frame/color_scheme.mojom-shared.h" #include "third_party/blink/public/common/frame/frame_policy.h" #include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.h" @@ -72,7 +73,7 @@ virtual bool AllowFullscreen() const = 0; virtual bool AllowPaymentRequest() const = 0; virtual bool IsDisplayNone() const = 0; - virtual ColorScheme GetColorScheme() const = 0; + virtual mojom::blink::ColorScheme GetColorScheme() const = 0; virtual AtomicString RequiredCsp() const = 0; // Returns whether or not children of the owned frame should be lazily loaded. @@ -151,7 +152,9 @@ bool AllowFullscreen() const override { return false; } bool AllowPaymentRequest() const override { return false; } bool IsDisplayNone() const override { return false; } - ColorScheme GetColorScheme() const override { return ColorScheme::kLight; } + mojom::blink::ColorScheme GetColorScheme() const override { + return mojom::blink::ColorScheme::kLight; + } AtomicString RequiredCsp() const override { return g_null_atom; } bool ShouldLazyLoadChildren() const override { return false; }
diff --git a/third_party/blink/renderer/core/frame/frame_test_helpers.cc b/third_party/blink/renderer/core/frame/frame_test_helpers.cc index 171d487..eed12fd 100644 --- a/third_party/blink/renderer/core/frame/frame_test_helpers.cc +++ b/third_party/blink/renderer/core/frame/frame_test_helpers.cc
@@ -654,6 +654,10 @@ --loads_in_progress_; } +bool TestWebFrameClient::SwapIn(WebFrame* previous_frame) { + return previous_frame->Swap(frame_); +} + void TestWebFrameClient::BeginNavigation( std::unique_ptr<WebNavigationInfo> info) { navigation_callback_.Cancel();
diff --git a/third_party/blink/renderer/core/frame/frame_test_helpers.h b/third_party/blink/renderer/core/frame/frame_test_helpers.h index 5f28a822b..509b5f7 100644 --- a/third_party/blink/renderer/core/frame/frame_test_helpers.h +++ b/third_party/blink/renderer/core/frame/frame_test_helpers.h
@@ -505,6 +505,7 @@ policy_container_host_receiver) override; void DidStartLoading() override; void DidStopLoading() override; + bool SwapIn(WebFrame* previous_frame) override; std::unique_ptr<blink::WebURLLoaderFactory> CreateURLLoaderFactory() override { return std::make_unique<WebURLLoaderFactoryWithMock>(
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index b11ef956..e3af04e 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -576,12 +576,7 @@ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! if (IsProvisional()) { - Frame* provisional_owner = nullptr; - if (Owner()) { - provisional_owner = Owner()->ContentFrame(); - } else { - provisional_owner = GetPage()->MainFrame(); - } + Frame* provisional_owner = GetProvisionalOwnerFrame(); // Having multiple provisional frames somehow associated with the same frame // to potentially replace is a logic error. DCHECK_EQ(provisional_owner->ProvisionalFrame(), this); @@ -2391,6 +2386,11 @@ return frozen_ || paused_; } +bool LocalFrame::SwapIn() { + WebLocalFrameClient* client = Client()->GetWebFrame()->Client(); + return client->SwapIn(WebFrame::FromCoreFrame(GetProvisionalOwnerFrame())); +} + WebURLLoader::DeferType LocalFrame::GetLoadDeferType() { if (GetPage()->GetPageScheduler()->IsInBackForwardCache() && base::FeatureList::IsEnabled(features::kLoadingTasksUnfreezable)) { @@ -2919,6 +2919,10 @@ } } +void LocalFrame::SwapInImmediately() { + SwapIn(); +} + void LocalFrame::StopLoading() { Loader().StopAllLoaders(/*abort_client=*/true); @@ -3366,6 +3370,14 @@ } #endif +Frame* LocalFrame::GetProvisionalOwnerFrame() { + DCHECK(IsProvisional()); + if (Owner()) { + return Owner()->ContentFrame(); + } + return GetPage()->MainFrame(); +} + void LocalFrame::BindToReceiver( blink::LocalFrame* frame, mojo::PendingAssociatedReceiver<mojom::blink::LocalFrame> receiver) {
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h index 4a77518..e17c360 100644 --- a/third_party/blink/renderer/core/frame/local_frame.h +++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -610,6 +610,7 @@ const WTF::String& message, bool discard_duplicates) final; void AddInspectorIssue(mojom::blink::InspectorIssueInfoPtr) final; + void SwapInImmediately() final; void StopLoading() final; void Collapse(bool collapsed) final; void EnableViewSourceMode() final; @@ -736,6 +737,8 @@ WebURLLoader::DeferType GetLoadDeferType(); bool IsLoadDeferred(); + bool SwapIn(); + private: friend class FrameNavigationDisabler; FRIEND_TEST_ALL_PREFIXES(LocalFrameTest, CharacterIndexAtPointWithPinchZoom); @@ -797,6 +800,10 @@ mojom::blink::TextInputHost& GetTextInputHost(); #endif + // Returns the `Frame` for which `provisional_frame_ == this`. May only be + // called on a provisional frame. + Frame* GetProvisionalOwnerFrame(); + static void BindToReceiver( blink::LocalFrame* frame, mojo::PendingAssociatedReceiver<mojom::blink::LocalFrame> receiver);
diff --git a/third_party/blink/renderer/core/frame/local_frame_view_test.cc b/third_party/blink/renderer/core/frame/local_frame_view_test.cc index 612655ae..f4d780e 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view_test.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view_test.cc
@@ -196,7 +196,8 @@ EXPECT_FALSE(ChildDocument().View()->CanHaveScrollbars()); ChildDocument().WillChangeFrameOwnerProperties( - 0, 0, mojom::blink::ScrollbarMode::kAlwaysOn, false, ColorScheme::kLight); + 0, 0, mojom::blink::ScrollbarMode::kAlwaysOn, false, + mojom::blink::ColorScheme::kLight); EXPECT_TRUE(ChildDocument().View()->CanHaveScrollbars()); }
diff --git a/third_party/blink/renderer/core/frame/remote_frame_owner.h b/third_party/blink/renderer/core/frame/remote_frame_owner.h index 1094753..201ae55 100644 --- a/third_party/blink/renderer/core/frame/remote_frame_owner.h +++ b/third_party/blink/renderer/core/frame/remote_frame_owner.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_REMOTE_FRAME_OWNER_H_ #include "third_party/blink/public/common/frame/frame_policy.h" +#include "third_party/blink/public/mojom/frame/color_scheme.mojom-blink-forward.h" #include "third_party/blink/public/mojom/frame/frame_owner_element_type.mojom-blink.h" #include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.h" #include "third_party/blink/public/web/web_frame_owner_properties.h" @@ -56,7 +57,9 @@ bool AllowFullscreen() const override { return allow_fullscreen_; } bool AllowPaymentRequest() const override { return allow_payment_request_; } bool IsDisplayNone() const override { return is_display_none_; } - ColorScheme GetColorScheme() const override { return color_scheme_; } + mojom::blink::ColorScheme GetColorScheme() const override { + return color_scheme_; + } AtomicString RequiredCsp() const override { return required_csp_; } bool ShouldLazyLoadChildren() const final; @@ -78,7 +81,7 @@ void SetIsDisplayNone(bool is_display_none) { is_display_none_ = is_display_none; } - void SetColorScheme(ColorScheme color_scheme) { + void SetColorScheme(mojom::blink::ColorScheme color_scheme) { color_scheme_ = color_scheme; } void SetRequiredCsp(const WebString& required_csp) { @@ -102,7 +105,7 @@ bool allow_fullscreen_; bool allow_payment_request_; bool is_display_none_; - ColorScheme color_scheme_; + mojom::blink::ColorScheme color_scheme_; bool needs_occlusion_tracking_; WebString required_csp_; const mojom::blink::FrameOwnerElementType frame_owner_element_type_;
diff --git a/third_party/blink/renderer/core/frame/root_frame_viewport.cc b/third_party/blink/renderer/core/frame/root_frame_viewport.cc index eda9c839..d2f47ad 100644 --- a/third_party/blink/renderer/core/frame/root_frame_viewport.cc +++ b/third_party/blink/renderer/core/frame/root_frame_viewport.cc
@@ -310,7 +310,7 @@ return LayoutViewport().ScrollBehaviorStyle(); } -ColorScheme RootFrameViewport::UsedColorScheme() const { +mojom::blink::ColorScheme RootFrameViewport::UsedColorScheme() const { return LayoutViewport().UsedColorScheme(); }
diff --git a/third_party/blink/renderer/core/frame/root_frame_viewport.h b/third_party/blink/renderer/core/frame/root_frame_viewport.h index c1c339645..58fe030 100644 --- a/third_party/blink/renderer/core/frame/root_frame_viewport.h +++ b/third_party/blink/renderer/core/frame/root_frame_viewport.h
@@ -112,7 +112,7 @@ void UpdateCompositorScrollAnimations() override; void CancelProgrammaticScrollAnimation() override; mojom::blink::ScrollBehavior ScrollBehaviorStyle() const override; - ColorScheme UsedColorScheme() const override; + mojom::blink::ColorScheme UsedColorScheme() const override; void ClearScrollableArea() override; LayoutBox* GetLayoutBox() const override; FloatQuad LocalToVisibleContentQuad(const FloatQuad&,
diff --git a/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc b/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc index 75a58b3a..bac6d698 100644 --- a/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc +++ b/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc
@@ -107,7 +107,7 @@ : user_input_scrollable_y_; } bool ScheduleAnimation() override { return true; } - ColorScheme UsedColorScheme() const override { + mojom::blink::ColorScheme UsedColorScheme() const override { return ComputedStyle::InitialStyle().UsedColorScheme(); }
diff --git a/third_party/blink/renderer/core/frame/visual_viewport.cc b/third_party/blink/renderer/core/frame/visual_viewport.cc index 6951851..c0e9b4c 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport.cc +++ b/third_party/blink/renderer/core/frame/visual_viewport.cc
@@ -836,7 +836,7 @@ return LocalMainFrame()->GetTaskRunner(TaskType::kInternalDefault); } -ColorScheme VisualViewport::UsedColorScheme() const { +mojom::blink::ColorScheme VisualViewport::UsedColorScheme() const { if (LocalFrame* main_frame = LocalMainFrame()) { if (Document* main_document = main_frame->GetDocument()) return main_document->GetLayoutView()->StyleRef().UsedColorScheme();
diff --git a/third_party/blink/renderer/core/frame/visual_viewport.h b/third_party/blink/renderer/core/frame/visual_viewport.h index 0a6fa4d8..4dc38ebe 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport.h +++ b/third_party/blink/renderer/core/frame/visual_viewport.h
@@ -220,7 +220,7 @@ IncludeScrollbarsInRect = kExcludeScrollbars) const override; scoped_refptr<base::SingleThreadTaskRunner> GetTimerTaskRunner() const override; - ColorScheme UsedColorScheme() const override; + mojom::blink::ColorScheme UsedColorScheme() const override; // VisualViewport scrolling may involve pinch zoom and gets routed through // WebViewImpl explicitly rather than via ScrollingCoordinator::DidScroll
diff --git a/third_party/blink/renderer/core/frame/visual_viewport_test.cc b/third_party/blink/renderer/core/frame/visual_viewport_test.cc index 18923ee..3855370f9 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport_test.cc +++ b/third_party/blink/renderer/core/frame/visual_viewport_test.cc
@@ -2729,7 +2729,8 @@ const VisualViewport& visual_viewport = WebView().GetPage()->GetVisualViewport(); - EXPECT_EQ(ColorScheme::kLight, visual_viewport.UsedColorScheme()); + EXPECT_EQ(mojom::blink::ColorScheme::kLight, + visual_viewport.UsedColorScheme()); SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); @@ -2741,7 +2742,8 @@ )HTML"); Compositor().BeginFrame(); - EXPECT_EQ(ColorScheme::kDark, visual_viewport.UsedColorScheme()); + EXPECT_EQ(mojom::blink::ColorScheme::kDark, + visual_viewport.UsedColorScheme()); } TEST_P(VisualViewportTest, SetLocationBeforePrePaint) {
diff --git a/third_party/blink/renderer/core/frame/web_frame_test.cc b/third_party/blink/renderer/core/frame/web_frame_test.cc index 5a579c3..c125c58 100644 --- a/third_party/blink/renderer/core/frame/web_frame_test.cc +++ b/third_party/blink/renderer/core/frame/web_frame_test.cc
@@ -8838,10 +8838,8 @@ WebLocalFrame* local_frame = web_view_helper_.CreateProvisional(*remote_frame); - remote_frame->Swap(local_frame); - // Finally, make sure an embedder triggered load in the local frame swapped - // back in works. + // Committing a navigation in `local_frame` should swap it back in. frame_test_helpers::LoadFrame(local_frame, base_url_ + "subframe-hello.html"); std::string content = @@ -9294,11 +9292,13 @@ WebLocalFrame* local_frame = web_view_helper_.CreateProvisional(*remote_frame); - remote_frame->Swap(local_frame); + // Committing a navigation in a provisional frame will swap it in. + frame_test_helpers::LoadFrame(local_frame, "data:text/html,"); v8::Local<v8::Value> local_window_top = MainFrame()->ExecuteScriptAndReturnValue(WebScriptSource("saved.top")); EXPECT_TRUE(local_window_top->IsObject()); EXPECT_TRUE(window_top->StrictEquals(local_window_top)); + local_frame->ExecuteScriptAndReturnValue(WebScriptSource("42")); } TEST_F(WebFrameSwapTest, RemoteFramesAreIndexable) { @@ -9410,9 +9410,6 @@ class RemoteToLocalSwapWebFrameClient : public frame_test_helpers::TestWebFrameClient { public: - explicit RemoteToLocalSwapWebFrameClient(WebRemoteFrame* remote_frame) - : history_commit_type_(kWebHistoryInertCommit), - remote_frame_(remote_frame) {} ~RemoteToLocalSwapWebFrameClient() override = default; // frame_test_helpers::TestWebFrameClient: @@ -9423,15 +9420,13 @@ const ParsedFeaturePolicy& feature_policy_header, const DocumentPolicyFeatureState& document_policy_header) override { history_commit_type_ = history_commit_type; - remote_frame_->Swap(Frame()); } WebHistoryCommitType HistoryCommitType() const { - return history_commit_type_; + return *history_commit_type_; } - WebHistoryCommitType history_commit_type_; - WebRemoteFrame* remote_frame_; + base::Optional<WebHistoryCommitType> history_commit_type_; }; // The commit type should be Initial if we are swapping a RemoteFrame to a @@ -9446,7 +9441,7 @@ ASSERT_TRUE(MainFrame()->FirstChild()); ASSERT_EQ(MainFrame()->FirstChild(), remote_frame); - RemoteToLocalSwapWebFrameClient client(remote_frame); + RemoteToLocalSwapWebFrameClient client; WebLocalFrame* local_frame = web_view_helper_.CreateProvisional(*remote_frame, &client); frame_test_helpers::LoadFrame(local_frame, base_url_ + "subframe-hello.html"); @@ -9468,7 +9463,7 @@ ASSERT_TRUE(MainFrame()->FirstChild()); ASSERT_EQ(MainFrame()->FirstChild(), remote_frame); - RemoteToLocalSwapWebFrameClient client(remote_frame); + RemoteToLocalSwapWebFrameClient client; WebLocalFrameImpl* local_frame = web_view_helper_.CreateProvisional(*remote_frame, &client); local_frame->SetCommittedFirstRealLoad();
diff --git a/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc b/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc index 4e79ecf..6855e10 100644 --- a/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc +++ b/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc
@@ -218,8 +218,8 @@ AddProperty("otherDateLabel", other_date_label_string, data); const ComputedStyle* style = OwnerElement().GetComputedStyle(); - ColorScheme color_scheme = - style ? style->UsedColorScheme() : ColorScheme::kLight; + mojom::blink::ColorScheme color_scheme = + style ? style->UsedColorScheme() : mojom::blink::ColorScheme::kLight; AddProperty("suggestionHighlightColor", LayoutTheme::GetTheme()
diff --git a/third_party/blink/renderer/core/html/html_frame_owner_element.cc b/third_party/blink/renderer/core/html/html_frame_owner_element.cc index 761d1d93..cc54e54d 100644 --- a/third_party/blink/renderer/core/html/html_frame_owner_element.cc +++ b/third_party/blink/renderer/core/html/html_frame_owner_element.cc
@@ -23,6 +23,7 @@ #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" +#include "third_party/blink/public/mojom/frame/color_scheme.mojom-blink.h" #include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-blink.h" #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h" #include "third_party/blink/renderer/core/css/style_change_reason.h" @@ -689,13 +690,14 @@ return content_frame_->IsAdSubframe(); } -ColorScheme HTMLFrameOwnerElement::GetColorScheme() const { +mojom::blink::ColorScheme HTMLFrameOwnerElement::GetColorScheme() const { if (const auto* style = GetComputedStyle()) return style->UsedColorSchemeForInitialColors(); - return ColorScheme::kLight; + return mojom::blink::ColorScheme::kLight; } -void HTMLFrameOwnerElement::SetColorScheme(ColorScheme color_scheme) { +void HTMLFrameOwnerElement::SetColorScheme( + mojom::blink::ColorScheme color_scheme) { Document* doc = contentDocument(); if (doc && doc->GetFrame()) { doc->WillChangeFrameOwnerProperties(MarginWidth(), MarginHeight(),
diff --git a/third_party/blink/renderer/core/html/html_frame_owner_element.h b/third_party/blink/renderer/core/html/html_frame_owner_element.h index 268bc70c..eda50e4 100644 --- a/third_party/blink/renderer/core/html/html_frame_owner_element.h +++ b/third_party/blink/renderer/core/html/html_frame_owner_element.h
@@ -74,7 +74,7 @@ return embedded_content_view_; } - void SetColorScheme(ColorScheme); + void SetColorScheme(mojom::blink::ColorScheme); class PluginDisposeSuspendScope { STACK_ALLOCATED(); @@ -118,7 +118,7 @@ bool AllowFullscreen() const override { return false; } bool AllowPaymentRequest() const override { return false; } bool IsDisplayNone() const override { return !embedded_content_view_; } - ColorScheme GetColorScheme() const override; + mojom::blink::ColorScheme GetColorScheme() const override; AtomicString RequiredCsp() const override { return g_null_atom; } bool ShouldLazyLoadChildren() const final;
diff --git a/third_party/blink/renderer/core/html/html_link_element.cc b/third_party/blink/renderer/core/html/html_link_element.cc index 8ae0f2ff..6e5ed75 100644 --- a/third_party/blink/renderer/core/html/html_link_element.cc +++ b/third_party/blink/renderer/core/html/html_link_element.cc
@@ -134,9 +134,6 @@ } else if (name == html_names::kMediaAttr) { media_ = value.LowerASCII(); Process(); - } else if (name == html_names::kScopeAttr) { - scope_ = value; - Process(); } else if (name == html_names::kIntegrityAttr) { integrity_ = value; } else if (name == html_names::kImportanceAttr &&
diff --git a/third_party/blink/renderer/core/html/html_link_element.h b/third_party/blink/renderer/core/html/html_link_element.h index 8bb59ce..a7bc4426 100644 --- a/third_party/blink/renderer/core/html/html_link_element.h +++ b/third_party/blink/renderer/core/html/html_link_element.h
@@ -69,7 +69,6 @@ DOMTokenList& relList() const { return static_cast<DOMTokenList&>(*rel_list_); } - String Scope() const { return scope_; } const AtomicString& GetType() const; @@ -177,7 +176,6 @@ Vector<gfx::Size> icon_sizes_; Member<RelList> rel_list_; LinkRelAttribute rel_attribute_; - String scope_; Member<DOMTokenList> resources_; HashSet<KURL> valid_resource_urls_;
diff --git a/third_party/blink/renderer/core/html/html_meta_element.cc b/third_party/blink/renderer/core/html/html_meta_element.cc index 389dcc9..d6b0d29 100644 --- a/third_party/blink/renderer/core/html/html_meta_element.cc +++ b/third_party/blink/renderer/core/html/html_meta_element.cc
@@ -22,8 +22,8 @@ #include "third_party/blink/renderer/core/html/html_meta_element.h" -#include "third_party/blink/public/common/css/color_scheme.h" #include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/mojom/frame/color_scheme.mojom-blink.h" #include "third_party/blink/renderer/core/css/style_engine.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/element_traversal.h"
diff --git a/third_party/blink/renderer/core/layout/layout_theme.cc b/third_party/blink/renderer/core/layout/layout_theme.cc index 6628945..de02277e 100644 --- a/third_party/blink/renderer/core/layout/layout_theme.cc +++ b/third_party/blink/renderer/core/layout/layout_theme.cc
@@ -325,50 +325,50 @@ } Color LayoutTheme::ActiveSelectionBackgroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { Color color = PlatformActiveSelectionBackgroundColor(color_scheme); #if defined(OS_MAC) // BlendWithWhite() darkens Mac system colors too much. // Apply .8 (204/255) alpha instead, same as Safari. - if (color_scheme == ColorScheme::kDark) + if (color_scheme == mojom::blink::ColorScheme::kDark) return Color(color.Red(), color.Green(), color.Blue(), 204); #endif return color.BlendWithWhite(); } Color LayoutTheme::InactiveSelectionBackgroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { return PlatformInactiveSelectionBackgroundColor(color_scheme) .BlendWithWhite(); } Color LayoutTheme::ActiveSelectionForegroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { return PlatformActiveSelectionForegroundColor(color_scheme); } Color LayoutTheme::InactiveSelectionForegroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { return PlatformInactiveSelectionForegroundColor(color_scheme); } Color LayoutTheme::ActiveListBoxSelectionBackgroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { return PlatformActiveListBoxSelectionBackgroundColor(color_scheme); } Color LayoutTheme::InactiveListBoxSelectionBackgroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { return PlatformInactiveListBoxSelectionBackgroundColor(color_scheme); } Color LayoutTheme::ActiveListBoxSelectionForegroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { return PlatformActiveListBoxSelectionForegroundColor(color_scheme); } Color LayoutTheme::InactiveListBoxSelectionForegroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { return PlatformInactiveListBoxSelectionForegroundColor(color_scheme); } @@ -385,47 +385,47 @@ } Color LayoutTheme::PlatformActiveSelectionBackgroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { // Use a blue color by default if the platform theme doesn't define anything. return Color(0, 0, 255); } Color LayoutTheme::PlatformActiveSelectionForegroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { // Use a white color by default if the platform theme doesn't define anything. return Color::kWhite; } Color LayoutTheme::PlatformInactiveSelectionBackgroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { // Use a grey color by default if the platform theme doesn't define anything. // This color matches Firefox's inactive color. return Color(176, 176, 176); } Color LayoutTheme::PlatformInactiveSelectionForegroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { // Use a black color by default. return Color::kBlack; } Color LayoutTheme::PlatformActiveListBoxSelectionBackgroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { return PlatformActiveSelectionBackgroundColor(color_scheme); } Color LayoutTheme::PlatformActiveListBoxSelectionForegroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { return PlatformActiveSelectionForegroundColor(color_scheme); } Color LayoutTheme::PlatformInactiveListBoxSelectionBackgroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { return PlatformInactiveSelectionBackgroundColor(color_scheme); } Color LayoutTheme::PlatformInactiveListBoxSelectionForegroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { return PlatformInactiveSelectionForegroundColor(color_scheme); } @@ -618,7 +618,7 @@ } Color LayoutTheme::SystemColor(CSSValueID css_value_id, - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { switch (css_value_id) { case CSSValueID::kActiveborder: return 0xFFFFFFFF; @@ -627,29 +627,36 @@ case CSSValueID::kActivetext: return 0xFFFF0000; case CSSValueID::kAppworkspace: - return color_scheme == ColorScheme::kDark ? 0xFF000000 : 0xFFFFFFFF; + return color_scheme == mojom::blink::ColorScheme::kDark ? 0xFF000000 + : 0xFFFFFFFF; case CSSValueID::kBackground: return 0xFF6363CE; case CSSValueID::kButtonface: - return color_scheme == ColorScheme::kDark ? 0xFF444444 : 0xFFDDDDDD; + return color_scheme == mojom::blink::ColorScheme::kDark ? 0xFF444444 + : 0xFFDDDDDD; case CSSValueID::kButtonhighlight: return 0xFFDDDDDD; case CSSValueID::kButtonshadow: return 0xFF888888; case CSSValueID::kButtontext: - return color_scheme == ColorScheme::kDark ? 0xFFAAAAAA : 0xFF000000; + return color_scheme == mojom::blink::ColorScheme::kDark ? 0xFFAAAAAA + : 0xFF000000; case CSSValueID::kCaptiontext: - return color_scheme == ColorScheme::kDark ? 0xFFFFFFFF : 0xFF000000; + return color_scheme == mojom::blink::ColorScheme::kDark ? 0xFFFFFFFF + : 0xFF000000; case CSSValueID::kField: - return color_scheme == ColorScheme::kDark ? 0xFF000000 : 0xFFFFFFFF; + return color_scheme == mojom::blink::ColorScheme::kDark ? 0xFF000000 + : 0xFFFFFFFF; case CSSValueID::kFieldtext: - return color_scheme == ColorScheme::kDark ? 0xFFFFFFFF : 0xFF000000; + return color_scheme == mojom::blink::ColorScheme::kDark ? 0xFFFFFFFF + : 0xFF000000; case CSSValueID::kGraytext: return 0xFF808080; case CSSValueID::kHighlight: return 0xFFB5D5FF; case CSSValueID::kHighlighttext: - return color_scheme == ColorScheme::kDark ? 0xFFFFFFFF : 0xFF000000; + return color_scheme == mojom::blink::ColorScheme::kDark ? 0xFFFFFFFF + : 0xFF000000; case CSSValueID::kInactiveborder: return 0xFFFFFFFF; case CSSValueID::kInactivecaption: @@ -657,19 +664,24 @@ case CSSValueID::kInactivecaptiontext: return 0xFF7F7F7F; case CSSValueID::kInfobackground: - return color_scheme == ColorScheme::kDark ? 0xFFB46E32 : 0xFFFBFCC5; + return color_scheme == mojom::blink::ColorScheme::kDark ? 0xFFB46E32 + : 0xFFFBFCC5; case CSSValueID::kInfotext: - return color_scheme == ColorScheme::kDark ? 0xFFFFFFFF : 0xFF000000; + return color_scheme == mojom::blink::ColorScheme::kDark ? 0xFFFFFFFF + : 0xFF000000; case CSSValueID::kLinktext: return 0xFF0000EE; case CSSValueID::kMenu: - return color_scheme == ColorScheme::kDark ? 0xFF404040 : 0xFFF7F7F7; + return color_scheme == mojom::blink::ColorScheme::kDark ? 0xFF404040 + : 0xFFF7F7F7; case CSSValueID::kMenutext: - return color_scheme == ColorScheme::kDark ? 0xFFFFFFFF : 0xFF000000; + return color_scheme == mojom::blink::ColorScheme::kDark ? 0xFFFFFFFF + : 0xFF000000; case CSSValueID::kScrollbar: return 0xFFFFFFFF; case CSSValueID::kText: - return color_scheme == ColorScheme::kDark ? 0xFFFFFFFF : 0xFF000000; + return color_scheme == mojom::blink::ColorScheme::kDark ? 0xFFFFFFFF + : 0xFF000000; case CSSValueID::kThreeddarkshadow: return 0xFF666666; case CSSValueID::kThreedface: @@ -684,12 +696,14 @@ return 0xFF551A8B; case CSSValueID::kWindow: case CSSValueID::kCanvas: - return color_scheme == ColorScheme::kDark ? 0xFF000000 : 0xFFFFFFFF; + return color_scheme == mojom::blink::ColorScheme::kDark ? 0xFF000000 + : 0xFFFFFFFF; case CSSValueID::kWindowframe: return 0xFFCCCCCC; case CSSValueID::kWindowtext: case CSSValueID::kCanvastext: - return color_scheme == ColorScheme::kDark ? 0xFFFFFFFF : 0xFF000000; + return color_scheme == mojom::blink::ColorScheme::kDark ? 0xFFFFFFFF + : 0xFF000000; case CSSValueID::kInternalActiveListBoxSelection: return ActiveListBoxSelectionBackgroundColor(color_scheme); case CSSValueID::kInternalActiveListBoxSelectionText: @@ -708,7 +722,7 @@ Color LayoutTheme::PlatformTextSearchHighlightColor( bool active_match, bool in_forced_colors_mode, - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { if (active_match) { if (in_forced_colors_mode) return GetTheme().SystemColor(CSSValueID::kHighlight, color_scheme); @@ -717,9 +731,10 @@ return Color(255, 255, 0); // Yellow. } -Color LayoutTheme::PlatformTextSearchColor(bool active_match, - bool in_forced_colors_mode, - ColorScheme color_scheme) const { +Color LayoutTheme::PlatformTextSearchColor( + bool active_match, + bool in_forced_colors_mode, + mojom::blink::ColorScheme color_scheme) const { if (in_forced_colors_mode && active_match) return GetTheme().SystemColor(CSSValueID::kHighlighttext, color_scheme); return Color::kBlack;
diff --git a/third_party/blink/renderer/core/layout/layout_theme.h b/third_party/blink/renderer/core/layout/layout_theme.h index e6d9e20..927f9f0 100644 --- a/third_party/blink/renderer/core/layout/layout_theme.h +++ b/third_party/blink/renderer/core/layout/layout_theme.h
@@ -23,7 +23,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_THEME_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_THEME_H_ -#include "third_party/blink/public/common/css/color_scheme.h" +#include "third_party/blink/public/mojom/frame/color_scheme.mojom-blink-forward.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/css_value_keywords.h" #include "third_party/blink/renderer/core/scroll/scroll_types.h" @@ -91,20 +91,28 @@ virtual bool SupportsCalendarPicker(const AtomicString&) const; // Text selection colors. - Color ActiveSelectionBackgroundColor(ColorScheme color_scheme) const; - Color InactiveSelectionBackgroundColor(ColorScheme color_scheme) const; - Color ActiveSelectionForegroundColor(ColorScheme color_scheme) const; - Color InactiveSelectionForegroundColor(ColorScheme color_scheme) const; + Color ActiveSelectionBackgroundColor( + mojom::blink::ColorScheme color_scheme) const; + Color InactiveSelectionBackgroundColor( + mojom::blink::ColorScheme color_scheme) const; + Color ActiveSelectionForegroundColor( + mojom::blink::ColorScheme color_scheme) const; + Color InactiveSelectionForegroundColor( + mojom::blink::ColorScheme color_scheme) const; virtual void SetSelectionColors(Color active_background_color, Color active_foreground_color, Color inactive_background_color, Color inactive_foreground_color) {} // List box selection colors - Color ActiveListBoxSelectionBackgroundColor(ColorScheme color_scheme) const; - Color ActiveListBoxSelectionForegroundColor(ColorScheme color_scheme) const; - Color InactiveListBoxSelectionBackgroundColor(ColorScheme color_scheme) const; - Color InactiveListBoxSelectionForegroundColor(ColorScheme color_scheme) const; + Color ActiveListBoxSelectionBackgroundColor( + mojom::blink::ColorScheme color_scheme) const; + Color ActiveListBoxSelectionForegroundColor( + mojom::blink::ColorScheme color_scheme) const; + Color InactiveListBoxSelectionBackgroundColor( + mojom::blink::ColorScheme color_scheme) const; + Color InactiveListBoxSelectionForegroundColor( + mojom::blink::ColorScheme color_scheme) const; virtual Color PlatformSpellingMarkerUnderlineColor() const; virtual Color PlatformGrammarMarkerUnderlineColor() const; @@ -112,12 +120,13 @@ Color PlatformActiveSpellingMarkerHighlightColor() const; // Highlight and text colors for TextMatches. - Color PlatformTextSearchHighlightColor(bool active_match, - bool in_forced_colors_mode, - ColorScheme color_scheme) const; + Color PlatformTextSearchHighlightColor( + bool active_match, + bool in_forced_colors_mode, + mojom::blink::ColorScheme color_scheme) const; Color PlatformTextSearchColor(bool active_match, bool in_forced_colors_mode, - ColorScheme color_scheme) const; + mojom::blink::ColorScheme color_scheme) const; virtual Color FocusRingColor() const; virtual Color PlatformFocusRingColor() const { return Color(0, 0, 0); } @@ -138,7 +147,8 @@ // System fonts and colors for CSS. void SystemFont(CSSValueID system_font_id, FontDescription&); - virtual Color SystemColor(CSSValueID, ColorScheme color_scheme) const; + virtual Color SystemColor(CSSValueID, + mojom::blink::ColorScheme color_scheme) const; virtual void AdjustSliderThumbSize(ComputedStyle&) const; @@ -178,22 +188,22 @@ protected: // The platform selection color. virtual Color PlatformActiveSelectionBackgroundColor( - ColorScheme color_scheme) const; + mojom::blink::ColorScheme color_scheme) const; virtual Color PlatformInactiveSelectionBackgroundColor( - ColorScheme color_scheme) const; + mojom::blink::ColorScheme color_scheme) const; virtual Color PlatformActiveSelectionForegroundColor( - ColorScheme color_scheme) const; + mojom::blink::ColorScheme color_scheme) const; virtual Color PlatformInactiveSelectionForegroundColor( - ColorScheme color_scheme) const; + mojom::blink::ColorScheme color_scheme) const; virtual Color PlatformActiveListBoxSelectionBackgroundColor( - ColorScheme color_scheme) const; + mojom::blink::ColorScheme color_scheme) const; virtual Color PlatformInactiveListBoxSelectionBackgroundColor( - ColorScheme color_scheme) const; + mojom::blink::ColorScheme color_scheme) const; virtual Color PlatformActiveListBoxSelectionForegroundColor( - ColorScheme color_scheme) const; + mojom::blink::ColorScheme color_scheme) const; virtual Color PlatformInactiveListBoxSelectionForegroundColor( - ColorScheme color_scheme) const; + mojom::blink::ColorScheme color_scheme) const; // Methods for each appearance value. virtual void AdjustCheckboxStyle(ComputedStyle&) const;
diff --git a/third_party/blink/renderer/core/layout/layout_theme_default.cc b/third_party/blink/renderer/core/layout/layout_theme_default.cc index ee082c7f..4f4845e 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_default.cc +++ b/third_party/blink/renderer/core/layout/layout_theme_default.cc
@@ -86,22 +86,22 @@ } Color LayoutThemeDefault::PlatformActiveSelectionBackgroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { return active_selection_background_color_; } Color LayoutThemeDefault::PlatformInactiveSelectionBackgroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { return inactive_selection_background_color_; } Color LayoutThemeDefault::PlatformActiveSelectionForegroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { return active_selection_foreground_color_; } Color LayoutThemeDefault::PlatformInactiveSelectionForegroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { return inactive_selection_foreground_color_; }
diff --git a/third_party/blink/renderer/core/layout/layout_theme_default.h b/third_party/blink/renderer/core/layout/layout_theme_default.h index 3111958..f249604c 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_default.h +++ b/third_party/blink/renderer/core/layout/layout_theme_default.h
@@ -41,13 +41,13 @@ String ExtraQuirksStyleSheet() override; Color PlatformActiveSelectionBackgroundColor( - ColorScheme color_scheme) const override; + mojom::blink::ColorScheme color_scheme) const override; Color PlatformInactiveSelectionBackgroundColor( - ColorScheme color_scheme) const override; + mojom::blink::ColorScheme color_scheme) const override; Color PlatformActiveSelectionForegroundColor( - ColorScheme color_scheme) const override; + mojom::blink::ColorScheme color_scheme) const override; Color PlatformInactiveSelectionForegroundColor( - ColorScheme color_scheme) const override; + mojom::blink::ColorScheme color_scheme) const override; IntSize SliderTickSize() const override; int SliderTickOffsetFromTrackCenter() const override;
diff --git a/third_party/blink/renderer/core/layout/layout_theme_mac.h b/third_party/blink/renderer/core/layout/layout_theme_mac.h index 9e3d799..61bbb5c 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_mac.h +++ b/third_party/blink/renderer/core/layout/layout_theme_mac.h
@@ -38,11 +38,11 @@ } Color PlatformActiveSelectionBackgroundColor( - ColorScheme color_scheme) const override; + mojom::blink::ColorScheme color_scheme) const override; Color PlatformInactiveSelectionBackgroundColor( - ColorScheme color_scheme) const override; + mojom::blink::ColorScheme color_scheme) const override; Color PlatformActiveSelectionForegroundColor( - ColorScheme color_scheme) const override; + mojom::blink::ColorScheme color_scheme) const override; Color PlatformSpellingMarkerUnderlineColor() const override; Color PlatformGrammarMarkerUnderlineColor() const override; Color FocusRingColor() const override; @@ -54,7 +54,7 @@ protected: // Controls color values returned from FocusRingColor(). bool UsesTestModeFocusRingColor() const; - bool IsAccentColorCustomized(ColorScheme color_scheme) const; + bool IsAccentColorCustomized(mojom::blink::ColorScheme color_scheme) const; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_theme_mac.mm b/third_party/blink/renderer/core/layout/layout_theme_mac.mm index 6fd8ee5d..748da2b 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_mac.mm +++ b/third_party/blink/renderer/core/layout/layout_theme_mac.mm
@@ -34,7 +34,8 @@ namespace blink { namespace { -Color GetSystemColor(MacSystemColorID color_id, ColorScheme color_scheme) { +Color GetSystemColor(MacSystemColorID color_id, + mojom::blink::ColorScheme color_scheme) { // In tests, a WebSandboxSupport may not be set up. Just return a dummy // color, in this case, black. auto* sandbox_support = Platform::Current()->GetSandboxSupport(); @@ -51,19 +52,19 @@ } Color LayoutThemeMac::PlatformActiveSelectionBackgroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { return GetSystemColor(MacSystemColorID::kSelectedTextBackground, color_scheme); } Color LayoutThemeMac::PlatformInactiveSelectionBackgroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { return GetSystemColor(MacSystemColorID::kSecondarySelectedControl, color_scheme); } Color LayoutThemeMac::PlatformActiveSelectionForegroundColor( - ColorScheme color_scheme) const { + mojom::blink::ColorScheme color_scheme) const { return Color::kBlack; } @@ -75,7 +76,8 @@ return Color(107, 107, 107); } -bool LayoutThemeMac::IsAccentColorCustomized(ColorScheme color_scheme) const { +bool LayoutThemeMac::IsAccentColorCustomized( + mojom::blink::ColorScheme color_scheme) const { if (@available(macOS 10.14, *)) { static const Color kControlBlueAccentColor = GetSystemColor(MacSystemColorID::kControlAccentBlueColor, color_scheme); @@ -107,7 +109,8 @@ } // TODO(crbug.com/929098) Need to pass an appropriate color scheme here. - ColorScheme color_scheme = ComputedStyle::InitialStyle().UsedColorScheme(); + mojom::blink::ColorScheme color_scheme = + ComputedStyle::InitialStyle().UsedColorScheme(); SkColor keyboard_focus_indicator = SkColor( GetSystemColor(MacSystemColorID::kKeyboardFocusIndicator, color_scheme));
diff --git a/third_party/blink/renderer/core/layout/layout_theme_mobile.h b/third_party/blink/renderer/core/layout/layout_theme_mobile.h index 185be962..09ee09d 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_mobile.h +++ b/third_party/blink/renderer/core/layout/layout_theme_mobile.h
@@ -44,7 +44,7 @@ } Color PlatformActiveSelectionBackgroundColor( - ColorScheme color_scheme) const override { + mojom::blink::ColorScheme color_scheme) const override { return LayoutThemeMobile::kDefaultActiveSelectionBackgroundColor; }
diff --git a/third_party/blink/renderer/core/layout/layout_theme_test.cc b/third_party/blink/renderer/core/layout/layout_theme_test.cc index 76d7557..10d1803 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_test.cc +++ b/third_party/blink/renderer/core/layout/layout_theme_test.cc
@@ -95,7 +95,7 @@ ASSERT_TRUE(dark_element); const ComputedStyle* style = dark_element->GetComputedStyle(); - EXPECT_EQ(ColorScheme::kLight, style->UsedColorScheme()); + EXPECT_EQ(mojom::blink::ColorScheme::kLight, style->UsedColorScheme()); EXPECT_EQ(Color(0xdd, 0xdd, 0xdd), style->VisitedDependentColor(GetCSSPropertyColor())); @@ -106,7 +106,7 @@ UpdateAllLifecyclePhasesForTest(); style = dark_element->GetComputedStyle(); - EXPECT_EQ(ColorScheme::kDark, style->UsedColorScheme()); + EXPECT_EQ(mojom::blink::ColorScheme::kDark, style->UsedColorScheme()); EXPECT_EQ(Color(0x44, 0x44, 0x44), style->VisitedDependentColor(GetCSSPropertyColor())); } @@ -116,7 +116,7 @@ Color::kBlack, Color::kBlack); EXPECT_EQ(Color::kBlack, LayoutTheme::GetTheme().ActiveSelectionForegroundColor( - ColorScheme::kLight)); + mojom::blink::ColorScheme::kLight)); { // Enabling MobileLayoutTheme switches which instance is returned from // LayoutTheme::GetTheme(). Devtools expect SetSelectionColors() to affect @@ -124,17 +124,17 @@ ScopedMobileLayoutThemeForTest scope(true); EXPECT_EQ(Color::kBlack, LayoutTheme::GetTheme().ActiveSelectionForegroundColor( - ColorScheme::kLight)); + mojom::blink::ColorScheme::kLight)); LayoutTheme::GetTheme().SetSelectionColors(Color::kWhite, Color::kWhite, Color::kWhite, Color::kWhite); EXPECT_EQ(Color::kWhite, LayoutTheme::GetTheme().ActiveSelectionForegroundColor( - ColorScheme::kLight)); + mojom::blink::ColorScheme::kLight)); } EXPECT_EQ(Color::kWhite, LayoutTheme::GetTheme().ActiveSelectionForegroundColor( - ColorScheme::kLight)); + mojom::blink::ColorScheme::kLight)); } #endif // !defined(OS_MAC)
diff --git a/third_party/blink/renderer/core/layout/layout_theme_win.cc b/third_party/blink/renderer/core/layout/layout_theme_win.cc index 7c23535..6db48d7 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_win.cc +++ b/third_party/blink/renderer/core/layout/layout_theme_win.cc
@@ -21,8 +21,9 @@ return *layout_theme; } -Color LayoutThemeWin::SystemColor(CSSValueID css_value_id, - ColorScheme color_scheme) const { +Color LayoutThemeWin::SystemColor( + CSSValueID css_value_id, + mojom::blink::ColorScheme color_scheme) const { blink::WebThemeEngine::SystemThemeColor theme_color; switch (css_value_id) { case CSSValueID::kActivetext:
diff --git a/third_party/blink/renderer/core/layout/layout_theme_win.h b/third_party/blink/renderer/core/layout/layout_theme_win.h index 97c897a..20ff279 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_win.h +++ b/third_party/blink/renderer/core/layout/layout_theme_win.h
@@ -14,7 +14,7 @@ static scoped_refptr<LayoutTheme> Create(); Color SystemColor(CSSValueID css_value_id, - ColorScheme color_scheme) const override; + mojom::blink::ColorScheme color_scheme) const override; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_layout_utils.cc index 788f0cc..e8a41053 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_layout_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_layout_utils.cc
@@ -210,6 +210,8 @@ LayoutUnit block_size = fragment_geometry.border_box_size.block_size; bool is_initial_block_size_indefinite = block_size == kIndefiniteSize; if (is_initial_block_size_indefinite) { + LayoutUnit intrinsic_block_size = layout_result.IntrinsicBlockSize(); + if (node.IsFlexibleBox()) { // Flex-boxes can have their children calculate their size based in their // parent's final block-size. E.g. @@ -227,8 +229,8 @@ // </div> // // If the previous |layout_result| was produced by a space which had a - // fixed block-size we can't use |NGLayoutResult::IntrinsicBlockSize()|, - // and need to layout. + // fixed block-size we can't use |intrinsic_block_size| for determining + // the new block-size. // // TODO(ikilpatrick): Similar to %-block-size descendants we could store // a bit on the |NGLayoutResult| which indicates if it had a child which @@ -238,7 +240,7 @@ // TODO(ikilaptrick): This may occur for other layout modes, e.g. // grid/custom-layout/etc. if (old_space.IsFixedBlockSize()) - return NGLayoutCacheStatus::kNeedsLayout; + intrinsic_block_size = kIndefiniteSize; // The intrinsic size of flex-boxes can depend on the %-block-size. This // occurs when: @@ -246,21 +248,22 @@ // - A row flex-box has "height: 100%" (or similar) and children which // stretch to this size. // - // Due to this we can't use cached |NGLayoutResult::IntrinsicBlockSize| - // value, as the following |block_size| calculation would be incorrect. + // Due to this we can't use the |intrinsic_block_size| value, as the + // following |block_size| calculation would be incorrect. // TODO(dgrogan): We can hit the cache here for row flexboxes when they // don't have stretchy children. - if (physical_fragment.DependsOnPercentageBlockSize()) { - if (new_space.PercentageResolutionBlockSize() != - old_space.PercentageResolutionBlockSize()) - return NGLayoutCacheStatus::kNeedsLayout; - } + if (physical_fragment.DependsOnPercentageBlockSize() && + new_space.PercentageResolutionBlockSize() != + old_space.PercentageResolutionBlockSize()) + intrinsic_block_size = kIndefiniteSize; } block_size = ComputeBlockSizeForFragment( new_space, style, fragment_geometry.border + fragment_geometry.padding, - layout_result.IntrinsicBlockSize(), - fragment_geometry.border_box_size.inline_size); + intrinsic_block_size, fragment_geometry.border_box_size.inline_size); + + if (block_size == kIndefiniteSize) + return NGLayoutCacheStatus::kNeedsLayout; } bool is_block_size_equal = block_size == fragment.BlockSize();
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc index 41b8498d..e729b1f 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc
@@ -103,6 +103,7 @@ bool has_content = false; if (const auto* box = DynamicTo<NGPhysicalBoxFragment>(fragment)) { + const LayoutObject* layout_object = box->GetLayoutObject(); if (flags_ & NGPhysicalFragment::DumpType) { builder_->Append("Box"); String box_type = StringForBoxType(*fragment); @@ -121,11 +122,10 @@ } has_content = AppendOffsetAndSize(fragment, fragment_offset, has_content); - if (flags_ & NGPhysicalFragment::DumpNodeName && - fragment->GetLayoutObject()) { + if (flags_ & NGPhysicalFragment::DumpNodeName && layout_object) { if (has_content) builder_->Append(" "); - builder_->Append(fragment->GetLayoutObject()->DebugName()); + builder_->Append(layout_object->DebugName()); } builder_->Append("\n"); @@ -138,6 +138,27 @@ } } if (flags_ & NGPhysicalFragment::DumpSubtree) { + if (flags_ & NGPhysicalFragment::DumpLegacyDescendants && + layout_object && !layout_object->IsLayoutNGObject()) { + DCHECK(box->Children().empty()); + for (const LayoutObject* descendant = layout_object->SlowFirstChild(); + descendant;) { + if (!descendant->IsLayoutNGObject()) { + descendant = descendant->NextInPreOrder(layout_object); + continue; + } + if (flags_ & NGPhysicalFragment::DumpHeaderText) { + AppendIndentation(indent + 2); + builder_->Append("(NG fragment root inside legacy subtree:)\n"); + } + const LayoutBox* box_descendant = To<LayoutBox>(descendant); + DCHECK_EQ(box_descendant->PhysicalFragmentCount(), 1u); + Append(box_descendant->GetPhysicalFragment(0), base::nullopt, + indent + 4); + descendant = descendant->NextInPreOrderAfterChildren(layout_object); + } + return; + } for (auto& child : box->Children()) { if (has_fragment_items && child->IsLineBox()) continue;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h index b8c25e4..85f21c8d9 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
@@ -446,6 +446,7 @@ DumpSelfPainting = 0x80, DumpNodeName = 0x100, DumpItems = 0x200, + DumpLegacyDescendants = 0x400, DumpAll = -1 }; typedef int DumpFlags;
diff --git a/third_party/blink/renderer/core/layout/scrollbars_test.cc b/third_party/blink/renderer/core/layout/scrollbars_test.cc index 028a8c4..c802f8e 100644 --- a/third_party/blink/renderer/core/layout/scrollbars_test.cc +++ b/third_party/blink/renderer/core/layout/scrollbars_test.cc
@@ -38,7 +38,9 @@ class StubWebThemeEngine : public WebThemeEngine { public: - StubWebThemeEngine() { painted_color_scheme_.fill(ColorScheme::kLight); } + StubWebThemeEngine() { + painted_color_scheme_.fill(mojom::blink::ColorScheme::kLight); + } gfx::Size GetSize(Part part) override { switch (part) { @@ -65,18 +67,19 @@ State, const gfx::Rect&, const ExtraParams*, - blink::ColorScheme color_scheme) override { + mojom::blink::ColorScheme color_scheme) override { // Make sure we don't overflow the array. DCHECK(part <= kPartProgressBar); painted_color_scheme_[part] = color_scheme; } - ColorScheme GetPaintedPartColorScheme(Part part) const { + mojom::blink::ColorScheme GetPaintedPartColorScheme(Part part) const { return painted_color_scheme_[part]; } private: - std::array<ColorScheme, kPartProgressBar + 1> painted_color_scheme_; + std::array<mojom::blink::ColorScheme, kPartProgressBar + 1> + painted_color_scheme_; }; constexpr int StubWebThemeEngine::kMinimumHorizontalLength; @@ -3012,14 +3015,15 @@ auto* theme_engine = static_cast<StubWebThemeEngine*>(Platform::Current()->ThemeEngine()); - EXPECT_EQ(ColorScheme::kDark, + EXPECT_EQ(mojom::blink::ColorScheme::kDark, theme_engine->GetPaintedPartColorScheme( WebThemeEngine::kPartScrollbarHorizontalThumb)); - EXPECT_EQ(ColorScheme::kDark, + EXPECT_EQ(mojom::blink::ColorScheme::kDark, theme_engine->GetPaintedPartColorScheme( WebThemeEngine::kPartScrollbarVerticalThumb)); - EXPECT_EQ(ColorScheme::kDark, theme_engine->GetPaintedPartColorScheme( - WebThemeEngine::kPartScrollbarCorner)); + EXPECT_EQ(mojom::blink::ColorScheme::kDark, + theme_engine->GetPaintedPartColorScheme( + WebThemeEngine::kPartScrollbarCorner)); } // Test scrollbar-gutter values with classic scrollbars and horizontal-tb text.
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index f22b3ca..5705f06 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -1849,19 +1849,6 @@ previous_window != frame_->DomWindow(), frame_->DomWindow()->GetSandboxFlags(), security_init.FeaturePolicyHeader(), document_policy_.feature_state); - // Originally, before OOPIFs, the previous document associated with the - // frame will always already by detached at this point, so no JS unload - // handlers should run. However, with OOPIFs, this `LocalFrame` might - // still be provisional: it doesn't become swapped in until Blink notifies - // the embedder by calling `DidCommitNavigation()`. As a result, - // `DidCommitLoad()` might end up running the unload handlers for the - // previous *frame* when swapping it out, which might detach `this`. - // - // TODO(https://crbug.com/1153043): Fix this so that the frame is swapped - // in earlier, at `FrameLoader::DetachDocument()`. At that point, it is - // certain that the navigation will commit. - if (!frame_) - return; } // TODO(dgozman): make DidCreateScriptContext notification call currently // triggered by installing new document happen here, after commit.
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index 98aff16..16f9a1d 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -1053,7 +1053,20 @@ DCHECK(Client()->HasWebView()); scoped_refptr<SecurityOrigin> security_origin = SecurityOrigin::Create(navigation_params->url); - if (!DetachDocument(security_origin.get(), &unload_timing)) + + // If `frame_` is provisional, this is largely a no-op other than cleaning + // up the initial (and unused) empty document. Otherwise, this unloads the + // previous Document and detaches subframes. If `DetachDocument()` returns + // false, JS caused `frame_` to be removed, so just return. + const bool is_provisional = frame_->IsProvisional(); + if (!DetachDocument(security_origin.get(), &unload_timing)) { + DCHECK(!is_provisional); + return; + } + + // If the frame is provisional, swap it in now. However, if `Swap()` returns + // false, JS caused `frame_` to be removed, so just return. + if (is_provisional && !frame_->SwapIn()) return; } @@ -1184,6 +1197,7 @@ DCHECK_EQ(client_navigation_.get(), client_navigation); // No more events will be dispatched so detach the Document. + // TODO(dcheng): Why is this a conditional check? // TODO(yoav): Should we also be nullifying domWindow's document (or // domWindow) since the doc is now detached? frame_->GetDocument()->Shutdown();
diff --git a/third_party/blink/renderer/core/paint/custom_scrollbar_theme.cc b/third_party/blink/renderer/core/paint/custom_scrollbar_theme.cc index cbec2f6..bf189b3 100644 --- a/third_party/blink/renderer/core/paint/custom_scrollbar_theme.cc +++ b/third_party/blink/renderer/core/paint/custom_scrollbar_theme.cc
@@ -135,7 +135,7 @@ const Scrollbar* vertical_scrollbar, const DisplayItemClient& display_item_client, const IntRect& corner_rect, - ColorScheme color_scheme) { + mojom::blink::ColorScheme color_scheme) { if (DrawingRecorder::UseCachedDrawingIfPossible(context, display_item_client, DisplayItem::kScrollCorner)) return;
diff --git a/third_party/blink/renderer/core/paint/custom_scrollbar_theme.h b/third_party/blink/renderer/core/paint/custom_scrollbar_theme.h index 43cacd9..ec8a9ec3 100644 --- a/third_party/blink/renderer/core/paint/custom_scrollbar_theme.h +++ b/third_party/blink/renderer/core/paint/custom_scrollbar_theme.h
@@ -50,7 +50,7 @@ const Scrollbar* vertical_scrollbar, const DisplayItemClient&, const IntRect& corner_rect, - ColorScheme color_scheme) override; + mojom::blink::ColorScheme color_scheme) override; bool ShouldCenterOnThumb(const Scrollbar& scrollbar, const WebMouseEvent& event) override {
diff --git a/third_party/blink/renderer/core/paint/highlight_painting_utils.cc b/third_party/blink/renderer/core/paint/highlight_painting_utils.cc index 5804267..ed8594f 100644 --- a/third_party/blink/renderer/core/paint/highlight_painting_utils.cc +++ b/third_party/blink/renderer/core/paint/highlight_painting_utils.cc
@@ -35,7 +35,7 @@ } Color ForcedSystemForegroundColor(PseudoId pseudo_id, - ColorScheme color_scheme) { + mojom::blink::ColorScheme color_scheme) { CSSValueID keyword = CSSValueID::kHighlighttext; switch (pseudo_id) { case kPseudoIdTargetText: @@ -53,7 +53,7 @@ } Color ForcedSystemBackgroundColor(PseudoId pseudo_id, - ColorScheme color_scheme) { + mojom::blink::ColorScheme color_scheme) { CSSValueID keyword = CSSValueID::kHighlight; switch (pseudo_id) { case kPseudoIdTargetText: @@ -174,7 +174,7 @@ scoped_refptr<const ComputedStyle> pseudo_style = HighlightPseudoStyle(node, pseudo); - ColorScheme color_scheme = style.UsedColorScheme(); + mojom::blink::ColorScheme color_scheme = style.UsedColorScheme(); if (pseudo_style) { if (!document.InForcedColorsMode() || pseudo_style->ForcedColorAdjust() == EForcedColorAdjust::kNone) { @@ -200,7 +200,7 @@ return Color::kTransparent; } - ColorScheme color_scheme = style.UsedColorScheme(); + mojom::blink::ColorScheme color_scheme = style.UsedColorScheme(); if (scoped_refptr<const ComputedStyle> pseudo_style = HighlightPseudoStyle(node, pseudo)) { if (!document.InForcedColorsMode() ||
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc index a93098f5..21236ef 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -1249,7 +1249,7 @@ return GetLayoutBox()->StyleRef().GetScrollBehavior(); } -ColorScheme PaintLayerScrollableArea::UsedColorScheme() const { +mojom::blink::ColorScheme PaintLayerScrollableArea::UsedColorScheme() const { return GetLayoutBox()->StyleRef().UsedColorScheme(); }
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h index a7a2903..6fad682f 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
@@ -350,7 +350,7 @@ bool ShouldPlaceVerticalScrollbarOnLeft() const override; int PageStep(ScrollbarOrientation) const override; mojom::blink::ScrollBehavior ScrollBehaviorStyle() const override; - ColorScheme UsedColorScheme() const override; + mojom::blink::ColorScheme UsedColorScheme() const override; cc::AnimationHost* GetCompositorAnimationHost() const override; CompositorAnimationTimeline* GetCompositorAnimationTimeline() const override; bool HasTickmarks() const override;
diff --git a/third_party/blink/renderer/core/paint/text_paint_style.h b/third_party/blink/renderer/core/paint/text_paint_style.h index 515c9c3..0ad9c1e 100644 --- a/third_party/blink/renderer/core/paint/text_paint_style.h +++ b/third_party/blink/renderer/core/paint/text_paint_style.h
@@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_TEXT_PAINT_STYLE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_TEXT_PAINT_STYLE_H_ -#include "third_party/blink/public/common/css/color_scheme.h" +#include "third_party/blink/public/mojom/frame/color_scheme.mojom-blink-forward.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/style/applied_text_decoration.h" #include "third_party/blink/renderer/platform/graphics/color.h" @@ -24,7 +24,7 @@ Color stroke_color; Color emphasis_mark_color; float stroke_width; - ColorScheme color_scheme; + mojom::blink::ColorScheme color_scheme; const ShadowList* shadow; base::Optional<AppliedTextDecoration> selection_text_decoration;
diff --git a/third_party/blink/renderer/core/paint/theme_painter_default.cc b/third_party/blink/renderer/core/paint/theme_painter_default.cc index 3dbb624..f982084 100644 --- a/third_party/blink/renderer/core/paint/theme_painter_default.cc +++ b/third_party/blink/renderer/core/paint/theme_painter_default.cc
@@ -523,7 +523,8 @@ cancel_button_size, cancel_button_size); IntRect painting_rect = ConvertToPaintingRect( input_layout_box, cancel_button_object, cancel_button_rect, r); - ColorScheme color_scheme = cancel_button_object.StyleRef().UsedColorScheme(); + mojom::blink::ColorScheme color_scheme = + cancel_button_object.StyleRef().UsedColorScheme(); DEFINE_STATIC_REF(Image, cancel_image, (Image::LoadPlatformResource(IDR_SEARCH_CANCEL))); DEFINE_STATIC_REF(Image, cancel_pressed_image, @@ -558,12 +559,14 @@ text_is_dark ? cancel_pressed_image_hc_light_mode : cancel_pressed_image_dark_mode; } else { - color_scheme_adjusted_cancel_image = color_scheme == ColorScheme::kLight - ? cancel_image - : cancel_image_dark_mode; + color_scheme_adjusted_cancel_image = + color_scheme == mojom::blink::ColorScheme::kLight + ? cancel_image + : cancel_image_dark_mode; color_scheme_adjusted_cancel_pressed_image = - color_scheme == ColorScheme::kLight ? cancel_pressed_image - : cancel_pressed_image_dark_mode; + color_scheme == mojom::blink::ColorScheme::kLight + ? cancel_pressed_image + : cancel_pressed_image_dark_mode; } paint_info.context.DrawImage( To<Element>(cancel_button_object.GetNode())->IsActive()
diff --git a/third_party/blink/renderer/core/scroll/scroll_animator_test.cc b/third_party/blink/renderer/core/scroll/scroll_animator_test.cc index e5dbd2b6..8bd5f668 100644 --- a/third_party/blink/renderer/core/scroll/scroll_animator_test.cc +++ b/third_party/blink/renderer/core/scroll/scroll_animator_test.cc
@@ -81,7 +81,7 @@ MOCK_CONST_METHOD0(ScrollbarsCanBeActive, bool()); MOCK_METHOD0(RegisterForAnimation, void()); MOCK_METHOD0(ScheduleAnimation, bool()); - MOCK_CONST_METHOD0(UsedColorScheme, ColorScheme()); + MOCK_CONST_METHOD0(UsedColorScheme, mojom::blink::ColorScheme()); bool UserInputScrollable(ScrollbarOrientation) const override { return true; } bool ShouldPlaceVerticalScrollbarOnLeft() const override { return false; }
diff --git a/third_party/blink/renderer/core/scroll/scrollable_area.h b/third_party/blink/renderer/core/scroll/scrollable_area.h index 9f81f06..c15845a 100644 --- a/third_party/blink/renderer/core/scroll/scrollable_area.h +++ b/third_party/blink/renderer/core/scroll/scrollable_area.h
@@ -28,7 +28,7 @@ #include "base/callback_helpers.h" #include "cc/input/scroll_snap_data.h" -#include "third_party/blink/public/common/css/color_scheme.h" +#include "third_party/blink/public/mojom/frame/color_scheme.mojom-blink-forward.h" #include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink-forward.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/layout/geometry/physical_rect.h" @@ -471,7 +471,7 @@ return mojom::blink::ScrollBehavior::kInstant; } - virtual ColorScheme UsedColorScheme() const = 0; + virtual mojom::blink::ColorScheme UsedColorScheme() const = 0; // Subtracts space occupied by this ScrollableArea's scrollbars. // Does nothing if overlay scrollbars are enabled.
diff --git a/third_party/blink/renderer/core/scroll/scrollbar.cc b/third_party/blink/renderer/core/scroll/scrollbar.cc index 3e7beab..6dad36bd 100644 --- a/third_party/blink/renderer/core/scroll/scrollbar.cc +++ b/third_party/blink/renderer/core/scroll/scrollbar.cc
@@ -833,7 +833,7 @@ return false; } -ColorScheme Scrollbar::UsedColorScheme() const { +mojom::blink::ColorScheme Scrollbar::UsedColorScheme() const { return scrollable_area_->UsedColorScheme(); }
diff --git a/third_party/blink/renderer/core/scroll/scrollbar.h b/third_party/blink/renderer/core/scroll/scrollbar.h index d4b4dcd..71d8652 100644 --- a/third_party/blink/renderer/core/scroll/scrollbar.h +++ b/third_party/blink/renderer/core/scroll/scrollbar.h
@@ -26,7 +26,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_H_ -#include "third_party/blink/public/common/css/color_scheme.h" +#include "third_party/blink/public/mojom/frame/color_scheme.mojom-blink-forward.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/scroll/scroll_types.h" #include "third_party/blink/renderer/platform/graphics/compositor_element_id.h" @@ -199,7 +199,7 @@ // is the element that owns our PaintLayerScrollableArea. Element* StyleSource() const { return style_source_.Get(); } - ColorScheme UsedColorScheme() const; + mojom::blink::ColorScheme UsedColorScheme() const; virtual void Trace(Visitor*) const;
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_test_suite.h b/third_party/blink/renderer/core/scroll/scrollbar_test_suite.h index 4e163575..e162dcc 100644 --- a/third_party/blink/renderer/core/scroll/scrollbar_test_suite.h +++ b/third_party/blink/renderer/core/scroll/scrollbar_test_suite.h
@@ -71,7 +71,7 @@ MOCK_CONST_METHOD0(VerticalScrollbar, Scrollbar*()); MOCK_CONST_METHOD0(ScrollbarsHiddenIfOverlay, bool()); MOCK_METHOD0(ScheduleAnimation, bool()); - MOCK_CONST_METHOD0(UsedColorScheme, ColorScheme()); + MOCK_CONST_METHOD0(UsedColorScheme, mojom::blink::ColorScheme()); bool UserInputScrollable(ScrollbarOrientation) const override { return true; } bool ScrollbarsCanBeActive() const override { return true; }
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_theme.cc b/third_party/blink/renderer/core/scroll/scrollbar_theme.cc index fdd88700..311edef 100644 --- a/third_party/blink/renderer/core/scroll/scrollbar_theme.cc +++ b/third_party/blink/renderer/core/scroll/scrollbar_theme.cc
@@ -108,7 +108,7 @@ const Scrollbar* vertical_scrollbar, const DisplayItemClient& display_item_client, const IntRect& corner_rect, - ColorScheme color_scheme) { + mojom::blink::ColorScheme color_scheme) { if (corner_rect.IsEmpty()) return;
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_theme.h b/third_party/blink/renderer/core/scroll/scrollbar_theme.h index a015ace..0405fe4 100644 --- a/third_party/blink/renderer/core/scroll/scrollbar_theme.h +++ b/third_party/blink/renderer/core/scroll/scrollbar_theme.h
@@ -97,7 +97,7 @@ const Scrollbar* vertical_scrollbar, const DisplayItemClient&, const IntRect& corner_rect, - ColorScheme color_scheme); + mojom::blink::ColorScheme color_scheme); virtual void PaintTickmarks(GraphicsContext&, const Scrollbar&, const IntRect&);
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h b/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h index 84325bb..c0188034 100644 --- a/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h +++ b/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h
@@ -125,7 +125,7 @@ const Scrollbar* vertical_scrollbar, const DisplayItemClient&, const IntRect& corner_rect, - ColorScheme color_scheme) override; + mojom::blink::ColorScheme color_scheme) override; void PaintThumbInternal(GraphicsContext&, const Scrollbar&, const IntRect&,
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.mm b/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.mm index bf96ece..4a9ca3c 100644 --- a/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.mm +++ b/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.mm
@@ -238,15 +238,17 @@ } params.scrollbar_extra.scrollbar_theme = - (scrollbar.UsedColorScheme() == ColorScheme::kDark) ? kDark : kLight; + (scrollbar.UsedColorScheme() == mojom::blink::ColorScheme::kDark) + ? mojom::blink::ColorScheme::kDark + : mojom::blink::ColorScheme::kLight; params.scrollbar_extra.is_overlay = overlay; if (overlay) { params.scrollbar_extra.scrollbar_theme = (scrollbar.GetScrollbarOverlayColorTheme() == kScrollbarOverlayColorThemeLight) - ? kDark - : kLight; + ? mojom::blink::ColorScheme::kDark + : mojom::blink::ColorScheme::kLight; } params.scrollbar_extra.is_hovering = @@ -296,11 +298,12 @@ context.EndLayer(); } -void ScrollbarThemeMac::PaintScrollCorner(GraphicsContext& context, - const Scrollbar* vertical_scrollbar, - const DisplayItemClient& item, - const IntRect& rect, - ColorScheme color_scheme) { +void ScrollbarThemeMac::PaintScrollCorner( + GraphicsContext& context, + const Scrollbar* vertical_scrollbar, + const DisplayItemClient& item, + const IntRect& rect, + mojom::blink::ColorScheme color_scheme) { if (!vertical_scrollbar) { ScrollbarTheme::PaintScrollCorner(context, vertical_scrollbar, item, rect, color_scheme);
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h index 111f154..39d7b2e1 100644 --- a/third_party/blink/renderer/core/style/computed_style.h +++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -2626,17 +2626,18 @@ // Load the images of CSS properties that were deferred by LazyLoad. void LoadDeferredImages(Document&) const; - enum ColorScheme ComputedColorScheme() const { - return DarkColorScheme() ? ColorScheme::kDark : ColorScheme::kLight; + mojom::blink::ColorScheme ComputedColorScheme() const { + return DarkColorScheme() ? mojom::blink::ColorScheme::kDark + : mojom::blink::ColorScheme::kLight; } - enum ColorScheme UsedColorScheme() const { + mojom::blink::ColorScheme UsedColorScheme() const { return RuntimeEnabledFeatures::CSSColorSchemeUARenderingEnabled() ? ComputedColorScheme() - : ColorScheme::kLight; + : mojom::blink::ColorScheme::kLight; } - enum ColorScheme UsedColorSchemeForInitialColors() const { + mojom::blink::ColorScheme UsedColorSchemeForInitialColors() const { return ComputedColorScheme(); }
diff --git a/third_party/blink/renderer/core/style/computed_style_test.cc b/third_party/blink/renderer/core/style/computed_style_test.cc index bb184154..5ccdd58 100644 --- a/third_party/blink/renderer/core/style/computed_style_test.cc +++ b/third_party/blink/renderer/core/style/computed_style_test.cc
@@ -690,10 +690,10 @@ light_value->Append(*CSSIdentifierValue::Create(CSSValueID::kLight)); To<Longhand>(ref.GetProperty()).ApplyValue(state, *dark_value); - EXPECT_EQ(ColorScheme::kDark, style->UsedColorScheme()); + EXPECT_EQ(mojom::blink::ColorScheme::kDark, style->UsedColorScheme()); To<Longhand>(ref.GetProperty()).ApplyValue(state, *light_value); - EXPECT_EQ(ColorScheme::kLight, style->UsedColorScheme()); + EXPECT_EQ(mojom::blink::ColorScheme::kLight, style->UsedColorScheme()); } TEST(ComputedStyleTest, ApplyInternalLightDarkColor) {
diff --git a/third_party/blink/renderer/core/style/shadow_list.cc b/third_party/blink/renderer/core/style/shadow_list.cc index 7d0a0a8..64ed569 100644 --- a/third_party/blink/renderer/core/style/shadow_list.cc +++ b/third_party/blink/renderer/core/style/shadow_list.cc
@@ -52,7 +52,7 @@ sk_sp<SkDrawLooper> ShadowList::CreateDrawLooper( DrawLooperBuilder::ShadowAlphaMode alpha_mode, const Color& current_color, - ColorScheme color_scheme, + mojom::blink::ColorScheme color_scheme, bool is_horizontal) const { DrawLooperBuilder draw_looper_builder; for (wtf_size_t i = Shadows().size(); i--;) {
diff --git a/third_party/blink/renderer/core/style/shadow_list.h b/third_party/blink/renderer/core/style/shadow_list.h index fa73caa..78ee292 100644 --- a/third_party/blink/renderer/core/style/shadow_list.h +++ b/third_party/blink/renderer/core/style/shadow_list.h
@@ -67,7 +67,7 @@ sk_sp<SkDrawLooper> CreateDrawLooper(DrawLooperBuilder::ShadowAlphaMode, const Color& current_color, - ColorScheme color_scheme, + mojom::blink::ColorScheme color_scheme, bool is_horizontal = true) const; private:
diff --git a/third_party/blink/renderer/core/svg/svg_animated_color.cc b/third_party/blink/renderer/core/svg/svg_animated_color.cc index abe32f0e..483620b 100644 --- a/third_party/blink/renderer/core/svg/svg_animated_color.cc +++ b/third_party/blink/renderer/core/svg/svg_animated_color.cc
@@ -56,12 +56,12 @@ return Color::kTransparent; } -static inline ColorScheme ColorSchemeForSVGElement( +static inline mojom::blink::ColorScheme ColorSchemeForSVGElement( const SVGElement* target_element) { DCHECK(target_element); if (const ComputedStyle* target_style = target_element->GetComputedStyle()) return target_style->UsedColorScheme(); - return ColorScheme::kLight; + return mojom::blink::ColorScheme::kLight; } void SVGColorProperty::Add(const SVGPropertyBase* other, @@ -69,7 +69,8 @@ DCHECK(context_element); Color fallback_color = FallbackColorForCurrentColor(context_element); - ColorScheme color_scheme = ColorSchemeForSVGElement(context_element); + mojom::blink::ColorScheme color_scheme = + ColorSchemeForSVGElement(context_element); Color from_color = To<SVGColorProperty>(other)->style_color_.Resolve( fallback_color, color_scheme); Color to_color = style_color_.Resolve(fallback_color, color_scheme); @@ -92,7 +93,8 @@ // Apply currentColor rules. DCHECK(context_element); Color fallback_color = FallbackColorForCurrentColor(context_element); - ColorScheme color_scheme = ColorSchemeForSVGElement(context_element); + mojom::blink::ColorScheme color_scheme = + ColorSchemeForSVGElement(context_element); Color from_color = from_style_color.Resolve(fallback_color, color_scheme); Color to_color = to_style_color.Resolve(fallback_color, color_scheme); Color to_at_end_of_duration_color = @@ -129,7 +131,8 @@ const SVGElement* context_element) const { DCHECK(context_element); Color fallback_color = FallbackColorForCurrentColor(context_element); - ColorScheme color_scheme = ColorSchemeForSVGElement(context_element); + mojom::blink::ColorScheme color_scheme = + ColorSchemeForSVGElement(context_element); Color from_color = style_color_.Resolve(fallback_color, color_scheme); Color to_color = To<SVGColorProperty>(to_value)->style_color_.Resolve(
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc index 89c1c49c..4fecf3d 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc
@@ -52,7 +52,7 @@ static ColorParseResult ParseColor(Color& parsed_color, const String& color_string, - ColorScheme color_scheme) { + mojom::blink::ColorScheme color_scheme) { if (EqualIgnoringASCIICase(color_string, "currentcolor")) return kParsedCurrentColor; const bool kUseStrictParsing = true; @@ -72,7 +72,7 @@ return color; } -static ColorScheme ColorScheme(HTMLCanvasElement* canvas) { +static mojom::blink::ColorScheme ColorScheme(HTMLCanvasElement* canvas) { if (canvas && canvas->isConnected()) { if (auto* style = canvas->GetComputedStyle()) return style->UsedColorScheme();
diff --git a/third_party/blink/renderer/modules/peerconnection/webrtc_audio_renderer_test.cc b/third_party/blink/renderer/modules/peerconnection/webrtc_audio_renderer_test.cc index d9cc7ff41..4d082c353 100644 --- a/third_party/blink/renderer/modules/peerconnection/webrtc_audio_renderer_test.cc +++ b/third_party/blink/renderer/modules/peerconnection/webrtc_audio_renderer_test.cc
@@ -208,6 +208,7 @@ } void TearDown() override { + base::RunLoop().RunUntilIdle(); renderer_proxy_ = nullptr; renderer_ = nullptr; stream_descriptor_ = nullptr;
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc b/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc index 5eafbdb5b..348295f7 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc +++ b/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc
@@ -9,6 +9,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/double_sequence_or_gpu_color_dict.h" #include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_enforce_range_sequence_or_gpu_extent_3d_dict.h" #include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_enforce_range_sequence_or_gpu_origin_3d_dict.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_index_format.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_programmable_stage_descriptor.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_copy_view.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_data_layout.h" @@ -435,6 +436,15 @@ return WGPUIndexFormat_Force32; } +WGPUIndexFormat AsDawnEnum(const V8GPUIndexFormat& webgpu_enum) { + switch (webgpu_enum.AsEnum()) { + case V8GPUIndexFormat::Enum::kUint16: + return WGPUIndexFormat_Uint16; + case V8GPUIndexFormat::Enum::kUint32: + return WGPUIndexFormat_Uint32; + } +} + template <> WGPUPrimitiveTopology AsDawnEnum<WGPUPrimitiveTopology>( const WTF::String& webgpu_enum) {
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_conversions.h b/third_party/blink/renderer/modules/webgpu/dawn_conversions.h index 4d37448..b4a688f53 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_conversions.h +++ b/third_party/blink/renderer/modules/webgpu/dawn_conversions.h
@@ -26,6 +26,7 @@ class GPUTextureDataLayout; class UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict; class UnsignedLongEnforceRangeSequenceOrGPUOrigin3DDict; +class V8GPUIndexFormat; // Convert WebGPU bitfield values to Dawn enums. These have the same value. template <typename DawnEnum> @@ -36,6 +37,7 @@ // Convert WebGPU string enums to Dawn enums. template <typename DawnEnum> DawnEnum AsDawnEnum(const WTF::String& webgpu_enum); +WGPUIndexFormat AsDawnEnum(const V8GPUIndexFormat& webgpu_enum); // These conversions are used multiple times and are declared here. Conversions // used only once, for example for object construction, are defined
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc b/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc index 0068120..cb8381b7 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc
@@ -110,12 +110,11 @@ } void GPURenderBundleEncoder::setIndexBuffer(GPUBuffer* buffer, - const WTF::String& format, + const V8GPUIndexFormat& format, uint64_t offset, uint64_t size) { GetProcs().renderBundleEncoderSetIndexBufferWithFormat( - GetHandle(), buffer->GetHandle(), AsDawnEnum<WGPUIndexFormat>(format), - offset, size); + GetHandle(), buffer->GetHandle(), AsDawnEnum(format), offset, size); } void GPURenderBundleEncoder::setVertexBuffer(uint32_t slot,
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h b/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h index 2f724df..de73fc6f 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_RENDER_BUNDLE_ENCODER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_RENDER_BUNDLE_ENCODER_H_ +#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_index_format.h" #include "third_party/blink/renderer/modules/webgpu/dawn_object.h" #include "third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" @@ -48,7 +49,7 @@ void setPipeline(GPURenderPipeline* pipeline); void setIndexBuffer(GPUBuffer* buffer, - const WTF::String& format, + const V8GPUIndexFormat& format, uint64_t offset, uint64_t size); void setVertexBuffer(uint32_t slot,
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc index bf94a533..f175ef5 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h" #include "third_party/blink/renderer/bindings/modules/v8/double_sequence_or_gpu_color_dict.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_index_format.h" #include "third_party/blink/renderer/core/typed_arrays/typed_flexible_array_buffer_view.h" #include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h" #include "third_party/blink/renderer/modules/webgpu/gpu_bind_group.h" @@ -109,12 +110,11 @@ } void GPURenderPassEncoder::setIndexBuffer(GPUBuffer* buffer, - const WTF::String& format, + const V8GPUIndexFormat& format, uint64_t offset, uint64_t size) { GetProcs().renderPassEncoderSetIndexBufferWithFormat( - GetHandle(), buffer->GetHandle(), AsDawnEnum<WGPUIndexFormat>(format), - offset, size); + GetHandle(), buffer->GetHandle(), AsDawnEnum(format), offset, size); } void GPURenderPassEncoder::setVertexBuffer(uint32_t slot,
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h index 955e1db..a2b22ee 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h
@@ -18,6 +18,7 @@ class GPURenderBundle; class GPURenderPipeline; class GPUQuerySet; +class V8GPUIndexFormat; class GPURenderPassEncoder : public DawnObject<WGPURenderPassEncoder>, public GPUProgrammablePassEncoder { @@ -54,7 +55,7 @@ float maxDepth); void setScissorRect(uint32_t x, uint32_t y, uint32_t width, uint32_t height); void setIndexBuffer(GPUBuffer* buffer, - const WTF::String& format, + const V8GPUIndexFormat& format, uint64_t offset, uint64_t size); void setVertexBuffer(uint32_t slot,
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index edef967..9c75ef6 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -1616,6 +1616,7 @@ "//mojo/public/cpp/base", "//mojo/public/cpp/bindings", "//services/network/public/mojom:mojom_headers", + "//third_party/blink/public/mojom:color_scheme_mojo_bindings", "//third_party/blink/public/mojom:embedded_frame_sink_mojo_bindings_blink", "//third_party/blink/renderer/platform/blob", "//third_party/blink/renderer/platform/heap",
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.cc b/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.cc index 3e7a6a0..50fe5ec5 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.cc
@@ -362,6 +362,14 @@ if (result_out->is_overflow) return ShapeToEnd(start, first_safe, range_start, range_end); break_opportunity.offset = range_end; + if (break_opportunity.non_hangable_run_end && + range_end < break_opportunity.non_hangable_run_end) { + break_opportunity.non_hangable_run_end = base::nullopt; + } + if (IsBreakableSpace(text[range_end - 1])) { + break_opportunity.non_hangable_run_end = + FindNonHangableEnd(text, range_end - 1); + } } CheckBreakOffset(break_opportunity.offset, start, range_end);
diff --git a/third_party/blink/renderer/platform/graphics/DEPS b/third_party/blink/renderer/platform/graphics/DEPS index 44d4fa7..978c513b 100644 --- a/third_party/blink/renderer/platform/graphics/DEPS +++ b/third_party/blink/renderer/platform/graphics/DEPS
@@ -75,6 +75,9 @@ "+ui/gl/buffer_format_utils.h", ], "(graphics_context|skia_utils)\.cc" : [ "+ui/base/ui_base_features.h" ], + "graphics_context.h": [ + "+third_party/blink/public/mojom/frame/frame_owner_properties.mojom-blink.h", + ], "rw_buffer_test.cc": [ "+base/threading/platform_thread.h", ],
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.cc b/third_party/blink/renderer/platform/graphics/graphics_context.cc index a4b57960..0fa9d765 100644 --- a/third_party/blink/renderer/platform/graphics/graphics_context.cc +++ b/third_party/blink/renderer/platform/graphics/graphics_context.cc
@@ -32,6 +32,7 @@ #include "build/build_config.h" #include "components/paint_preview/common/paint_preview_tracker.h" #include "skia/ext/platform_canvas.h" +#include "third_party/blink/public/mojom/frame/color_scheme.mojom-blink.h" #include "third_party/blink/renderer/platform/fonts/text_run_paint_info.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/geometry/float_rounded_rect.h" @@ -426,14 +427,14 @@ float border_radius, float min_border_width, const Color& color, - ColorScheme color_scheme) { + mojom::blink::ColorScheme color_scheme) { #if defined(OS_MAC) - const Color& inner_color = color_scheme == ColorScheme::kDark + const Color& inner_color = color_scheme == mojom::blink::ColorScheme::kDark ? SkColorSetRGB(0x99, 0xC8, 0xFF) : color; #else const Color& inner_color = - color_scheme == ColorScheme::kDark ? SK_ColorWHITE : color; + color_scheme == mojom::blink::ColorScheme::kDark ? SK_ColorWHITE : color; #endif if (::features::IsFormControlsRefreshEnabled()) { // The focus ring is made of two borders which have a 2:1 ratio. @@ -445,7 +446,7 @@ if (min_border_width >= inside_border_width) { offset -= inside_border_width; } - const Color& outer_color = color_scheme == ColorScheme::kDark + const Color& outer_color = color_scheme == mojom::blink::ColorScheme::kDark ? SkColorSetRGB(0x10, 0x10, 0x10) : SK_ColorWHITE; // The outer ring is drawn first, and we overdraw to ensure no gaps or AA
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.h b/third_party/blink/renderer/platform/graphics/graphics_context.h index f7c07b9..9c1bf446 100644 --- a/third_party/blink/renderer/platform/graphics/graphics_context.h +++ b/third_party/blink/renderer/platform/graphics/graphics_context.h
@@ -31,7 +31,7 @@ #include <memory> #include "base/macros.h" -#include "third_party/blink/public/common/css/color_scheme.h" +#include "third_party/blink/public/mojom/frame/color_scheme.mojom-blink-forward.h" #include "third_party/blink/renderer/platform/fonts/font.h" #include "third_party/blink/renderer/platform/graphics/dark_mode_filter.h" #include "third_party/blink/renderer/platform/graphics/dark_mode_settings.h" @@ -356,7 +356,7 @@ float border_radius, float min_border_width, const Color&, - ColorScheme color_scheme); + mojom::blink::ColorScheme color_scheme); void DrawFocusRing(const Path&, float width, int offset, const Color&); const PaintFlags& FillFlags() const { return ImmutableState()->FillFlags(); }
diff --git a/third_party/blink/renderer/platform/scheduler/common/features.h b/third_party/blink/renderer/platform/scheduler/common/features.h index 103b2b14..bab6727 100644 --- a/third_party/blink/renderer/platform/scheduler/common/features.h +++ b/third_party/blink/renderer/platform/scheduler/common/features.h
@@ -301,6 +301,12 @@ &kPerAgentSchedulingExperiments, "signal", PerAgentSignal::kFirstMeaningfulPaint, &kPerAgentSignalOptions}; +// If enabled, base::ThreadTaskRunnerHandle::Get() and +// base::SequencedTaskRunnerHandle::Get() returns the current active +// per-ASG task runner instead of the per-thread task runner. +const base::Feature kMbiOverrideTaskRunnerHandle{ + "MbiOverrideTaskRunnerHandle", base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kThrottleVisibleNotFocusedTimers{ "ThrottleVisibleNotFocusedTimers", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h b/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h index b12d21e..7bf92a97 100644 --- a/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h +++ b/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h
@@ -121,6 +121,10 @@ virtual void ShutdownAllQueues() {} + const scoped_refptr<base::SingleThreadTaskRunner>& default_task_runner() { + return default_task_runner_; + } + base::ThreadChecker thread_checker_; base::sequence_manager::SequenceManager* sequence_manager_; // NOT OWNED
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.cc index 0aacf6d..6aa9bf02 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.cc
@@ -37,7 +37,7 @@ } AgentGroupSchedulerImpl::~AgentGroupSchedulerImpl() { - default_task_queue_->ShutdownTaskQueue(); + default_task_queue_->DetachFromMainThreadScheduler(); main_thread_scheduler_.RemoveAgentGroupScheduler(this); }
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.cc b/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.cc index ad03fa3..4092e81e 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.cc
@@ -10,11 +10,11 @@ namespace scheduler { IdleTimeEstimator::IdleTimeEstimator( - const scoped_refptr<MainThreadTaskQueue>& compositor_task_runner, + const scoped_refptr<MainThreadTaskQueue>& compositor_task_queue, const base::TickClock* time_source, int sample_count, double estimation_percentile) - : compositor_task_queue_(compositor_task_runner), + : compositor_task_queue_(compositor_task_queue), per_frame_compositor_task_runtime_(sample_count), time_source_(time_source), estimation_percentile_(estimation_percentile),
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h b/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h index db4b01b..659e914 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h
@@ -19,7 +19,7 @@ class PLATFORM_EXPORT IdleTimeEstimator : public base::TaskObserver { public: IdleTimeEstimator( - const scoped_refptr<MainThreadTaskQueue>& compositor_task_runner, + const scoped_refptr<MainThreadTaskQueue>& compositor_task_queue, const base::TickClock* time_source, int sample_count, double estimation_percentile);
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc index a15e2a4..11360b0 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc
@@ -42,7 +42,7 @@ const scoped_refptr<base::SingleThreadTaskRunner>& MainThreadSchedulerHelper::DefaultTaskRunner() { - return default_task_queue_->GetTaskRunnerWithDefaultTaskType(); + return default_task_runner(); } scoped_refptr<MainThreadTaskQueue> @@ -59,7 +59,7 @@ MainThreadSchedulerHelper::DeprecatedDefaultTaskRunner() { // TODO(hajimehoshi): Introduce a different task queue from the default task // queue and return the task runner created from it. - return DefaultTaskRunner(); + return default_task_runner(); } scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerHelper::NewTaskQueue(
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc index d6bdc95..e5651e4 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
@@ -376,10 +376,10 @@ MainThreadSchedulerImpl::MainThreadOnly::MainThreadOnly( MainThreadSchedulerImpl* main_thread_scheduler_impl, - const scoped_refptr<MainThreadTaskQueue>& compositor_task_runner, + const scoped_refptr<MainThreadTaskQueue>& compositor_task_queue, const base::TickClock* time_source, base::TimeTicks now) - : idle_time_estimator(compositor_task_runner, + : idle_time_estimator(compositor_task_queue, time_source, kShortIdlePeriodDurationSampleCount, kShortIdlePeriodDurationPercentile), @@ -2465,30 +2465,91 @@ return current_agent_group_scheduler_; } -void MainThreadSchedulerImpl::SetCurrentAgentGroupScheduler( - WebAgentGroupScheduler* agent_group_scheduler) { - helper_.CheckOnValidThread(); - if (current_agent_group_scheduler_) { - TRACE_EVENT_NESTABLE_ASYNC_END1( - TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), - "scheduler.agent_scope", current_agent_group_scheduler_, - "agent_group_scheduler", current_agent_group_scheduler_); +void MainThreadSchedulerImpl::BeginAgentGroupSchedulerScope( + WebAgentGroupScheduler* next_agent_group_scheduler) { + scoped_refptr<base::SingleThreadTaskRunner> next_task_runner; + const char* trace_event_scope_name; + void* trace_event_scope_id; + + if (next_agent_group_scheduler) { + // If the |next_agent_group_scheduler| is not null, it means that a + // per-AgentSchedulingGroup task is about to start. In this case, a + // per-AgentGroupScheduler scope starts. + next_task_runner = next_agent_group_scheduler->DefaultTaskRunner(), + trace_event_scope_name = "scheduler.agent_scope"; + trace_event_scope_id = next_agent_group_scheduler; } else { - TRACE_EVENT_NESTABLE_ASYNC_END0( - TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), - "scheduler.thread_scope", this); + // If the |next_agent_group_scheduler| is null, it means that a + // per-thread task is about to start. In this case, a per-thread scope + // starts. + next_task_runner = helper_.DefaultTaskRunner(); + trace_event_scope_name = "scheduler.thread_scope"; + trace_event_scope_id = this; } - current_agent_group_scheduler_ = agent_group_scheduler; - if (current_agent_group_scheduler_) { - TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( - TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), - "scheduler.agent_scope", current_agent_group_scheduler_, - "agent_group_scheduler", current_agent_group_scheduler_); - } else { - TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( - TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), - "scheduler.thread_scope", this); + + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( + TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), trace_event_scope_name, + trace_event_scope_id, "agent_group_scheduler", + next_agent_group_scheduler); + + WebAgentGroupScheduler* previous_agent_group_scheduler = + current_agent_group_scheduler_; + current_agent_group_scheduler_ = next_agent_group_scheduler; + + scoped_refptr<base::SingleThreadTaskRunner> previous_task_runner = + base::ThreadTaskRunnerHandle::Get(); + std::unique_ptr<base::ThreadTaskRunnerHandleOverride> + thread_task_runner_handle_override; + if (base::FeatureList::IsEnabled(kMbiOverrideTaskRunnerHandle) && + next_task_runner != previous_task_runner) { + // per-thread and per-AgentSchedulingGroup task runner allows nested + // runloop. |MainThreadSchedulerImpl| guarantees that + // |ThreadTaskRunnerHandle::Get()| and |SequencedTaskRunnerHandle::Get()| + // return a proper task runner even when a nested runloop is used. Because + // |MainThreadSchedulerImpl::OnTaskStarted()| always overrides + // TTRH/STRH::Get() properly. So there is no concern about returning an + // unexpected task runner from TTRH/STRH::Get() in this specific case. + thread_task_runner_handle_override = + std::unique_ptr<base::ThreadTaskRunnerHandleOverride>( + new base::ThreadTaskRunnerHandleOverride( + next_task_runner, + /*allow_nested_runloop=*/true)); } + + main_thread_only().agent_group_scheduler_scope_stack.emplace_back( + AgentGroupSchedulerScope{ + std::move(thread_task_runner_handle_override), + previous_agent_group_scheduler, next_agent_group_scheduler, + std::move(previous_task_runner), std::move(next_task_runner), + trace_event_scope_name, trace_event_scope_id}); +} + +void MainThreadSchedulerImpl::EndAgentGroupSchedulerScope() { + AgentGroupSchedulerScope& agent_group_scheduler_scope = + main_thread_only().agent_group_scheduler_scope_stack.back(); + + if (base::FeatureList::IsEnabled(kMbiOverrideTaskRunnerHandle)) { + DCHECK_EQ(base::ThreadTaskRunnerHandle::Get(), + agent_group_scheduler_scope.current_task_runner); + DCHECK_EQ(base::SequencedTaskRunnerHandle::Get(), + agent_group_scheduler_scope.current_task_runner); + } + agent_group_scheduler_scope.thread_task_runner_handle_override = nullptr; + DCHECK_EQ(base::ThreadTaskRunnerHandle::Get(), + agent_group_scheduler_scope.previous_task_runner); + DCHECK_EQ(base::SequencedTaskRunnerHandle::Get(), + agent_group_scheduler_scope.previous_task_runner); + + current_agent_group_scheduler_ = + agent_group_scheduler_scope.previous_agent_group_scheduler; + + TRACE_EVENT_NESTABLE_ASYNC_END1( + TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + agent_group_scheduler_scope.trace_event_scope_name, + agent_group_scheduler_scope.trace_event_scope_id, "agent_group_scheduler", + agent_group_scheduler_scope.current_agent_group_scheduler); + + main_thread_only().agent_group_scheduler_scope_stack.pop_back(); } std::unique_ptr<ThreadScheduler::RendererPauseHandle> @@ -2603,7 +2664,7 @@ MainThreadTaskQueue* queue, const base::sequence_manager::Task& task, const TaskQueue::TaskTiming& task_timing) { - SetCurrentAgentGroupScheduler(queue ? queue->GetAgentGroupScheduler() + BeginAgentGroupSchedulerScope(queue ? queue->GetAgentGroupScheduler() : nullptr); main_thread_only().running_queues.push(queue); @@ -2640,6 +2701,10 @@ if (task_timing->has_wall_time() && queue && queue->GetFrameScheduler()) queue->GetFrameScheduler()->AddTaskTime(task_timing->wall_duration()); main_thread_only().running_queues.pop(); + + // The overriding TaskRunnerHandle scope ends here. + EndAgentGroupSchedulerScope(); + if (main_thread_only().nested_runloop) return; @@ -2666,10 +2731,6 @@ find_in_page_budget_pool_controller_->OnTaskCompleted(queue.get(), task_timing); - - // GetCurrentAgentGroupScheduler() should return nullptr when - // it's running thread global task runners. - SetCurrentAgentGroupScheduler(nullptr); } void MainThreadSchedulerImpl::RecordTaskUkm(
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h index 2ef822d..b945303 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
@@ -223,8 +223,6 @@ scoped_refptr<base::SingleThreadTaskRunner> CompositorTaskRunner() override; std::unique_ptr<WebAgentGroupScheduler> CreateAgentGroupScheduler() override; WebAgentGroupScheduler* GetCurrentAgentGroupScheduler() override; - void SetCurrentAgentGroupScheduler( - WebAgentGroupScheduler* agent_group_scheduler); std::unique_ptr<ThreadScheduler::RendererPauseHandle> PauseScheduler() override; base::TimeTicks MonotonicallyIncreasingVirtualTime() override; @@ -494,6 +492,21 @@ void AddAgentGroupScheduler(AgentGroupSchedulerImpl*); + struct AgentGroupSchedulerScope { + std::unique_ptr<base::ThreadTaskRunnerHandleOverride> + thread_task_runner_handle_override; + WebAgentGroupScheduler* previous_agent_group_scheduler; + WebAgentGroupScheduler* current_agent_group_scheduler; + scoped_refptr<base::SingleThreadTaskRunner> previous_task_runner; + scoped_refptr<base::SingleThreadTaskRunner> current_task_runner; + const char* trace_event_scope_name; + void* trace_event_scope_id; + }; + + void BeginAgentGroupSchedulerScope( + WebAgentGroupScheduler* next_agent_group_scheduler); + void EndAgentGroupSchedulerScope(); + bool IsAnyMainFrameWaitingForFirstContentfulPaint() const; bool IsAnyMainFrameWaitingForFirstMeaningfulPaint() const; @@ -862,7 +875,7 @@ struct MainThreadOnly { MainThreadOnly( MainThreadSchedulerImpl* main_thread_scheduler_impl, - const scoped_refptr<MainThreadTaskQueue>& compositor_task_runner, + const scoped_refptr<MainThreadTaskQueue>& compositor_task_queue, const base::TickClock* time_source, base::TimeTicks now); ~MainThreadOnly(); @@ -965,6 +978,8 @@ // kNormalPriority and is updated via UpdateCompositorTaskQueuePriority(). TraceableState<TaskQueue::QueuePriority, TracingCategoryName::kDefault> compositor_priority; + + WTF::Vector<AgentGroupSchedulerScope> agent_group_scheduler_scope_stack; }; struct AnyThread {
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng index 5057588..6199b34 100644 --- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng +++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -247,6 +247,9 @@ crbug.com/1155633 external/wpt/css/css-text/white-space/trailing-ideographic-space-break-spaces-005.html [ Failure ] crbug.com/1155633 external/wpt/css/css-text/white-space/trailing-ideographic-space-break-spaces-006.html [ Failure ] crbug.com/1155633 external/wpt/css/css-text/white-space/trailing-ideographic-space-break-spaces-007.html [ Failure ] +crbug.com/1162836 external/wpt/css/css-text/white-space/trailing-ideographic-space-017.html [ Failure ] +crbug.com/1162836 external/wpt/css/css-text/white-space/trailing-ideographic-space-020.html [ Failure ] +crbug.com/1162836 external/wpt/css/css-text/white-space/trailing-ideographic-space-023.html [ Failure ] ### external/wpt/css/css-text/word-break/ crbug.com/591099 external/wpt/css/css-text/word-break/word-break-break-all-004.html [ Failure ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index c194dc8..14e5e01 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1545,10 +1545,10 @@ crbug.com/1129834 external/wpt/css/css-text/white-space/trailing-other-space-separators-002.html [ Failure ] crbug.com/1129834 external/wpt/css/css-text/white-space/trailing-other-space-separators-003.html [ Failure ] crbug.com/1129834 external/wpt/css/css-text/white-space/trailing-other-space-separators-004.html [ Failure ] -crbug.com/1129834 external/wpt/css/css-text/white-space/full-width-leading-spaces-004.html [ Failure ] crbug.com/1129834 external/wpt/css/css-text/white-space/trailing-ideographic-space-001.html [ Failure ] crbug.com/1129834 external/wpt/css/css-text/white-space/trailing-ideographic-space-002.html [ Failure ] +crbug.com/1162836 external/wpt/css/css-text/white-space/full-width-leading-spaces-004.html [ Failure ] # Follow up the spec change for U+2010, U+2013 crbug.com/1052717 external/wpt/css/css-text/line-break/line-break-loose-hyphens-001.html [ Failure ] @@ -5863,3 +5863,5 @@ crbug.com/1164459 [ Mac ] virtual/synchronous_html_parser/external/wpt/preload/download-resources.html [ Pass Timeout ] crbug.com/1164568 [ Mac ] external/wpt/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-allow-popups-report-to.https.html [ Pass Failure ] +# Sheriff 2021-01-12 +crbug.com/1163793 http/tests/inspector-protocol/page/page-events-associated.js [ Pass Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 1e7c197..733d9af 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -109,6 +109,15 @@ "--disable-blink-features=DecodeJpeg420ImagesToYUV"] }, { + "prefix": "v8-off-thread-finalization", + "bases": [ + "external/wpt/html/semantics/scripting-1", + "fast/dom", + "http/tests/devtools/isolated-code-cache/" + ], + "args": ["--enable-features=V8OffThreadFinalization,SmallScriptStreaming"] + }, + { "prefix": "exotic-color-space", "bases": ["images"], "args": ["--force-color-profile=srgb",
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index 9f227db..d6f23f6 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -777,6 +777,19 @@ } }, "html": { + "browsers": { + "origin": { + "origin-keyed-agent-clusters": { + "popups-crash.https.html": [ + "dcfb5eb277489b5849f250275d6ce8197eedc224", + [ + null, + {} + ] + ] + } + } + }, "canvas": { "element": { "manual": { @@ -1097,15 +1110,6 @@ ] } }, - "origin-isolation": { - "popups-crash.https.html": [ - "dcfb5eb277489b5849f250275d6ce8197eedc224", - [ - null, - {} - ] - ] - }, "portals": { "portals-no-frame-crash.html": [ "c87afa38c29bf98344c9d01039ed6bf9af1d5d96", @@ -221262,7 +221266,7 @@ [] ], "idlharness-extensions.window-expected.txt": [ - "8f261de6141c5b9a74ede23340cb3bb90ffe4a61", + "2add0e7fd942673ae9c2b9deb57a862e2916864e", [] ], "idlharness.https.window-expected.txt": [ @@ -222583,6 +222587,246 @@ [] ] }, + "origin-keyed-agent-clusters": { + "1-iframe": { + "parent-yes-child-no-port.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "parent-yes-child-no-same.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "parent-yes-child-no-subdomain.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "parent-yes-child-yes-port.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "parent-yes-child-yes-same.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "parent-yes-child-yes-subdomain.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ] + }, + "2-iframes": { + "parent-yes-child1-no-subdomain-child2-no-subdomain.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "parent-yes-child1-no-subdomain-child2-no-subdomain2.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "parent-yes-child1-no-subdomain-child2-yes-subdomain.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "parent-yes-child1-no-subdomain-child2-yes-subdomain2.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "parent-yes-child1-no-subdomain-child2-yes-subdomainport.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "parent-yes-child1-yes-subdomain-child2-no-port.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "parent-yes-child1-yes-subdomain-child2-no-subdomain.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "parent-yes-child1-yes-subdomain-child2-yes-subdomain.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "parent-yes-child1-yes-subdomain-child2-yes-subdomain2.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "parent-yes-child1-yes-subdomain-child2-yes-subdomainport.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ] + }, + "META.yml": [ + "f21ce69f6a710cafbb84cdbe715ffd8ae0bc75af", + [] + ], + "OWNERS": [ + "263ee12ddb3e9a1f485fcc61802915f7bfb14bcd", + [] + ], + "README.md": [ + "85ba3bce7f8740793791923a7d711b755531048a", + [] + ], + "about-blank.https.sub.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "document-domain.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "getter-special-cases": { + "csp-sandbox-no.https.html.headers": [ + "4705ce9dedeeabf8208bf602176511c0cbe2cb76", + [] + ], + "csp-sandbox-yes.https.html.headers": [ + "a52bf509006a3b9a5518f4f0679b05d7cff12b42", + [] + ], + "data-to-javascript-yes.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "data-url-yes.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "javascript-url-yes.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "removed-iframe.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "resources": { + "data-to-javascript-test.mjs": [ + "3a88253ee3053465472ef7d6ecba74b92fab79ce", + [] + ], + "data-url-test.mjs": [ + "1a9b3be47f67b57bc8299def97cc660f6a282b9d", + [] + ], + "helpers.mjs": [ + "4610ffcad0a2f4be0f495a4d9e0107ecadf63eae", + [] + ], + "javascript-url-test.mjs": [ + "de474d8cafca9c073f306034b6c70c68d4222b31", + [] + ], + "sandboxed-iframe-test.sub.mjs": [ + "9357df00c5c686f0c06e7822644cff71d40dc20d", + [] + ], + "sandboxed-same-origin-iframe-test.sub.mjs": [ + "272f805870c932377b80b442f850d55018fdf0dd", + [] + ] + }, + "sandboxed-iframe-yes.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "sandboxed-same-origin-iframe-yes.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ] + }, + "going-back.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "iframe-navigation": { + "parent-yes-1-no-same-2-no-port.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "parent-yes-1-no-same-2-no-subdomain.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ] + }, + "insecure-http.sub.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "popups": { + "opener-yes-openee-no-port.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "opener-yes-openee-no-same.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "opener-yes-openee-no-subdomain.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "opener-yes-openee-yes-port.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "opener-yes-openee-yes-same.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "opener-yes-openee-yes-subdomain.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ] + }, + "removing-iframes.sub.https.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "resources": { + "README.md": [ + "9292fe3894e4a82f77a8877b76faa19fe6dfdb47", + [] + ], + "crashy-popup.sub.html": [ + "45c8d5074d22b3233d8bee4c6d1236e8899009e4", + [] + ], + "crashy-popup.sub.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "frame.html": [ + "537de07b140d79367161c5be16918b79e8d40048", + [] + ], + "frame.html.headers": [ + "79a20f30fc0f486014c8b93edef7483605101504", + [] + ], + "helpers.mjs": [ + "f858c5fefbca75c30a958e31ac46c264e7007337", + [] + ], + "helpers.mjs.headers": [ + "cb762eff806849df46dc758ef7b98b63f27f54c9", + [] + ], + "send-header-page-script.mjs": [ + "17b00684d643c85a30465435489ac31bceb9eb2d", + [] + ], + "send-header-page-script.mjs.headers": [ + "cb762eff806849df46dc758ef7b98b63f27f54c9", + [] + ], + "send-oac-header.py": [ + "cc8860fe75b0ab504553513ac17f1cf5ee805758", + [] + ] + } + }, "relaxing-the-same-origin-restriction": { "sandboxed-document_domain.html.headers": [ "82e8023d0ba61851af5747ee2ccba154193d1875", @@ -233878,6 +234122,10 @@ [] ], "pseudo-classes": { + "autofill-expected.txt": [ + "501f68598b2549f4f62f0d929986dfd32cfab619", + [] + ], "dir-expected.txt": [ "dc9646444d83d4389f765d7a10af342ed2168547", [] @@ -235381,6 +235629,16 @@ ] } }, + "multiple-import-maps": { + "basic-expected.txt": [ + "b56a107449385239c4e36849df466cd961dd97d4", + [] + ], + "with-errors-expected.txt": [ + "2ac5edb148929e6f1c9d3db59cd3989895b89a00", + [] + ] + }, "resources": { "empty.js": [ "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", @@ -236234,7 +236492,7 @@ [] ], "gamepad-extensions.idl": [ - "2d353b061c4b728ce61e61ed4be1f5981027865f", + "29ab815c411b4ce399570e9493f86559bfc0c85c", [] ], "gamepad.idl": [ @@ -239600,246 +239858,6 @@ [] ] }, - "origin-isolation": { - "1-iframe": { - "parent-yes-child-no-port.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "parent-yes-child-no-same.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "parent-yes-child-no-subdomain.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "parent-yes-child-yes-port.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "parent-yes-child-yes-same.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "parent-yes-child-yes-subdomain.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ] - }, - "2-iframes": { - "parent-yes-child1-no-subdomain-child2-no-subdomain.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "parent-yes-child1-no-subdomain-child2-no-subdomain2.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "parent-yes-child1-no-subdomain-child2-yes-subdomain.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "parent-yes-child1-no-subdomain-child2-yes-subdomain2.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "parent-yes-child1-no-subdomain-child2-yes-subdomainport.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "parent-yes-child1-yes-subdomain-child2-no-port.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "parent-yes-child1-yes-subdomain-child2-no-subdomain.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "parent-yes-child1-yes-subdomain-child2-yes-subdomain.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "parent-yes-child1-yes-subdomain-child2-yes-subdomain2.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "parent-yes-child1-yes-subdomain-child2-yes-subdomainport.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ] - }, - "META.yml": [ - "937eca52e71dffcbd50b6f9dd869cb95e1808cd5", - [] - ], - "OWNERS": [ - "263ee12ddb3e9a1f485fcc61802915f7bfb14bcd", - [] - ], - "README.md": [ - "7446ff2495d6ac03d38335817364a6ead115d61e", - [] - ], - "about-blank.https.sub.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "document-domain.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "getter-special-cases": { - "csp-sandbox-no.https.html.headers": [ - "4705ce9dedeeabf8208bf602176511c0cbe2cb76", - [] - ], - "csp-sandbox-yes.https.html.headers": [ - "a52bf509006a3b9a5518f4f0679b05d7cff12b42", - [] - ], - "data-to-javascript-yes.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "data-url-yes.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "javascript-url-yes.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "removed-iframe.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "resources": { - "data-to-javascript-test.mjs": [ - "3a88253ee3053465472ef7d6ecba74b92fab79ce", - [] - ], - "data-url-test.mjs": [ - "d32d8521be47187b7f8db5d8d5d915e8f9d79de3", - [] - ], - "helpers.mjs": [ - "6cc2ed6b697956b859ade3e0c0956c804cc5f8a4", - [] - ], - "javascript-url-test.mjs": [ - "de474d8cafca9c073f306034b6c70c68d4222b31", - [] - ], - "sandboxed-iframe-test.sub.mjs": [ - "98575b8d80ecda8c294d29ca8c40199ef40f6fe9", - [] - ], - "sandboxed-same-origin-iframe-test.sub.mjs": [ - "272f805870c932377b80b442f850d55018fdf0dd", - [] - ] - }, - "sandboxed-iframe-yes.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "sandboxed-same-origin-iframe-yes.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ] - }, - "going-back.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "iframe-navigation": { - "parent-yes-1-no-same-2-no-port.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "parent-yes-1-no-same-2-no-subdomain.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ] - }, - "insecure-http.sub.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "popups": { - "opener-yes-openee-no-port.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "opener-yes-openee-no-same.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "opener-yes-openee-no-subdomain.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "opener-yes-openee-yes-port.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "opener-yes-openee-yes-same.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "opener-yes-openee-yes-subdomain.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ] - }, - "removing-iframes.sub.https.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "resources": { - "README.md": [ - "9292fe3894e4a82f77a8877b76faa19fe6dfdb47", - [] - ], - "crashy-popup.sub.html": [ - "f8d077c2a29ff494d502d70fc7f2cd80a443da68", - [] - ], - "crashy-popup.sub.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "frame.html": [ - "537de07b140d79367161c5be16918b79e8d40048", - [] - ], - "frame.html.headers": [ - "79a20f30fc0f486014c8b93edef7483605101504", - [] - ], - "helpers.mjs": [ - "02ba405c60190019b909ca84bb05c3370b912855", - [] - ], - "helpers.mjs.headers": [ - "cb762eff806849df46dc758ef7b98b63f27f54c9", - [] - ], - "send-header-page-script.mjs": [ - "515987f3f20de655f4d1bab87850e7a625fd1faa", - [] - ], - "send-header-page-script.mjs.headers": [ - "cb762eff806849df46dc758ef7b98b63f27f54c9", - [] - ], - "send-origin-isolation-header.py": [ - "8acf989f964d9964007fa84771843525580fc5fc", - [] - ] - } - }, "origin-policy": { "META.yml": [ "9efb2a7d6718d1c98161329470238a165a004824", @@ -256606,7 +256624,7 @@ [] ], "server.py": [ - "d4472811e593e0232d3ffe86536479e68b11808f", + "2b5ed4a27d5125ba3474b2036fa006924a5dec1f", [] ], "sslutils": { @@ -258984,6 +259002,18 @@ [] ] }, + "get_computed_label": { + "__init__.py": [ + "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + [] + ] + }, + "get_computed_role": { + "__init__.py": [ + "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + [] + ] + }, "get_current_url": { "__init__.py": [ "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", @@ -346988,6 +347018,452 @@ ] ] }, + "origin-keyed-agent-clusters": { + "1-iframe": { + "parent-no-child-bad-subdomain.sub.https.html": [ + "3a45ee6d6a8e2b0d5e449e4d98229ae37aab82ee", + [ + null, + {} + ] + ], + "parent-no-child-yes-port.sub.https.html": [ + "85fb1f64e0975434f838943364d4fe205027f95f", + [ + null, + {} + ] + ], + "parent-no-child-yes-same.sub.https.html": [ + "7ece02c81a257feff3d4ab2f2eb19545384d2928", + [ + null, + {} + ] + ], + "parent-no-child-yes-subdomain-with-redirect.sub.https.html": [ + "994f80876d5f6d31d74ed73fe2dfeef4f1575684", + [ + null, + {} + ] + ], + "parent-no-child-yes-subdomain.sub.https.html": [ + "5fc2fa29f3e851a4d3ab588a9dd8fa4b6e5d81cc", + [ + null, + {} + ] + ], + "parent-no-child-yeswithparams-subdomain.sub.https.html": [ + "3e7c8419b36a096b385f047e7192bc27d352c085", + [ + null, + {} + ] + ], + "parent-yes-child-no-port.sub.https.html": [ + "f00814cfbf63b293b3c6060f3df986127a53056c", + [ + null, + {} + ] + ], + "parent-yes-child-no-same.sub.https.html": [ + "307f8c48d74e5dbfa77b4627ef6e03a75884e1da", + [ + null, + {} + ] + ], + "parent-yes-child-no-subdomain.sub.https.html": [ + "8c823fa36f5bc2321ca87f2e0f4d1bb5cb164c0e", + [ + null, + {} + ] + ], + "parent-yes-child-yes-port.sub.https.html": [ + "5e431e6e41310bb22db730c49deb44886e02dc98", + [ + null, + {} + ] + ], + "parent-yes-child-yes-same.sub.https.html": [ + "3b8c214a6186740e0224486092a8efb42083c949", + [ + null, + {} + ] + ], + "parent-yes-child-yes-subdomain.sub.https.html": [ + "136a3a0bbadbffceafd3512cd8a0e2f4edf95ee2", + [ + null, + {} + ] + ] + }, + "2-iframes": { + "parent-no-child1-no-subdomain-child2-yes-subdomain.sub.https.html": [ + "1bb252f0ab3ad066a48b665e604ce2450f33c2ac", + [ + null, + {} + ] + ], + "parent-no-child1-no-subdomain-child2-yes-subdomainport.sub.https.html": [ + "5b80c528f00895c81f1c2f41a5e253bd4149fd7d", + [ + null, + {} + ] + ], + "parent-no-child1-no-subdomain1-child2-yes-subdomain2.sub.https.html": [ + "bba13b82a4d74cfa41a9c3efe1695bcf9d27be99", + [ + null, + {} + ] + ], + "parent-no-child1-yes-subdomain-child2-no-port.sub.https.html": [ + "d01d1802135c797dd4dd449f4c033d7c50b6366b", + [ + null, + {} + ] + ], + "parent-no-child1-yes-subdomain-child2-no-subdomain.sub.https.html": [ + "9a245b3acef0821934df63efbd3b7aa80cef6e42", + [ + null, + {} + ] + ], + "parent-yes-child1-no-subdomain-child2-no-subdomain.sub.https.html": [ + "c308b9a17acabdcb5403a89d9f3a22e48ad4db6c", + [ + null, + {} + ] + ], + "parent-yes-child1-no-subdomain-child2-no-subdomain2.sub.https.html": [ + "767d908c21f377fc0556d300b23549d18570fee4", + [ + null, + {} + ] + ], + "parent-yes-child1-no-subdomain-child2-yes-subdomain.sub.https.html": [ + "45047f3ae150023df115ae4e7731356ec326e55f", + [ + null, + {} + ] + ], + "parent-yes-child1-no-subdomain-child2-yes-subdomain2.sub.https.html": [ + "202b916767c61a79f149170c851af76afcbdf088", + [ + null, + {} + ] + ], + "parent-yes-child1-no-subdomain-child2-yes-subdomainport.sub.https.html": [ + "a1316731ac2e46c3ee4427d97aaf63f983132764", + [ + null, + {} + ] + ], + "parent-yes-child1-yes-subdomain-child2-no-port.sub.https.html": [ + "46bef4b9a9e9e69189acd1307207a6da5c1d2592", + [ + null, + {} + ] + ], + "parent-yes-child1-yes-subdomain-child2-no-subdomain.sub.https.html": [ + "39dcfc04b096f6ecaa94d7e82d5ffff3c83aa63b", + [ + null, + {} + ] + ], + "parent-yes-child1-yes-subdomain-child2-yes-subdomain.sub.https.html": [ + "b6daf91b54e0ab25901cec44076047decd0056b2", + [ + null, + {} + ] + ], + "parent-yes-child1-yes-subdomain-child2-yes-subdomain2.sub.https.html": [ + "b94f9392d462e880bc96f8cf49ba188eb63a2da8", + [ + null, + {} + ] + ], + "parent-yes-child1-yes-subdomain-child2-yes-subdomainport.sub.https.html": [ + "fb3fda1bf27e1576a5c6af66b99221f07b0591a6", + [ + null, + {} + ] + ] + }, + "about-blank.https.sub.html": [ + "edc98b363e46471b3e5db54b6b5a0b827dbb0a6d", + [ + null, + {} + ] + ], + "document-domain.sub.https.html": [ + "b4535d9e548c7010c676114dfa259f5201f5ce7f", + [ + null, + {} + ] + ], + "getter-special-cases": { + "csp-sandbox-no.https.html": [ + "e0b5f92376287417ab099c49e0b7396dc0d87256", + [ + null, + {} + ] + ], + "csp-sandbox-yes.https.html": [ + "a2220c5acc5c4bfac7c158fd2ba4f965ad05d039", + [ + null, + {} + ] + ], + "data-to-javascript-no.https.html": [ + "06149cda8ab72081769a926d169620be9d0f5cd5", + [ + null, + {} + ] + ], + "data-to-javascript-yes.https.html": [ + "af6fea0ad979b65c74ab6ae8062c8e025b2f13a8", + [ + null, + {} + ] + ], + "data-url-no.https.html": [ + "8ae564a072a4b8338e00e3a6b8f54b7425d4f563", + [ + null, + {} + ] + ], + "data-url-yes.https.html": [ + "bcbf098a664ef20a8c083e7f43fd939ac49c5c64", + [ + null, + {} + ] + ], + "javascript-url-no.https.html": [ + "1b54ad42a4333b333bf1897ab4a47567d9c141b3", + [ + null, + {} + ] + ], + "javascript-url-yes.https.html": [ + "e2b7730dd2b3cffb5bc7f7422175ef931a538b62", + [ + null, + {} + ] + ], + "removed-iframe.sub.https.html": [ + "fcf5068908800f6fcec7d6a951d5c7b06895ba29", + [ + null, + {} + ] + ], + "sandboxed-iframe-no.https.html": [ + "29758a17b877ab0561388e2b5a92c70f4f010c56", + [ + null, + {} + ] + ], + "sandboxed-iframe-yes.https.html": [ + "5eb5d08d10f6ec621e454232c342bcdcc0d005b9", + [ + null, + {} + ] + ], + "sandboxed-same-origin-iframe-no.https.html": [ + "3ed4096f399175e133797a4116af5cca566b7dd0", + [ + null, + {} + ] + ], + "sandboxed-same-origin-iframe-yes.https.html": [ + "c7ea5f069321f6f65d114ce44f843bcbaf1c2f1a", + [ + null, + {} + ] + ] + }, + "going-back.sub.https.html": [ + "a593619ea64a98ccc6151be606ab245016e4b885", + [ + null, + {} + ] + ], + "iframe-navigation": { + "parent-no-1-no-same-2-yes-port.sub.https.html": [ + "8237f2f23f9479bd1669642b7d2077e9681859e2", + [ + null, + {} + ] + ], + "parent-no-1-no-same-2-yes-subdomain.sub.https.html": [ + "00d8c3164a699bb2daa86aac333b24a29cc51af5", + [ + null, + {} + ] + ], + "parent-no-1-no-subdomain-2-yes-subdomain.sub.https.html": [ + "803e684e1ca2d6cbad82a307f7f0d55c6c513c7e", + [ + null, + {} + ] + ], + "parent-no-1-no-subdomain-2-yes-subdomain2.sub.https.html": [ + "b96d10afd13b9009e9c39d1bb5941682f751e7f3", + [ + null, + {} + ] + ], + "parent-no-1-subdomain-yes-2-subdomain2-no.sub.https.html": [ + "a70ed566708ce99a77e0386f3acacdd4f309fc32", + [ + null, + {} + ] + ], + "parent-no-1-yes-subdomain-2-no-subdomain.sub.https.html": [ + "38e26301288d190e6547f0d34312aed686cab26f", + [ + null, + {} + ] + ], + "parent-yes-1-no-same-2-no-port.sub.https.html": [ + "6211845be1f74e6686ee6f47400c6d8895444199", + [ + null, + {} + ] + ], + "parent-yes-1-no-same-2-no-subdomain.sub.https.html": [ + "ead56754a7085acf8e82bddcc6cc76df6f7f7dad", + [ + null, + {} + ] + ] + }, + "insecure-http.sub.html": [ + "6f9e5d8b73a1a811710e4450515a36f7ce9cc4d9", + [ + null, + {} + ] + ], + "popups": { + "opener-no-openee-yes-port.sub.https.html": [ + "a0bf569b124b449d7884ce96f8e0e46a765f13ce", + [ + null, + {} + ] + ], + "opener-no-openee-yes-same.sub.https.html": [ + "196dff1449b34b5fea5fc6369b2eda992cceee6b", + [ + null, + {} + ] + ], + "opener-no-openee-yes-subdomain.sub.https.html": [ + "f96d2273d5e73ff75581df5ba465c0cc4ffdf0f7", + [ + null, + {} + ] + ], + "opener-yes-openee-no-port.sub.https.html": [ + "51c5a208c5ef088091fc5a6019e61fac53f4d07b", + [ + null, + {} + ] + ], + "opener-yes-openee-no-same.sub.https.html": [ + "562ab40c68bf4163a540d96f447dc13287f9438f", + [ + null, + {} + ] + ], + "opener-yes-openee-no-subdomain.sub.https.html": [ + "d7d4791459eb30470fca7d77950fc9c8d79df721", + [ + null, + {} + ] + ], + "opener-yes-openee-yes-port.sub.https.html": [ + "32a5066d2eef6ba0fb3264d9b01666a71cdc30ff", + [ + null, + {} + ] + ], + "opener-yes-openee-yes-same.sub.https.html": [ + "a85decac3c1906a35399786c5a56914c047eede3", + [ + null, + {} + ] + ], + "opener-yes-openee-yes-subdomain.sub.https.html": [ + "148b39af232f3e4588f0c74187f416b8a5c395ed", + [ + null, + {} + ] + ] + }, + "removing-iframes.sub.https.html": [ + "b83aa9f5bedbaf64c7af9215d926d86013894cab", + [ + null, + {} + ] + ] + }, "origin-of-data-document.html": [ "448f47fa244c1134549150367a0991f79c13da86", [ @@ -379414,6 +379890,13 @@ }, "selectors": { "pseudo-classes": { + "autofill.html": [ + "b7c3644bdbad02f7775c3ae4a341715d082870c2", + [ + null, + {} + ] + ], "checked-type-change.html": [ "661d9e4355eb46a6ea0bb64ea44daa0c9c0d2497", [ @@ -384050,6 +384533,22 @@ {} ] ], + "multiple-import-maps": { + "basic.html": [ + "9ab03ddc302af11ad7fc12d4dc8c1ed6b90084a6", + [ + null, + {} + ] + ], + "with-errors.html": [ + "a93ecaaeff5b329916bfd003959d4cb067d5ee41", + [ + null, + {} + ] + ] + }, "not-as-classic-script.html": [ "5f97394e4408bc8db5624e5d0c6f1b2fa1b028dd", [ @@ -394594,452 +395093,6 @@ ] ] }, - "origin-isolation": { - "1-iframe": { - "parent-no-child-bad-subdomain.sub.https.html": [ - "27085aa151ed219718a9538ba44f720ad20c62ca", - [ - null, - {} - ] - ], - "parent-no-child-yes-port.sub.https.html": [ - "d1466e55c04136f04263bd288f7299bf33ed5a15", - [ - null, - {} - ] - ], - "parent-no-child-yes-same.sub.https.html": [ - "39d6cf996a842c6e84d9b8bec6a74dbf5d0e4a2b", - [ - null, - {} - ] - ], - "parent-no-child-yes-subdomain-with-redirect.sub.https.html": [ - "9004500b764191493112feeb26c48d61acf54fb8", - [ - null, - {} - ] - ], - "parent-no-child-yes-subdomain.sub.https.html": [ - "648c641553cdd6d6f5a0f53ce4fc94f2314e2e11", - [ - null, - {} - ] - ], - "parent-no-child-yeswithparams-subdomain.sub.https.html": [ - "400a8f72332a2620c3957bfe1aa7d6b572c927e2", - [ - null, - {} - ] - ], - "parent-yes-child-no-port.sub.https.html": [ - "793c47328e103c5f63677ebdaa6818b07ce0e198", - [ - null, - {} - ] - ], - "parent-yes-child-no-same.sub.https.html": [ - "f1ca9a9a7cdec13d38b42abcc93f2eb9a57242a1", - [ - null, - {} - ] - ], - "parent-yes-child-no-subdomain.sub.https.html": [ - "be84ecac2d1891554bab21ae4c12cdfb59f1ebf3", - [ - null, - {} - ] - ], - "parent-yes-child-yes-port.sub.https.html": [ - "58516b86742e4ea3ccae560066bdf44a4fd80a9e", - [ - null, - {} - ] - ], - "parent-yes-child-yes-same.sub.https.html": [ - "b08206b4478fceb24013abe39907dee5d2d95446", - [ - null, - {} - ] - ], - "parent-yes-child-yes-subdomain.sub.https.html": [ - "9a426d068aef3b6115c803aa1e3828dbe6a2fbc9", - [ - null, - {} - ] - ] - }, - "2-iframes": { - "parent-no-child1-no-subdomain-child2-yes-subdomain.sub.https.html": [ - "55c158381275a4d63e43bf7dbb8b40c366e3ba55", - [ - null, - {} - ] - ], - "parent-no-child1-no-subdomain-child2-yes-subdomainport.sub.https.html": [ - "2c0bb614b50b35dab4086dc35d360601570084ec", - [ - null, - {} - ] - ], - "parent-no-child1-no-subdomain1-child2-yes-subdomain2.sub.https.html": [ - "e31af2061fb9ae5bb5000c7980c6637f391a444b", - [ - null, - {} - ] - ], - "parent-no-child1-yes-subdomain-child2-no-port.sub.https.html": [ - "eaccc8509cdc4d8afb2d9144af15acb9fd67ef18", - [ - null, - {} - ] - ], - "parent-no-child1-yes-subdomain-child2-no-subdomain.sub.https.html": [ - "5adb911ae8b466125696caf0d828db43f66afdaa", - [ - null, - {} - ] - ], - "parent-yes-child1-no-subdomain-child2-no-subdomain.sub.https.html": [ - "e463f328f19d1c91f51c6494c182ece8ee8072ef", - [ - null, - {} - ] - ], - "parent-yes-child1-no-subdomain-child2-no-subdomain2.sub.https.html": [ - "2d67979b68a355c0860847b9a4779cfa833647bf", - [ - null, - {} - ] - ], - "parent-yes-child1-no-subdomain-child2-yes-subdomain.sub.https.html": [ - "ecf759cde06706311e77c0244ca796906deec83d", - [ - null, - {} - ] - ], - "parent-yes-child1-no-subdomain-child2-yes-subdomain2.sub.https.html": [ - "0448076178aa3a2956e98116afa8bcad549cc5f6", - [ - null, - {} - ] - ], - "parent-yes-child1-no-subdomain-child2-yes-subdomainport.sub.https.html": [ - "1b14ca48ba730791c9128da85490c606dada3f3a", - [ - null, - {} - ] - ], - "parent-yes-child1-yes-subdomain-child2-no-port.sub.https.html": [ - "fcdb13699710bf8ba5aca0d15b0e2908d60e7af1", - [ - null, - {} - ] - ], - "parent-yes-child1-yes-subdomain-child2-no-subdomain.sub.https.html": [ - "011bcd1637b818b24d552f25fcfcd615c6e25528", - [ - null, - {} - ] - ], - "parent-yes-child1-yes-subdomain-child2-yes-subdomain.sub.https.html": [ - "1a4dd4c9a655b56c4c94a0b8297bc0faa711154c", - [ - null, - {} - ] - ], - "parent-yes-child1-yes-subdomain-child2-yes-subdomain2.sub.https.html": [ - "852fd2d216e3be0f0b1b18606ad46fa313a4782c", - [ - null, - {} - ] - ], - "parent-yes-child1-yes-subdomain-child2-yes-subdomainport.sub.https.html": [ - "ba8edadc188c7cc7fe8de79e95a06a824911e458", - [ - null, - {} - ] - ] - }, - "about-blank.https.sub.html": [ - "edc98b363e46471b3e5db54b6b5a0b827dbb0a6d", - [ - null, - {} - ] - ], - "document-domain.sub.https.html": [ - "48f9a99b5f7dbe10b7dac7f12764029657d4ff0d", - [ - null, - {} - ] - ], - "getter-special-cases": { - "csp-sandbox-no.https.html": [ - "16ecb45192950d29329c6bd54a6b561f281b07a2", - [ - null, - {} - ] - ], - "csp-sandbox-yes.https.html": [ - "b9a7359974d5651f955cb65c03862a0eeb79a35d", - [ - null, - {} - ] - ], - "data-to-javascript-no.https.html": [ - "cb00ef782d0cf558ebcc28a6fa103b9826fb541d", - [ - null, - {} - ] - ], - "data-to-javascript-yes.https.html": [ - "6856441deff1d0c707dbc8b1217dd6fb718eea36", - [ - null, - {} - ] - ], - "data-url-no.https.html": [ - "5b194eaef3552fd7c7f5ba64ab3f4db648f0d457", - [ - null, - {} - ] - ], - "data-url-yes.https.html": [ - "85821be32b53245bc1356321a8bc085716a710c2", - [ - null, - {} - ] - ], - "javascript-url-no.https.html": [ - "b75cae47cdbb6c49b33044729a141ed52462af7e", - [ - null, - {} - ] - ], - "javascript-url-yes.https.html": [ - "573b1a0b712bd6c93c3931642fbe3603cc721d54", - [ - null, - {} - ] - ], - "removed-iframe.sub.https.html": [ - "8a29076e56111444a7f8d83b8d0e413291de4e51", - [ - null, - {} - ] - ], - "sandboxed-iframe-no.https.html": [ - "bc2276fede8ac74f4cb7fb9b119a8e306bc9160a", - [ - null, - {} - ] - ], - "sandboxed-iframe-yes.https.html": [ - "5805d3421ebe2590585f0f7166d781eb979e6277", - [ - null, - {} - ] - ], - "sandboxed-same-origin-iframe-no.https.html": [ - "a1b44a1e5b34778aa7f8aa8fc64d5f0cbceced52", - [ - null, - {} - ] - ], - "sandboxed-same-origin-iframe-yes.https.html": [ - "b9339afae2e802178d55972af5033cf7050a2408", - [ - null, - {} - ] - ] - }, - "going-back.sub.https.html": [ - "7e95f19366996ce0c97b87631b10d660d07c2e56", - [ - null, - {} - ] - ], - "iframe-navigation": { - "parent-no-1-no-same-2-yes-port.sub.https.html": [ - "85ee2f677f31dd23814276c015c39ac8abb88bef", - [ - null, - {} - ] - ], - "parent-no-1-no-same-2-yes-subdomain.sub.https.html": [ - "bb39de648acf177ef0ee6479a4b7a8655ee8b168", - [ - null, - {} - ] - ], - "parent-no-1-no-subdomain-2-yes-subdomain.sub.https.html": [ - "b52ca783f6f711fae40f9e01795d5072c9d36644", - [ - null, - {} - ] - ], - "parent-no-1-no-subdomain-2-yes-subdomain2.sub.https.html": [ - "67e99cee090ad9766b3734784dec96e39dda511a", - [ - null, - {} - ] - ], - "parent-no-1-subdomain-yes-2-subdomain2-no.sub.https.html": [ - "1b7dd01947f69eb7311ef3d7235701fe229b6aa3", - [ - null, - {} - ] - ], - "parent-no-1-yes-subdomain-2-no-subdomain.sub.https.html": [ - "783f5870a839b1b63f96e28a9c734e0538839547", - [ - null, - {} - ] - ], - "parent-yes-1-no-same-2-no-port.sub.https.html": [ - "461fd0ddc4b88697fb49cd3a89166f88c0310636", - [ - null, - {} - ] - ], - "parent-yes-1-no-same-2-no-subdomain.sub.https.html": [ - "6832cd03858cab38e03993b676a52ca81c594c97", - [ - null, - {} - ] - ] - }, - "insecure-http.sub.html": [ - "18e0216e2627a2f81d9237be5e497aed3f22a482", - [ - null, - {} - ] - ], - "popups": { - "opener-no-openee-yes-port.sub.https.html": [ - "270162530b100da850d4834c049553fc01d32a84", - [ - null, - {} - ] - ], - "opener-no-openee-yes-same.sub.https.html": [ - "0c8d89b8e66bf21ac2aa693f5dbf2131d9f8b4d0", - [ - null, - {} - ] - ], - "opener-no-openee-yes-subdomain.sub.https.html": [ - "d1aaabd9206239469b2e7871cf6a0ab30a48bcb1", - [ - null, - {} - ] - ], - "opener-yes-openee-no-port.sub.https.html": [ - "96b839e167f92326d72afad1b62a36b36ee25b6a", - [ - null, - {} - ] - ], - "opener-yes-openee-no-same.sub.https.html": [ - "0dee5fae002277fdb3811524b37e8025a4118a3e", - [ - null, - {} - ] - ], - "opener-yes-openee-no-subdomain.sub.https.html": [ - "cfec0fda1301d90bf71da00e1f93f02e71fb8119", - [ - null, - {} - ] - ], - "opener-yes-openee-yes-port.sub.https.html": [ - "4ea37421df0ac11baa99d6fc435ca5be50af2b6b", - [ - null, - {} - ] - ], - "opener-yes-openee-yes-same.sub.https.html": [ - "603f11d8de6cb78b96735a740330145787f5cf75", - [ - null, - {} - ] - ], - "opener-yes-openee-yes-subdomain.sub.https.html": [ - "b182d496a9278b17e26c7ee870aa9252f0a05b18", - [ - null, - {} - ] - ] - }, - "removing-iframes.sub.https.html": [ - "cbe13af820798a1a88300cea92ea2bf843b77933", - [ - null, - {} - ] - ] - }, "origin-policy": { "bad-server": { "bad-headers.https.html": [ @@ -399015,7 +399068,7 @@ ] ], "avoid-prefetching-on-text-plain.html": [ - "45564e1bfaca07f2ea21bf460132c7f18ed6a24a", + "b14b7e4f8a90241c30cccbcd9e5b754fde515b8b", [ null, {} @@ -437461,7 +437514,7 @@ }, "webcodecs": { "audio-decoder.any.js": [ - "70110a7822ea0fb374b08a8fd5f3811a6164c3ea", + "a6367231b234a6e078bd96dc2e689ffb429593c6", [ "webcodecs/audio-decoder.any.html", { @@ -464252,6 +464305,24 @@ ] ] }, + "get_computed_label": { + "get.py": [ + "89c0f9d2b29b410a5ccf55806c677d20b94576b1", + [ + null, + {} + ] + ] + }, + "get_computed_role": { + "get.py": [ + "06173ee6fcb2b169c11cb76e6e2955870a59e77f", + [ + null, + {} + ] + ] + }, "get_current_url": { "get.py": [ "fa2ff6a6595f165987f13ad7a7ad60fd6e3cbb44",
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-017.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-017.html new file mode 100644 index 0000000..742e389 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-017.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: handling trailing ideographic space sequence</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" title="4.1.3. Phase II: Trimming and Positioning" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-normal"> +<link rel="help" href="https://drafts.csswg.org/css-writing-modes-3/#valdef-unicode-bidi-plaintext"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-hyphens-none"> +<link rel="match" href="reference/white-space-break-spaces-005-ref.html"> +<meta name="assert" content="Disabled hypenation and unicode-bidi 'plaintext' should not affect, hence the trailing ideographic spaces must hang; however, the rest of the sequence is wrapped due to the forced break."> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> +<style> +div { + font: 50px/1 Ahem; + width: 1ch; +} +span { + background: green; + color: transparent; + + unicode-bidi: plaintext; + hyphens: none; +} +.ref { + position: absolute; + color: red; + z-index: -1; +} +</style> + +<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p> +<div class="ref">XX<br>XX</div> +<div><span>X <br>  </span></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-018.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-018.html new file mode 100644 index 0000000..16bb876 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-018.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: handling trailing ideographic space sequence</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" title="4.1.3. Phase II: Trimming and Positioning" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-normal"> +<link rel="help" href="https://drafts.csswg.org/css-writing-modes-3/#valdef-unicode-bidi-plaintext"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-hyphens-none"> +<link rel="match" href="reference/white-space-break-spaces-005-ref.html"> +<meta name="assert" content="Disabled hypenation and unicode-bidi 'plaintext' should not affect, hence the trailing ideographic spaces must hang; however, the rest of the sequence is wrapped due to the forced break."> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> +<style> +div { + font: 50px/1 Ahem; + width: 1ch; +} +span { + background: green; + color: transparent; + + unicode-bidi: plaintext; + hyphens: none; +} +.ref { + position: absolute; + color: red; + z-index: -1; +} +</style> + +<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p> +<div class="ref">XX<br>XX</div> +<div><span>X <br>XX</span></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-019.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-019.html new file mode 100644 index 0000000..0707000 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-019.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: handling trailing ideographic space sequence</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" title="4.1.3. Phase II: Trimming and Positioning" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-normal"> +<link rel="help" href="https://drafts.csswg.org/css-writing-modes-3/#valdef-unicode-bidi-plaintext"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-hyphens-none"> +<link rel="match" href="reference/white-space-break-spaces-005-ref.html"> +<meta name="assert" content="Disabled hypenation and unicode-bidi 'plaintext' should not affect, hence the trailing ideographic spaces must hang; however, the rest of the sequence is wrapped due to the forced break."> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> +<style> +div { + font: 50px/1 Ahem; + width: 1ch; +} +span { + background: green; + color: transparent; + + unicode-bidi: plaintext; + hyphens: none; +} +.ref { + position: absolute; + color: red; + z-index: -1; +} +</style> + +<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p> +<div class="ref">XX<br>XX</div> +<div><span>X <br>X </span></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-020.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-020.html new file mode 100644 index 0000000..97ae007 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-020.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: handling trailing ideographic space sequence</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" title="4.1.3. Phase II: Trimming and Positioning" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-normal"> +<link rel="help" href="https://drafts.csswg.org/css-writing-modes-3/#valdef-unicode-bidi-isolate"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-hyphens-none"> +<link rel="match" href="reference/white-space-break-spaces-005-ref.html"> +<meta name="assert" content="Disabled hypenation and unicode-bidi 'isolate' should not affect, hence the trailing ideographic spaces must hang; however, the rest of the sequence is wrapped due to the forced break."> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> +<style> +div { + font: 50px/1 Ahem; + width: 1ch; +} +span { + background: green; + color: transparent; + + unicode-bidi: isolate; + hyphens: none; +} +.ref { + position: absolute; + color: red; + z-index: -1; +} +</style> + +<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p> +<div class="ref">XX<br>XX</div> +<div><span>X <br>  </span></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-021.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-021.html new file mode 100644 index 0000000..b75327a6 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-021.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: handling trailing ideographic space sequence</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" title="4.1.3. Phase II: Trimming and Positioning" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-normal"> +<link rel="help" href="https://drafts.csswg.org/css-writing-modes-3/#valdef-unicode-bidi-isolate"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-hyphens-none"> +<link rel="match" href="reference/white-space-break-spaces-005-ref.html"> +<meta name="assert" content="Disabled hypenation and unicode-bidi 'isolate' should not affect, hence the trailing ideographic spaces must hang; however, the rest of the sequence is wrapped due to the forced break."> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> +<style> +div { + font: 50px/1 Ahem; + width: 1ch; +} +span { + background: green; + color: transparent; + + unicode-bidi: isolate; + hyphens: none; +} +.ref { + position: absolute; + color: red; + z-index: -1; +} +</style> + +<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p> +<div class="ref">XX<br>XX</div> +<div><span>X <br>XX</span></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-022.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-022.html new file mode 100644 index 0000000..71720c2 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-022.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: handling trailing ideographic space sequence</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" title="4.1.3. Phase II: Trimming and Positioning" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-normal"> +<link rel="help" href="https://drafts.csswg.org/css-writing-modes-3/#valdef-unicode-bidi-isolate"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-hyphens-none"> +<link rel="match" href="reference/white-space-break-spaces-005-ref.html"> +<meta name="assert" content="Disabled hypenation and unicode-bidi 'isolate' should not affect, hence the trailing ideographic spaces must hang; however, the rest of the sequence is wrapped due to the forced break."> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> +<style> +div { + font: 50px/1 Ahem; + width: 1ch; +} +span { + background: green; + color: transparent; + + unicode-bidi: isolate; + hyphens: none; +} +.ref { + position: absolute; + color: red; + z-index: -1; +} +</style> + +<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p> +<div class="ref">XX<br>XX</div> +<div><span>X <br>X </span></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-023.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-023.html new file mode 100644 index 0000000..ea95ab1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-023.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: handling trailing ideographic space sequence</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" title="4.1.3. Phase II: Trimming and Positioning" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-normal"> +<link rel="help" href="https://drafts.csswg.org/css-writing-modes-3/#valdef-unicode-bidi-plaintext"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-hyphens-auto"> +<link rel="match" href="reference/white-space-break-spaces-005-ref.html"> +<meta name="assert" content="Auto hypenation and unicode-bidi 'plaintext' should not affect, hence the trailing ideographic spaces must hang; however, the rest of the sequence is wrapped due to the forced break."> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> +<style> +div { + font: 50px/1 Ahem; + width: 1ch; +} +span { + background: green; + color: transparent; + + unicode-bidi: plaintext; + hyphens: auto; +} +.ref { + position: absolute; + color: red; + z-index: -1; +} +</style> + +<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p> +<div class="ref">XX<br>XX</div> +<div><span>X <br>  </span></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-024.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-024.html new file mode 100644 index 0000000..2a65400 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-024.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: handling trailing ideographic space sequence</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" title="4.1.3. Phase II: Trimming and Positioning" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-normal"> +<link rel="help" href="https://drafts.csswg.org/css-writing-modes-3/#valdef-unicode-bidi-plaintext"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-hyphens-auto"> +<link rel="match" href="reference/white-space-break-spaces-005-ref.html"> +<meta name="assert" content="Auto hypenation and unicode-bidi 'plaintext' should not affect, hence the trailing ideographic spaces must hang; however, the rest of the sequence is wrapped due to the forced break."> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> +<style> +div { + font: 50px/1 Ahem; + width: 1ch; +} +span { + background: green; + color: transparent; + + unicode-bidi: plaintext; + hyphens: auto; +} +.ref { + position: absolute; + color: red; + z-index: -1; +} +</style> + +<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p> +<div class="ref">XX<br>XX</div> +<div><span>X <br>XX</span></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-025.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-025.html new file mode 100644 index 0000000..5123e10 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/trailing-ideographic-space-025.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: handling trailing ideographic space sequence</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" title="4.1.3. Phase II: Trimming and Positioning" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-normal"> +<link rel="help" href="https://drafts.csswg.org/css-writing-modes-3/#valdef-unicode-bidi-plaintext"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-hyphens-auto"> +<link rel="match" href="reference/white-space-break-spaces-005-ref.html"> +<meta name="assert" content="Auto hypenation and unicode-bidi 'plaintext' should not affect, hence the trailing ideographic spaces must hang; however, the rest of the sequence is wrapped due to the forced break."> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> +<style> +div { + font: 50px/1 Ahem; + width: 1ch; +} +span { + background: green; + color: transparent; + + unicode-bidi: plaintext; + hyphens: auto; +} +.ref { + position: absolute; + color: red; + z-index: -1; +} +</style> + +<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p> +<div class="ref">XX<br>XX</div> +<div><span>X <br>X </span></div>
diff --git a/third_party/blink/web_tests/external/wpt/gamepad/idlharness-extensions.window-expected.txt b/third_party/blink/web_tests/external/wpt/gamepad/idlharness-extensions.window-expected.txt index 8f261de..2add0e7 100644 --- a/third_party/blink/web_tests/external/wpt/gamepad/idlharness-extensions.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/gamepad/idlharness-extensions.window-expected.txt
@@ -25,8 +25,19 @@ FAIL GamepadPose interface: attribute orientation assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing FAIL GamepadPose interface: attribute angularVelocity assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing FAIL GamepadPose interface: attribute angularAcceleration assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadTouch interface: existence and properties of interface object assert_own_property: self does not have own property "GamepadTouch" expected property "GamepadTouch" missing +FAIL GamepadTouch interface object length assert_own_property: self does not have own property "GamepadTouch" expected property "GamepadTouch" missing +FAIL GamepadTouch interface object name assert_own_property: self does not have own property "GamepadTouch" expected property "GamepadTouch" missing +FAIL GamepadTouch interface: existence and properties of interface prototype object assert_own_property: self does not have own property "GamepadTouch" expected property "GamepadTouch" missing +FAIL GamepadTouch interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "GamepadTouch" expected property "GamepadTouch" missing +FAIL GamepadTouch interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "GamepadTouch" expected property "GamepadTouch" missing +FAIL GamepadTouch interface: attribute touchId assert_own_property: self does not have own property "GamepadTouch" expected property "GamepadTouch" missing +FAIL GamepadTouch interface: attribute surfaceId assert_own_property: self does not have own property "GamepadTouch" expected property "GamepadTouch" missing +FAIL GamepadTouch interface: attribute position assert_own_property: self does not have own property "GamepadTouch" expected property "GamepadTouch" missing +FAIL GamepadTouch interface: attribute surfaceDimensions assert_own_property: self does not have own property "GamepadTouch" expected property "GamepadTouch" missing FAIL Gamepad interface: attribute hand assert_true: The prototype object must have a property "hand" expected true got false FAIL Gamepad interface: attribute hapticActuators assert_true: The prototype object must have a property "hapticActuators" expected true got false FAIL Gamepad interface: attribute pose assert_true: The prototype object must have a property "pose" expected true got false +FAIL Gamepad interface: attribute touchEvents assert_true: The prototype object must have a property "touchEvents" expected true got false Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/autofill-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/autofill-expected.txt new file mode 100644 index 0000000..501f685 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/autofill-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +FAIL ":autofill" should be a valid selector Failed to execute 'querySelector' on 'Document': ':autofill' is not a valid selector. +PASS ":-webkit-autofill" should be a valid selector +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/autofill.html b/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/autofill.html new file mode 100644 index 0000000..b7c3644 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/selectors/pseudo-classes/autofill.html
@@ -0,0 +1,11 @@ +<!doctype html> +<meta charset=utf-8> +<title>Selector: pseudo-classes (:autofill)</title> +<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +<script> +test_valid_selector(":autofill"); +test_valid_selector(":-webkit-autofill", [":autofill", ":-webkit-autofill"]); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/gamepad-extensions.idl b/third_party/blink/web_tests/external/wpt/interfaces/gamepad-extensions.idl index 2d353b0..29ab815 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/gamepad-extensions.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/gamepad-extensions.idl
@@ -32,8 +32,17 @@ readonly attribute Float32Array? angularAcceleration; }; +[Exposed=Window, SecureContext] +interface GamepadTouch { + readonly attribute unsigned long touchId; + readonly attribute octet surfaceId; + readonly attribute Float32Array position; + readonly attribute Uint32Array? surfaceDimensions; +}; + partial interface Gamepad { readonly attribute GamepadHand hand; readonly attribute FrozenArray<GamepadHapticActuator> hapticActuators; readonly attribute GamepadPose? pose; + readonly attribute FrozenArray<GamepadTouch>? touchEvents; };
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptserve/wptserve/server.py b/third_party/blink/web_tests/external/wpt/tools/wptserve/wptserve/server.py index d447281..2b5ed4a2 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wptserve/wptserve/server.py +++ b/third_party/blink/web_tests/external/wpt/tools/wptserve/wptserve/server.py
@@ -429,7 +429,7 @@ return False method = extract_method_header(frame.headers) - if method != "CONNECT": + if method != b"CONNECT": return False protocol = "" @@ -437,7 +437,7 @@ if key in (b':protocol', u':protocol'): protocol = isomorphic_encode(value) break - if protocol != "websocket": + if protocol != b"websocket": raise ProtocolError("Invalid protocol %s with CONNECT METHOD" % (protocol,)) return True
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_computed_label/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/get_computed_label/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/get_computed_label/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_computed_label/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/get_computed_label/get.py new file mode 100644 index 0000000..89c0f9d2 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/get_computed_label/get.py
@@ -0,0 +1,37 @@ +import pytest +from six import text_type + +from webdriver.error import NoSuchAlertException + +from tests.support.asserts import assert_error, assert_success +from tests.support.inline import inline + + +def get_computed_label(session, element): + return session.transport.send( + "GET", "session/{session_id}/element/{element_id}/computedlabel".format( + session_id=session.session_id, + element_id=element)) + + +def test_no_browsing_context(session, closed_window): + response = get_computed_label(session) + assert_error(response, "no such window") + + +def test_no_user_prompt(session): + response = get_computed_label(session) + assert_error(response, "no such alert") + + +@pytest.mark.parametrize("html,tag,label", [ + ("<button>ok</button>", "button", "ok"), + ("<button aria-labelledby=\"one two\"></button><div id=one>ok</div><div id=two>go</div>", "button", "ok go"), + ("<button aria-label=foo>bar</button>", "button", "foo"), + ("<label><input> foo</label>", "input", "foo"), + ("<label for=b>foo<label><input id=b>", "input", "foo")]) +def test_get_computed_label(session, html, tag, label): + session.url = inline("{0}".format(tag)) + element = session.find.css(tag, all=False) + result = get_computed_label(session, element.id) + assert_success(result, label)
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_computed_role/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/get_computed_role/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/get_computed_role/__init__.py
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_computed_role/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/get_computed_role/get.py new file mode 100644 index 0000000..06173ee --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/get_computed_role/get.py
@@ -0,0 +1,35 @@ +import pytest +from six import text_type + +from webdriver.error import NoSuchAlertException + +from tests.support.asserts import assert_error, assert_success +from tests.support.inline import inline + + +def get_computed_role(session, element): + return session.transport.send( + "GET", "session/{session_id}/element/{element_id}/computedrole".format( + session_id=session.session_id, + element_id=element)) + + +def test_no_browsing_context(session, closed_window): + response = get_computed_role(session, "id") + assert_error(response, "no such window") + + +def test_no_user_prompt(session): + response = get_computed_role(session, "id") + assert_error(response, "no such alert") + + +@pytest.mark.parametrize("html,tag,expected", [ + ("<li role=menuitem>foo", "li", "menu"), + ("<input role=searchbox>", "input", "searchbox"), + ("<img role=presentation>", "img", "presentation")]) +def test_computed_roles(session, html, tag, expected): + session.url = inline(html) + element = session.find.css(tag, all=False) + result = get_computed_role(session, element.id) + assert_success(result, expected)
diff --git a/third_party/blink/web_tests/external/wpt/webusb/resources/manual.js b/third_party/blink/web_tests/external/wpt/webusb/resources/manual.js index 869ac450..e8dc08a 100644 --- a/third_party/blink/web_tests/external/wpt/webusb/resources/manual.js +++ b/third_party/blink/web_tests/external/wpt/webusb/resources/manual.js
@@ -36,3 +36,75 @@ await func(test, await getDeviceForManualTest()); }, name, properties); } + +function manual_usb_serial_test(func, name, properties) { + promise_test(async (test) => { + const device = await getDeviceForManualTest(); + await device.open(); + test.add_cleanup(async () => { + if (device.opened) { + await device.close(); + } + }); + + await device.selectConfiguration(1); + + let controlInterface = undefined; + for (const iface of device.configuration.interfaces) { + const alternate = iface.alternates[0]; + if (alternate.interfaceClass == 2 && + alternate.interfaceSubclass == 2 && + alternate.interfaceProtocol == 0) { + controlInterface = iface; + break; + } + } + assert_not_equals(controlInterface, undefined, + 'No control interface found.'); + + let dataInterface = undefined; + for (const iface of device.configuration.interfaces) { + const alternate = iface.alternates[0]; + if (alternate.interfaceClass == 10 && + alternate.interfaceSubclass == 0 && + alternate.interfaceProtocol == 0) { + dataInterface = iface; + break; + } + } + assert_not_equals(dataInterface, undefined, 'No data interface found.'); + + await device.claimInterface(controlInterface.interfaceNumber); + await device.claimInterface(dataInterface.interfaceNumber); + + let inEndpoint = undefined; + for (const endpoint of dataInterface.alternate.endpoints) { + if (endpoint.type == 'bulk' && endpoint.direction == 'in') { + inEndpoint = endpoint; + break; + } + } + assert_not_equals(inEndpoint, undefined, 'No IN endpoint found.'); + + let outEndpoint = undefined; + for (const endpoint of dataInterface.alternate.endpoints) { + if (endpoint.type == 'bulk' && endpoint.direction == 'out') { + outEndpoint = endpoint; + break; + } + } + assert_not_equals(outEndpoint, undefined, 'No OUT endpoint found.'); + + // Execute a SET_CONTROL_LINE_STATE command to let the device know the + // host is ready to transmit and receive data. + await device.controlTransferOut({ + requestType: 'class', + recipient: 'interface', + request: 0x22, + value: 0x01, + index: controlInterface.interfaceNumber, + }); + + await func(test, device, inEndpoint, outEndpoint); + }, name, properties); +} \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/webusb/usbDevice_transferIn-manual.https.html b/third_party/blink/web_tests/external/wpt/webusb/usbDevice_transferIn-manual.https.html index bd3df7d5..c0fad37 100644 --- a/third_party/blink/web_tests/external/wpt/webusb/usbDevice_transferIn-manual.https.html +++ b/third_party/blink/web_tests/external/wpt/webusb/usbDevice_transferIn-manual.https.html
@@ -16,6 +16,7 @@ <pre> void setup() { Serial.begin(115200); + Serial.setTimeout(0); while (!Serial) { ; } @@ -23,78 +24,15 @@ void loop() { if (Serial.available()) { - Serial.write(Serial.read()); + char buf[1024]; // Greater than the endpoint packet size. + int count = Serial.readBytes(buf, sizeof buf); + Serial.write(buf, count); } } </pre> </p> <script> - manual_usb_test(async (t, device) => { - await device.open(); - t.add_cleanup(async () => { - if (device.opened) { - await device.close(); - } - }); - - await device.selectConfiguration(1); - - let controlInterface = undefined; - for (const iface of device.configuration.interfaces) { - const alternate = iface.alternates[0]; - if (alternate.interfaceClass == 2 && - alternate.interfaceSubclass == 2 && - alternate.interfaceProtocol == 0) { - controlInterface = iface; - break; - } - } - assert_not_equals(controlInterface, undefined, - 'No control interface found.'); - - let dataInterface = undefined; - for (const iface of device.configuration.interfaces) { - const alternate = iface.alternates[0]; - if (alternate.interfaceClass == 10 && - alternate.interfaceSubclass == 0 && - alternate.interfaceProtocol == 0) { - dataInterface = iface; - break; - } - } - assert_not_equals(dataInterface, undefined, 'No data interface found.'); - - await device.claimInterface(controlInterface.interfaceNumber); - await device.claimInterface(dataInterface.interfaceNumber); - - let inEndpoint = undefined; - for (const endpoint of dataInterface.alternate.endpoints) { - if (endpoint.type == 'bulk' && endpoint.direction == 'in') { - inEndpoint = endpoint; - break; - } - } - assert_not_equals(inEndpoint, undefined, 'No IN endpoint found.'); - - let outEndpoint = undefined; - for (const endpoint of dataInterface.alternate.endpoints) { - if (endpoint.type == 'bulk' && endpoint.direction == 'out') { - outEndpoint = endpoint; - break; - } - } - assert_not_equals(outEndpoint, undefined, 'No OUT endpoint found.'); - - // Execute a SET_CONTROL_LINE_STATE command to let the device know the - // host is ready to transmit and receive data. - await device.controlTransferOut({ - requestType: 'class', - recipient: 'interface', - request: 0x22, - value: 0x01, - index: controlInterface.interfaceNumber, - }); - + manual_usb_serial_test(async (t, device, inEndpoint, outEndpoint) => { // Set up two IN transfers which should complete in order. const transfer1 = device.transferIn(inEndpoint.endpointNumber, inEndpoint.packetSize); @@ -111,13 +49,13 @@ result = await transfer1; assert_equals(result.status, 'ok'); assert_not_equals(result.data, null); - assert_equals(result.data.byteLength, 1); + assert_equals(result.data.byteLength, 1, 'byteLength'); assert_equals(result.data.getUint8(0), 'a'.charCodeAt(0)); // Set up a third IN transfer which will be canceled when the device is // closed at the end of the test. const transfer3 = promise_rejects_dom( - t, 'NetworkError', + t, 'AbortError', device.transferIn(inEndpoint.endpointNumber, inEndpoint.packetSize)); @@ -131,12 +69,80 @@ result = await transfer2; assert_equals(result.status, 'ok'); assert_not_equals(result.data, null); - assert_equals(result.data.byteLength, 1); + assert_equals(result.data.byteLength, 1, 'byteLength'); assert_equals(result.data.getUint8(0), 'b'.charCodeAt(0)); await device.close(); await transfer3; - }, 'Multiple IN transfers on an endpoint complete in order'); + }, 'Multiple small IN transfers on an endpoint complete in order'); + + manual_usb_serial_test(async (t, device, inEndpoint, outEndpoint) => { + const bufferLength = outEndpoint.packetSize * 20; + const parallelRequests = 6; + + // Keep track of the order in which transfers are submitted. + let enqueueSequence = 0; + let dequeueSequence = 0; + const received = new Uint8Array(bufferLength); + let receivedOffset = 0; + let done = false; + const transfers = []; + + async function readNext(sequence) { + let result; + try { + result = await device.transferIn(inEndpoint.endpointNumber, + inEndpoint.packetSize); + } catch (e) { + // The last few transfers will fail when the device is closed. + assert_true(done); + assert_equals(dequeueSequence++, sequence, 'dequeueSequence done'); + assert_equals(receivedOffset, bufferLength, 'receivedOffset'); + assert_equals(e.name, 'AbortError'); + return; + } + + assert_equals(dequeueSequence++, sequence, 'dequeueSequence'); + assert_equals(result.status, 'ok'); + assert_not_equals(result.data, null); + + const data = new Uint8Array( + result.data.buffer, result.data.byteOffset, + result.data.byteLength); + received.set(data, receivedOffset); + receivedOffset += result.data.byteLength; + + // Check |done| because there might be zero-length packet completions + // after the data has been completely received. + if (!done) { + if (receivedOffset == bufferLength) { + done = true; + assert_array_equals(received, buffer); + await device.close(); + } else { + await readNext(enqueueSequence++); + } + } + } + + for (let i = 0; i < parallelRequests; ++i) { + transfers.push(readNext(enqueueSequence++)); + } + + // Write a large buffer to the device which will be split up into + // smaller packets when echoed back. + const buffer = new Uint8Array(bufferLength); + for (let i = 0; i < buffer.byteLength; ++i) { + buffer[i] = i; + } + let result = await device.transferOut( + outEndpoint.endpointNumber, buffer); + assert_equals(result.status, 'ok'); + assert_equals(result.bytesWritten, buffer.byteLength); + + await Promise.all(transfers); + assert_equals(dequeueSequence, enqueueSequence); + }, 'Multiple large IN transfers on an endpoint complete in order'); </script> </body> </html>
diff --git a/third_party/blink/web_tests/http/tests/devtools/components/utilities-expected.txt b/third_party/blink/web_tests/http/tests/devtools/components/utilities-expected.txt index 6728aff1..7bc90f76 100644 --- a/third_party/blink/web_tests/http/tests/devtools/components/utilities-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/components/utilities-expected.txt
@@ -3,8 +3,6 @@ Running: orderedMergeIntersect -Running: binaryIndexOfTest - Running: lowerBoundTest Running: upperBoundTest
diff --git a/third_party/blink/web_tests/http/tests/devtools/components/utilities.js b/third_party/blink/web_tests/http/tests/devtools/components/utilities.js index d9316da..cfc5a83 100644 --- a/third_party/blink/web_tests/http/tests/devtools/components/utilities.js +++ b/third_party/blink/web_tests/http/tests/devtools/components/utilities.js
@@ -44,29 +44,6 @@ next(); }, - function binaryIndexOfTest(next) { - var testArrays = [ - [], [1], [1, 10], [1, 10, 11, 12, 13, 14, 100], [-100, -50, 0, 50, 100], [-100, -14, -13, -12, -11, -10, -1] - ]; - - function testArray(array) { - function comparator(a, b) { - return a < b ? -1 : (a > b ? 1 : 0); - } - - for (var i = -100; i <= 100; ++i) { - var reference = array.indexOf(i); - var actual = array.binaryIndexOf(i, comparator); - TestRunner.assertEquals(reference, actual, 'binaryIndexOf'); - } - return true; - } - - for (var i = 0, l = testArrays.length; i < l; ++i) - testArray(testArrays[i]); - next(); - }, - function lowerBoundTest(next) { var testArrays = [[], [1], [-1, -1, 0, 0, 0, 0, 2, 3, 4, 4, 4, 7, 9, 9, 9]];
diff --git a/third_party/blink/web_tests/platform/mac-mac-arm11.0/external/wpt/gamepad/idlharness-extensions.window-expected.txt b/third_party/blink/web_tests/platform/mac-mac-arm11.0/external/wpt/gamepad/idlharness-extensions.window-expected.txt new file mode 100644 index 0000000..8f261de --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac-arm11.0/external/wpt/gamepad/idlharness-extensions.window-expected.txt
@@ -0,0 +1,32 @@ +This is a testharness.js-based test. +PASS idl_test setup +PASS idl_test validation +PASS Partial interface Gamepad: original interface defined +PASS Partial interface Gamepad: member names are unique +PASS GamepadHapticActuator interface: existence and properties of interface object +PASS GamepadHapticActuator interface object length +PASS GamepadHapticActuator interface object name +PASS GamepadHapticActuator interface: existence and properties of interface prototype object +PASS GamepadHapticActuator interface: existence and properties of interface prototype object's "constructor" property +PASS GamepadHapticActuator interface: existence and properties of interface prototype object's @@unscopables property +PASS GamepadHapticActuator interface: attribute type +FAIL GamepadHapticActuator interface: operation pulse(double, double) assert_own_property: interface prototype object missing non-static operation expected property "pulse" missing +FAIL GamepadPose interface: existence and properties of interface object assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface object length assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface object name assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: existence and properties of interface prototype object assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute hasOrientation assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute hasPosition assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute position assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute linearVelocity assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute linearAcceleration assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute orientation assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute angularVelocity assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute angularAcceleration assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL Gamepad interface: attribute hand assert_true: The prototype object must have a property "hand" expected true got false +FAIL Gamepad interface: attribute hapticActuators assert_true: The prototype object must have a property "hapticActuators" expected true got false +FAIL Gamepad interface: attribute pose assert_true: The prototype object must have a property "pose" expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/mac-mac-arm11.0/virtual/restrict-gamepad/external/wpt/gamepad/idlharness-extensions.window-expected.txt b/third_party/blink/web_tests/platform/mac-mac-arm11.0/virtual/restrict-gamepad/external/wpt/gamepad/idlharness-extensions.window-expected.txt new file mode 100644 index 0000000..8f261de --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac-arm11.0/virtual/restrict-gamepad/external/wpt/gamepad/idlharness-extensions.window-expected.txt
@@ -0,0 +1,32 @@ +This is a testharness.js-based test. +PASS idl_test setup +PASS idl_test validation +PASS Partial interface Gamepad: original interface defined +PASS Partial interface Gamepad: member names are unique +PASS GamepadHapticActuator interface: existence and properties of interface object +PASS GamepadHapticActuator interface object length +PASS GamepadHapticActuator interface object name +PASS GamepadHapticActuator interface: existence and properties of interface prototype object +PASS GamepadHapticActuator interface: existence and properties of interface prototype object's "constructor" property +PASS GamepadHapticActuator interface: existence and properties of interface prototype object's @@unscopables property +PASS GamepadHapticActuator interface: attribute type +FAIL GamepadHapticActuator interface: operation pulse(double, double) assert_own_property: interface prototype object missing non-static operation expected property "pulse" missing +FAIL GamepadPose interface: existence and properties of interface object assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface object length assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface object name assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: existence and properties of interface prototype object assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute hasOrientation assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute hasPosition assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute position assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute linearVelocity assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute linearAcceleration assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute orientation assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute angularVelocity assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute angularAcceleration assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL Gamepad interface: attribute hand assert_true: The prototype object must have a property "hand" expected true got false +FAIL Gamepad interface: attribute hapticActuators assert_true: The prototype object must have a property "hapticActuators" expected true got false +FAIL Gamepad interface: attribute pose assert_true: The prototype object must have a property "pose" expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/third_party/OWNERS b/third_party/blink/web_tests/third_party/OWNERS new file mode 100644 index 0000000..db08449 --- /dev/null +++ b/third_party/blink/web_tests/third_party/OWNERS
@@ -0,0 +1,2 @@ +file://third_party/test_fonts/OWNERS +
diff --git a/third_party/blink/web_tests/virtual/restrict-gamepad/external/wpt/gamepad/idlharness-extensions.window-expected.txt b/third_party/blink/web_tests/virtual/restrict-gamepad/external/wpt/gamepad/idlharness-extensions.window-expected.txt new file mode 100644 index 0000000..2add0e7 --- /dev/null +++ b/third_party/blink/web_tests/virtual/restrict-gamepad/external/wpt/gamepad/idlharness-extensions.window-expected.txt
@@ -0,0 +1,43 @@ +This is a testharness.js-based test. +PASS idl_test setup +PASS idl_test validation +PASS Partial interface Gamepad: original interface defined +PASS Partial interface Gamepad: member names are unique +PASS GamepadHapticActuator interface: existence and properties of interface object +PASS GamepadHapticActuator interface object length +PASS GamepadHapticActuator interface object name +PASS GamepadHapticActuator interface: existence and properties of interface prototype object +PASS GamepadHapticActuator interface: existence and properties of interface prototype object's "constructor" property +PASS GamepadHapticActuator interface: existence and properties of interface prototype object's @@unscopables property +PASS GamepadHapticActuator interface: attribute type +FAIL GamepadHapticActuator interface: operation pulse(double, double) assert_own_property: interface prototype object missing non-static operation expected property "pulse" missing +FAIL GamepadPose interface: existence and properties of interface object assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface object length assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface object name assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: existence and properties of interface prototype object assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute hasOrientation assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute hasPosition assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute position assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute linearVelocity assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute linearAcceleration assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute orientation assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute angularVelocity assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadPose interface: attribute angularAcceleration assert_own_property: self does not have own property "GamepadPose" expected property "GamepadPose" missing +FAIL GamepadTouch interface: existence and properties of interface object assert_own_property: self does not have own property "GamepadTouch" expected property "GamepadTouch" missing +FAIL GamepadTouch interface object length assert_own_property: self does not have own property "GamepadTouch" expected property "GamepadTouch" missing +FAIL GamepadTouch interface object name assert_own_property: self does not have own property "GamepadTouch" expected property "GamepadTouch" missing +FAIL GamepadTouch interface: existence and properties of interface prototype object assert_own_property: self does not have own property "GamepadTouch" expected property "GamepadTouch" missing +FAIL GamepadTouch interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "GamepadTouch" expected property "GamepadTouch" missing +FAIL GamepadTouch interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "GamepadTouch" expected property "GamepadTouch" missing +FAIL GamepadTouch interface: attribute touchId assert_own_property: self does not have own property "GamepadTouch" expected property "GamepadTouch" missing +FAIL GamepadTouch interface: attribute surfaceId assert_own_property: self does not have own property "GamepadTouch" expected property "GamepadTouch" missing +FAIL GamepadTouch interface: attribute position assert_own_property: self does not have own property "GamepadTouch" expected property "GamepadTouch" missing +FAIL GamepadTouch interface: attribute surfaceDimensions assert_own_property: self does not have own property "GamepadTouch" expected property "GamepadTouch" missing +FAIL Gamepad interface: attribute hand assert_true: The prototype object must have a property "hand" expected true got false +FAIL Gamepad interface: attribute hapticActuators assert_true: The prototype object must have a property "hapticActuators" expected true got false +FAIL Gamepad interface: attribute pose assert_true: The prototype object must have a property "pose" expected true got false +FAIL Gamepad interface: attribute touchEvents assert_true: The prototype object must have a property "touchEvents" expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/v8-off-thread-finalization/README.txt b/third_party/blink/web_tests/virtual/v8-off-thread-finalization/README.txt new file mode 100644 index 0000000..2ecd845 --- /dev/null +++ b/third_party/blink/web_tests/virtual/v8-off-thread-finalization/README.txt
@@ -0,0 +1,2 @@ +Virtual test suite for testing background finalization and streaming +of small scripts.
diff --git a/third_party/blink/web_tests/virtual/v8-off-thread-finalization/external/wpt/html/semantics/scripting-1/README.txt b/third_party/blink/web_tests/virtual/v8-off-thread-finalization/external/wpt/html/semantics/scripting-1/README.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/third_party/blink/web_tests/virtual/v8-off-thread-finalization/external/wpt/html/semantics/scripting-1/README.txt
diff --git a/third_party/blink/web_tests/virtual/v8-off-thread-finalization/fast/dom/README.txt b/third_party/blink/web_tests/virtual/v8-off-thread-finalization/fast/dom/README.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/third_party/blink/web_tests/virtual/v8-off-thread-finalization/fast/dom/README.txt
diff --git a/third_party/blink/web_tests/virtual/v8-off-thread-finalization/http/tests/devtools/isolated-code-cache/README.txt b/third_party/blink/web_tests/virtual/v8-off-thread-finalization/http/tests/devtools/isolated-code-cache/README.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/third_party/blink/web_tests/virtual/v8-off-thread-finalization/http/tests/devtools/isolated-code-cache/README.txt
diff --git a/third_party/blink/web_tests/virtual/v8-off-thread-finalization/http/tests/devtools/isolated-code-cache/same-origin-module-test-expected.txt b/third_party/blink/web_tests/virtual/v8-off-thread-finalization/http/tests/devtools/isolated-code-cache/same-origin-module-test-expected.txt new file mode 100644 index 0000000..6d08c710 --- /dev/null +++ b/third_party/blink/web_tests/virtual/v8-off-thread-finalization/http/tests/devtools/isolated-code-cache/same-origin-module-test-expected.txt
@@ -0,0 +1,111 @@ +Tests V8 code cache for javascript resources + +--- Trace events related to code caches ------ +v8.compileModule Properties: +{ + data : { + columnNumber : 1 + lineNumber : 1 + streamed : <boolean> + url : .../devtools/resources/v8-cache-script.cgi + } + endTime : <number> + startTime : <number> + type : "v8.compileModule" +} +Text details for v8.compileModule: v8-cache-script.cgi +v8.compileModule Properties: +{ + data : { + columnNumber : 1 + lineNumber : 1 + notStreamedReason : "already used streamed data" + streamed : <boolean> + url : .../devtools/resources/v8-cache-script.cgi + } + endTime : <number> + startTime : <number> + type : "v8.compileModule" +} +Text details for v8.compileModule: v8-cache-script.cgi +v8.compileModule Properties: +{ + data : { + columnNumber : 1 + lineNumber : 1 + notStreamedReason : "module script" + producedCacheSize : <number> + streamed : <boolean> + url : .../devtools/resources/v8-cache-script.cgi + } + endTime : <number> + startTime : <number> + type : "v8.compileModule" +} +Text details for v8.compileModule: v8-cache-script.cgi +v8.compileModule Properties: +{ + data : { + cacheConsumeOptions : "code" + cacheRejected : false + columnNumber : 1 + consumedCacheSize : <number> + lineNumber : 1 + notStreamedReason : "already used streamed data" + streamed : <boolean> + url : .../devtools/resources/v8-cache-script.cgi + } + endTime : <number> + startTime : <number> + type : "v8.compileModule" +} +Text details for v8.compileModule: v8-cache-script.cgi +v8.compileModule Properties: +{ + data : { + columnNumber : 1 + lineNumber : 1 + streamed : <boolean> + url : .../devtools/resources/v8-cache-script.cgi + } + endTime : <number> + startTime : <number> + type : "v8.compileModule" +} +Text details for v8.compileModule: v8-cache-script.cgi +v8.compileModule Properties: +{ + data : { + cacheConsumeOptions : "code" + cacheRejected : false + columnNumber : 1 + consumedCacheSize : <number> + lineNumber : 1 + notStreamedReason : "already used streamed data" + streamed : <boolean> + url : .../devtools/resources/v8-cache-script.cgi + } + endTime : <number> + startTime : <number> + type : "v8.compileModule" +} +Text details for v8.compileModule: v8-cache-script.cgi +v8.compileModule Properties: +{ + data : { + cacheConsumeOptions : "code" + cacheRejected : false + columnNumber : 1 + consumedCacheSize : <number> + lineNumber : 1 + notStreamedReason : "script has code-cache available" + streamed : <boolean> + url : .../devtools/resources/v8-cache-script.cgi + } + endTime : <number> + startTime : <number> + type : "v8.compileModule" +} +Text details for v8.compileModule: v8-cache-script.cgi +----------------------------------------------- +
diff --git a/third_party/blink/web_tests/virtual/v8-off-thread-finalization/http/tests/devtools/isolated-code-cache/same-origin-test-expected.txt b/third_party/blink/web_tests/virtual/v8-off-thread-finalization/http/tests/devtools/isolated-code-cache/same-origin-test-expected.txt new file mode 100644 index 0000000..c906a4c --- /dev/null +++ b/third_party/blink/web_tests/virtual/v8-off-thread-finalization/http/tests/devtools/isolated-code-cache/same-origin-test-expected.txt
@@ -0,0 +1,118 @@ +Tests V8 code cache for javascript resources + +--- Trace events related to code caches ------ +Load [A] 1st time. Produce timestamp. --> +v8.compile Properties: +{ + data : { + columnNumber : 0 + lineNumber : 0 + streamed : <boolean> + url : .../devtools/resources/v8-cache-script.cgi + } + endTime : <number> + startTime : <number> + type : "v8.compile" +} +Text details for v8.compile: v8-cache-script.cgi:1 +Load [A] 2nd time. Produce code cache. --> +v8.compile Properties: +{ + data : { + columnNumber : 0 + lineNumber : 0 + notStreamedReason : "already used streamed data" + streamed : <boolean> + url : .../devtools/resources/v8-cache-script.cgi + } + endTime : <number> + startTime : <number> + type : "v8.compile" +} +Text details for v8.compile: v8-cache-script.cgi:1 +v8.compile Properties: +{ + data : { + columnNumber : 0 + lineNumber : 0 + notStreamedReason : "already used streamed data" + producedCacheSize : <number> + streamed : <boolean> + url : .../devtools/resources/v8-cache-script.cgi + } + endTime : <number> + startTime : <number> + type : "v8.compile" +} +Text details for v8.compile: v8-cache-script.cgi:1 +Load [A] 3rd time. Consume code cache. --> +v8.compile Properties: +{ + data : { + cacheConsumeOptions : "code" + cacheRejected : false + columnNumber : 0 + consumedCacheSize : <number> + lineNumber : 0 + notStreamedReason : "already used streamed data" + streamed : <boolean> + url : .../devtools/resources/v8-cache-script.cgi + } + endTime : <number> + startTime : <number> + type : "v8.compile" +} +Text details for v8.compile: v8-cache-script.cgi:1 +Load [B]. Should not use the cached code. --> +v8.compile Properties: +{ + data : { + columnNumber : 0 + lineNumber : 0 + streamed : <boolean> + url : .../devtools/resources/v8-cache-script.cgi + } + endTime : <number> + startTime : <number> + type : "v8.compile" +} +Text details for v8.compile: v8-cache-script.cgi:1 +Load [A] again from MemoryCache. Should use the cached code. --> +v8.compile Properties: +{ + data : { + cacheConsumeOptions : "code" + cacheRejected : false + columnNumber : 0 + consumedCacheSize : <number> + lineNumber : 0 + notStreamedReason : "already used streamed data" + streamed : <boolean> + url : .../devtools/resources/v8-cache-script.cgi + } + endTime : <number> + startTime : <number> + type : "v8.compile" +} +Text details for v8.compile: v8-cache-script.cgi:1 +Clear [A] from MemoryCache. --> +Load [A] from Disk Cache. --> +v8.compile Properties: +{ + data : { + cacheConsumeOptions : "code" + cacheRejected : false + columnNumber : 0 + consumedCacheSize : <number> + lineNumber : 0 + notStreamedReason : "script has code-cache available" + streamed : <boolean> + url : .../devtools/resources/v8-cache-script.cgi + } + endTime : <number> + startTime : <number> + type : "v8.compile" +} +Text details for v8.compile: v8-cache-script.cgi:1 +----------------------------------------------- +
diff --git a/third_party/blink/web_tests/virtual/v8-off-thread-finalization/http/tests/devtools/isolated-code-cache/stale-revalidation-test-expected.txt b/third_party/blink/web_tests/virtual/v8-off-thread-finalization/http/tests/devtools/isolated-code-cache/stale-revalidation-test-expected.txt new file mode 100644 index 0000000..dd6b1f3 --- /dev/null +++ b/third_party/blink/web_tests/virtual/v8-off-thread-finalization/http/tests/devtools/isolated-code-cache/stale-revalidation-test-expected.txt
@@ -0,0 +1,82 @@ +Tests V8 code cache for resources revalidated with 304. + +--- Begin trace events related to code cache. ------ +1st load. Produce timestamp. --> +v8.compile Properties: +{ + data : { + columnNumber : 0 + lineNumber : 0 + streamed : <boolean> + url : .../devtools/resources/v8-cache-revalidated-script.cgi + } + endTime : <number> + startTime : <number> + type : "v8.compile" +} +Text details for v8.compile: v8-cache-revalidated-script.cgi:1 +2nd load. Produce code cache. --> +v8.compile Properties: +{ + data : { + columnNumber : 0 + lineNumber : 0 + notStreamedReason : "already used streamed data" + streamed : <boolean> + url : .../devtools/resources/v8-cache-revalidated-script.cgi + } + endTime : <number> + startTime : <number> + type : "v8.compile" +} +Text details for v8.compile: v8-cache-revalidated-script.cgi:1 +v8.compile Properties: +{ + data : { + columnNumber : 0 + lineNumber : 0 + notStreamedReason : "already used streamed data" + producedCacheSize : <number> + streamed : <boolean> + url : .../devtools/resources/v8-cache-revalidated-script.cgi + } + endTime : <number> + startTime : <number> + type : "v8.compile" +} +Text details for v8.compile: v8-cache-revalidated-script.cgi:1 +3rd load. Consume code cache. --> +v8.compile Properties: +{ + data : { + cacheConsumeOptions : "code" + cacheRejected : false + columnNumber : 0 + consumedCacheSize : <number> + lineNumber : 0 + notStreamedReason : "already used streamed data" + streamed : <boolean> + url : .../devtools/resources/v8-cache-revalidated-script.cgi + } + endTime : <number> + startTime : <number> + type : "v8.compile" +} +Text details for v8.compile: v8-cache-revalidated-script.cgi:1 +Clear the resource from the MemoryCache. --> +Load the resource with revalidation. The code cache got dropped because its timestamp did not match the one of the request. --> +v8.compile Properties: +{ + data : { + columnNumber : 0 + lineNumber : 0 + streamed : <boolean> + url : .../devtools/resources/v8-cache-revalidated-script.cgi + } + endTime : <number> + startTime : <number> + type : "v8.compile" +} +Text details for v8.compile: v8-cache-revalidated-script.cgi:1 +----- End trace events related to code cache. ------ +
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 66e6316..2bcb0b9 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -21099,7 +21099,8 @@ <owner>andzaytsev@google.com</owner> <owner>msramek@chromium.org</owner> <description> - User clicks the manage passwords button in safety check. + User clicks the manage passwords button in safety check when compromised + passwords have been found. </description> </action> @@ -21126,6 +21127,15 @@ <description>User clicks the safe browsing row in safety check.</description> </action> +<action name="Settings.SafetyCheck.ManageWeakPasswords"> + <owner>rainhard@chromium.org</owner> + <owner>msramek@chromium.org</owner> + <description> + User clicks the manage passwords button in safety check when weak passwords + have been found. + </description> +</action> + <action name="Settings.SafetyCheck.RelaunchAfterUpdates"> <owner>rainhard@chromium.org</owner> <owner>andzaytsev@google.com</owner>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index bd1c8c4..6007237 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -4749,6 +4749,12 @@ <int value="3" label="Initially incomplete & Failure"/> </enum> +<enum name="AutofillAwGSuggestionAvailability"> + <int value="0" label="No suggestion"/> + <int value="1" label="Has suggestion, user doesn't select it"/> + <int value="2" label="Has suggestion, user selects it"/> +</enum> + <enum name="AutofillCardholderNameFixFlowPromptEvent"> <int value="0" label="Shown"/> <int value="1" label="Accepted"/> @@ -5800,6 +5806,12 @@ <int value="99" label="NOT_PASSWORD"/> </enum> +<enum name="AutofillServerPredictionAvailability"> + <int value="0" label="Not available"/> + <int value="1" label="Available on session start"/> + <int value="2" label="Available after session start"/> +</enum> + <enum name="AutofillSessionStates"> <int value="0" label="Unknown"/> <int value="1" label="No callback from framework"/> @@ -43636,6 +43648,8 @@ <int value="-854716639" label="TranslateAndroidManualTrigger:enabled"/> <int value="-854519621" label="PointerLockOptions:disabled"/> <int value="-853594220" label="disable-new-avatar-menu"/> + <int value="-853455968" + label="OmniboxDefaultTypedNavigationsToHttps:disabled"/> <int value="-850821337" label="WebContentsForceDark:enabled"/> <int value="-848691867" label="DesktopPWAWindowing:enabled"/> <int value="-847216521" label="ChromeDuplex:enabled"/> @@ -46712,6 +46726,8 @@ <int value="2099945365" label="OmniboxAssistantVoiceSearch:enabled"/> <int value="2101151142" label="disable-direct-write"/> <int value="2104340988" label="CrostiniUsername:disabled"/> + <int value="2104439359" + label="OmniboxDefaultTypedNavigationsToHttps:enabled"/> <int value="2104788328" label="use-winrt-midi-api"/> <int value="2106798283" label="SafetyTip:disabled"/> <int value="2106855416" label="HostWindowsInAppShimProcess:enabled"/>
diff --git a/tools/metrics/histograms/histograms_xml/autofill/histograms.xml b/tools/metrics/histograms/histograms_xml/autofill/histograms.xml index 6749739..3fe54b4 100644 --- a/tools/metrics/histograms/histograms_xml/autofill/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/autofill/histograms.xml
@@ -2019,6 +2019,17 @@ <summary>Records the state of an autofill session.</summary> </histogram> +<histogram name="Autofill.WebView.AwGIsCurrentService" enum="BooleanYesNo" + expires_after="2021-06-08"> + <owner>michaelbai@chromium.org</owner> + <owner>src/android_webview/OWNERS</owner> + <summary> + Records whether Autofill with Google is the current Android autofill + service. It is recorded on AutofillProvider initialization. Only recorded in + Android P and beyond. + </summary> +</histogram> + <histogram name="Autofill.WebView.CreatedByActivityContext" enum="BooleanEnabled" expires_after="2021-06-08"> <owner>michaelbai@chromium.org</owner> @@ -2035,6 +2046,42 @@ </summary> </histogram> +<histogram name="Autofill.WebView.ServerPrediction.AwGSuggestionAvailability" + enum="AutofillAwGSuggestionAvailability" expires_after="2021-06-08"> + <owner>michaelbai@chromium.org</owner> + <owner>src/android_webview/OWNERS</owner> + <summary> + Records whether Autofill with Google has suggestions and if the user selects + any suggestion. It is recorded when the form is submitted. Only recorded in + Android P and beyond. + </summary> +</histogram> + +<histogram name="Autofill.WebView.ServerPredicton.HasValidServerPrediction" + enum="BooleanYesNo" expires_after="2021-06-08"> + <owner>michaelbai@chromium.org</owner> + <owner>src/android_webview/OWNERS</owner> + <summary> + Records whether the server prediction of any field isn't NO_SERVER_DATA. + This histogram is recorded when the server prediction is available for the + current form, and only if AndroidAutofillQueryServerFieldTypes feature is + enabled. + </summary> +</histogram> + +<histogram name="Autofill.WebView.ServerPredicton.PredictionAvailability" + enum="AutofillServerPredictionAvailability" expires_after="2021-06-08"> + <owner>michaelbai@chromium.org</owner> + <owner>src/android_webview/OWNERS</owner> + <summary> + Records whether and when the server prediction response of current autofill + session is available even if query failed or there is no server data. This + histogram is recorded when the prediction becomes available or the new + session starts, and only if AndroidAutofillQueryServerFieldTypes feature is + enabled. + </summary> +</histogram> + <histogram name="Autofill.WebView.SubmissionSource" enum="AutofillSubmissionSource" expires_after="2021-06-08"> <owner>michaelbai@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/file/histograms.xml b/tools/metrics/histograms/histograms_xml/file/histograms.xml index e9341a3..0a04f794b 100644 --- a/tools/metrics/histograms/histograms_xml/file/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/file/histograms.xml
@@ -22,9 +22,9 @@ <histograms> <histogram name="FileBrowser.ChangeDirectory.RootType" - enum="FileManagerRootType" expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + enum="FileManagerRootType" expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: Counts the number of directory-changed events, bucketed by the RootType of the directory newly displayed. @@ -32,9 +32,9 @@ </histogram> <histogram name="FileBrowser.ComputersCount" units="Computers" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: number of Computers a user has available in the Files app. Computed every time the File Browser is opened (including file @@ -43,15 +43,17 @@ </summary> </histogram> -<histogram name="FileBrowser.Create" enum="FileDialogType" expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> - <summary>Chrome OS File Browser opening mode.</summary> +<histogram name="FileBrowser.Create" enum="FileDialogType" expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> + <summary> + Chrome OS File Browser: The mode in which the File Browser was opened. + </summary> </histogram> -<histogram name="FileBrowser.DirectoryScan" units="ms" expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> +<histogram name="FileBrowser.DirectoryScan" units="ms" expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: time to scan a directory. Measured on every File Browser directory change. @@ -59,9 +61,9 @@ </histogram> <histogram name="FileBrowser.DownloadDestination.IsGoogleDrive.Changed" - enum="BooleanEnabled" expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + enum="BooleanEnabled" expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Tracks whether download destination is set to a Google Drive folder when the download destination is changed by the user in the settings page. @@ -69,9 +71,9 @@ </histogram> <histogram name="FileBrowser.DownloadDestination.IsGoogleDrive.Started" - enum="BooleanEnabled" expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + enum="BooleanEnabled" expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Tracks whether download destination is set to a Google Drive folder on startup. @@ -79,29 +81,30 @@ </histogram> <histogram name="FileBrowser.Downloads.DirectoryPercentageOfDiskUsage" - units="%" expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + units="%" expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> The size of the space consumed by a users files in "My Files" folder and it's children, calculated as a percentage of the total disk - space. Caluclated on user login. + space. Caluclated on user login and recorded by VolumeManager. </summary> </histogram> <histogram name="FileBrowser.Downloads.DirectorySizeMiB" units="MiB" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> The total size of all of the users files stored in the "My Files" - folder and it's children. Caluclated on user login. + folder and it's children. Caluclated on user login and recorded by + VolumeManager. </summary> </histogram> -<histogram name="FileBrowser.DownloadsCount" units="units" expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> +<histogram name="FileBrowser.DownloadsCount" units="units" expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: number of files and directories in the Downloads directory (not including the contents of nested directories). Computed every @@ -110,9 +113,9 @@ </histogram> <histogram name="FileBrowser.DriveDuplicateFinder.LongComputeHash" units="ms" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> The time taken to calculate the hash of a file, only recorded if the time exceeds a local threshold that is currenty 5 seconds. @@ -120,9 +123,9 @@ </histogram> <histogram name="FileBrowser.DriveDuplicateFinder.LongSearchByHash" units="ms" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> The time taken to search for a file using it's hash value, only recorded if the time exceeds a local threshold that is currently 1 second. @@ -144,9 +147,9 @@ </histogram> <histogram name="FileBrowser.FileSystemProviderMounted" - enum="FileSystemProviderMountType" expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + enum="FileSystemProviderMountType" expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> The type of file system provider that has been mounted. This metric is emmitted on mounting of the filesystem. @@ -154,9 +157,9 @@ </histogram> <histogram name="FileBrowser.FolderShortcut.Add" units="units" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: this is recorded when the user adds a folder shortcut. @@ -164,9 +167,9 @@ </histogram> <histogram name="FileBrowser.FolderShortcut.Count" units="units" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: number of saved folder shorcuts. This is recorded when the Files app is launched. @@ -174,9 +177,9 @@ </histogram> <histogram name="FileBrowser.FolderShortcut.Navigate" units="units" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: this is recorded when the user clicks or selects a folder shortcut and is navigated to the target folder. @@ -184,9 +187,9 @@ </histogram> <histogram name="FileBrowser.FolderShortcut.Remove" units="units" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: this is recorded when the user removes a folder shortcut. @@ -217,8 +220,8 @@ <histogram name="FileBrowser.ImportController.DeviceYanked" enum="Boolean" expires_after="M92"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS Files App: Whether an external media device was removed during the upload process. @@ -227,17 +230,17 @@ <histogram name="FileBrowser.ImportController.ImportCancelled" enum="BooleanCanceled" expires_after="M92"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS Files App: Whether the media import process was cancelled. </summary> </histogram> <histogram name="FileBrowser.LauncherSearch.Drive" units="ms" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> The time taken to execute launcher search for drive files. Recorded when the complete result set is returned from drive. @@ -245,9 +248,9 @@ </histogram> <histogram name="FileBrowser.LauncherSearch.Local" units="ms" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> The time taken to execute launcher search for local files. Recorded when the complete result set has been calculated for files on the local disk. @@ -255,9 +258,9 @@ </histogram> <histogram name="FileBrowser.Load{FileBrowserLoad}" units="ms" - expires_after="M92"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser is an built-in extension without a background page. Its main.html file is loaded every time the user opens a File Browser tab or @@ -322,9 +325,9 @@ </histogram> <histogram name="FileBrowser.Location.OnEntryExpandedOrCollapsed.NonTopLevel" - enum="FileManagerRootType" expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + enum="FileManagerRootType" expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS Files App: The locations (root types) of non-top-level entries when they are expanded or collapsed (expand icon clicked) in the directory @@ -333,9 +336,9 @@ </histogram> <histogram name="FileBrowser.Location.OnEntryExpandedOrCollapsed.TopLevel" - enum="FileManagerRootType" expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + enum="FileManagerRootType" expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS Files App: The locations (root types) of top-level entries (root entries) when they are expanded or collapsed (expand icon clicked) in the @@ -344,22 +347,24 @@ </histogram> <histogram name="FileBrowser.Location.OnEntrySelected.NonTopLevel" - enum="FileManagerRootType" expires_after="M79"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + enum="FileManagerRootType" expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS Files App: The locations (root types) of non-top-level entries - when they are clicked in the directory tree. + when they are clicked in the directory tree. Contains incomplete data from + M80 to M87 inclusively. </summary> </histogram> <histogram name="FileBrowser.Location.OnEntrySelected.TopLevel" - enum="FileManagerRootType" expires_after="M79"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + enum="FileManagerRootType" expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS Files App: The locations (root types) of top-level entries (root - entries) when they are clicked in the directory tree. + entries) when they are clicked in the directory tree. Contains incomplete + data from M80 to M87 inclusively. </summary> </histogram> @@ -423,36 +428,36 @@ </histogram> <histogram name="FileBrowser.MenuItemSelected" enum="FileManagerMenuCommands" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS Files App: The commands selected in the menu by the files app. </summary> </histogram> <histogram name="FileBrowser.Notification.Show" - enum="FileManagerNotificationType" expires_after="M92"> - <owner>fukino@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + enum="FileManagerNotificationType" expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: Notification types what were shown to the user. </summary> </histogram> <histogram name="FileBrowser.Notification.UserAction" - enum="FileManagerNotificationUserAction" expires_after="M92"> - <owner>fukino@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + enum="FileManagerNotificationUserAction" expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: User actions responding to a notification. </summary> </histogram> <histogram name="FileBrowser.OpenFiles.RootType" enum="FileManagerRootType" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: The locations (root types) of files which are opened by the file picker. @@ -460,9 +465,9 @@ </histogram> <histogram name="FileBrowser.PhotoEditor.DisplayTime" units="ms" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M92"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS Photo Editor: time to display an image. Measured from the moment the user selected the image till the moment it is displayed (not counting @@ -471,46 +476,46 @@ </histogram> <histogram name="FileBrowser.PhotoEditor.FileType" enum="PhotoEditorFileType" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M92"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary>Chrome OS Photo Editor: the type of the file opened.</summary> </histogram> <histogram name="FileBrowser.PhotoEditor.LoadMode" enum="PhotoEditorLoadMode" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M92"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary>Chrome OS Photo Editor: the way the image has been loaded.</summary> </histogram> <histogram name="FileBrowser.PhotoEditor.LoadTime" units="ms" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M92"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary>Chrome OS Photo Editor: time to load an image from a file.</summary> </histogram> <histogram name="FileBrowser.PhotoEditor.SaveResult" - enum="PhotoEditorSaveResult" expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + enum="PhotoEditorSaveResult" expires_after="M92"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS Photo Editor: the result of a file save operation. </summary> </histogram> <histogram name="FileBrowser.PhotoEditor.SaveTime" units="ms" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M92"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary>Chrome OS Photo Editor: time to save an image to a file.</summary> </histogram> <histogram name="FileBrowser.PhotoEditor.Size.MB" units="MBytes" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M92"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS Photo Editor: size of an image file in megabytes. Measured on every image load. @@ -518,9 +523,9 @@ </histogram> <histogram name="FileBrowser.PhotoEditor.Size.MPix" units="MPixels" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M92"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS Photo Editor: size of an image in megapixels. Measured on every image load. @@ -528,53 +533,53 @@ </histogram> <histogram name="FileBrowser.PhotoEditor.Tool" enum="PhotoEditorToolType" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M92"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary>Chrome OS Photo Editor: the button which the user clicked.</summary> </histogram> <histogram name="FileBrowser.QuickView.DialogType" enum="FileDialogType" - expires_after="M90"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> File dialog type (e.g. Full page, Save as file) when quick view is launched. </summary> </histogram> <histogram name="FileBrowser.QuickView.FileType" enum="ViewFileType" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary>File types that were tried to be opened with quick view.</summary> </histogram> <histogram name="FileBrowser.QuickView.FileTypeOnLaunch" enum="ViewFileType" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary>File types that were selected when quick view is launched.</summary> </histogram> <histogram name="FileBrowser.QuickView.VolumeType" enum="FileManagerVolumeType" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary>The volume type where quick view is opened.</summary> </histogram> <histogram name="FileBrowser.QuickView.WayToOpen" - enum="FileManagerQuickViewWayToOpen" expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + enum="FileManagerQuickViewWayToOpen" expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary>How quick view was opened.</summary> </histogram> <histogram name="FileBrowser.Recent.LoadArcMedia" units="ms" - expires_after="M92"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Time to load a recently modified file list from Media Views. It is triggered when the user opens or reloads Recent view in the Files app. @@ -582,9 +587,9 @@ </histogram> <histogram name="FileBrowser.Recent.LoadCrostini" units="ms" - expires_after="M92"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Time to load a recently modified file list from Crostini. It is triggered when the user opens or reloads Recent view in the Files app. @@ -592,27 +597,27 @@ </histogram> <histogram name="FileBrowser.Recent.LoadDownloads" units="ms" - expires_after="M92"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Time to load a recently modified file list from Downloads. It is triggered when the user opens or reloads Recent view in the Files app. </summary> </histogram> -<histogram name="FileBrowser.Recent.LoadDrive" units="ms" expires_after="M92"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> +<histogram name="FileBrowser.Recent.LoadDrive" units="ms" expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Time to load a recently modified file list from Drive. It is triggered when the user opens or reloads Recent view in the Files app. </summary> </histogram> -<histogram name="FileBrowser.Recent.LoadTotal" units="ms" expires_after="M92"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> +<histogram name="FileBrowser.Recent.LoadTotal" units="ms" expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Time to load a recently modified file list from all sources. It is triggered when the user opens or reloads Recent view in the Files app. @@ -647,18 +652,18 @@ </histogram> <histogram name="FileBrowser.SuggestApps.CloseDialog" - enum="SuggestAppsDialogCloseReason" expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + enum="SuggestAppsDialogCloseReason" expires_after="M92"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: the reason why the suggest apps dialog was closed. </summary> </histogram> <histogram name="FileBrowser.SuggestApps.Install" - enum="SuggestAppsDialogInstall" expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + enum="SuggestAppsDialogInstall" expires_after="M92"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: whether the Webstore item user selected was successfully installed or not. @@ -666,9 +671,9 @@ </histogram> <histogram name="FileBrowser.SuggestApps.Load" enum="SuggestAppsDialogLoad" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M92"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: whether the initialization of the dialog succeeded or not. @@ -676,9 +681,9 @@ </histogram> <histogram name="FileBrowser.SuggestApps.LoadTime" units="ms" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M92"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: time to load the suggest apps dialog. Measured between the moment window appears and the moment all the contents in the @@ -687,9 +692,9 @@ </histogram> <histogram name="FileBrowser.TeamDrivesCount" units="Team Drives" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: number of Team Drives a user has available in the Files app. Computed every time the File Browser is opened (including file @@ -699,9 +704,9 @@ </histogram> <histogram name="FileBrowser.ToggleFileListType" enum="FileManagerListType" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS Files App: Recorded when the Grid View/List View toggle menu icon is selected. @@ -709,9 +714,9 @@ </histogram> <histogram name="FileBrowser.ViewingFileType" enum="ViewFileType" - expires_after="M92"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> File types that were tried to be viewed through browser. This is recorded when the user tries to view a file from the Files app. @@ -719,9 +724,9 @@ </histogram> <histogram name="FileBrowser.ViewingFileType.Offline" enum="ViewFileType" - expires_after="M92"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> File types that were tried to be viewed through browser while the user is offline. This is recorded when the user tries to view a file from the Files @@ -730,9 +735,9 @@ </histogram> <histogram name="FileBrowser.ViewingFileType.Online" enum="ViewFileType" - expires_after="M92"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> File types that were tried to be viewed through browser while the user is online. This is recorded when the user tries to view a file from the Files @@ -741,9 +746,9 @@ </histogram> <histogram name="FileBrowser.ViewingRootType" enum="FileManagerRootType" - expires_after="M92"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: The locations (root types) of files which are opened in stand-alone mode. This does not include files opened in file picker mode. @@ -751,9 +756,9 @@ </histogram> <histogram name="FileBrowser.ViewingRootType.Offline" - enum="FileManagerRootType" expires_after="M92"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + enum="FileManagerRootType" expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: The locations (root types) of files which are opened in stand-alone mode while the user is offline. This does not include files @@ -762,9 +767,9 @@ </histogram> <histogram name="FileBrowser.ViewingRootType.Online" enum="FileManagerRootType" - expires_after="M92"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: The locations (root types) of files which are opened in stand-alone mode while the user is online. This does not include files @@ -773,9 +778,9 @@ </histogram> <histogram name="FileBrowser.ViewingTaskType" enum="FileManagerTaskType" - expires_after="M92"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: The type of the handler to be used to open files. This is recorded when the user tries to view a file from the Files app. @@ -783,9 +788,9 @@ </histogram> <histogram name="FileBrowser.ViewingTaskType.Offline" - enum="FileManagerTaskType" expires_after="M92"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + enum="FileManagerTaskType" expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: The type of the handler to be used to open files when the user is offline. This is recorded when the user tries to view a @@ -794,9 +799,9 @@ </histogram> <histogram name="FileBrowser.ViewingTaskType.Online" enum="FileManagerTaskType" - expires_after="M92"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: The type of the handler to be used to open files when the user is online. This is recorded when the user tries to view a file @@ -805,9 +810,9 @@ </histogram> <histogram name="FileBrowser.VolumeType" enum="FileManagerVolumeType" - expires_after="M92"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: counts the number of times volumes are mounted for each volume type. @@ -815,9 +820,9 @@ </histogram> <histogram name="FileBrowser.ZipFileTask" enum="FileManagerZipHandlerType" - expires_after="M89"> - <owner>slangley@chromium.org</owner> - <owner>weifangsun@chromium.org</owner> + expires_after="M98"> + <owner>simmonsjosh@google.com</owner> + <owner>src/ui/file_manager/OWNERS</owner> <summary> Chrome OS File Browser: counts the number of times ZIP file was opened or created, categorized by component extensions and its operation types.
diff --git a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml index c491856e..f5ccc08 100644 --- a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml +++ b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
@@ -12016,7 +12016,12 @@ <suffix name="Family-link-notice.Done" label=""/> <suffix name="Fingerprint-setup.Next" label=""/> <suffix name="Gaia-signin.Back" label=""/> - <suffix name="Gaia-signin.CloseDialog" label=""/> + <suffix name="Gaia-signin.Cancel" label=""/> + <suffix name="Gaia-signin.CloseDialog" label=""> + <obsolete> + Removed in M89. + </obsolete> + </suffix> <suffix name="Gaia-signin.EnterpriseEnroll" label=""/> <suffix name="Gaia-signin.StartConsumerKiosk" label=""/> <suffix name="Gesture-navigation.Next" label=""/>
diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml index 9219e87..5625c03 100644 --- a/tools/metrics/histograms/histograms_xml/others/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml
@@ -12676,6 +12676,27 @@ <summary>Number of unread entries in reading list.</summary> </histogram> +<histogram name="ReadingList.WebUI.LoadCompletedTime" units="ms" + expires_after="M92"> + <owner>corising@chromium.org</owner> + <owner>chrome-desktop-ui-sea@google.com</owner> + <summary> + The amount of time between the render frame host StartProvisionalLoad event + and the render frame DocumentOnLoadCompleted event for the Read Later WebUI + page. + </summary> +</histogram> + +<histogram name="ReadingList.WebUI.LoadDocumentTime" units="ms" + expires_after="M92"> + <owner>corising@chromium.org</owner> + <owner>chrome-desktop-ui-sea@google.com</owner> + <summary> + The amount of time between the render frame host StartProvisionalLoad and + DidFinishDocumentLoad events for the Read Later WebUI page. + </summary> +</histogram> + <histogram name="RecoveryComponent.Event" enum="RecoveryComponentEvent" expires_after="M77"> <owner>robertshield@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/service/histograms.xml b/tools/metrics/histograms/histograms_xml/service/histograms.xml index 2078bc6..b3d6db30 100644 --- a/tools/metrics/histograms/histograms_xml/service/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/service/histograms.xml
@@ -371,6 +371,9 @@ <histogram name="ServiceWorker.GetAllOriginsInfoTime" units="ms" expires_after="2021-01-24"> + <obsolete> + Removed 2021-01-12. + </obsolete> <owner>bashi@chromium.org</owner> <owner>chrome-worker@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/histograms_xml/settings/histograms.xml b/tools/metrics/histograms/histograms_xml/settings/histograms.xml index 4ab4cffb..3ac2564 100644 --- a/tools/metrics/histograms/histograms_xml/settings/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/settings/histograms.xml
@@ -186,7 +186,7 @@ <summary> Which user actions were taken in safety check. Recorded every time a user does an interaction in safety check. Value 5 and 6 got added with M86, 7-9 - with M87, and 10 with M88. + with M87, 10 with M88, and 11 with M89. </summary> </histogram>
diff --git a/tools/metrics/histograms/histograms_xml/v8/histograms.xml b/tools/metrics/histograms/histograms_xml/v8/histograms.xml index a56c1789..5a21d97 100644 --- a/tools/metrics/histograms/histograms_xml/v8/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/v8/histograms.xml
@@ -337,8 +337,9 @@ </histogram> <histogram name="V8.DebugFeatureUsage" enum="V8DebugFeature" - expires_after="2021-01-10"> + expires_after="2022-01-10"> <owner>yangguo@chromium.org</owner> + <owner>bmeurer@chromium.org</owner> <summary> Debugger feature used at least once per isolate, recorded on first use. </summary>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 79b6faa..74eb1c5 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -1,12 +1,12 @@ { "trace_processor_shell": { "win": { - "hash": "26aa7f0361bf6a3fbf5627c8c8699301ab51c6e6", - "remote_path": "perfetto_binaries/trace_processor_shell/win/026943fd29be9ac85975ddb8afdd2853bb03b3da/trace_processor_shell.exe" + "hash": "f3800b3c8e2857a159879265b67126c6ab2495e7", + "remote_path": "perfetto_binaries/trace_processor_shell/win/53a231c0ae868366179bd560b68a2f5f4b166541/trace_processor_shell.exe" }, "mac": { - "hash": "f0efd147e6c4c6f1b295bb5755a0e927fd94da5b", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/026943fd29be9ac85975ddb8afdd2853bb03b3da/trace_processor_shell" + "hash": "fd0d9f70fe09c168bbb999ade77e6f9e4c991c3c", + "remote_path": "perfetto_binaries/trace_processor_shell/mac/53a231c0ae868366179bd560b68a2f5f4b166541/trace_processor_shell" }, "linux": { "hash": "9de25afa2969d17640815fe3b83e4427b0526564",
diff --git a/ui/accessibility/ax_tree.cc b/ui/accessibility/ax_tree.cc index b543710..2d9cda3 100644 --- a/ui/accessibility/ax_tree.cc +++ b/ui/accessibility/ax_tree.cc
@@ -5,12 +5,12 @@ #include "ui/accessibility/ax_tree.h" #include <stddef.h> - #include <algorithm> #include <numeric> #include <utility> #include "base/auto_reset.h" +#include "base/callback_helpers.h" #include "base/check_op.h" #include "base/command_line.h" #include "base/containers/contains.h"
diff --git a/ui/base/clipboard/clipboard_ozone.cc b/ui/base/clipboard/clipboard_ozone.cc index 1140e65..4975a153 100644 --- a/ui/base/clipboard/clipboard_ozone.cc +++ b/ui/base/clipboard/clipboard_ozone.cc
@@ -201,7 +201,6 @@ void PerformRequestAndWaitForResult(ClipboardBuffer buffer, Request* request) { DCHECK(request); - DCHECK(!abort_timer_.IsRunning()); DCHECK(!pending_request_); pending_request_ = request; @@ -228,16 +227,12 @@ request->finish_closure = run_loop.QuitClosure(); // Set a timeout timer after which the request will be aborted. - abort_timer_.Start(FROM_HERE, kRequestTimeout, this, - &AsyncClipboardOzone::AbortStalledRequest); + base::OneShotTimer abort_timer; + abort_timer.Start(FROM_HERE, kRequestTimeout, this, + &AsyncClipboardOzone::CompleteRequest); run_loop.Run(); } - void AbortStalledRequest() { - if (pending_request_ && pending_request_->finish_closure) - std::move(pending_request_->finish_closure).Run(); - } - void DispatchReadRequest(ClipboardBuffer buffer, Request* request) { auto callback = base::BindOnce(&AsyncClipboardOzone::OnTextRead, weak_factory_.GetWeakPtr()); @@ -275,7 +270,7 @@ void CompleteRequest() { if (!pending_request_) return; - abort_timer_.Stop(); + if (pending_request_->finish_closure) std::move(pending_request_->finish_closure).Run(); pending_request_ = nullptr; @@ -295,9 +290,6 @@ // A current pending request being processed. Request* pending_request_ = nullptr; - // Aborts |pending_request| after Request::timeout. - base::RepeatingTimer abort_timer_; - // Provides communication to a system clipboard under ozone level. PlatformClipboard* const platform_clipboard_ = nullptr;
diff --git a/ui/events/ozone/evdev/event_device_info.cc b/ui/events/ozone/evdev/event_device_info.cc index 637942d..797489b 100644 --- a/ui/events/ozone/evdev/event_device_info.cc +++ b/ui/events/ozone/evdev/event_device_info.cc
@@ -50,6 +50,10 @@ {0x1050, 0x0010}, // Yubico.com Yubikey {0x1050, 0x0407}, // Yubico.com Yubikey 4 OTP+U2F+CCID {0x1bcf, 0x08a0}, // Kensington Pro Fit Full-size + {0x256c, 0x006d}, // Huion HS64 + {0x28bd, 0x0914}, // XP-Pen Star G640 + {0x28bd, 0x091f}, // XP-Pen Artist 12 Pro + {0x28bd, 0x0928}, // XP-Pen Deco mini7W }; constexpr struct {
diff --git a/ui/file_manager/file_manager/background/js/BUILD.gn b/ui/file_manager/file_manager/background/js/BUILD.gn index fb3480a..ae5f2b50 100644 --- a/ui/file_manager/file_manager/background/js/BUILD.gn +++ b/ui/file_manager/file_manager/background/js/BUILD.gn
@@ -1020,7 +1020,10 @@ "//ui/file_manager/file_manager/common/js:util.m", "//ui/webui/resources/js:assert.m", ] - visibility += [ "//ui/file_manager/file_manager/foreground/js:navigation_list_model_unittest.m" ] + visibility += [ + "//ui/file_manager/file_manager/foreground/js:navigation_list_model_unittest.m", + "//ui/file_manager/file_manager/foreground/js:providers_model_unittest.m", + ] extra_deps = [ ":modulize" ] }
diff --git a/ui/file_manager/file_manager/foreground/js/BUILD.gn b/ui/file_manager/file_manager/foreground/js/BUILD.gn index b1fdf499..302fe1e 100644 --- a/ui/file_manager/file_manager/foreground/js/BUILD.gn +++ b/ui/file_manager/file_manager/foreground/js/BUILD.gn
@@ -39,13 +39,21 @@ ":empty_folder_controller.m", ":fake_android_app_list_model.m", ":file_list_model.m", + ":file_type_filters_controller.m", ":file_watcher.m", ":folder_shortcuts_data_model.m", + ":launch_param.m", + ":metrics_start.m", + ":mock_actions_model.m", ":mock_directory_model.m", ":mock_folder_shortcut_data_model.m", ":mock_navigation_list_model.m", ":navigation_list_model.m", + ":navigation_uma.m", + ":providers_model.m", + ":spinner_controller.m", ":thumbnail_loader.m", + ":web_store_utils.m", ] } @@ -185,6 +193,16 @@ ] } +js_library("mock_actions_model.m") { + sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/mock_actions_model.m.js" ] + deps = [ + "//ui/webui/resources/js:cr.m", + "//ui/webui/resources/js/cr:event_target.m", + ] + + extra_deps = [ ":modulize" ] +} + js_library("fake_file_selection_handler") { testonly = true deps = [ @@ -463,6 +481,17 @@ ] } +js_library("navigation_uma.m") { + sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/navigation_uma.m.js" ] + deps = [ + "//ui/file_manager/base/js:volume_manager_types.m", + "//ui/file_manager/externs:volume_manager.m", + "//ui/file_manager/file_manager/common/js:metrics.m", + ] + + extra_deps = [ ":modulize" ] +} + js_library("directory_tree_naming_controller") { deps = [ ":directory_model", @@ -708,10 +737,28 @@ ] } -js_unittest("file_type_filters_controller_unittest") { +js_library("file_type_filters_controller.m") { + sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/file_type_filters_controller.m.js" ] deps = [ - ":file_type_filters_controller", - "//ui/webui/resources/js:webui_resource_test", + ":directory_model.m", + "//ui/file_manager/externs:files_app_entry_interfaces.m", + "//ui/file_manager/file_manager/common/js:util.m", + ] + + extra_deps = [ ":modulize" ] +} + +js_unittest("file_type_filters_controller_unittest.m") { + deps = [ + ":directory_model.m", + ":file_type_filters_controller.m", + "//chrome/test/data/webui:chai_assert", + "//ui/file_manager/base/js:mock_chrome", + "//ui/file_manager/base/js:volume_manager_types.m", + "//ui/file_manager/externs:files_app_entry_interfaces.m", + "//ui/file_manager/file_manager/common/js:files_app_entry_types.m", + "//ui/webui/resources/js:load_time_data.m", + "//ui/webui/resources/js/cr:event_target.m", ] } @@ -827,6 +874,16 @@ ] } +js_library("launch_param.m") { + sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/launch_param.m.js" ] + deps = [ + ":dialog_type.m", + "//ui/file_manager/base/js:volume_manager_types.m", + ] + + extra_deps = [ ":modulize" ] +} + js_library("list_thumbnail_loader") { deps = [ ":directory_model", @@ -892,6 +949,13 @@ deps = [ "//ui/file_manager/file_manager/common/js:metrics" ] } +js_library("metrics_start.m") { + sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/metrics_start.m.js" ] + deps = [ "//ui/file_manager/file_manager/common/js:metrics.m" ] + + extra_deps = [ ":modulize" ] +} + js_library("naming_controller") { deps = [ ":directory_contents", @@ -962,13 +1026,28 @@ deps = [ "//ui/webui/resources/js:assert" ] } -js_unittest("providers_model_unittest") { +js_library("providers_model.m") { + sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/providers_model.m.js" ] deps = [ - ":providers_model", - "//ui/file_manager/base/js:mock_chrome", - "//ui/file_manager/base/js:test_error_reporting", - "//ui/file_manager/file_manager/background/js:mock_volume_manager", - "//ui/webui/resources/js:load_time_data", + "//ui/file_manager/base/js:volume_manager_types.m", + "//ui/file_manager/externs:volume_manager.m", + "//ui/webui/resources/js:assert.m", + ] + + extra_deps = [ ":modulize" ] +} + +js_unittest("providers_model_unittest.m") { + deps = [ + ":providers_model.m", + "//chrome/test/data/webui:chai_assert", + "//ui/file_manager/base/js:mock_chrome.m", + "//ui/file_manager/base/js:test_error_reporting.m", + "//ui/file_manager/base/js:volume_manager_types.m", + "//ui/file_manager/externs:volume_manager.m", + "//ui/file_manager/file_manager/background/js:mock_volume_manager.m", + "//ui/file_manager/file_manager/background/js:volume_info_impl.m", + "//ui/file_manager/file_manager/common/js:mock_entry.m", ] } @@ -1038,12 +1117,18 @@ js_library("spinner_controller") { } -js_unittest("spinner_controller_unittest") { +js_library("spinner_controller.m") { + sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/spinner_controller.m.js" ] + + extra_deps = [ ":modulize" ] +} + +js_unittest("spinner_controller_unittest.m") { deps = [ - ":spinner_controller", - "//ui/file_manager/base/js:test_error_reporting", - "//ui/webui/resources/js:assert", - "//ui/webui/resources/js:util", + ":spinner_controller.m", + "//chrome/test/data/webui:chai_assert", + "//ui/file_manager/base/js:test_error_reporting.m", + "//ui/webui/resources/js:assert.m", ] } @@ -1126,6 +1211,13 @@ deps = [ ":constants" ] } +js_library("web_store_utils.m") { + sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/web_store_utils.m.js" ] + deps = [ ":constants.m" ] + + extra_deps = [ ":modulize" ] +} + js_library("webui_command_extender") { deps = [ "//ui/webui/resources/js:cr", @@ -1137,7 +1229,10 @@ deps = [ ":directory_contents_unittest.m", ":file_list_model_unittest.m", + ":file_type_filters_controller_unittest.m", ":navigation_list_model_unittest.m", + ":providers_model_unittest.m", + ":spinner_controller_unittest.m", ":thumbnail_loader_unittest.m", ] js_module = true @@ -1157,11 +1252,8 @@ ":file_manager_commands_unittest", ":file_tasks_unittest", ":file_transfer_controller_unittest", - ":file_type_filters_controller_unittest", ":import_controller_unittest", ":list_thumbnail_loader_unittest", - ":providers_model_unittest", - ":spinner_controller_unittest", ":task_controller_unittest", ] mocks = [ "$externs_path/file_manager_private.js" ] @@ -1182,11 +1274,19 @@ "file_list_model.js", "file_watcher.js", "folder_shortcuts_data_model.js", + "launch_param.js", "mock_directory_model.js", "mock_folder_shortcut_data_model.js", "mock_navigation_list_model.js", "navigation_list_model.js", + "providers_model.js", "thumbnail_loader.js", + "web_store_utils.js", + "file_type_filters_controller.js", + "navigation_uma.js", + "metrics_start.js", + "mock_actions_model.js", + "spinner_controller.js", ] namespace_rewrites = cr_namespace_rewrites
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js index 58f9b893..dbd9dfa 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -1775,12 +1775,21 @@ this.addsItems_; } + /** @override */ execute(event, fileManager) { if (this.addsItems_ === undefined) { return; } - const entries = fileManager.selectionHandler.selection.entries; + // Filter out entries from unsupported volumes. + const allowedVolumeTypes = HoldingSpaceUtil.getAllowedVolumeTypes(); + const entries = + fileManager.selectionHandler.selection.entries.filter(entry => { + const volumeInfo = fileManager.volumeManager.getVolumeInfo(entry); + return volumeInfo && + allowedVolumeTypes.includes(volumeInfo.volumeType); + }); + chrome.fileManagerPrivate.toggleAddedToHoldingSpace( entries, this.addsItems_); @@ -1800,17 +1809,25 @@ } const allowedVolumeTypes = HoldingSpaceUtil.getAllowedVolumeTypes(); - const currentVolumeInfo = fileManager.directoryModel.getCurrentVolumeInfo(); - if (!currentVolumeInfo || - !allowedVolumeTypes.includes(currentVolumeInfo.volumeType)) { - event.canExecute = false; - command.setHidden(true); - return; + const currentRootType = fileManager.directoryModel.getCurrentRootType(); + if (!util.isRecentRootType(currentRootType)) { + const volumeInfo = fileManager.directoryModel.getCurrentVolumeInfo(); + if (!volumeInfo || !allowedVolumeTypes.includes(volumeInfo.volumeType)) { + event.canExecute = false; + command.setHidden(true); + return; + } } - const entries = fileManager.selectionHandler.selection.entries; + // Filter out entries from unsupported volumes. + const entries = + fileManager.selectionHandler.selection.entries.filter(entry => { + const volumeInfo = fileManager.volumeManager.getVolumeInfo(entry); + return volumeInfo && + allowedVolumeTypes.includes(volumeInfo.volumeType); + }); - if (!entries || entries.length === 0) { + if (entries.length === 0) { event.canExecute = false; command.setHidden(true); return;
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands_unittest.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands_unittest.js index e576458..65f96b1 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager_commands_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands_unittest.js
@@ -30,3 +30,205 @@ } } +/** + * Checks that the `toggle-holding-space` command is appropriately enabled/ + * disabled given the current selection state and executes as expected. + */ +function testToggleHoldingSpaceCommand() { + // Verify `toggle-holding-space` command exists. + const command = CommandHandler.getCommand('toggle-holding-space'); + assertNotEqual(command, undefined); + + // Enable the holding space feature and provide strings. + loadTimeData.data = { + HOLDING_SPACE_ENABLED: true, + HOLDING_SPACE_PIN_TO_SHELF_COMMAND_LABEL: 'Pin to shelf', + HOLDING_SPACE_UNPIN_TO_SHELF_COMMAND_LABEL: 'Unpin to shelf', + }; + + // Mock private API. + chrome.fileManagerPrivate.getHoldingSpaceState = (callback) => { + callback({itemUrls: []}); + }; + + // Mock volume manager. + const volumeManager = new MockVolumeManager(); + + // Create `DOWNLOADS` volume. + const downloadsVolumeInfo = volumeManager.createVolumeInfo( + VolumeManagerCommon.VolumeType.DOWNLOADS, 'downloadsVolumeId', + 'Downloads volume'); + const downloadsFileSystem = downloadsVolumeInfo.fileSystem; + + // Create `REMOVABLE` volume. + const removableVolumeInfo = volumeManager.createVolumeInfo( + VolumeManagerCommon.VolumeType.REMOVABLE, 'removableVolumeId', + 'Removable volume'); + const removableFileSystem = removableVolumeInfo.fileSystem; + + // Mock file/folder entries. + const audioFileEntry = new MockEntry(downloadsFileSystem, '/audio.mp3'); + const downloadFileEntry = new MockEntry(downloadsFileSystem, '/download.txt'); + const folderEntry = MockDirectoryEntry.create(downloadsFileSystem, '/folder'); + const imageFileEntry = new MockEntry(downloadsFileSystem, '/image.png'); + const removableFileEntry = + new MockEntry(removableFileSystem, '/removable.txt'); + const videoFileEntry = new MockEntry(downloadsFileSystem, 'video.mp4'); + + // Define test cases. + const testCases = [ + { + description: 'Tests empty selection in `Downloads`', + currentRootType: VolumeManagerCommon.RootType.DOWNLOADS, + currentVolumeInfo: { + volumeType: VolumeManagerCommon.VolumeType.DOWNLOADS, + }, + selection: [], + expect: { + canExecute: false, + hidden: true, + }, + }, + { + description: 'Tests selection from supported volume in `Downloads`', + currentRootType: VolumeManagerCommon.RootType.DOWNLOADS, + currentVolumeInfo: { + volumeType: VolumeManagerCommon.VolumeType.DOWNLOADS, + }, + selection: [downloadFileEntry], + expect: { + canExecute: true, + hidden: false, + entries: [downloadFileEntry], + }, + }, + { + description: + 'Tests folder selection from supported volume in `Downloads`', + currentRootType: VolumeManagerCommon.RootType.DOWNLOADS, + currentVolumeInfo: { + volumeType: VolumeManagerCommon.VolumeType.DOWNLOADS, + }, + selection: [folderEntry], + expect: { + canExecute: true, + hidden: false, + entries: [folderEntry], + }, + }, + { + description: 'Tests selection from supported volume in `Recent`', + currentRootType: VolumeManagerCommon.RootType.RECENT, + currentVolumeInfo: null, + selection: [downloadFileEntry], + expect: { + canExecute: true, + hidden: false, + entries: [downloadFileEntry], + }, + }, + { + description: 'Test selection from unsupported volume in `Recent`', + currentRootType: VolumeManagerCommon.RootType.RECENT, + currentVolumeInfo: null, + selection: [removableFileEntry], + expect: { + canExecute: false, + hidden: true, + }, + }, + { + description: 'Test selection from mix of volumes in `Recent`', + currentRootType: VolumeManagerCommon.RootType.RECENT, + currentVolumeInfo: null, + selection: [audioFileEntry, removableFileEntry, downloadFileEntry], + expect: { + canExecute: true, + hidden: false, + entries: [audioFileEntry, downloadFileEntry], + }, + }, + { + description: 'Tests selection from supported volume in `Recent Audio`', + currentRootType: VolumeManagerCommon.RootType.RECENT_AUDIO, + currentVolumeInfo: null, + selection: [audioFileEntry], + expect: { + canExecute: true, + hidden: false, + entries: [audioFileEntry], + }, + }, + { + description: 'Tests selection from supported volume in `Recent Images`', + currentRootType: VolumeManagerCommon.RootType.RECENT_AUDIO, + currentVolumeInfo: null, + selection: [imageFileEntry], + expect: { + canExecute: true, + hidden: false, + entries: [imageFileEntry], + }, + }, + { + description: 'Tests selection from supported volume in `Recent Videos`', + currentRootType: VolumeManagerCommon.RootType.RECENT_AUDIO, + currentVolumeInfo: null, + selection: [videoFileEntry], + expect: { + canExecute: true, + hidden: false, + entries: [videoFileEntry], + }, + }, + ]; + + // Run test cases. + for (const testCase of testCases) { + console.log('Starting test case... ' + testCase.description); + + // Mock `Event`. + const event = { + canExecute: true, + command: { + hidden: false, + setHidden: (hidden) => { + event.command.hidden = hidden; + }, + }, + }; + + // Mock `FileManager`. + const fileManager = { + directoryModel: { + getCurrentRootType: () => testCase.currentRootType, + getCurrentVolumeInfo: () => testCase.currentVolumeInfo, + }, + selectionHandler: { + selection: {entries: testCase.selection}, + }, + volumeManager: volumeManager, + }; + + // Verify `command.canExecute()` results in expected `event` state. + command.canExecute(event, fileManager); + assertEquals(event.canExecute, testCase.expect.canExecute); + assertEquals(event.command.hidden, testCase.expect.hidden); + + if (!event.canExecute || event.command.hidden) { + continue; + } + + // Mock private API. + let didInteractWithMockPrivateApi = false; + chrome.fileManagerPrivate.toggleAddedToHoldingSpace = (entries, isAdd) => { + didInteractWithMockPrivateApi = true; + assertArrayEquals(entries, testCase.expect.entries); + assertTrue(isAdd); + }; + + // Verify `command.execute()` results in expected mock API interactions. + command.execute(event, fileManager); + assertTrue(didInteractWithMockPrivateApi); + } +}
diff --git a/ui/file_manager/file_manager/foreground/js/file_type_filters_controller.js b/ui/file_manager/file_manager/foreground/js/file_type_filters_controller.js index f7d8e94..83ca4b1 100644 --- a/ui/file_manager/file_manager/foreground/js/file_type_filters_controller.js +++ b/ui/file_manager/file_manager/foreground/js/file_type_filters_controller.js
@@ -2,11 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// #import {FakeEntry} from '../../../externs/files_app_entry_interfaces.m.js'; +// #import {DirectoryModel} from './directory_model.m.js'; +// #import {str, util} from '../../common/js/util.m.js'; + /** * This class controls wires file-type filter UI and the filter settings in * Recents view. */ -class FileTypeFiltersController { +/* #export */ class FileTypeFiltersController { /** * @param {!HTMLElement} fileTypeFilterContainer * @param {!DirectoryModel} directoryModel
diff --git a/ui/file_manager/file_manager/foreground/js/file_type_filters_controller_unittest.js b/ui/file_manager/file_manager/foreground/js/file_type_filters_controller_unittest.m.js similarity index 79% rename from ui/file_manager/file_manager/foreground/js/file_type_filters_controller_unittest.js rename to ui/file_manager/file_manager/foreground/js/file_type_filters_controller_unittest.m.js index 41d5b53..4b7ad71 100644 --- a/ui/file_manager/file_manager/foreground/js/file_type_filters_controller_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/file_type_filters_controller_unittest.m.js
@@ -2,6 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; +import {assertEquals, assertFalse, assertTrue} from 'chrome://test/chai_assert.js'; + +import {installMockChrome} from '../../../base/js/mock_chrome.m.js'; +import {VolumeManagerCommon} from '../../../base/js/volume_manager_types.m.js'; +import {FakeEntry} from '../../../externs/files_app_entry_interfaces.m.js'; +import {EntryList, FakeEntryImpl} from '../../common/js/files_app_entry_types.m.js'; + +import {DirectoryModel} from './directory_model.m.js'; +import {FileTypeFiltersController} from './file_type_filters_controller.m.js'; + /** * @type {!HTMLElement} */ @@ -27,15 +39,36 @@ */ let fileTypeFiltersController; -function setUp() { +export function setUp() { // Mock loadTimeData strings. - window.loadTimeData.data = { + loadTimeData.data = { MEDIA_VIEW_AUDIO_ROOT_LABEL: 'Audio', MEDIA_VIEW_IMAGES_ROOT_LABEL: 'Images', MEDIA_VIEW_VIDEOS_ROOT_LABEL: 'Videos', }; - class MockDirectoryModel extends cr.EventTarget { + /** + * Mock chrome APIs. + * @type {!Object} + */ + const mockChrome = { + fileManagerPrivate: { + SourceRestriction: { + ANY_SOURCE: 'any_source', + NATIVE_SOURCE: 'native_source', + }, + RecentFileType: { + ALL: 'all', + AUDIO: 'audio', + IMAGE: 'image', + VIDEO: 'video', + }, + }, + }; + + installMockChrome(mockChrome); + + class MockDirectoryModel extends EventTarget { constructor() { super(); @@ -83,7 +116,7 @@ * Tests that creating FileTypeFiltersController generates three buttons in the * given container element. */ -function testCreatedButtonLabels() { +export function testCreatedButtonLabels() { const buttons = container.children; assertEquals(buttons.length, 3); @@ -95,7 +128,7 @@ /** * Tests that initial states of all buttons inside container are inactive. */ -function testButtonInitialActiveState() { +export function testButtonInitialActiveState() { const buttons = container.children; assertEquals(buttons.length, 3); @@ -107,7 +140,7 @@ /** * Tests that click events toggle button state (inactive -> active -> inactive). */ -function testButtonToggleState() { +export function testButtonToggleState() { const buttons = container.children; assertEquals(buttons.length, 3); @@ -123,7 +156,7 @@ * If button_1 is clicked then button_0 is active, button_0 becomes inactive and * button_1 becomes active. */ -function testOnlyOneButtonCanActive() { +export function testOnlyOneButtonCanActive() { const buttons = container.children; assertEquals(buttons.length, 3); @@ -148,7 +181,7 @@ * Tests that container element is visible only when the current directory is * Recents view. */ -function testContainerIsShownOnlyInRecents() { +export function testContainerIsShownOnlyInRecents() { container.hidden = true; directoryModel.changeDirectoryEntry(recentEntry); assertFalse(container.hidden); @@ -160,7 +193,7 @@ * Tests that button's active state is reset to inactive when the user leaves * Recents view. */ -function testActiveButtonIsResetOnLeavingRecents() { +export function testActiveButtonIsResetOnLeavingRecents() { const buttons = container.children; assertEquals(buttons.length, 3); @@ -182,7 +215,7 @@ * recentFileType property, and DirectoryModel.rescan() is called after the * Recent entry's property is modified. */ -function testAppliedFilters() { +export function testAppliedFilters() { const buttons = container.children; assertEquals(buttons.length, 3);
diff --git a/ui/file_manager/file_manager/foreground/js/launch_param.js b/ui/file_manager/file_manager/foreground/js/launch_param.js index 3cf673f..5b0bd5f 100644 --- a/ui/file_manager/file_manager/foreground/js/launch_param.js +++ b/ui/file_manager/file_manager/foreground/js/launch_param.js
@@ -2,15 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// #import {AllowedPaths} from '../../../base/js/volume_manager_types.m.js'; +// #import {DialogType} from './dialog_type.m.js'; + /** * @typedef {{ * overrideCwsContainerUrlForTest: (string|undefined), * overrideCwsContainerOriginForTest: (string|undefined) * }} */ -let SuggestAppDialogState; +/* #export */ let SuggestAppDialogState; -class LaunchParam { +/* #export */ class LaunchParam { /** * @param {!Object} unformatted Unformatted option. */
diff --git a/ui/file_manager/file_manager/foreground/js/metrics_start.js b/ui/file_manager/file_manager/foreground/js/metrics_start.js index 8695c097..6427034 100644 --- a/ui/file_manager/file_manager/foreground/js/metrics_start.js +++ b/ui/file_manager/file_manager/foreground/js/metrics_start.js
@@ -8,5 +8,7 @@ * define the metrics namespace). */ +// #import {metrics} from '../../../common/js/metrics.m.js'; + metrics.startInterval('Load.Total'); metrics.startInterval('Load.Script');
diff --git a/ui/file_manager/file_manager/foreground/js/mock_actions_model.js b/ui/file_manager/file_manager/foreground/js/mock_actions_model.js index cbb4b4a..546d322 100644 --- a/ui/file_manager/file_manager/foreground/js/mock_actions_model.js +++ b/ui/file_manager/file_manager/foreground/js/mock_actions_model.js
@@ -2,12 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -class MockActionModel { +// clang-format off +// #import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js'; +// #import {dispatchSimpleEvent} from 'chrome://resources/js/cr.m.js'; +// clang-format on + +/* #export */ class MockActionModel extends cr.EventTarget { /** * @param {string} title * @param {Array<!Entry>} entries */ constructor(title, entries) { + super(); + this.title = title; this.entries = entries; this.actionsModel = null; @@ -20,11 +27,11 @@ onCanExecute() {} onExecute() { - cr.dispatchSimpleEvent('invalidated', this.actionsModel); + cr.dispatchSimpleEvent(this, 'invalidated', true); } } -class MockActionsModel extends cr.EventTarget { +/* #export */ class MockActionsModel extends cr.EventTarget { constructor(actions) { super();
diff --git a/ui/file_manager/file_manager/foreground/js/navigation_uma.js b/ui/file_manager/file_manager/foreground/js/navigation_uma.js index 4e94fbc..d9601c62 100644 --- a/ui/file_manager/file_manager/foreground/js/navigation_uma.js +++ b/ui/file_manager/file_manager/foreground/js/navigation_uma.js
@@ -2,11 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// clang-format off +// #import {VolumeManagerCommon} from '../../../base/js/volume_manager_types.m.js'; +// #import {VolumeManager} from '../../../externs/volume_manager.m.js'; +// #import {metrics} from '../../../common/js/metrics.m.js'; +// clang-format on + /** * UMA exporter for navigation in the Files app. * */ -class NavigationUma { +/* #export */ class NavigationUma { /** * @param {!VolumeManager} volumeManager *
diff --git a/ui/file_manager/file_manager/foreground/js/providers_model.js b/ui/file_manager/file_manager/foreground/js/providers_model.js index 5066dc2..de1edc2 100644 --- a/ui/file_manager/file_manager/foreground/js/providers_model.js +++ b/ui/file_manager/file_manager/foreground/js/providers_model.js
@@ -2,6 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// clang-format off +// #import {VolumeManagerCommon} from '../../../base/js/volume_manager_types.m.js'; +// #import {assert} from 'chrome://resources/js/assert.m.js'; +// #import {VolumeManager} from '../../../externs/volume_manager.m.js'; +// clang-format on /** * An item in the model. Represents a single providing extension. @@ -96,7 +101,7 @@ * providing extensions as well as performing operations on them, such as * requesting a new mount point. */ -class ProvidersModel { +/* #export */ class ProvidersModel { /** * @param {!VolumeManager} volumeManager */
diff --git a/ui/file_manager/file_manager/foreground/js/providers_model_unittest.js b/ui/file_manager/file_manager/foreground/js/providers_model_unittest.m.js similarity index 62% rename from ui/file_manager/file_manager/foreground/js/providers_model_unittest.js rename to ui/file_manager/file_manager/foreground/js/providers_model_unittest.m.js index a00d7eb..609f7e1 100644 --- a/ui/file_manager/file_manager/foreground/js/providers_model_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/providers_model_unittest.m.js
@@ -2,6 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {assertEquals} from 'chrome://test/chai_assert.js'; + +import {installMockChrome, MockCommandLinePrivate} from '../../../base/js/mock_chrome.m.js'; +import {reportPromise} from '../../../base/js/test_error_reporting.m.js'; +import {VolumeManagerCommon} from '../../../base/js/volume_manager_types.m.js'; +import {VolumeManager} from '../../../externs/volume_manager.m.js'; +import {MockVolumeManager} from '../../background/js/mock_volume_manager.m.js'; +import {VolumeInfoImpl} from '../../background/js/volume_info_impl.m.js'; +import {MockDirectoryEntry, MockFileSystem} from '../../common/js/mock_entry.m.js'; + +import {ProvidersModel} from './providers_model.m.js'; + /** * Providing extension which has a mounted file system and doesn't support * multiple mounts. @@ -103,6 +115,9 @@ multipleMounts: true, }; +/** @type {!VolumeManager} */ +let volumeManager; + function addProvidedVolume(volumeManager, providerId, volumeId) { const fileSystem = new MockFileSystem(volumeId, 'filesystem:' + volumeId); fileSystem.entries['/'] = MockDirectoryEntry.create(fileSystem, ''); @@ -129,7 +144,7 @@ volumeManager.volumeInfoList.add(volumeInfo); } -function setUp() { +export function setUp() { window.loadTimeData.getString = id => id; // Create and install a mock fileManagerPrivate API for fetching the list of @@ -152,9 +167,8 @@ installMockChrome(mockChrome); new MockCommandLinePrivate(); - // Create and install a volume manager. - const volumeManager = new MockVolumeManager(); - MockVolumeManager.installMockSingleton(volumeManager); + // Install mock volume manager. + volumeManager = new MockVolumeManager(); // Add provided test volumes. const single = MOUNTED_SINGLE_PROVIDING_EXTENSION.providerId; @@ -163,79 +177,68 @@ addProvidedVolume(volumeManager, multiple, 'volume-2'); } -function testGetInstalledProviders(callback) { +export function testGetInstalledProviders(callback) { + const model = new ProvidersModel(volumeManager); reportPromise( - volumeManagerFactory.getInstance() - .then(volumeManager => { - const model = new ProvidersModel(volumeManager); - return model.getInstalledProviders(); - }) - .then(providers => { - assertEquals(5, providers.length); - assertEquals( - MOUNTED_SINGLE_PROVIDING_EXTENSION.providerId, - providers[0].providerId); - assertEquals( - MOUNTED_SINGLE_PROVIDING_EXTENSION.iconSet, - providers[0].iconSet); - assertEquals( - MOUNTED_SINGLE_PROVIDING_EXTENSION.name, providers[0].name); - assertEquals( - MOUNTED_SINGLE_PROVIDING_EXTENSION.configurable, - providers[0].configurable); - assertEquals( - MOUNTED_SINGLE_PROVIDING_EXTENSION.watchable, - providers[0].watchable); - assertEquals( - MOUNTED_SINGLE_PROVIDING_EXTENSION.multipleMounts, - providers[0].multipleMounts); - assertEquals( - MOUNTED_SINGLE_PROVIDING_EXTENSION.source, providers[0].source); + model.getInstalledProviders().then(providers => { + assertEquals(5, providers.length); + assertEquals( + MOUNTED_SINGLE_PROVIDING_EXTENSION.providerId, + providers[0].providerId); + assertEquals( + MOUNTED_SINGLE_PROVIDING_EXTENSION.iconSet, providers[0].iconSet); + assertEquals( + MOUNTED_SINGLE_PROVIDING_EXTENSION.name, providers[0].name); + assertEquals( + MOUNTED_SINGLE_PROVIDING_EXTENSION.configurable, + providers[0].configurable); + assertEquals( + MOUNTED_SINGLE_PROVIDING_EXTENSION.watchable, + providers[0].watchable); + assertEquals( + MOUNTED_SINGLE_PROVIDING_EXTENSION.multipleMounts, + providers[0].multipleMounts); + assertEquals( + MOUNTED_SINGLE_PROVIDING_EXTENSION.source, providers[0].source); - assertEquals( - NOT_MOUNTED_SINGLE_PROVIDING_EXTENSION.providerId, - providers[1].providerId); - assertEquals( - MOUNTED_MULTIPLE_PROVIDING_EXTENSION.providerId, - providers[2].providerId); - assertEquals( - NOT_MOUNTED_FILE_PROVIDING_EXTENSION.providerId, - providers[3].providerId); - assertEquals( - NOT_MOUNTED_DEVICE_PROVIDING_EXTENSION.providerId, - providers[4].providerId); + assertEquals( + NOT_MOUNTED_SINGLE_PROVIDING_EXTENSION.providerId, + providers[1].providerId); + assertEquals( + MOUNTED_MULTIPLE_PROVIDING_EXTENSION.providerId, + providers[2].providerId); + assertEquals( + NOT_MOUNTED_FILE_PROVIDING_EXTENSION.providerId, + providers[3].providerId); + assertEquals( + NOT_MOUNTED_DEVICE_PROVIDING_EXTENSION.providerId, + providers[4].providerId); - assertEquals( - NOT_MOUNTED_SINGLE_PROVIDING_EXTENSION.iconSet, - providers[1].iconSet); - assertEquals( - MOUNTED_MULTIPLE_PROVIDING_EXTENSION.iconSet, - providers[2].iconSet); - assertEquals( - NOT_MOUNTED_FILE_PROVIDING_EXTENSION.iconSet, - providers[3].iconSet); - assertEquals( - NOT_MOUNTED_DEVICE_PROVIDING_EXTENSION.iconSet, - providers[4].iconSet); - }), + assertEquals( + NOT_MOUNTED_SINGLE_PROVIDING_EXTENSION.iconSet, + providers[1].iconSet); + assertEquals( + MOUNTED_MULTIPLE_PROVIDING_EXTENSION.iconSet, providers[2].iconSet); + assertEquals( + NOT_MOUNTED_FILE_PROVIDING_EXTENSION.iconSet, providers[3].iconSet); + assertEquals( + NOT_MOUNTED_DEVICE_PROVIDING_EXTENSION.iconSet, + providers[4].iconSet); + }), callback); } -function testGetMountableProviders(callback) { +export function testGetMountableProviders(callback) { + const model = new ProvidersModel(volumeManager); reportPromise( - volumeManagerFactory.getInstance() - .then(volumeManager => { - const model = new ProvidersModel(volumeManager); - return model.getMountableProviders(); - }) - .then(providers => { - assertEquals(2, providers.length); - assertEquals( - NOT_MOUNTED_SINGLE_PROVIDING_EXTENSION.providerId, - providers[0].providerId); - assertEquals( - MOUNTED_MULTIPLE_PROVIDING_EXTENSION.providerId, - providers[1].providerId); - }), + model.getMountableProviders().then(providers => { + assertEquals(2, providers.length); + assertEquals( + NOT_MOUNTED_SINGLE_PROVIDING_EXTENSION.providerId, + providers[0].providerId); + assertEquals( + MOUNTED_MULTIPLE_PROVIDING_EXTENSION.providerId, + providers[1].providerId); + }), callback); }
diff --git a/ui/file_manager/file_manager/foreground/js/spinner_controller.js b/ui/file_manager/file_manager/foreground/js/spinner_controller.js index 4d92c44..cd9361c 100644 --- a/ui/file_manager/file_manager/foreground/js/spinner_controller.js +++ b/ui/file_manager/file_manager/foreground/js/spinner_controller.js
@@ -7,7 +7,7 @@ * is called 3 times, the hide callback has to be called 3 times to make the * spinner invisible. */ -class SpinnerController { +/* #export */ class SpinnerController { /** @param {!Element} element */ constructor(element) { /**
diff --git a/ui/file_manager/file_manager/foreground/js/spinner_controller_unittest.js b/ui/file_manager/file_manager/foreground/js/spinner_controller_unittest.m.js similarity index 88% rename from ui/file_manager/file_manager/foreground/js/spinner_controller_unittest.js rename to ui/file_manager/file_manager/foreground/js/spinner_controller_unittest.m.js index e5b12861..68afffe 100644 --- a/ui/file_manager/file_manager/foreground/js/spinner_controller_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/spinner_controller_unittest.m.js
@@ -2,6 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {assert} from 'chrome://resources/js/assert.m.js'; +import {assertFalse, assertTrue} from 'chrome://test/chai_assert.js'; + +import {reportPromise} from '../../../base/js/test_error_reporting.m.js'; + +import {SpinnerController} from './spinner_controller.m.js'; + /** * @type {Element} */ @@ -22,7 +29,7 @@ }); } -function setUp() { +export function setUp() { spinner = document.createElement('div'); spinner.id = 'spinner'; spinner.textContent = 'LOADING...'; @@ -33,7 +40,7 @@ controller.setBlinkDurationForTesting(100); } -function testBlink(callback) { +export function testBlink(callback) { assertTrue(spinner.hidden); controller.blink(); @@ -49,7 +56,7 @@ callback); } -function testShow(callback) { +export function testShow(callback) { assertTrue(spinner.hidden); const hideCallback = controller.show(); @@ -73,7 +80,7 @@ callback); } -function testShowDuringBlink(callback) { +export function testShowDuringBlink(callback) { assertTrue(spinner.hidden); controller.blink(); const hideCallback = controller.show(); @@ -103,7 +110,7 @@ callback); } -function testStackedShows(callback) { +export function testStackedShows(callback) { assertTrue(spinner.hidden); const hideCallbacks = [];
diff --git a/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn b/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn index 5f0c8fb..f69daea 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn +++ b/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn
@@ -25,9 +25,16 @@ uses_js_modules = true deps = [ ":directory_tree.m", + ":drag_selector.m", ":empty_folder.m", ":file_list_selection_model.m", + ":file_manager_dialog_base.m", ":files_alert_dialog.m", + ":files_confirm_dialog.m", + ":files_menu.m", + ":multi_menu.m", + ":multi_menu_button.m", + ":suggest_apps_dialog.m", "table:table.m", "table:table_column.m", "table:table_column_model.m", @@ -264,6 +271,14 @@ externs_list = [ "//ui/file_manager/externs/drag_target.js" ] } +js_library("drag_selector.m") { + sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/ui/drag_selector.m.js" ] + deps = [ "//ui/webui/resources/js/cr/ui:list.m" ] + externs_list = [ "//ui/file_manager/externs/drag_target.js" ] + + extra_deps = [ ":modulize" ] +} + js_library("empty_folder") { deps = [ "//ui/webui/resources/js:util" ] } @@ -324,11 +339,22 @@ externs_list = [ "$externs_path/chrome_extensions.js" ] } -js_unittest("file_manager_dialog_base_unittest") { +js_library("file_manager_dialog_base.m") { + sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/ui/file_manager_dialog_base.m.js" ] deps = [ - ":file_manager_dialog_base", - "//ui/file_manager/base/js:test_error_reporting", - "//ui/webui/resources/js:webui_resource_test", + "//ui/file_manager/file_manager/common/js:util.m", + "//ui/webui/resources/js/cr/ui:dialogs.m", + ] + + extra_deps = [ ":modulize" ] +} + +js_unittest("file_manager_dialog_base_unittest.m") { + deps = [ + ":file_manager_dialog_base.m", + "//chrome/test/data/webui:chai_assert", + "//ui/file_manager/base/js:test_error_reporting.m", + "//ui/webui/resources/js:assert.m", ] } @@ -465,6 +491,16 @@ deps = [ "//ui/webui/resources/js/cr/ui:dialogs" ] } +js_library("files_confirm_dialog.m") { + sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/ui/files_confirm_dialog.m.js" ] + deps = [ + "//ui/file_manager/file_manager/common/js:util.m", + "//ui/webui/resources/js/cr/ui:dialogs.m", + ] + + extra_deps = [ ":modulize" ] +} + js_library("files_menu") { deps = [ "//ui/webui/resources/js:assert", @@ -474,6 +510,18 @@ externs_list = [ "//ui/file_manager/externs/paper_elements.js" ] } +js_library("files_menu.m") { + sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/ui/files_menu.m.js" ] + deps = [ + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js/cr/ui:menu.m", + "//ui/webui/resources/js/cr/ui:menu_item.m", + ] + externs_list = [ "//ui/file_manager/externs/paper_elements.js" ] + + extra_deps = [ ":modulize" ] +} + js_library("gear_menu") { deps = [ "//ui/file_manager/file_manager/common/js:util" ] } @@ -534,6 +582,20 @@ externs_list = [ "$externs_path/pending.js" ] } +js_library("multi_menu.m") { + sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/ui/multi_menu.m.js" ] + + deps = [ + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:event_tracker.m", + "//ui/webui/resources/js/cr:ui.m", + "//ui/webui/resources/js/cr/ui:menu.m", + "//ui/webui/resources/js/cr/ui:menu_item.m", + ] + + extra_deps = [ ":modulize" ] +} + js_library("multi_menu_button") { deps = [ # TODO(files-ng): remove util dep when the files-ng flag is removed. @@ -547,13 +609,32 @@ externs_list = [ "$externs_path/pending.js" ] } -js_unittest("multi_menu_unittest") { +js_library("multi_menu_button.m") { + sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/ui/multi_menu_button.m.js" ] deps = [ - ":multi_menu", - ":multi_menu_button", - "//ui/file_manager/base/js:test_error_reporting", - "//ui/file_manager/file_manager/common/js:util", - "//ui/webui/resources/js:webui_resource_test", + ":multi_menu.m", + "//ui/file_manager/file_manager/common/js:util.m", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:event_tracker.m", + "//ui/webui/resources/js/cr:ui.m", + "//ui/webui/resources/js/cr/ui:menu.m", + "//ui/webui/resources/js/cr/ui:menu_button.m", + "//ui/webui/resources/js/cr/ui:menu_item.m", + "//ui/webui/resources/js/cr/ui:position_util.m", + ] + + extra_deps = [ ":modulize" ] +} + +js_unittest("multi_menu_unittest.m") { + deps = [ + ":multi_menu_button.m", + "//chrome/test/data/webui:chai_assert", + "//ui/file_manager/file_manager/common/js:util.m", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js/cr:ui.m", + "//ui/webui/resources/js/cr/ui:command.m", + "//ui/webui/resources/js/cr/ui:menu.m", ] } @@ -615,10 +696,31 @@ [ "//ui/file_manager/externs/chrome_webstore_widget_private.js" ] } +js_library("suggest_apps_dialog.m") { + sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/ui/suggest_apps_dialog.m.js" ] + deps = [ + ":file_manager_dialog_base.m", + "//ui/file_manager/file_manager/common/js:metrics.m", + "//ui/file_manager/file_manager/common/js:util.m", + "//ui/file_manager/file_manager/cws_widget:cws_widget_container.m", + "//ui/file_manager/file_manager/cws_widget:cws_widget_container_platform_delegate.m", + "//ui/file_manager/file_manager/foreground/js:launch_param.m", + "//ui/file_manager/file_manager/foreground/js:providers_model.m", + "//ui/file_manager/file_manager/foreground/js:web_store_utils.m", + "//ui/webui/resources/js:assert.m", + ] + externs_list = + [ "//ui/file_manager/externs/chrome_webstore_widget_private.js" ] + + extra_deps = [ ":modulize" ] +} + js_test_gen_html("js_test_gen_html_modules") { deps = [ ":directory_tree_unittest.m", ":file_list_selection_model_unittest.m", + ":file_manager_dialog_base_unittest.m", + ":multi_menu_unittest.m", ] js_module = true @@ -636,22 +738,31 @@ deps = [ ":actions_submenu_unittest", ":breadcrumb_unittest", - ":file_manager_dialog_base_unittest", ":file_table_list_unittest", ":file_table_unittest", ":file_tap_handler_unittest", ":install_linux_package_dialog_unittest", - ":multi_menu_unittest", ] } js_modulizer("modulize") { input_files = [ "directory_tree.js", + "drag_selector.js", "empty_folder.js", "file_list_selection_model.js", + "file_manager_dialog_base.js", "files_alert_dialog.js", + "files_confirm_dialog.js", + "files_menu.js", + "multi_menu.js", + "multi_menu_button.js", + "suggest_apps_dialog.js", ] namespace_rewrites = cr_namespace_rewrites + namespace_rewrites += [ + "cr.ui.MultiMenu|MultiMenu", + "cr.ui.FilesMenuItem|FilesMenuItem", + ] }
diff --git a/ui/file_manager/file_manager/foreground/js/ui/drag_selector.js b/ui/file_manager/file_manager/foreground/js/ui/drag_selector.js index 0de8d341..b661d0b3 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/drag_selector.js +++ b/ui/file_manager/file_manager/foreground/js/ui/drag_selector.js
@@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -class DragSelector { +// #import {List} from 'chrome://resources/js/cr/ui/list.m.js'; + +/* #export */ class DragSelector { /** * Drag selector used on the file list or the grid table. */
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_manager_dialog_base.js b/ui/file_manager/file_manager/foreground/js/ui/file_manager_dialog_base.js index a9e33e5..63818e9 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_manager_dialog_base.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_manager_dialog_base.js
@@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// #import {util} from '../../../common/js/util.m.js'; +// #import {BaseDialog} from 'chrome://resources/js/cr/ui/dialogs.m.js'; + /** * This class is an extended class, to manage the status of the dialogs. */ -class FileManagerDialogBase extends cr.ui.dialogs.BaseDialog { +/* #export */ class FileManagerDialogBase extends cr.ui.dialogs.BaseDialog { /** * @param {HTMLElement} parentNode Parent node of the dialog. */
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_manager_dialog_base_unittest.js b/ui/file_manager/file_manager/foreground/js/ui/file_manager_dialog_base_unittest.m.js similarity index 75% rename from ui/file_manager/file_manager/foreground/js/ui/file_manager_dialog_base_unittest.js rename to ui/file_manager/file_manager/foreground/js/ui/file_manager_dialog_base_unittest.m.js index 55ba581..30dcfc5 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_manager_dialog_base_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_manager_dialog_base_unittest.m.js
@@ -2,7 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -function setUp() { +import {assertInstanceof} from 'chrome://resources/js/assert.m.js'; +import {assertFalse} from 'chrome://test/chai_assert.js'; +import {waitUntil} from '../../../../base/js/test_error_reporting.m.js'; +import {FileManagerDialogBase} from './file_manager_dialog_base.m.js'; + +export function setUp() { // Polyfill chrome.app.window.current(). /** @suppress {duplicate,checkTypes,const} */ chrome.app = {window: {current: () => null}}; @@ -12,7 +17,7 @@ }; } -async function testShowDialogAfterHide(done) { +export async function testShowDialogAfterHide(done) { const container = assertInstanceof(document.createElement('div'), HTMLElement);
diff --git a/ui/file_manager/file_manager/foreground/js/ui/files_confirm_dialog.js b/ui/file_manager/file_manager/foreground/js/ui/files_confirm_dialog.js index 7d0a56c..1b07e2a 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/files_confirm_dialog.js +++ b/ui/file_manager/file_manager/foreground/js/ui/files_confirm_dialog.js
@@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// #import {util} from '../../../common/js/util.m.js'; +// #import {ConfirmDialog} from 'chrome://resources/js/cr/ui/dialogs.m.js'; + /** * Confirm dialog. */ -class FilesConfirmDialog extends cr.ui.dialogs.ConfirmDialog { +/* #export */ class FilesConfirmDialog extends cr.ui.dialogs.ConfirmDialog { /** * @param {!Element} parentElement */
diff --git a/ui/file_manager/file_manager/foreground/js/ui/files_menu.js b/ui/file_manager/file_manager/foreground/js/ui/files_menu.js index f8e69d9..dbeb14cc 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/files_menu.js +++ b/ui/file_manager/file_manager/foreground/js/ui/files_menu.js
@@ -2,11 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// #import {Menu} from 'chrome://resources/js/cr/ui/menu.m.js'; +// #import {assertInstanceof} from 'chrome://resources/js/assert.m.js'; +// #import {MenuItem} from 'chrome://resources/js/cr/ui/menu_item.m.js'; + cr.define('cr.ui', () => { /** * Menu item with ripple animation. */ - class FilesMenuItem extends cr.ui.MenuItem { + /* #export */ class FilesMenuItem extends cr.ui.MenuItem { constructor() { super(); @@ -204,6 +208,7 @@ } } + // #cr_define_end return { FilesMenuItem: FilesMenuItem, };
diff --git a/ui/file_manager/file_manager/foreground/js/ui/multi_menu.js b/ui/file_manager/file_manager/foreground/js/ui/multi_menu.js index 2352b28..52c1023 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/multi_menu.js +++ b/ui/file_manager/file_manager/foreground/js/ui/multi_menu.js
@@ -2,6 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// #import {MenuItem} from 'chrome://resources/js/cr/ui/menu_item.m.js'; +// #import {EventTracker} from 'chrome://resources/js/event_tracker.m.js'; +// #import {assertInstanceof} from 'chrome://resources/js/assert.m.js'; +// #import {Menu} from 'chrome://resources/js/cr/ui/menu.m.js'; +// #import {decorate} from 'chrome://resources/js/cr/ui.m.js'; + cr.define('cr.ui', () => { /** * Creates a menu that supports sub-menus. @@ -14,7 +20,7 @@ * @extends {cr.ui.Menu} * @implements {EventListener} */ - class MultiMenu { + /* #export */ class MultiMenu { constructor() { /** * Whether a sub-menu is positioned on the left of its parent. @@ -207,9 +213,7 @@ positionSubMenu_(item, subMenu) { const style = subMenu.style; - if (util.isFilesNg()) { - style.marginTop = '0'; // crbug.com/1066727 - } + style.marginTop = '0'; // crbug.com/1066727 // The sub-menu needs to sit aligned to the top and side of // the menu-item passed in. It also needs to fit inside the viewport @@ -299,7 +303,7 @@ * @private */ findMenuItem(node) { - const MenuItem = cr.ui.MenuItem; + /* #ignore */ const MenuItem = cr.ui.MenuItem; while (node && node.parentNode !== this && !(node instanceof MenuItem)) { node = node.parentNode; } @@ -453,5 +457,6 @@ } // Export + // #cr_define_end return {MultiMenu}; });
diff --git a/ui/file_manager/file_manager/foreground/js/ui/multi_menu_button.js b/ui/file_manager/file_manager/foreground/js/ui/multi_menu_button.js index 567c3eb7..a4a4f95b 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/multi_menu_button.js +++ b/ui/file_manager/file_manager/foreground/js/ui/multi_menu_button.js
@@ -2,16 +2,27 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// clang-format off +// #import {assert} from 'chrome://resources/js/assert.m.js'; +// #import {Menu} from 'chrome://resources/js/cr/ui/menu.m.js'; +// #import {AnchorType, positionPopupAroundElement} from 'chrome://resources/js/cr/ui/position_util.m.js'; +// #import {util} from '../../../common/js/util.m.js'; +// #import {HideType} from 'chrome://resources/js/cr/ui/menu_button.m.js'; +// #import {MenuItem} from 'chrome://resources/js/cr/ui/menu_item.m.js'; +// #import {MultiMenu} from './multi_menu.m.js'; +// #import {decorate} from 'chrome://resources/js/cr/ui.m.js'; +// #import {EventTracker} from 'chrome://resources/js/event_tracker.m.js'; +// clang-format on + cr.define('cr.ui', () => { - /** @const */ - const HideType = cr.ui.HideType; + /* #ignore */ /** @const */ const HideType = cr.ui.HideType; /** * A button that displays a MultiMenu (menu with sub-menus). * @extends {HTMLButtonElement} * @implements {EventListener} */ - class MultiMenuButton { + /* #export */ class MultiMenuButton { constructor() { /** * Property that hosts sub-menus for filling with overflow items. @@ -445,5 +456,6 @@ MultiMenuButton.prototype.__proto__ = HTMLButtonElement.prototype; // Export + // #cr_define_end return {MultiMenuButton}; });
diff --git a/ui/file_manager/file_manager/foreground/js/ui/multi_menu_unittest.js b/ui/file_manager/file_manager/foreground/js/ui/multi_menu_unittest.m.js similarity index 87% rename from ui/file_manager/file_manager/foreground/js/ui/multi_menu_unittest.js rename to ui/file_manager/file_manager/foreground/js/ui/multi_menu_unittest.m.js index d2948ac..29bec58 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/multi_menu_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/ui/multi_menu_unittest.m.js
@@ -2,25 +2,45 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -'use strict'; +import {assert} from 'chrome://resources/js/assert.m.js'; +import {decorate} from 'chrome://resources/js/cr/ui.m.js'; +import {Command} from 'chrome://resources/js/cr/ui/command.m.js'; +import {Menu} from 'chrome://resources/js/cr/ui/menu.m.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; +import {assertEquals, assertFalse, assertTrue} from 'chrome://test/chai_assert.js'; -/** @type {cr.ui.MultiMenuButton} */ +import {util} from '../../../common/js/util.m.js'; + +import {MultiMenuButton} from './multi_menu_button.m.js'; + +/** @type {MultiMenuButton} */ let menubutton; -/** @type {cr.ui.Menu} */ +/** @type {Menu} */ let topMenu; -/** @type {cr.ui.Menu} */ +/** @type {Menu} */ let subMenu; -/** @type {cr.ui.Menu} */ +/** @type {Menu} */ let secondSubMenu; +/** @type {number} */ +let initialWindowHeight; + // Set up test components. -function setUp() { +export function setUp() { // Internals of WebUI reference this property when processing // keyboard events, so we need to prepare it to stop asserts. loadTimeData.data = {'SHORTCUT_ENTER': 'Enter'}; + + // Multiple tests rely on the window height, reset between tests to avoid + // interference. + if (!initialWindowHeight) { + initialWindowHeight = window.innerHeight; + } + window.innerHeight = initialWindowHeight; + // Install cr.ui <command> elements and <cr-menu>s on the page. document.body.innerHTML = [ '<style>', @@ -63,12 +83,11 @@ ].join(''); // Initialize cr.ui.Command with the <command>s. - cr.ui.decorate('command', cr.ui.Command); - menubutton = - util.queryDecoratedElement('#test-menu-button', cr.ui.MultiMenuButton); - topMenu = util.queryDecoratedElement('#menu', cr.ui.Menu); - subMenu = util.queryDecoratedElement('#sub-menu', cr.ui.Menu); - secondSubMenu = util.queryDecoratedElement('#second-sub-menu', cr.ui.Menu); + decorate('command', Command); + menubutton = util.queryDecoratedElement('#test-menu-button', MultiMenuButton); + topMenu = util.queryDecoratedElement('#menu', Menu); + subMenu = util.queryDecoratedElement('#sub-menu', Menu); + secondSubMenu = util.queryDecoratedElement('#second-sub-menu', Menu); } /** @@ -137,7 +156,7 @@ * Tests that making the top level menu visible doesn't * cause the sub-menu to become visible. */ -function testShowMenuDoesntShowSubMenu() { +export function testShowMenuDoesntShowSubMenu() { menubutton.showMenu(true); // Check the top level menu is not hidden. assertFalse(topMenu.hasAttribute('hidden')); @@ -149,7 +168,7 @@ * Tests that a 'mouseover' event on top of normal menu-items * doesn't cause the sub-menu to become visible. */ -function testMouseOverNormalItemsDoesntShowSubMenu() { +export function testMouseOverNormalItemsDoesntShowSubMenu() { menubutton.showMenu(true); sendMouseOver('#default-task'); assertTrue(subMenu.hasAttribute('hidden')); @@ -161,7 +180,7 @@ * Tests that 'mouseover' on a menu-item with 'show-submenu' command * causes the sub-menu to become visible. */ -function testMouseOverHostMenuShowsSubMenu() { +export function testMouseOverHostMenuShowsSubMenu() { menubutton.showMenu(true); sendMouseOver('#host-sub-menu'); assertFalse(subMenu.hasAttribute('hidden')); @@ -171,7 +190,7 @@ * Tests that 'mouseout' with the mouse over the top level * menu causes the sub-menu to hide. */ -function testMouseoutFromHostMenuItemToHostMenu() { +export function testMouseoutFromHostMenuItemToHostMenu() { menubutton.showMenu(true); sendMouseOver('#host-sub-menu'); assertFalse(subMenu.hasAttribute('hidden')); @@ -186,7 +205,7 @@ * Tests that 'mouseout' with the mouse over the sub-menu * doesn't hide the sub-menu. */ -function testMouseoutFromHostMenuToSubMenu() { +export function testMouseoutFromHostMenuToSubMenu() { menubutton.showMenu(true); sendMouseOver('#host-sub-menu'); assertFalse(subMenu.hasAttribute('hidden')); @@ -200,7 +219,7 @@ * Tests that selecting a menu-item with a 'show-submenu' command * doesn't cause the sub-menu to become visible. */ -function testSelectHostMenuItem() { +export function testSelectHostMenuItem() { menubutton.showMenu(true); topMenu.selectedIndex = 2; const hostItem = document.querySelector('#host-sub-menu'); @@ -216,7 +235,7 @@ * (Note: in an application, this would happen from a command * being executed rather than a direct showSubMenu() call.) */ -function testSelectHostMenuItemAndCallShowSubMenu() { +export function testSelectHostMenuItemAndCallShowSubMenu() { testSelectHostMenuItem(); menubutton.menu.showSubMenu(); assertFalse(subMenu.hasAttribute('hidden')); @@ -226,7 +245,7 @@ * Tests that a mouse click outside of a menu and sub-menu causes * both menus to hide. */ -function testClickOutsideVisibleMenuAndSubMenu() { +export function testClickOutsideVisibleMenuAndSubMenu() { testSelectHostMenuItemAndCallShowSubMenu(); const event = new MouseEvent('mousedown', { bubbles: true, @@ -245,7 +264,7 @@ * Tests that shrinking the window height will limit * the height of the sub-menu. */ -function testShrinkWindowSizesSubMenu() { +export function testShrinkWindowSizesSubMenu() { testSelectHostMenuItemAndCallShowSubMenu(); const subMenuPosition = subMenu.getBoundingClientRect(); // Reduce window innerHeight so sub-menu won't fit. @@ -264,7 +283,7 @@ * Tests that growing the window height will increase * the height of the sub-menu. */ -function testGrowWindowSizesSubMenu() { +export function testGrowWindowSizesSubMenu() { // Remember the full size of the sub-menu testSelectHostMenuItemAndCallShowSubMenu(); const subMenuPosition = subMenu.getBoundingClientRect(); @@ -303,7 +322,7 @@ /** * Tests that arrow navigates from main menu to sub-menu. */ -function testNavigateFromMenuToSubMenu() { +export function testNavigateFromMenuToSubMenu() { prepareForKeyboardNavigation(); // Check that the hosting menu-item is not selected. const hostItem = document.querySelector('#host-sub-menu'); @@ -317,7 +336,7 @@ * Tests that arrow left moves back to the top level menu * only when the selected sub-menu item is the first one. */ -function testNavigateFromSubMenuToParentMenu() { +export function testNavigateFromSubMenuToParentMenu() { testNavigateFromMenuToSubMenu(); // Use the arrow key to go to the next sub-menu item. sendKeyDown('#test-menu-button', 'ArrowDown'); @@ -346,7 +365,7 @@ * Tests that arrow up on the top level menu hides the * sub menu when the sub-menu is visible. */ -function testTopMenuArrowUpDismissesSubMenu() { +export function testTopMenuArrowUpDismissesSubMenu() { prepareForKeyboardNavigation(); // Check that the hosting menu-item is not selected. const hostItem = document.querySelector('#host-sub-menu'); @@ -365,7 +384,7 @@ * Tests that the top level menu is resized when the parent * window is too small to fit in without clipping. */ -function testShrinkWindowSizesTopMenu() { +export function testShrinkWindowSizesTopMenu() { menubutton.showMenu(true); const menuPosition = topMenu.getBoundingClientRect(); // Reduce window innerHeight so the menu won't fit. @@ -380,7 +399,7 @@ /** * Tests that mousedown the menu button grabs focus. */ -function testFocusMenuButtonWithMouse() { +export function testFocusMenuButtonWithMouse() { // Set focus on a div element. //* @type {HTMLElement} */ const divElement = document.querySelector('#focus-div'); @@ -424,7 +443,7 @@ /** * Tests that opening a sub menu hides any showing sub menu. */ -function testShowSubMenuHidesExisting() { +export function testShowSubMenuHidesExisting() { testMouseOverHostMenuShowsSubMenu(); sendMouseOver('#host-second-sub-menu'); // Check the previously shown sub menu is hidden.
diff --git a/ui/file_manager/file_manager/foreground/js/ui/suggest_apps_dialog.js b/ui/file_manager/file_manager/foreground/js/ui/suggest_apps_dialog.js index e5fe23a..b03e88c 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/suggest_apps_dialog.js +++ b/ui/file_manager/file_manager/foreground/js/ui/suggest_apps_dialog.js
@@ -3,16 +3,28 @@ // found in the LICENSE file. /** - * SuggestAppsDialog contains a list box to select an app to be opened the file - * with. This dialog should be used as action picker for file operations. + * @fileoverview SuggestAppsDialog contains a list box to select an app to be + * opened the file with. This dialog should be used as action picker for file + * operations. */ +// clang-format off +// #import {SuggestAppDialogState} from '../launch_param.m.js'; +// #import {ProvidersModel} from '../providers_model.m.js'; +// #import {CWSWidgetContainerPlatformDelegate} from '../../../cws_widget/cws_widget_container_platform_delegate.m.js'; +// #import {FileManagerDialogBase} from './file_manager_dialog_base.m.js'; +// #import {CWSWidgetContainer} from '../../../cws_widget/cws_widget_container.m.js'; +// #import {webStoreUtils} from '../web_store_utils.m.js'; +// #import {str, util} from '../../../common/js/util.m.js'; +// #import {metrics} from '../../common/js/metrics.m.js'; +// #import {assert} from 'chrome://resources/js/assert.m.js'; +// clang-format on /** * Creates dialog in DOM tree. * */ -class SuggestAppsDialog extends FileManagerDialogBase { +/* #export */ class SuggestAppsDialog extends FileManagerDialogBase { /** * @param {!ProvidersModel} providersModel Model for providers. * @param {!HTMLElement} parentNode Node to be parent for this dialog.
diff --git a/ui/file_manager/file_manager/foreground/js/web_store_utils.js b/ui/file_manager/file_manager/foreground/js/web_store_utils.js index 75c2f5ff8..8f5682c 100644 --- a/ui/file_manager/file_manager/foreground/js/web_store_utils.js +++ b/ui/file_manager/file_manager/foreground/js/web_store_utils.js
@@ -3,6 +3,13 @@ // found in the LICENSE file. /** + * @fileoverview + * @suppress {uselessCode} Temporary suppress because of the line exporting. + */ + +// #import {constants} from './constants.m.js'; + +/** * Namespace for web store utility functions. * @namespace */ @@ -53,3 +60,6 @@ } return url; }; + +// eslint-disable-next-line semi,no-extra-semi +/* #export */ {webStoreUtils};
diff --git a/ui/message_center/views/message_popup_view.cc b/ui/message_center/views/message_popup_view.cc index 7b40bb5f..c3ed17bb 100644 --- a/ui/message_center/views/message_popup_view.cc +++ b/ui/message_center/views/message_popup_view.cc
@@ -15,6 +15,7 @@ #include "ui/message_center/views/message_view.h" #include "ui/message_center/views/message_view_factory.h" #include "ui/views/layout/fill_layout.h" +#include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/widget/widget.h" #if defined(OS_WIN) @@ -182,10 +183,6 @@ node_data->role = ax::mojom::Role::kAlertDialog; } -const char* MessagePopupView::GetClassName() const { - return "MessagePopupView"; -} - void MessagePopupView::OnDisplayChanged() { OnWorkAreaChanged(); } @@ -224,4 +221,7 @@ return GetWidget() && !GetWidget()->IsClosed(); } +BEGIN_METADATA(MessagePopupView, views::WidgetDelegateView) +END_METADATA + } // namespace message_center
diff --git a/ui/message_center/views/message_popup_view.h b/ui/message_center/views/message_popup_view.h index 9b5476c5d..edd309b 100644 --- a/ui/message_center/views/message_popup_view.h +++ b/ui/message_center/views/message_popup_view.h
@@ -21,8 +21,12 @@ class MESSAGE_CENTER_EXPORT MessagePopupView : public views::WidgetDelegateView, public views::WidgetObserver { public: + METADATA_HEADER(MessagePopupView); + MessagePopupView(const Notification& notification, MessagePopupCollection* popup_collection); + MessagePopupView(const MessagePopupView&) = delete; + MessagePopupView& operator=(const MessagePopupView&) = delete; ~MessagePopupView() override; // Update notification contents to |notification|. Virtual for unit testing. @@ -54,7 +58,6 @@ void OnMouseExited(const ui::MouseEvent& event) override; void ChildPreferredSizeChanged(views::View* child) override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override; - const char* GetClassName() const override; void OnDisplayChanged() override; void OnWorkAreaChanged() override; void OnFocus() override; @@ -70,7 +73,7 @@ protected: // For unit testing. - MessagePopupView(MessagePopupCollection* popup_collection); + explicit MessagePopupView(MessagePopupCollection* popup_collection); private: // True if the view has a widget and the widget is not closed. @@ -87,8 +90,6 @@ bool is_active_ = false; ScopedObserver<views::Widget, views::WidgetObserver> observer_{this}; - - DISALLOW_COPY_AND_ASSIGN(MessagePopupView); }; } // namespace message_center
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_details_dialog.html b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_details_dialog.html index 10d45a0..6aae7084 100644 --- a/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_details_dialog.html +++ b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_details_dialog.html
@@ -29,25 +29,41 @@ </div> <div slot="body"> <div class="two-line"> - <div class="label">[[i18n('certificateProvisioningProfileName')]]</div> - <div class="value">[[model.certProfileName]]</div> + <div class="label" aria-describedby="certProfileName"> + [[i18n('certificateProvisioningProfileName')]] + </div> + <div class="value" id="certProfileName" aria-hidden="true"> + [[model.certProfileName]] + </div> </div> <div class="two-line"> - <div class="label">[[i18n('certificateProvisioningProfileId')]]</div> - <div class="value">[[model.certProfileId]]</div> + <div class="label" aria-describedby="certProfileId"> + [[i18n('certificateProvisioningProfileId')]] + </div> + <div class="value" id="certProfileId" aria-hidden="true"> + [[model.certProfileId]] + </div> </div> <div class="button-box"> <div class="two-line flex"> - <div class="label">[[i18n('certificateProvisioningStatus')]]</div> - <span class="value">[[model.status]]</span> + <div class="label" aria-describedby="status"> + [[i18n('certificateProvisioningStatus')]] + </div> + <span class="value" id="status" aria-hidden="true"> + [[model.status]] + </span> </div> <cr-button id="refresh" role="button" on-click="onRefresh_"> [[i18n('certificateProvisioningRefresh')]] </cr-button> </div> <div class="two-line"> - <div class="label">[[i18n('certificateProvisioningLastUpdate')]]</div> - <div class="value">[[model.timeSinceLastUpdate]]</div> + <div class="label" aria-describedby="timeSinceLastUpdate"> + [[i18n('certificateProvisioningLastUpdate')]] + </div> + <div class="value" id="timeSinceLastUpdate" aria-hidden="true"> + [[model.timeSinceLastUpdate]] + </div> </div> <hr></hr> <cr-expand-button expanded="{{advancedExpanded_}}" @@ -56,12 +72,20 @@ </cr-expand-button> <iron-collapse id="advancedInfo" opened="[[advancedExpanded_]]"> <div class="two-line"> - <div class="label">[[i18n('certificateProvisioningStatusId')]]</div> - <div class="value">[[model.stateId]]</div> + <div class="label" aria-describedby="stateId"> + [[i18n('certificateProvisioningStatusId')]] + </div> + <div class="value" id="stateId" aria-hidden="true"> + [[model.stateId]] + </div> </div> <div class="two-line"> - <div class="label">[[i18n('certificateProvisioningPublicKey')]]</div> - <div class="value">[[model.publicKey]]</div> + <div class="label" aria-describedby="publicKey"> + [[i18n('certificateProvisioningPublicKey')]] + </div> + <div class="value" id="publicKey" aria-hidden="true"> + [[model.publicKey]] + </div> </div> </iron-collapse> </div>
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_list_item.html b/ui/webui/resources/cr_components/chromeos/network/network_list_item.html index 8a58ff8d7..a1bfbb7d 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_list_item.html +++ b/ui/webui/resources/cr_components/chromeos/network/network_list_item.html
@@ -24,11 +24,26 @@ } #divOuter { - margin-bottom: 8px; - margin-top: 8px; - min-height: 48px; + height: var(--cr-network-row-height, 48px); overflow: auto; + padding-bottom: var(--cr-network-row-padding-bottom, 0); padding-inline-end: var(--cr-icon-ripple-padding); + padding-top: var(--cr-network-row-padding-bottom, 0); + } + + :host([is-e-sim-pending-profile_]) #divText { + opacity: 0.4; + } + + :host(:not([is-e-sim-pending-profile_])) #divIcon { + height: 24px; + width: 24px; + } + + :host([is-e-sim-pending-profile_]) #divIcon { + height: 20px; + opacity: 0.4; + width: 20px; } #divDetail { @@ -53,24 +68,10 @@ color: var(--google-green-500); } - iron-icon :not(.esim-pending-profile) { - height: 24px; - width: 24px; - } - - iron-icon .esim-pending-profile { - height: 20px; - width: 20px; - } - cr-policy-indicator { padding: 0 var(--cr-controlled-by-spacing); } - .esim-pending-profile { - opacity: 0.4; - } - #wrapper { height: 100%; } @@ -106,11 +107,9 @@ </network-icon> </template> <template is="dom-if" if="[[item.polymerIcon]]"> - <iron-icon icon="[[item.polymerIcon]]" - class$="[[getItemClassName_(item, item.customItemType]]"></iron-icon> + <iron-icon id="divIcon" icon="[[item.polymerIcon]]"></iron-icon> </template> - <div id="divText" class$="layout horizontal flex - [[getItemClassName_(item, item.customItemType)]]"> + <div id="divText" class="layout horizontal flex"> <div id="networkName" aria-hidden="true"> [[getItemName_(item)]] </div> @@ -144,7 +143,7 @@ </cr-icon-button> </div> </template> - <template is="dom-if" if="[[isESimPendingProfile_(item, item.customItemType)]]" restamp> + <template is="dom-if" if="[[isESimPendingProfile_]]" restamp> <cr-button id="installButton" aria-label$="[[getItemName_(item)]], $i18n{networkListItemDownload}" on-click="onInstallButtonClick_">
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_list_item.js b/ui/webui/resources/cr_components/chromeos/network/network_list_item.js index f106d20..faeb93d 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_list_item.js +++ b/ui/webui/resources/cr_components/chromeos/network/network_list_item.js
@@ -72,6 +72,17 @@ }, /** + * Whether the network item is a cellular one and is of an esim + * pending profile. + */ + isESimPendingProfile_: { + type: Boolean, + reflectToAttribute: true, + value: false, + computed: 'computeIsESimPendingProfile_(item, item.customItemType)', + }, + + /** * The cached ConnectionState for the network. * @type {!chromeos.networkConfig.mojom.ConnectionStateType|undefined} */ @@ -368,7 +379,7 @@ 'networkListItemLabelWifi', index, total, this.getItemName_(), secured, this.item.typeState.wifi.signalStrength); default: - if (this.isESimPendingProfile_()) { + if (this.isESimPendingProfile_) { if (this.subtitle_) { return this.i18n( 'networkListItemLabelESimPendingProfileWithProviderName', index, @@ -504,7 +515,7 @@ if (this.isSubpageButtonVisible_(this.networkState, this.showButtons) && this.$$('#subpage-button') === this.shadowRoot.activeElement) { this.fireShowDetails_(event); - } else if (this.isESimPendingProfile_()) { + } else if (this.isESimPendingProfile_) { this.onInstallButtonClick_(); } else if (this.item.hasOwnProperty('customItemName')) { this.fire('custom-item-selected', this.item); @@ -572,21 +583,13 @@ * @return {boolean} * @private */ - isESimPendingProfile_() { + computeIsESimPendingProfile_() { return !!this.item && this.item.hasOwnProperty('customItemType') && this.item.customItemType === NetworkList.CustomItemType.ESIM_PENDING_PROFILE; }, /** - * @return {string} - * @private - */ - getItemClassName_() { - return this.isESimPendingProfile_() ? 'esim-pending-profile' : ''; - }, - - /** * @return {boolean} * @private */
diff --git a/weblayer/browser/subresource_filter_browsertest.cc b/weblayer/browser/subresource_filter_browsertest.cc index b0f77ef..5995af45 100644 --- a/weblayer/browser/subresource_filter_browsertest.cc +++ b/weblayer/browser/subresource_filter_browsertest.cc
@@ -4,6 +4,7 @@ #include "base/json/json_reader.h" #include "build/build_config.h" +#include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h" #include "components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h" #include "components/subresource_filter/content/browser/ruleset_service.h" @@ -15,6 +16,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/resource/resource_bundle.h" #include "weblayer/browser/browser_process.h" +#include "weblayer/browser/host_content_settings_map_factory.h" #include "weblayer/browser/subresource_filter_client_impl.h" #include "weblayer/browser/tab_impl.h" #include "weblayer/grit/weblayer_resources.h" @@ -89,8 +91,7 @@ protected: void SetRulesetToDisallowURLsWithPathSuffix(const std::string& suffix) { subresource_filter::testing::TestRulesetPair test_ruleset_pair; - subresource_filter::testing::TestRulesetCreator test_ruleset_creator; - test_ruleset_creator.CreateRulesetToDisallowURLsWithPathSuffix( + test_ruleset_creator_.CreateRulesetToDisallowURLsWithPathSuffix( suffix, &test_ruleset_pair); subresource_filter::testing::TestRulesetPublisher test_ruleset_publisher( @@ -114,6 +115,9 @@ ->client()); client_impl->set_database_manager_for_testing(std::move(database_manager)); } + + private: + subresource_filter::testing::TestRulesetCreator test_ruleset_creator_; }; // Tests that the ruleset service is available. @@ -294,6 +298,68 @@ EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); } +IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, + ContentSettingsAllowlist_DoNotActivate) { + auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents(); + + GURL test_url( + embedded_test_server()->GetURL("/frame_with_included_script.html")); + + ASSERT_NO_FATAL_FAILURE( + SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); + ActivateSubresourceFilterInWebContentsForURL(web_contents, test_url); + + NavigateAndWaitForCompletion(test_url, shell()); + EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + + content::WebContentsConsoleObserver console_observer(web_contents); + console_observer.SetPattern(subresource_filter::kActivationConsoleMessage); + + // Simulate explicitly allowlisting via content settings. + HostContentSettingsMap* settings_map = + HostContentSettingsMapFactory::GetForBrowserContext( + web_contents->GetBrowserContext()); + settings_map->SetContentSettingDefaultScope( + test_url, test_url, ContentSettingsType::ADS, CONTENT_SETTING_ALLOW); + + NavigateAndWaitForCompletion(test_url, shell()); + EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + + // No message for allowlisted url. + EXPECT_TRUE(console_observer.messages().empty()); +} + +IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, + ContentSettingsAllowlistGlobal_DoNotActivate) { + auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents(); + + GURL test_url( + embedded_test_server()->GetURL("/frame_with_included_script.html")); + + ASSERT_NO_FATAL_FAILURE( + SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); + ActivateSubresourceFilterInWebContentsForURL(web_contents, test_url); + + NavigateAndWaitForCompletion(test_url, shell()); + EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + + content::WebContentsConsoleObserver console_observer(web_contents); + console_observer.SetPattern(subresource_filter::kActivationConsoleMessage); + + // Simulate globally allowing ads via content settings. + HostContentSettingsMap* settings_map = + HostContentSettingsMapFactory::GetForBrowserContext( + web_contents->GetBrowserContext()); + settings_map->SetDefaultContentSetting(ContentSettingsType::ADS, + CONTENT_SETTING_ALLOW); + + NavigateAndWaitForCompletion(test_url, shell()); + EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + + // No message for loads that are not activated. + EXPECT_TRUE(console_observer.messages().empty()); +} + #if defined(OS_ANDROID) // Test that the ads blocked infobar is presented when visiting a page where the // subresource filter blocks resources from being loaded and is removed when
diff --git a/weblayer/browser/subresource_filter_client_impl.cc b/weblayer/browser/subresource_filter_client_impl.cc index ba3eebb..a99f17ce 100644 --- a/weblayer/browser/subresource_filter_client_impl.cc +++ b/weblayer/browser/subresource_filter_client_impl.cc
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "build/build_config.h" #include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h" +#include "components/subresource_filter/content/browser/profile_interaction_manager.h" #include "components/subresource_filter/content/browser/ruleset_service.h" #include "components/subresource_filter/core/browser/subresource_filter_features.h" #include "components/subresource_filter/core/common/activation_decision.h" @@ -18,6 +19,7 @@ #include "content/public/browser/render_frame_host.h" #include "weblayer/browser/browser_process.h" #include "weblayer/browser/safe_browsing/safe_browsing_service.h" +#include "weblayer/browser/subresource_filter_profile_context_factory.h" #if defined(OS_ANDROID) #include "components/safe_browsing/android/remote_database_manager.h" @@ -53,7 +55,12 @@ #if defined(OS_ANDROID) web_contents_(web_contents), #endif - database_manager_(GetDatabaseManagerFromSafeBrowsingService()) { + database_manager_(GetDatabaseManagerFromSafeBrowsingService()), + profile_interaction_manager_( + std::make_unique<subresource_filter::ProfileInteractionManager>( + web_contents, + SubresourceFilterProfileContextFactory::GetForBrowserContext( + web_contents->GetBrowserContext()))) { } SubresourceFilterClientImpl::~SubresourceFilterClientImpl() = default; @@ -87,16 +94,6 @@ #endif } -subresource_filter::mojom::ActivationLevel -SubresourceFilterClientImpl::OnPageActivationComputed( - content::NavigationHandle* navigation_handle, - subresource_filter::mojom::ActivationLevel initial_activation_level, - subresource_filter::ActivationDecision* decision) { - DCHECK(navigation_handle->IsInMainFrame()); - - return initial_activation_level; -} - void SubresourceFilterClientImpl::OnAdsViolationTriggered( content::RenderFrameHost* rfh, subresource_filter::mojom::AdsViolation triggered_violation) {} @@ -106,4 +103,9 @@ return database_manager_; } +subresource_filter::ProfileInteractionManager* +SubresourceFilterClientImpl::GetProfileInteractionManager() { + return profile_interaction_manager_.get(); +} + } // namespace weblayer
diff --git a/weblayer/browser/subresource_filter_client_impl.h b/weblayer/browser/subresource_filter_client_impl.h index 1debbf2..cceb5d2 100644 --- a/weblayer/browser/subresource_filter_client_impl.h +++ b/weblayer/browser/subresource_filter_client_impl.h
@@ -43,15 +43,13 @@ // SubresourceFilterClient: void ShowNotification() override; - subresource_filter::mojom::ActivationLevel OnPageActivationComputed( - content::NavigationHandle* navigation_handle, - subresource_filter::mojom::ActivationLevel initial_activation_level, - subresource_filter::ActivationDecision* decision) override; void OnAdsViolationTriggered( content::RenderFrameHost* rfh, subresource_filter::mojom::AdsViolation triggered_violation) override; const scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> GetSafeBrowsingDatabaseManager() override; + subresource_filter::ProfileInteractionManager* GetProfileInteractionManager() + override; void OnReloadRequested() override; // Sets the SafeBrowsingDatabaseManager instance used to |database_manager|. @@ -70,6 +68,8 @@ std::unique_ptr<subresource_filter::ContentSubresourceFilterThrottleManager> throttle_manager_; scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager_; + std::unique_ptr<subresource_filter::ProfileInteractionManager> + profile_interaction_manager_; }; } // namespace weblayer